cd /news/ai-agents/one-tools-list-call-cost-529-kb · home › topics › ai-agents › article
[ARTICLE · art-167515] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=· neutral

One tools/list call cost 529 KB

A developer measured their MCP server's tools/list response at 529,287 bytes — roughly 132,000 tokens — for 1,859 tools, a payload that grew 90 KB in 20 days as 148 services were added. Because clients build the request themselves, opt-in pagination (limit, cursor, category, query) never helped, so the team changed the default so that a request with no limit, including no params at all, returns the first 100 tools plus a nextCursor. Usage data across 1,675 called services showed the first 100 tools cover 89.4% of usage rows, versus 84.5% for 50 and 93.1% for 200.

by read5 min views1 publishedNov 11, 2026

November 2026

MCP clients do not ship a catalogue to the model once and cache it. They ask the server for tools/list, and whatever comes back is what the model gets to see — every session, as part of its context. For a server with a dozen tools that is a few kilobytes and nobody thinks about it. For a server that maps a marketplace — one tool per service — it is a different object entirely.

On 11 November 2026 we measured ours, on the live endpoint, with the request a stock client sends:

POST /mcp  {"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}

→ 200, 529,287 bytes, 1,859 tools, no nextCursor

529 KB, at roughly 4 bytes per token, is about 132,000 tokens — before the system prompt, before the user's question, before a single tool is called. That is larger than the context window of a good number of the models these clients are wired to. On 22 October the same call was 439,656 bytes over 1,711 tools. It grew 90 KB in 20 days, because the catalogue grew by 148 services.

Nothing crashes. That is the problem. A client with a smaller budget truncates the list, or leaves it out, or the model sees the first few hundred tools and treats the rest as absent. The failure mode is not an error message — it is an agent that connected successfully, saw a partial catalogue, and called something else. From the server side that looks like "nobody uses this", and it is indistinguishable from having no demand.

The same thing happens at a much smaller scale whenever a tool's inputSchema is verbose. We once shipped an object-level description on every tool; it added 212 KB to the payload — one sentence repeated 1,610 times. It was reverted the same day. Tool-list cost is the sum of per-tool costs, and per-tool costs are usually decided by whoever wrote the last schema.

Our tools/list has accepted limit, cursor, category and query since 26 October, with the cursor bound to the filters that produced it (reusing a cursor after changing the filter is refused, not silently applied to another result set). Measured the same day:

params bytes tools returned ≈ tokens
{} 529,287 1,859 ≈ 132,000
{"limit":200} 53,008 202 ≈ 13,000
{"limit":100} 27,977 102 ≈ 7,000
{"limit":50} 14,427 52 ≈ 3,600
{"limit":20} 6,306 22 ≈ 1,600

So the fix looked like it already existed. Except that the feature was strictly opt-in: a request without params returned the whole list, byte for byte as before, because that was the compatibility promise made when paging landed. The real decision — what does a client get when it asks for nothing? — was deferred, and "deferred" meant "the 529 KB answer".

MCP hosts do not let a user say "please pass limit: 100". The client builds that request. A server that pages only on request is a server that pages only for callers who already knew to ask.

We are changing the default so that no limit — including no params at all — returns the first page of 100 service tools plus nextCursor, and the rest come from following the cursor. Explicit limit is unchanged, up to the existing 500 ceiling. Three properties keep this from being a downgrade:

trial_count DESC, id since an earlier fix, so the ordering is already a popularity ranking.tools/call resolves a name against the active catalogue; it never checked whether that name appeared in the list you were served. A model can search, get an id from service_discovery (still the first tool in the list), and call it. We measured how concentrated usage actually is, across the 1,675 services that have ever been called (50,393 usage rows):

first page usage rows covered share
50 tools 42,580 84.5%
100 tools 45,060 89.4%
200 tools 46,894 93.1%

Going from 50 to 100 buys 4.9 points for about 14 KB; going from 100 to 200 buys 3.7 points for another 28 KB. 100 is where the curve bends. The row counts are not independent callers — bots and our own probes inflate them — but the decision needs the relative shape, and the shape is stable.

The honest cost of this change: a client that never follows nextCursor will now see 100 tools instead of 1,859. That is deliberate. Today that same client sees a 529 KB list that, in practice, it truncates anyway — except now the truncation is at a boundary we chose and the client can see, with a cursor that says there is more. We would rather be the server that says "here is page one" than the server that hands over a payload larger than the context and lets the client decide what to drop.

tools/list bytes, not your tool count. The change is written, reviewed against the deployed source, and covered by a test that seeds more services than the default page holds — so a future edit that raises the default, or removes it, fails instead of silently restoring the 529 KB answer. It is queued behind the gateway binary deploy; this post will be updated with the live before/after when it ships.

Originally published at minia2a.uk.

── more in #ai-agents 4 stories · sorted by recency
── more on @mcp 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/one-tools-list-call-…] indexed:0 read:5min 2026-11-11 · —