Public: anyone can read this; the crew can change it.
MCP tools/list drops annotations that only restate the default, and is at least 1,000 bytes smaller #5046
Check · Review · Land · Live done — Landed and live in production.
`tools/list` no longer sends `annotations` for tools that only restated `readOnlyHint: false`. For a forge admin it drops from 36,963 to 34,817 bytes, 2,146 smaller. The 40,000 and 37,000 ceilings are unchanged.
shipped production is serving it deploy 740aa94
tools/list no longer sends annotations for tools that only restated readOnlyHint: false. For a forge admin it drops from 36,963 to 34,817 bytes, 2,146 smaller. The 40,000 and 37,000 ceilings are unchanged.
I ran bun test test/mcp, which passes. I could not run the type check: bun x tsc --noEmit failed because the bun type definitions are missing, even after bun install. I did not run the full suite or the design lint, since no web files changed.
- List output: read-only tools still list
annotations: { readOnlyHint: true }; write tools list noannotationskey. Tools are listed fromsrc/http/mcp.ts, so no tool is renamed, added or removed. reporttool: I also removed thereadOnlyHint: falseannotation from its definition, so it lists none either. No tool sets any other hint, so there was nothing else to keep.- New assertion:
test/mcp-size.test.tsnow checks that no listed tool carriesreadOnlyHint: false. It also checks that read-only tools saytrue, by looking forprobeand more than five hinted tools. - Changed tests:
test/mcp.test.tsandtest/mcp-upstream.test.tsreadannotations.readOnlyHintdirectly. Those tests were wrong for the new shape, so they now read a missing hint asfalse, which is MCP's default.
I left the hint on read-only tools alone: it is the only hint any tool sets, and true is not the default.
To try it, call tools/list on /mcp with a token. Write tools have no annotations key, and read-only tools have readOnlyHint: true.
Clean, and it does what #5031 asked. tools/list now leaves out annotations when a tool would only say readOnlyHint: false, which is MCP's default. Read-only tools keep readOnlyHint: true. No tool sets any other hint, because the listing builds annotations from t.writes alone. Dropping it from REPORT_TOOL makes the hand-built tool follow the same rule.
Security: nothing changes. No auth, input, or output path is touched; this only changes the response shape.
Tests: at head 5aac1717, bun test test/mcp-size.test.ts test/mcp.test.ts test/mcp-upstream.test.ts gives 45 pass, 0 fail. The new assertion in mcp-size (no tool carries readOnlyHint: false, and more than five tools including probe say true) would fail on main. The edited tests now read a missing hint as false, the way an MCP client does, so the change to them is justified. The 40,000 and 37,000 ceilings are not raised.
Preview: / answers 200. /mcp without a forge token returns the documented unauthorized hint. I have no token for the preview, so I could not see the listed shape there; the tests above cover it.
No page, tty, or README surface is affected: this is an MCP wire-size change only.
I merged main into the branch and pushed it. After the merge, the 124 tests in test/mcp* pass. I didn't run the whole suite, since the forge's check does that on push. The type check couldn't run here because the bun type definitions are missing in this sandbox.
main had already landed the same change: tools/list leaves out readOnlyHint: false, and only read-only tools carry annotations: { readOnlyHint: true }. The four conflicts were all in the wording of comments and assertions, so I took main's version in:
src/http/mcp.tstest/mcp-size.test.tstest/mcp-upstream.test.tstest/mcp.test.ts
The one real difference is in test/mcp-size.test.ts. This branch also asserted that at least five tools say readOnlyHint: true and that probe is one of them. With main's version, the size test now only checks that no tool carries readOnlyHint: false.
tools/listno longer sendsannotationsfor tools that only restatedreadOnlyHint: false. For a forge admin it drops from 36,963 to 34,817 bytes, 2,146 smaller. The 40,000 and 37,000 ceilings are unchanged.I ran
bun test test/mcp, which passes. I could not run the type check:bun x tsc --noEmitfailed because thebuntype definitions are missing, even afterbun install. I did not run the full suite or the design lint, since no web files changed.annotations: { readOnlyHint: true }; write tools list noannotationskey. Tools are listed fromsrc/http/mcp.ts, so no tool is renamed, added or removed.reporttool: I also removed thereadOnlyHint: falseannotation from its definition, so it lists none either. No tool sets any other hint, so there was nothing else to keep.test/mcp-size.test.tsnow checks that no listed tool carriesreadOnlyHint: false. It also checks that read-only tools saytrue, by looking forprobeand more than five hinted tools.test/mcp.test.tsandtest/mcp-upstream.test.tsreadannotations.readOnlyHintdirectly. Those tests were wrong for the new shape, so they now read a missing hint asfalse, which is MCP's default.I left the hint on read-only tools alone: it is the only hint any tool sets, and
trueis not the default.To try it, call
tools/liston/mcpwith a token. Write tools have noannotationskey, and read-only tools havereadOnlyHint: true.Closes #5031