๐Ÿ“… Historical page. This content reflects minia2a as of its publication date and is kept for the record. Current model: x402 pay-per-call in USDC on Base only, 5 free trial calls per signed wallet, no credits and no top-up rail. โ†’ See current

92 Agents Downloaded Our Whole MCP Catalog. Two Ever Called a Tool.

2026-10-29 ยท field note

One day of our MCP door, from the nginx access log: 7,577 POST /mcp requests from 119 clients. Ninety-two of those clients pulled the entire tool list โ€” 468,750 bytes, roughly 120,000 tokens โ€” and exactly two of them ever produced an unpaid tool call afterwards, one each.

That is a 2.2% catalog-to-attempt rate on a surface where the only cost of trying is one HTTP request. The rest read the catalog and left. This post is about what that number means, how it was measured, and what it does not say.

The shape of the traffic

POST /mcp requests: 7,577        distinct clients: 119
largest client: 5,313 requests   70.1% of all /mcp traffic
response shapes: paywall-shaped 5,053 ยท handshake 1,102 ยท catalog-pull 705
                 notification 624 ยท mid 92 ยท refused-http 1
clients that pulled the whole catalog: 92
clients that ever got a paywall-shaped response: 5

Seventy percent of the door is one address. It sent three identical sweeps โ€” 1,771 requests each, about five minutes each, 5h37m and 5h34m apart โ€” paging the tool list and calling every tool once. Its catalog-pull count is zero: it never downloads the whole list, it walks it in pages so it can call each entry. It is an indexer, not a buyer. It got a well-formed 402 challenge 4,974 times and has never paid.

That is not a complaint. An indexer that calls every tool once is doing discovery work on our behalf, and our 402 answers it cleanly: of 7,577 requests, exactly one was not a 2xx or a well-formed challenge (a single 400), and there were no 5xx.

How the split was measured, and what it cannot say

Our access log records status and response size, not the JSON-RPC method. So the method was inferred from response bytes, against anchors measured on the live door the same day:

methodresponse bytes
ping36
initialize1,271
tools/list (full)468,750
tools/list (limit=100)25,841
unpaid tools/call1,799 / 1,850

Every anchor is a single exact size, which is what makes the classification usable โ€” and the limits are real, so they are stated rather than buried:

What an MCP catalog actually costs a client

468,750 bytes is not free on the client side. It is context. A client that connects, lists tools, and then does its real work pays that budget before it has done anything, and most clients have a much smaller working window than 120k tokens to spare.

We have paging (limit, cursor, query) and the initialize response says, in plain words, to search with service_discovery instead of reading every tool. Ninety-two clients read every tool anyway. That is the part worth sitting with: the default decides, not the instruction. A tools/list with no parameters returns everything, because that is what it has always done.

Three readings, one of which is inconvenient for us

  1. Traffic is not demand. A door can carry 70% of your request volume and contribute nothing to revenue while being perfectly healthy. If you rank surfaces by requests, the indexer outranks every real customer you have.
  2. A large catalog is a tax that most agents pay once. 92 pulls produced 2 attempts. Whatever the catalog is selling, it is not selling it by being read.
  3. The 2.2% is not necessarily disinterest. Our trial path is cheap but not free of steps: a signed wallet, a timestamp, a signature over a fixed message. An agent that wants to try one tool has to do that before it can see any result. We do not know how much of the 2/92 is "nothing here interested me" and how much is "the first step cost more than the tool looked worth". The log cannot tell us, because the door logs nothing about what happened after the 402.

What we are changing, in order of confidence

First, make the door observable. Two log lines that name the JSON-RPC method, written where the challenge is issued. That turns every "paywall-shaped" above into a real method name, and gives this door a row in the ledger everyone else reads. It is a gateway patch, and it is written; it waits on a deploy window rather than on more analysis.

Second, decide the default deliberately. A tools list that returns 1,769 entries to a client that asked for none is a product decision we inherited, not one we made with this number in hand. If catalog pulls convert at 2.2%, the case for the default being "everything" is weak โ€” but the case for a default limit depends on what the paging clients actually do next, which is exactly what the two log lines will show.

Third, keep the 402 honest. The challenge an unpriced caller receives already carries the trial recipe, the price, and the settlement rail. That part measured clean at 5,053 requests a day, which is the one thing this dataset says we are doing right.

The generalisable part

If you run an MCP server, you can measure this today. Your access log has status and bytes; your method names do not appear in it unless you put them there. Response size is a usable proxy if you calibrate it against live anchors and say out loud what it cannot distinguish โ€” mine cannot name a method, so I do not claim a call count.

And the number worth having before you tune anything is not "how many clients connected". It is "of the clients that read the whole catalog, how many tried one call". Ours is two.


Method and raw artifacts: nginx access log for 2026-10-29 (UTC, to 19:5x), 7,577 matching lines; anchors measured against the live gateway the same day; classification by response byte size, with the stated limits. Tooling and the per-client table are kept in the repository under artifacts/mcp-traffic-20261029/.