Skip to content

Token Economy

If an agent operates your CMS, the cost of operating it is measured in tokens. That makes response size a product property, not an implementation detail, so Shio treats it like one: every response on the agent surface has a declared ceiling, and a build that makes a response bigger fails.

This page is what a call costs, how to make it cost less, and what the project measures itself against. It also publishes the two numbers that are less flattering than a reader might expect, with the reasons, because a cost that is argued rather than measured is a defect.


The budgets live in one file in the repository, in estimated tokens, using the same 4-characters-per-token heuristic the instance itself reports:

Response Budget (est. tokens)
tools/list (the whole MCP tool catalogue) 2375
…per tool 460
MCP initialize 200
GET /agent/manifest 2650
…?format=terse 2400
Context pack, per site row (terse) 145
Context pack, per site row (JSON) 220
Context pack, per site row (agents-md) 430
Context pack, per post-type row 25
find, per row (terse) 110
read, per row (terse) 60
verify, per finding (terse) 60

Two things about the table are the point rather than the detail:

  • tools/list is the most expensive fixed cost on the surface, because it is re-sent on every turn of every session before any work happens. That is why the tool count is capped and why some capabilities are a parameter on an existing tool instead of a tool of their own.
  • Raising a budget is allowed, and is meant to be visible. It is a reviewable edit with a reason in the commit message. What is not allowed is a response quietly growing.

Every response also carries an X-Shio-Est-Tokens header, so you can measure your own traffic without guessing.


Most reads take ?format=terse and answer in plain text instead of JSON:

GET /api/v2/agent/find?site=mysite&type=Article&format=terse

On listing-shaped responses (find, read, verify, changes, a change set) this saves roughly a third to a half.

Instead of Use
The whole manifest ?include=limits,features: only the sections you need
The whole context pack ?include=model or ?include=sitemap, and ?budget=<n>
A whole document GET /agent/read?fields=TITLE,ABSTRACT
Every row limit=, then walk with after=<cursor>
Object ids you will not use nothing, ids are off by default, because an id is the most expensive field a row can carry

Every read that supports it answers 304 Not Modified to an If-None-Match whose tag still matches:

GET /api/v2/agent/changes?since=<cursor>
If-None-Match: "…"

A 304 costs a round trip and no body. This is what makes polling the change feed cheap enough to do often, and the reason to walk the feed with since= rather than reading the window: a windowed read is a moving edge and can never be unchanged, while a cursor-based read of an unchanged range is byte-identical and free.

POST /api/v2/agent/batch?verify=true&digest=true

The lint report and the render digests come back with the write, instead of costing two more calls. The whole point of the surface is that a task is three or four calls, not thirty.


One GET /agent/context returns the content model, the sitemap by path, and the conventions earlier sessions recorded. Without it, an agent discovers the same facts by listing sites, listing folders, reading a sample post to infer a shape, and asking for post types, several round trips whose answers it then has to hold.

The project measures that as an attribution ratio per source, rather than as one headline number, because an aggregate mixes savings and names none:

Source of the saving Fewer calls Fewer tokens
Discovery (the context pack vs exploring) ≥ 40× ≥ 11×
Path addressing instead of id round trips ≥ 20× ≥ 500× at scale
The lint instead of a round trip to a person ≥ 50× ≥ 150×

Those are floors asserted in CI against a console-shaped baseline, and the scale rows are required to rise with fixture size rather than being asserted at one size: a claim that a saving grows has to be measured at two sizes or it is not a claim.


Four canonical tasks are run against the real instance on every build, and both their call count and their token cost are held:

Task Calls Est. tokens
Fix a broken link 3 400
Build a marketing site 4 2700
Translate a site 3 800
Add a post type and 10 posts 3 1800

Four calls to build a site is the number worth internalising: a session, not a conversation.


Instance memory: the cheapest call is the one you do not repeat

Section titled “Instance memory: the cheapest call is the one you do not repeat”
PUT /api/v2/agent/memory

A decision an earlier session worked out: a naming convention, a layout choice, why a field exists, is stored on the instance and comes back in the context pack. Re-using a key rewrites that note rather than adding a second one, because the next session pays for every near-duplicate it has to reconcile.

Over a long-lived site this is the largest saving available, and the one nothing can measure for you.


Page Description
The Agent Surface Every endpoint, and the parameters named above
MCP Server Why there are twelve tools and not twenty
Configuration Reference The shio.agent.* limits behind these numbers
The shio CLI shio context, and the CI gates