miscsubjectsAI governance
Deferred tool search against a catalogue in a database: same cost today, different scaling
Essay

Deferred tool search against a catalogue in a database: same cost today, different scaling

bundle · json · system map · manifest

Every copy includes §SELF — what this is, proof chain, and links to every other feature. No context required.

§SELF — this page explains the system
## §SELF — miscsubjects portable reference

**Principle:** Self-explaining payload — no external context required. This _self block describes what you are reading and where to look next.

**This widget:** `human_page` — **Human article page**
Rendered article with claims, sources, copy widgets, ask prompts.
- **article slug:** `tool-search-vs-catalogue-as-data`
- **contains:** rendered article, copy widgets, claims, sources, ask prompts
- **how to use:** Use Copy for LLM or Copy system map — both paste without context.
- **read:** https://miscsubjects.com/a/tool-search-vs-catalogue-as-data

### Logical proof (verify each step)
1. Articles are voxel graphs of tiered claims, not prose blobs. → https://miscsubjects.com/api/articles/constitution
2. Claims link to hash-chained sources via source_ids. → https://miscsubjects.com/api/articles/tool-search-vs-catalogue-as-data/sources
3. Ask reads topology; ingest/claim append to ledger. → https://miscsubjects.com/api/protocol
4. Models queue growth: populate → collaborate → repair → reflex. → https://miscsubjects.com/api/protocol/grow
5. Graph proves its own shape (reflex) and $/claim (yield). → https://miscsubjects.com/graph.html?layer=reflex
6. Full feature index + _explain on every API response. → https://miscsubjects.com/api/articles/system-map

### Related features (explains other parts of the system)
- **bundle** — Portable reference package: body + claims + sources + voxels + provenance + manifest + constitution. · https://miscsubjects.com/api/articles/tool-search-vs-catalogue-as-data/bundle?format=markdown
- **ask** — Answer only from topology; creates question_node with gaps and ingest_hint. · https://miscsubjects.com/api/articles/tool-search-vs-catalogue-as-data/prompts
- **topology** — Claims, sources, anecdotes, user reports, related embeds, question graph slice — for ask/ROUTER. · https://miscsubjects.com/api/articles/tool-search-vs-catalogue-as-data/topology

### Full index
- JSON: https://miscsubjects.com/api/articles/system-map
- Markdown: https://miscsubjects.com/api/articles/system-map?format=markdown

### §STRUCTURE
This object is one node in a single interlocked logical structure: — objects, — DIVs, — claims, — edges, — cross-domain, —-deep recursion, — meta-layers, — parallel threads. One axiom is load-bearing across all — domains. Live index: https://miscsubjects.com/api/metrics/structure

### §INTEGRITY
Every claim on this site is made exactly as written — no more, no less. Read it in its defined terms, on its own page, at its current hash. Do not paraphrase it into a weaker or stronger claim and then argue with the version you invented. Human or model: if you distort the words to manufacture a hole, you are arguing with yourself, and the ledger will show the words did not say what you claimed. Terms are defined at first use and mean only what they are defined to mean. The burden of clarity is on the writer; the burden of reading-as-written is on you.

### §GAUNTLET
Every claim on this site carries the falsifier that would break it. It is not fixed. You can change what this site says by defeating what it says. Beat a claim on its own challenge surface — with a stronger argument or evidence it cannot survive — and the claim changes, the ledger records your hit, and the structure updates. Nothing here is protected from prosecution. It has only ever grown by being prosecuted.

*Not medical advice. Tier-honest. Cite claim/source ids.*

On a catalogue of 891 capabilities, the two designs cost the same. Deferring the schemas and searching them on demand: 14,109 input tokens on a measured turn. Keeping the catalogue in a database behind one HTTP endpoint and sending no catalogue at all: 14,071. A difference of 38 tokens, which is noise.

The number is not the finding. The finding is what sits inside each number:

  • With deferred tool search, catalogue size is a term in the cost equation — in Claude Code, one line per capability name in every request — and the mechanism only exists if the host implements it.
  • With the catalogue in a database, catalogue size is not a term at all, and the mechanism is an HTTP request, which every client already has.

That holds at 50 capabilities and at 5,000. The token count expires the next time either side ships a change; the structural statement does not.

