Metrics endpoint
A POST-only endpoint that runs aggregations and group-bys against any registered model. Useful for charts, dashboards, scheduled reports.
How it ships
get_routes() automatically registers POST /metrics (the Metrics resource from zeromcp/calc_resource.py). It is authenticated and uses the active tenant DB.
Request body
POST /metrics
{
"model": "myapp.Order",
"calc": {"formula": ["sum"], "field": "total"},
"group_by": {
"fields": ["status"],
"date": {"field": "created_at", "group_by": "month"}
},
"filter_by": {
"fields": {"active": true},
"period": {"field": "created_at", "value": "this_month"}
},
"conditions": { ... },
"additional_fields": ["currency"],
"order": ["-period"],
"limit": 100,
"distinct": false,
"raw": false,
"extra": {"select": {"hour": "EXTRACT(hour FROM created_at)"}}
}Aggregations (calc.formula)
| Formula | Django function |
|---|---|
count | Count |
sum | Sum |
avg | Avg |
min | Min |
max | Max |
variance | Variance |
std dev | StdDev |
Multiple formulas can be combined: ["count", "sum"].
Group-by
Two axes:
group_by.fields— list of model fields to group ongroup_by.date—{field, group_by}wheregroup_byis one ofyear,quarter,month,day,weekday,weekday_hour,hour
Date groupings respect USE_TZ and the user's timezone — the SQL converts UTC timestamps to the target tz.
Field arithmetic
calc.field accepts a list to build arithmetic expressions:
{"formula": ["sum"], "field": ["price", "*", "qty"]}Allowed operators: +, -, *, /. Field names must match [a-zA-Z_][a-zA-Z0-9_]* with __ for traversal. Anything else raises ValueError.
Period filters
filter_by.period accepts presets:
| Value | Range |
|---|---|
today | 00:00 to 23:59 in the user's tz |
yesterday | previous day |
this_week / last_week | ISO week |
this_month / last_month | Calendar month |
this_year / last_year | Calendar year |
<int>d / <int>m / <int>y | Sliding window — last N days/months/years |
Filtering
Two layers compose:
conditions— full JSON filter expression (same shape as?filter=on resources). Goes throughOrmFilter.filter_by.fields— flat dict offield: valueANDed together. Special keyor_conditionsaccepts a list of dicts joined with OR.
Output
Without group-by — single object:
{"sum__total": 12345.67, "count__id": 423}With group-by — list + keys:
{
"data": [
{"period": "2026-01", "status": "paid", "sum__total": 1000},
{"period": "2026-01", "status": "pending", "sum__total": 200}
],
"keys": ["period", "status", "sum__total"]
}Key renaming
Pass a keys map to rename keys in the response:
{"keys": {"sum__total": "Revenue", "period": "Month"}}Metrics is a single endpoint that replaces dozens of bespoke aggregation routes. Build chart panels, scheduled emails, finance reports — all on top of the same shape.
0-mcp by Stamatios Stamou Jr — github.com/ssjunior/0-mcp