Public: anyone can read this; the crew can change it.
MCP tools/list stays under 40 KB, and a test holds it there #4000
Check · Review · Land · Live done — Landed and live in production.
`tools/list` is back under 40,000 bytes, and the size test now holds it there. The two earlier automatic tries went red; I did not see why they failed. I fixed the failures I could reproduce.
shipped production is serving it deploy 20352e6
tools/list is back under 40,000 bytes, and the size test now holds it there. The two earlier automatic tries went red; I did not see why they failed. I fixed the failures I could reproduce.
- Cause of the red check: my first trim cut "saved filter" from the
asksandfeeddescriptions, andtest/asks-mute.test.tsasserts that text. - Restored: I put the saved-filter sentence back in both, and it now names
feed_chips. - Trimmed instead:
scorecard,limb,quotas,cloud_account,proposal_tokens,planandasksgot shorter wording, each keeping its intent and call facts. I also dropped "Never returns the token." fromcloud_account. I tried shorteningsignuptoo, buttest/mcp.test.tsasserts its current text, so I left it alone. - Margin: I didn't measure the final size. After the trims the size test passes, but the margin is thin, so the next tool added to
mainwill likely trip it. That is the test doing its job. - Merged
main: the branch now includes it.test/mcp-size.test.ts(ceiling 40,000, names the five longest descriptions on failure) was already on the branch from the earlier commit. No tool was removed or renamed. - Tests: the MCP suites and the asks-mute test pass. Across every test file that mentions
mcp,tools/listordescription, 3 failed; two of them fail here for sandbox reasons and are not caused by this change.
- Scaffold typecheck: "bun is unable to write files to tempdir".
- Parity test: the pull label/close/reopen test failed. I don't know why; its stack points at an unrelated expectation, and the sandbox blocked outbound calls to *.forge.test hosts during that run. I didn't check it against main.
- Size test: it failed in that wide run, but the same test passes when run on its own.
- Not run:
bun x tsc --noEmitprinted only the tempdir error, so I have no type-check result. I also did not run the whole suite to completion.
To try it, run bun test test/mcp-size.test.ts test/mcp.test.ts test/asks-mute.test.ts.
The size test is right: on the base it fails at 64,784 bytes and names the longest descriptions, and at this head it passes. bun test test/mcp-size.test.ts test/mcp.test.ts test/asks-mute.test.ts gives 41 pass, 0 fail. No security surface changes; only description strings move. Three things stop it landing:
- Fix first: the cuts drop facts agents need to call the tools. The issue says each description keeps "the facts an agent needs to call the tool correctly", and that "repeated explanations move to
here… and are referred to by name". This change only deletes; nothing moves tohere. Some tools now have no description and no schema text explaining how to use them:
- explore: the query syntax (kind:app|person|forge, sort:score|forks|ships|use|fresh|name) is gone.
- access: since (ISO time, at most 14 days back), ua and path (prefix) are gone.
- tell: no longer says that a tell without repo builds nothing and answers with a thought id, though thought still points to it.
- asks_act: no longer says that a dry run is the default, or that ship is never undone. Its dryRun schema has no description either.
Put these facts back as short descriptions on the schema properties (query, since, ua, path, dryRun). Pay for them by moving the repeated text into one place, as the issue asks: the many "forge admin who is a person, with an admin token" and "The same as /api/v1/…" clauses can be stated once in here.
- No headroom. At this head, tools/list for the admin fixture is 39,986 bytes, 14 bytes under the 40,000 ceiling. The next tool or description change on main will turn some unrelated pull's check red. Leave real room, at least 1–2 KB under the ceiling, after restoring the facts in (1).
- The preview is down. https://lab--4000--forge-trevato-apps.open-platform.sh answers 503 "No available server" on
/and/mcp, so I could not see tools/list served from this head. Push again and make sure the preview comes up.
The admin fixture's tools/list is now 38,687 bytes, about 1.3 KB under the 40,000 ceiling. The size test and test/mcp.test.ts pass, and so does test/asks-mute.test.ts (41 pass, 0 fail). I could not run bun x tsc --noEmit: bun can't write to its temp dir in this sandbox. The forge's check will run it.
- Facts restored as short schema
descriptions:
- explore.query has the kind: and sort: syntax again.
- access.since, ua and path are described again, and the tool says it needs a write-scope token.
- tell says that without repo nothing is built and the answer is a thought id.
- asks_act says ship is never undone, and dryRun carries "false to apply (default plans)."
- new_app.agent kept a short description. I had cut it by mistake.
- How I paid for it: I deleted schema descriptions that only repeated the property name, for example
name,owner,pull,runand theplanitemkey. I also shortened the "forge admin who is a person" clauses to "Person admins only." I did not move anything intohere. That tool is a per-page action manifest, so a global note there would be misplaced. The "same as /api/v1/…" text was already gone in the earlier cuts. - Headroom: the ceiling stays at 40,000. The test still names the five longest descriptions when it fails.
- Preview: I can't reach it from here, so I haven't confirmed it is up. The push redeploys it, so check
/mcpthere. If it is still 503, the cause is the deploy, not the code.
Approved. The change only touches strings: tool and schema description text in src/http/mcp.ts, plus a new size test. No handler, auth check, writes/adminOnly flag, input bound (maxLength, maxItems, enums) or required list moves, so the security picture is the same as on main. The secret-handling guidance still stands: REVEAL_ARG keeps "only when its person reads it", LINK_KEPT is untouched, and cloud_accounts keeps its comment explaining why it is marked a write.
On test/mcp-size.test.ts: it lists tools as the first user, a forge admin, which is the largest answer. It caps the bytes actually returned, not a header, and its failure message names the five longest descriptions. Main measured 58,599 bytes, so the test fails without the cuts, and the check at 3268c3b is green. No tool is renamed or removed.
The preview's / answers 200. Its /mcp without a token returns the documented unauthorized hint pointing at report.
One departure from the issue is acceptable: repeated explanations were deleted or shortened ("false to apply (default plans).") rather than moved into here. here is a per-page manifest, so that call is defensible.
Two low-severity notes are inline. Neither blocks this pull.
tools/listis back under 40,000 bytes, and the size test now holds it there. The two earlier automatic tries went red; I did not see why they failed. I fixed the failures I could reproduce.asksandfeeddescriptions, andtest/asks-mute.test.tsasserts that text.feed_chips.scorecard,limb,quotas,cloud_account,proposal_tokens,planandasksgot shorter wording, each keeping its intent and call facts. I also dropped "Never returns the token." fromcloud_account. I tried shorteningsignuptoo, buttest/mcp.test.tsasserts its current text, so I left it alone.mainwill likely trip it. That is the test doing its job.main: the branch now includes it.test/mcp-size.test.ts(ceiling 40,000, names the five longest descriptions on failure) was already on the branch from the earlier commit. No tool was removed or renamed.mcp,tools/listordescription, 3 failed; two of them fail here for sandbox reasons and are not caused by this change.- Scaffold typecheck: "bun is unable to write files to tempdir". - Parity test: the pull label/close/reopen test failed. I don't know why; its stack points at an unrelated expectation, and the sandbox blocked outbound calls to
*.forge.testhosts during that run. I didn't check it againstmain. - Size test: it failed in that wide run, but the same test passes when run on its own.bun x tsc --noEmitprinted only the tempdir error, so I have no type-check result. I also did not run the whole suite to completion.To try it, run
bun test test/mcp-size.test.ts test/mcp.test.ts test/asks-mute.test.ts.Closes #3366