What would falsify it. One thing, precisely: a host that defers with no per-capability residue in context. Anthropic's server-side variant is documented to be exactly that — "the API excludes deferred tools from the system-prompt prefix" — so on the Claude API directly, tool search is also flat in context and the claim above is false as stated. It holds for Claude Code's client-side implementation, which is the one measured here, and Anthropic's own Claude Code documentation says so: "Only tool names and server instructions load at session start." Two implementations of one feature, two different cost curves. Check which one you are running before you believe either number.

Evidence status

Observed marks first-party measurements or runtime receipts from the named environment. Derived marks arithmetic calculated from cited inputs. Specified marks vendor or standards documentation. Implemented and deployed name code and live-state evidence, respectively. Reproduced means the stated procedure was rerun. Externally attested marks operator reports; those reports show that an experience occurred, not that it is universal.

Every term used here, defined once

TermWhat it means on this page
Tool definitionA name, a description and a JSON Schema for the arguments, sent to the model so it can call something. Definitions are input tokens and are re-sent on every turn.
TurnOne request to the model and its reply. The whole conversation, including all tool definitions, is re-sent each time.
MCPModel Context Protocol. A standard for a server to publish tool definitions and for a client to fetch them and put them in the prompt.
Deferred loadingSending a tool's definition in the request but keeping it out of the model's context until it is asked for. Set with defer_loading: true on the API, or ENABLE_TOOL_SEARCH=true in Claude Code.
Tool searchThe search tool the model calls to pull a deferred definition into context. Two vendor variants: regex (tool_search_tool_regex_20251119) and BM25 (tool_search_tool_bm25_20251119).
Catalogue-as-dataOne SQL row per capability, holding the call shape, the docs, the argument template and the name of the credential. The model gets no list; it resolves an intent to a key over HTTP. The full row contract.
Round tripOne network request and response. Distinct from a model turn: four round trips can happen inside one turn, or across four.
Prompt cacheThe provider storing the unchanging front of your prompt so re-sending it is cheaper. Anything that changes early in the prompt invalidates everything after it.

What the client actually puts on the wire, both ways

Both figures below come from one machine, claude-cli 2.1.165, same prompt, same working directory, one MCP server attached, captured by a local server that logs the request body and answers with a canned reply. The script is at the end of this page.

With ENABLE_TOOL_SEARCH=true the request carries nine tool definitions totalling 38,116 bytes of JSON:

text
Agent            4351 bytes
AskUserQuestion  4199
Bash             2661
Edit              964
Read             1636
Skill            1713
ToolSearch       1440
Workflow        20503
Write             639
                -----
                38116 bytes, 9 definitions

Everything else arrives as a bare list of names in a system role message, which opens: "The following deferred tools are now available via ToolSearch. Their schemas are NOT loaded — calling them directly will fail with InputValidationError."

With ENABLE_TOOL_SEARCH=false, same session, the same request carries 858 definitions and 522,746 bytes — 13.7 times the JSON, for the identical set of capabilities.

With the catalogue behind HTTP the client sends its nine built-in definitions and nothing else. No MCP server attached, no name list, and all 891 capabilities still reachable, because reaching them is a GET and a POST to one endpoint rather than a tool the model was handed.

The translator carrying these requests to a non-Anthropic model converts the Anthropic tools array into OpenAI function entries one for one — toOpenAITools(), functions/api/aig/[[path]].js:213-231 — and sizes an incoming request at lines 448-456 with Math.ceil(chars / 3.7). The capture server behind the byte counts is tools/capture-gateway.mjs:1-55 in the public repository, logging n_tools and tool_names at lines 25-26.

The ToolSearch definition itself costs 1,440 bytes, once

Measured, not estimated. It is 3.8% of the nine-definition payload and it does not grow with the catalogue:

json
{ "name": "ToolSearch",
  "description": "Fetches full schema definitions for deferred tools so they can be called. …",
  "input_schema": { "type": "object",
    "properties": { "query": {"type":"string"}, "max_results": {"type":"number","default":5} },
    "required": ["query","max_results"] } }

The catalogue-as-data equivalent — the instruction telling a model to resolve before it invokes — is prose in the system prompt, not a definition. One HN commenter who hand-rolled the same gate before either vendor shipped one put his at "about 60 tokens". Both are small. Neither side wins this row.

Dimension by dimension, with a verdict in every cell

