Time series for agents

When a tool, an MCP response or an API returns a time series that an agent will read, return the points as CSV under a header the server computes.

The shape to return

A response has two parts: a header of facts the server already knows, then the points.

The header carries, as comment lines:

The points follow as CSV with ISO 8601 UTC timestamps, one row per bucket. A missing bucket is an empty field, never a zero. A status column carries partial on the bucket that is still filling.

# range: 2026-10-04T14:00:00Z to 2026-10-06T14:00:00Z, 48 buckets of 1 hour, UTC; timestamps are bucket starts
# now: 2026-10-06T14:00:00Z
# series transaction_count{namespace=api}
#   counter: each value is the count within its bucket (a sum, not cumulative); unit: requests
#   peak 15,098 at 2026-10-04T14:00:00Z; low 8,751 at 2026-10-06T02:00:00Z; mean 11,941; total 537,332
#   3 buckets have NO DATA (missing, not zero): 2026-10-05T10:00:00Z to 2026-10-05T13:00:00Z
# missing buckets are empty fields; `partial` marks an incomplete bucket
timestamp,transaction_count{namespace=api},status
2026-10-04T14:00:00Z,15098,
2026-10-04T15:00:00Z,14667,
2026-10-04T16:00:00Z,15050,
...
2026-10-05T09:00:00Z,9412,
2026-10-05T10:00:00Z,,
2026-10-05T11:00:00Z,,
2026-10-05T12:00:00Z,,
2026-10-05T13:00:00Z,9876,
...
2026-10-06T13:00:00Z,14729,
2026-10-06T14:00:00Z,3105,partial

The header is what the server works out. The points underneath are plain CSV. An agent that only reads uses the header; an agent with a shell parses the points and can still check its work against the header.

What to avoid

Don't fill a missing bucket with zero

A zero is a measurement and a gap is the absence of one. An agent that sees zeros reports an outage where there was a collection gap, and computes a mean that is too low. Leave the field empty and name the gap in the header.

Don't send a summary with no points

A summary written by the server can only answer the questions its author anticipated. It cannot say what one bucket held, the median over a window, or the ratio of two series at one hour. A shell does not help, because there is nothing to compute over.

Don't send epoch timestamps

An agent reading a raw payload converts epochs by eye and gets the hour wrong. ISO 8601 costs more tokens than a ten-digit epoch and removes the arithmetic.

Don't rely on an image or a sparkline

Agents in coding harnesses work from printed numbers and rarely open a plot they made. A sparkline also throws away the exact values most questions ask for. An image can accompany the numbers; it cannot replace them.

Why this shape

The header answers the questions agents most often get wrong from raw data. Without it, agents read a gap as zero, a per-bucket count as a rate, a partial bucket as a drop, and an epoch as the wrong hour.

The header follows the one Sentry's MCP server returns, with one deliberate difference. Sentry prints a missing bucket as zero, and this format leaves it empty, because an agent cannot tell a zero from a real measurement.

Send the header even when the agent has a shell. An agent with a shell can parse any format, but it still makes mistakes the header prevents, such as differencing per-bucket counts as if they were a cumulative counter. Running code also costs several times the tokens and time of reading the response directly.

The research behind this page, including its tasks, data and results, is in the timeseries arena in the appsignal/design repository.