Both convert at
bytes / 4 tokens and $3 per million input tokens, from one constant.
1. Read cost per session first
It is on the overview, and it is the number someone deciding whether to keep your server installed will quote back to you. It falls when either half falls: fewer bytes per call, or fewer calls per session. Improving first-call success does the second, because a retried call is a call the session paid for twice.2. Fix the heavy tools
Open tool health and look at avg response and the heavy payload badge, which fires above 10,000 bytes. Work down by calls × average bytes, not by average alone — a 40kB tool called twice matters less than a 12kB tool called nine hundred times. The heavy payload insight states both figures for exactly this reason. Then, in the order they usually pay off:1
Return fields, not records
A row with 40 columns costs 40 columns of context. Return what the model needs to answer the next question, and offer a
get_x for the full record.2
Add a limit, and default it low
A default of 10 with an explicit
limit argument beats a default of 100. The model can ask for more and usually will not need to.3
Stop pretty-printing
JSON.stringify(x, null, 2) is more bytes than JSON.stringify(x), and no model reads the indentation.4
Stop echoing the request
The model already has the arguments it sent. Returning them alongside results doubles small responses.
5
Summarise where a summary answers it
A count plus five examples often beats four hundred rows — and if it does not, narrowing and asking again costs far less than the four hundred rows would have.
3. Then fix the schema
This is the cost that is invisible without instrumentation, because nothing in the protocol reports it back. Every registered tool is sent to the model at the start of every session. Forty tools averaging 400 bytes is 16kB — roughly 4,000 tokens — before a single question is answered, paid by every user, forever.- Dead tools first. Pure loss: schema cost, zero use.
- Then the largest schemas. Over 1,500 bytes is worth a look — usually a deeply nested optional object or a long enum. Long descriptions are generally worth their bytes; deep optional nesting generally is not.
- Then the tool count itself. Sixteen near-identical tools over one underlying query cost sixteen schemas every session and give the model sixteen chances to choose wrong.
get_overview({ metrics: ["calls"] }) returns calls and nothing else — one schema, one round trip, a small answer.
4. Measure it
Response size and cost are live — no nightly lag — so a deploy is visible as soon as traffic arrives. Set the range to the period after the change. The cost-per-session card compares against the preceding window of equal length, and treats a rise as the bad direction.Under a tool filter, cost per session goes blank. Sessions have no tool dimension, so there is no denominator to divide by.
total_cost_usd still narrows.