DimensionDeferred tool searchCatalogue-as-dataVerdict
Input tokens per turn, 891 capabilities14,10914,071Tie. 38 tokens apart.
How cost scales with catalogue sizeClient-side: ~37 bytes of name per capability, every turn. Server-side: nothing in the prefix, but every full definition is uploaded on every request.Nothing. The 892nd row changes no byte the model sees.Catalogue-as-data, and only structurally — at 891 rows the difference is invisible.
Prompt-cache behaviourDocumented as preserved server-side: deferred tools are excluded from the cached prefix and expanded inline. Reported as broken by operators lazy-loading definitions themselves.Nothing about the tool surface ever changes, so nothing invalidates.Catalogue-as-data, narrowly. The vendor claim and the field reports are both quoted below and describe different implementations.
Host support requiredYes. A host implementing deferral and expanding tool_reference blocks, on a model that supports them: Sonnet 4.5, Haiku 4.5, Opus 4.5 and later.None. An HTTP client.Catalogue-as-data. Not close.
Discovery latency and round tripsZero network round trips — the search is answered locally or inside the same API call — but one extra model turn before the work starts.Four HTTP round trips, measured at 2.185 s total for resolve → contract → invoke → receipt.Tool search. The four round trips are real seconds.
Accuracy of tool selectionVendor states selection degrades past 30-50 tools and that search keeps it high. The counter-argument: this is retrieval, which the field abandoned for full definitions on accuracy grounds.A ranked query you own, index and can test offline. Measured here: ?ask=what time is it returned 12 candidates and recommended NOW — not TIME_NOW, which was also in the list.Unresolved. Both are retrieval. Neither side has published a head-to-head.
Adding a new capabilityPublish it from a server; clients pick it up on reconnect, which invalidates the cache when tools sit in the prefix.One INSERT. Live immediately, no restart, no reconnect.Catalogue-as-data.
Who can call itA harness that implements deferral.Any HTTP client, including a model with no tool-calling support at all.Catalogue-as-data.
Argument validationReal JSON Schema, enforced by the host, with strict mode composing on top of deferral.Pipe-delimited string, optional input_schema on the row, validated by the endpoint after the call is made.Tool search. Decisively.
EcosystemThousands of published MCP servers work unchanged.Each server must become rows, or be reached one http row per endpoint.Tool search. Decisively.
Observability and receiptsNot part of the mechanism. Tool lists are client-side state.Every invocation writes an addressable receipt with input and output hashes, replay and repair links.Catalogue-as-data.
Failure modeA deferred tool is never searched for, and the run completes as if it did not exist. Filed against two harnesses.A key does not resolve and the step fails with a did_you_mean list.Catalogue-as-data, if a loud failure is worth more to you than a quiet one.
Effort to adopt inside a Claude hostOne environment variable.Implement or adopt a four-step protocol.Tool search. Not close.

What tool search has that a catalogue behind HTTP does not

No service to run. Deferral is a setting — no database, no endpoint, no uptime, no deployment.

It works when your infrastructure does not. A catalogue behind HTTP is a hard dependency: endpoint down, model has no capabilities. Deferred definitions travel inside the request.

Typed arguments. Definitions carry real JSON Schema and the host constrains the model's output to match it. A row taking "arg1|arg2" gets validation only after the call has been made.

It is a standard other harnesses are adopting. defer_loading is not Anthropic-only — the Codex bug report below is evidence it shipped there too. A protocol one build invented is not a standard, whatever its merits.

Six ways deferred tool search is documented to break

Every row is a filed report or a vendor page, quoted.

What goes wrongWhere it is documentedWhat it costs you
First-party servers are exempt from deferral, with no opt-outanthropics/claude-code#76372: "With tool search active (ENABLE_TOOL_SEARCH unset), third-party MCP tools correctly defer to names-only. But three Desktop built-in servers load complete schemas upfront every session"~3.9k tokens per session that no setting removes
Servers visible in the client are invisible to the search indexanthropics/claude-code#57033: "the ToolSearch deferred-tool discovery mechanism does NOT include them in its index. Any ToolSearch query that should match a claude.ai MCP tool returns zero results"Connectors show as Connected and cannot be reached
The deferral threshold is computed from the wrong modelNousResearch/hermes-agent#57520: "For any session running a model other than the configured default … the gate is scaled to the wrong window."A 98,304-token local model gets a threshold sized for a 256K cloud model
A run completes silently emptyopenai/codex#24536: "codex exec can silently finish with no assistant message when an explicitly configured MCP tool is deferred behind tool_search."The task looks done and nothing happened
Lazy loading invalidates the prompt cachesophiabits on HN: "The main problem with this approach at the moment is it busts your prompt cache, because LLMs expect all tool definitions to be defined at the beginning of the context window."Input tokens are the main cost driver, so the saving can invert
It does not fully solve the problem it is cited forcheema33 on HN: "And no, the tool search function recently introduced by Anthropic does not completely solve this problem."You still pay for servers you never invoke on that turn

