Measurement & correction for MCP tool descriptions

Agents choose your tools by reading.

A name, a description, a parameter schema — three strings are the entire interface an agent sees. When the words are off, it picks the wrong tool or pads the job with calls it never needed, and your server takes the blame. Toolmetry measures how often agents get it right, rewrites the descriptions, and re-measures until the improvement is proven.

npx mcp-toolmetry measure ./scenarios
Star on GitHub →

Exhibit A describe_table official sqlite MCP server — the full diff, unedited

Get the schema information for a specific table Get the column schema for one table. Use only when the user asks about a table’s structure — do not call this merely to check that a table exists before running a query.

strict success 34.0%100% n = 50 runs · one sentence changed Agents ritually inspected the schema before two-thirds of queries. This sentence stopped it.

Procedure

The fix-and-prove loop

Eval runners tell you the score and stop. Toolmetry is the step after — the rewrite is only kept if the numbers say so.

  1. Measure

    Every scenario runs N=5 against your live server. Tool choice, arguments, and extra calls are recorded — never a conclusion from a single run.

  2. Diagnose

    Failures are grouped by cause: wrong-tool confusion, wrong arguments, or ritual extra calls the task never needed.

  3. Rewrite

    An LLM redrafts only the failing descriptions, targeting the diagnosed failure — not a blanket rewrite of your server.

  4. Re-measure

    Same scenarios, same N, new words. The before/after delta is the product.

  5. Keep or discard

    Regressions are thrown away automatically. Only measured improvement ever ships.

Results

Four official servers. 51 scenarios. About $4.

Strict success = right tool + right args + no extra calls, over N=5 runs per scenario.

before after rewrite scale 0–100% strict success

sqliteofficial server

34.0100

+66.0

Agents ritually inspected the schema before two-thirds of queries. One added sentence fixed it.

memoryofficial server

61.896.4

+34.5

Wrong-tool confusion between overlapping tools; hit rate went 80% → 100%.

gitofficial server

75.096.7

+21.7

Perfect tool choice — but constant ritual git_status / git_log verification calls.

filesystemofficial server

74.484.4

+10.0

A deprecated read_file alias kept trapping agents into the old tool.

Every number above comes from committed run data, and the memory and git rewrites were sent upstream with the evidence attached — servers#4519 and servers#4520.

The cheap-agent tax

A stronger agent, Claude Haiku 4.5, baselined at 84.4% on the same suite. Bad descriptions tax cheap agents hardest — and cheap agents are what everyone deploys at scale.

Run it on your server

Three commands, no fork required

MeasureScore your server as-is: strict success, hit rate, and extra-call rate per scenario.

npx mcp-toolmetry measure ./scenarios

OptimizeRun the full loop. Produces a before/after report and the winning descriptions.

npx mcp-toolmetry optimize scenarios/your-server.yaml --rounds 2

ShipA proxy rewrites tools/list on the fly — better descriptions without forking the server.

npx mcp-toolmetry proxy --overrides best.json -- <server cmd>

Uncertainty budget

What these numbers can’t tell you

A measurement is only as honest as its error bars.

N=5 quantizes.

Per-scenario rates move in 20-point steps. Small deltas need more runs before you believe them.

Rewrites are high-variance.

Two attempts on the same baseline scored +10.0 and −2.2 points. That’s why the loop measures every rewrite and discards regressions automatically.

Deltas are agent-specific.

An improvement measured with one model doesn’t transfer one-to-one to another. Measure with the agent you actually deploy.

Words can’t fix tool design.

If two tools genuinely overlap, no description will save the agent. Renaming or merging them is still your job.