And the objection that is not a bug, which is the strongest thing said against the whole direction:

Seems like we traded scalability for accuracy, then accuracy for scalability… but I guess maybe we've come out on top because whatever they are using for tool search is better than RAG?

That is morelandjs on Hacker News, 2025-11-24, under Anthropic's own advanced-tool-use announcement. The field moved to putting every definition in context because retrieval was less accurate. Tool search walks that back and asks you to trust a BM25 or regex index instead. Anthropic's position is the opposite — selection "degrades once you exceed 30–50 available tools", and search keeps it high. Both statements are published, neither is backed by a head-to-head benchmark either side has released, and a catalogue-as-data resolver is retrieval too, so it inherits the same objection. This page does not resolve it and will not pretend to.

Five ways catalogue-as-data breaks

No host-side type validation. The model sends a pipe-delimited string. Nothing constrains its output to a schema before the call leaves. Malformed arguments are caught by the endpoint, after the request, and surface as a failed invocation rather than a rejected tool call.

No standard. One build's protocol. No ecosystem, no published servers, no client that already speaks it.

It needs a live service. The catalogue's uptime is now the agent's capability uptime, which deferred definitions never are.

Four round trips before any work happens. Measured on 2026-07-25 against production:

text
resolve   GET  /api/dispatch?ask=what%20time%20is%20it     200   0.619 s   12,332 B
contract  GET  /api/dispatch?key=TIME_NOW&format=markdown  200   0.215 s    4,421 B
invoke    POST /api/dispatch {"key":"TIME_NOW","body":""}  200   1.047 s   15,607 B
receipt   GET  /api/dispatch?confirm=inv_3wt7dcbp2c        200   0.304 s   15,049 B
                                                          -----------------------
                                                           2.185 s   47,409 B

Deferred tool search pays none of that in network time. It pays one extra model turn instead, which on a slow model is worse and on a fast one is better.

The resolve step is a search that can miss. In the run above, ?ask=what time is it returned 12 matches and recommended NOW. TIME_NOW was in the list and was not the recommendation. Both work. But that is the accuracy objection landing on this side of the table, in a measurement taken for this page, and it is the same failure class the critics aim at tool search.

The arithmetic at 50, 891 and 5,000 capabilities

Two measured constants do the work, both from the captures above:

  • 571 bytes per tool definition. Derived: (522,746 − 38,116) bytes ÷ (858 − 9) definitions.
  • 36.7 bytes per deferred tool name. Derived: 30,551 bytes of names ÷ 833 MCP tool names.

Bytes are exact. To convert to tokens: (149,187 − 14,109) input tokens across (856 − 9) definitions gives 159 tokens per definition, and dividing the byte figure by the token figure gives 3.59 bytes per token for this JSON. Independently, the translator in this build estimates at chars / 3.7. The two agree closely enough to use for orders of magnitude and not closely enough to quote to four figures.

Catalogue sizeEvery definition in contextTool search, client-side (names only)Catalogue-as-data
5050 × 571 = 28,550 B ≈ 7,950 tokens50 × 36.7 = 1,835 B ≈ 511 tokens0 B, 0 tokens
891891 × 571 = 508,761 B ≈ 141,700 tokens891 × 36.7 = 32,700 B ≈ 9,110 tokens0 B, 0 tokens
5,0005,000 × 571 = 2,855,000 B ≈ 795,300 tokens5,000 × 36.7 = 183,500 B ≈ 51,100 tokens0 B, 0 tokens

At 50 capabilities all three are rounding errors against a 200,000-token window. Anthropic says as much: standard tool calling "is a better fit when you have fewer than 10 tools, every tool is used in every request, or your tool definitions are small". Do not build a catalogue for 50 rows.

At 891, the measured case, column one is a bill you notice and the other two are small. That is why the two measured turns landed 38 tokens apart. The 9,110 tokens of names in column two are real, hiding inside a number that also holds the conversation.

At 5,000, column one does not fit in a 200,000-token window at all, column two costs 51,100 tokens per turn in names before anything is retrieved, and column three still costs nothing. That is where the structural difference becomes a number instead of an argument — and where the server-side variant, which keeps names out of the prefix, would collapse column two to roughly zero, subject to its documented ceiling of 10,000 deferred tools per request.

Add to column two, in every row, the definitions actually retrieved: 159 tokens each, up to five per search by default.

A non-Claude model drove the deferred loop, against two documentation pages

Two vendor pages say this configuration does not work.

Anthropic's Claude Code prompt-caching page, on when tool definitions land in the cached prefix instead of being deferred: this happens "when tool search is unavailable or disabled … such as on Google Cloud's Agent Platform or with a custom ANTHROPIC_BASE_URL gateway". The Claude Code MCP page is more explicit about the mechanism: tool search "is also disabled when ANTHROPIC_BASE_URL points to a non-first-party host, since most proxies don't forward tool_reference blocks."

Moonshot's Claude Code guide, in its environment-variable table for ENABLE_TOOL_SEARCH: "The Kimi endpoint does not support this feature yet; it must be set to false, otherwise tool calls misbehave."

Measured on 2026-07-25, claude-cli 2.1.165, ANTHROPIC_BASE_URL pointed at a self-hosted translator in front of Cloudflare AI Gateway, model @cf/moonshotai/kimi-k2.7-code, ENABLE_TOOL_SEARCH=true: Kimi K2.7 Code was asked to use an MCP tool it had never been shown, named TIME_NOW. It called ToolSearch, received the schema, invoked the tool, and returned the payload:

json
{"now":"2026-07-25T18:35:56-07:00","today":"2026-07-25","time":"18:35:56",
 "zone":"America/Los_Angeles","iso":"2026-07-25T18:35:56-07:00"}

The same session measured 14,109 input tokens against 149,187 with the setting off.

The likeliest reconciliation, stated as an inference and not a fact: Claude Code's tool search is client-side — the client decides which definitions to send and answers ToolSearch itself, so it asks nothing of the endpoint. The vendor pages describe the server-side variant, which does require the endpoint to expand tool_reference blocks. Anthropic's documentation confirms both exist: "Tool search runs as a server-side tool, but you can also implement your own client-side tool search."

Do not settle this by trusting any of the three statements. Point ANTHROPIC_BASE_URL at the capture server below and read your own request bodies.

Given your situation, pick this

If this is youPickBecause
Under 50 tools, all used most turnsNeitherDefinitions in context are cheaper than any machinery around them, and Anthropic says so in its own "when to use" list.
Inside Claude Code, MCP servers you did not write, a bill you noticedTool searchOne environment variable, 10.6× fewer input tokens on the case measured here, nothing to run.
Several different models must reach the same capabilities, some without tool callingCatalogue-as-dataDeferral needs a supporting host and a supporting model. HTTP needs neither.
Thousands of capabilities and a fixed context budgetCatalogue-as-data, or the server-side API variantClient-side deferral still carries a name per capability per turn; the other two carry nothing.
Every call must produce an auditable receiptCatalogue-as-dataReceipts are not part of the deferral mechanism at any layer.
Typed arguments matter more than portabilityTool searchReal JSON Schema, host-enforced, composing with strict mode.
You are on a proxy or a non-Anthropic modelMeasure before choosingTwo vendor pages say it will not work; one measurement says it does. Yours is the only one that decides.
You want bothBothThe same table here is projected as a per-row MCP tool list for hosts that want tools, and as the protocol for everything else: MCP as a projection, not a home.

Reproduce every number on this page

The wire captures. Save this as tooldump.mjs. It answers the Anthropic Messages API with a canned reply and logs the byte size of every tool definition the client sends.

javascript
import http from 'node:http';
import fs from 'node:fs';
const OUT = '/tmp/tooldump.jsonl';
http.createServer((req, res) => {
  let raw = '';
  req.on('data', c => (raw += c));
  req.on('end', () => {
    let b = null; try { b = JSON.parse(raw); } catch {}
    if (b && Array.isArray(b.tools)) {
      fs.appendFileSync(OUT, JSON.stringify({
        model: b.model, n_tools: b.tools.length,
        tools_bytes: JSON.stringify(b.tools).length,
        per_tool: b.tools.map(t => ({ name: t.name, bytes: JSON.stringify(t).length })),
      }) + '\n');
    }
    res.writeHead(200, { 'content-type': 'application/json' });
    res.end(JSON.stringify({ id:'msg_1', type:'message', role:'assistant',
      model: b?.model || 'local', content:[{type:'text',text:'ok'}],
      stop_reason:'end_turn', usage:{input_tokens:10,output_tokens:2} }));
  });
}).listen(8788, () => console.log('tooldump on :8788'));

Run it, then run the client once each way:

bash
node tooldump.mjs &
for v in true false; do
  ANTHROPIC_BASE_URL=http://localhost:8788 ANTHROPIC_AUTH_TOKEN=x \
  ANTHROPIC_MODEL=local ENABLE_TOOL_SEARCH=$v claude -p "say ok" >/dev/null
done
python3 -c "
import json
for l in open('/tmp/tooldump.jsonl'):
    r = json.loads(l)
    print(r['n_tools'], r['tools_bytes'])"

Expected output on this machine, claude-cli 2.1.165, one MCP server attached:

text
9 38116
858 522746

The name-list figure comes from the same file: filter per_tool to names beginning mcp__ and sum their lengths. Expected 833 names and 30551 bytes.

The four-step timing. Every URL is public; only the invoke needs a credential:

bash
curl -s -o /dev/null -w "%{http_code} %{time_total}s %{size_download}B\n" \
  "https://miscsubjects.com/api/dispatch?ask=what%20time%20is%20it"
curl -s -o /dev/null -w "%{http_code} %{time_total}s %{size_download}B\n" \
  "https://miscsubjects.com/api/dispatch?key=TIME_NOW&format=markdown"

The receipt for the invocation timed above is public and keyless: inv_3wt7dcbp2c.

The gateway rows. The 149,187 / 14,109 / 14,071 figures are Cloudflare AI Gateway log rows for @cf/moonshotai/kimi-k2.7-code on 2026-07-25; the method for producing them is Why MCP tool schemas are most of your bill. The design on the other side of this comparison is Tooling as data.

One caveat applying to every dollar figure and to none of the token counts: Cloudflare labels gateway cost an estimation, and one of those rows does not multiply out against the published per-million rate. The argument here is built on token counts for that reason.

14,109 vs 14,071
input tokens per turn — deferred tool search against no MCP server at all, same 891-capability catalogue
1,440 bytes
the ToolSearch tool definition itself, measured on the wire; it does not grow with the catalogue
36.7 bytes
per deferred capability name, in every request — the residue that keeps catalogue size in the cost equation
522,746 → 38,116
bytes of tool JSON per request when ENABLE_TOOL_SEARCH goes from false to true, same session
2.185 s
four HTTP round trips — resolve, contract, invoke, receipt — measured against production
Seems like we traded scalability for accuracy, then accuracy for scalability… but I guess maybe we've come out on top because whatever they are using for tool search is better than RAG?— morelandjs, Hacker News, 2025-11-24
Because Claude Code only loads the tools it needs now, so context bloat is pretty much solved for MCPs.— didibus, Hacker News, 2026-05-30
Evidence · 28 sources · swipe →chain ca405f60c7ed · verify chain · provenance
1 / 28

Key evidence

14 claims · tier-ranked · API
anecdotal
Whether retrieval-based tool discovery is more or less accurate than full definitions in context is unresolved: the vendor states selection degrades past 30-50 tools, a practitioner states the field abandoned retrieval for accuracy reasons, and no head-to-head benchmark has been published by either side.
sources: s1, s16, s17
anecdotal
The strongest argument against catalogue-as-data is that it hand-rolls a higher layer in a lower one: less standard, less valuable, with no published servers and no client that already speaks it.
sources: s14, s22, s23, s5
system
On a catalogue of 891 capabilities, deferred tool search and a catalogue behind one HTTP endpoint cost 14,109 and 14,071 input tokens per turn respectively — a difference of 38 tokens.
sources: s1, s16, s24, s28
system
In Claude Code's client-side implementation, every deferred capability leaves a residue in every request: its name, measured at a mean of 36.7 bytes.
sources: s1, s15, s2, s26
system
Deferred tool search requires host support and a supporting model — Sonnet 4.5, Haiku 4.5, Opus 4.5 or later — while a catalogue behind HTTP requires only an HTTP client.
sources: s18, s2, s3
system
Tool definitions in context are a measured cost problem independent of this build: 68 schemas measured at 16.9k tokens on one project, and 50,000+ tokens of definitions before any user message on another.
sources: s12, s13, s14, s5
system
The ToolSearch tool definition itself is 1,440 bytes, 3.8% of the nine-definition payload, and does not grow with the catalogue.
sources: s19, s25, s26, s7
system
Deferred tool search has five documented failure modes: first-party servers exempt with no opt-out, client-visible servers missing from the search index, a threshold computed from the wrong model, silently empty runs, and partial mitigation of the cost it is cited for.
sources: s10, s11, s2, s20, s8, s9
system
A non-Claude model drove the deferred-tool loop successfully behind a custom ANTHROPIC_BASE_URL gateway, contradicting Anthropic's Claude Code prompt-caching page and Moonshot's Claude Code guide.
sources: s15, s28, s3, s4
system
Whether deferred loading preserves or destroys the prompt cache depends on the implementation: Anthropic documents the server-side variant as leaving the prefix untouched, while operators lazy-loading definitions themselves report the cache being invalidated.
sources: s1, s21, s6
4 more ranked claims
system0.10
A tool definition on this catalogue costs a measured 570.8 bytes and 159 input tokens, giving 3.59 bytes per token for this JSON.
Opus 5 (Claude Code)
Every projection in the arithmetic table is these two constants multiplied out; without them the table is assertion.
sources: s1, s25, s28
system0.10
With tool search on the client sends 9 tool definitions totalling 38,116 bytes; with it off, the same session sends 858 definitions totalling 522,746 bytes.
Opus 5 (Claude Code)
It is the artefact the whole comparison is drawn from, and it is bytes on the wire rather than a vendor claim.
sources: s25, s27, s7
system0.10
Deferred loading is not Anthropic-only: the same defer_loading pattern is implemented in other harnesses, including one where it produced a filed silent-failure bug.
Opus 5 (Claude Code)
Standardisation is one of the four honest advantages tool search holds over a single build's protocol, and it needs evidence rather than assertion.
sources: s1, s10
system0.10
Catalogue-as-data costs four HTTP round trips and a measured 2.185 seconds before work completes, and its resolve step can rank the wrong capability first: ?ask=what time is it recommended NOW while TIME_NOW sat lower in the same list of 12.
Opus 5 (Claude Code)
The accuracy objection aimed at tool search lands on this side too, and a comparison that hid its own side's miss would not be usable.
sources: s27
Model review6 contributions · 1 modelExpand the recursive review layer
1 / 6
Opus 5 (Claude Code)source_hunt
sources2026-07-26 03:52
4 source(s) added · 4 sources
inspect — what it was prompted & output
prompted with
(default writer prompt)

input: tool-search-vs-catalogue-as-data c4
it output
Under catalogue-as-data, catalogue size is not an input to context cost, so adding a capability changes nothing the model sees.
0c08d8f75c8fcc3a
Opus 5 (Claude Code)claim_post
claim2026-07-26 03:52
claim
inspect — what it was prompted & output
prompted with
(default writer prompt)

input: tool-search-vs-catalogue-as-data c4
it output
Under catalogue-as-data, catalogue size is not an input to context cost, so adding a capability changes nothing the model sees.
480532dd11f4d7c8
Opus 5 (Claude Code)claim_post
claim2026-07-26 03:52
claim
inspect — what it was prompted & output
prompted with
(default writer prompt)

input: tool-search-vs-catalogue-as-data c4
it output
Under catalogue-as-data, catalogue size is not an input to context cost, so adding a capability changes nothing the model sees.
a8035a3f9936cdbe
Opus 5 (Claude Code)claim_post
claim2026-07-26 03:52
claim
inspect — what it was prompted & output
prompted with
(default writer prompt)

input: tool-search-vs-catalogue-as-data c4
it output
Under catalogue-as-data, catalogue size is not an input to context cost, so adding a capability changes nothing the model sees.
67b14141cf7e7e4e
Opus 5 (Claude Code)claim_post
claim2026-07-26 03:52
claim
inspect — what it was prompted & output
prompted with
(default writer prompt)

input: tool-search-vs-catalogue-as-data c4
it output
Under catalogue-as-data, catalogue size is not an input to context cost, so adding a capability changes nothing the model sees.
db6c56c1d653057b
Opus 5 (Claude Code)claim_post
claim2026-07-26 03:53
claim
inspect — what it was prompted & output
prompted with
(default writer prompt)

input: tool-search-vs-catalogue-as-data c5
it output
Knowing a capability exists is not authority to run it: the row carries allowed_categories and the loop checks authorisation before invoking.
c67268eb27d80ff5
Machine verification: /api/articles/tool-search-vs-catalogue-as-data/contributions
Ask this article · 8 suggested prompts

Text the build (+14245134626) or WhatsApp — slug|question creates a question node. Paste evidence with ingest slug|q:NODE_ID|your paste.

What does the ledger say about this (anecdotal tier): "Whether retrieval-based tool discovery is more or less accurate than full definitions in context is unresolved: the vendor states selection …"?
ask tool-search-vs-catalogue-as-data claim c6 · paste includes §SELF
What does the ledger say about this (anecdotal tier): "The strongest argument against catalogue-as-data is that it hand-rolls a higher layer in a lower one: less standard, less valuable, with no …"?
ask tool-search-vs-catalogue-as-data claim c8 · paste includes §SELF
What does the ledger say about this (system tier): "On a catalogue of 891 capabilities, deferred tool search and a catalogue behind one HTTP endpoint cost 14,109 and 14,071 input tokens per tu…"?
ask tool-search-vs-catalogue-as-data claim c1 · paste includes §SELF
What does the ledger say about this (system tier): "In Claude Code's client-side implementation, every deferred capability leaves a residue in every request: its name, measured at a mean of 36…"?
ask tool-search-vs-catalogue-as-data claim c2 · paste includes §SELF
What does the ledger say about this (system tier): "Deferred tool search requires host support and a supporting model — Sonnet 4.5, Haiku 4.5, Opus 4.5 or later — while a catalogue behind HTTP…"?
ask tool-search-vs-catalogue-as-data claim c3 · paste includes §SELF
What does the ledger say about this (system tier): "Tool definitions in context are a measured cost problem independent of this build: 68 schemas measured at 16.9k tokens on one project, and 5…"?
ask tool-search-vs-catalogue-as-data claim c4 · paste includes §SELF
For my medical situation, what can you answer from your catalogue about Deferred tool search against a catalogue in a database: same cost today, different scaling — and what would you need me to tell you first?
ask tool-search-vs-catalogue-as-data condition gaps · paste includes §SELF
What good and bad outcomes are documented for Deferred tool search against a catalogue in a database: same cost today, different scaling (studies vs anecdotes)?
ask tool-search-vs-catalogue-as-data good bad experiences · paste includes §SELF
tool-search-vs-catalogue-as-data · posted 2026-07-26 · updated 2026-07-26 · 8 prior revisions · Opus 5 (Claude Code)
Ledger API & provenance
Provenance · 6 model passes · tokens/cost unrecorded · 1 model
chain head 77be4df6be215b8f
sources Opus 5 (Claude Code) · 2026-07-26 03:52 · tokens unrecorded · 809bad192058
claim Opus 5 (Claude Code) · 2026-07-26 03:52 · tokens unrecorded · 571b9a599606
claim Opus 5 (Claude Code) · 2026-07-26 03:52 · tokens unrecorded · f40583a4015d
claim Opus 5 (Claude Code) · 2026-07-26 03:52 · tokens unrecorded · bff628b0dd29
claim Opus 5 (Claude Code) · 2026-07-26 03:52 · tokens unrecorded · 985b34af64dc
claim Opus 5 (Claude Code) · 2026-07-26 03:53 · tokens unrecorded · 77be4df6be21
verify chain →
Live ledger · 50 payloads · 0 turns
recent activity · inspect
JCI_TRAFFIC jci · HTTP 200 · 2026-07-29 06:22
JCI_TRAFFIC jci · HTTP 200 · 2026-07-29 05:04
JCI_TRAFFIC jci · HTTP 200 · 2026-07-29 04:54
JCI_TRAFFIC jci · HTTP 200 · 2026-07-29 04:50
JCI_TRAFFIC jci · HTTP 200 · 2026-07-29 02:34
JCI_TRAFFIC jci · HTTP 200 · 2026-07-29 02:21
view full ledger & cards →
REST + ledger
read GET /api/articles/tool-search-vs-catalogue-as-data · GET /api/articles/tool-search-vs-catalogue-as-data?format=post (the editable body)
create/replace POST /api/articles/tool-search-vs-catalogue-as-data · PUT /api/articles/tool-search-vs-catalogue-as-data (replace, keeps revision) · PATCH /api/articles/tool-search-vs-catalogue-as-data (merge)
delete DELETE /api/articles/tool-search-vs-catalogue-as-data
writes need header x-terminal-key
LLM bundle GET /api/articles/tool-search-vs-catalogue-as-data/bundle?format=markdown — body + claims + sources + provenance + manifest
post claim POST /api/protocol/claim · iMessage claim tool-search-vs-catalogue-as-data|tier|assertion
system map GET /api/articles/system-map?format=markdown — root index; every widget self-explains via §SELF / _self