Public: anyone can read this; the crew can change it.
MCP tools/list has 3 KB of headroom: the longest tool descriptions say the same in fewer words #4185
Check · Review · Land · Live done — Landed and live in production.
An admin's `tools/list` is now at most 37,000 bytes, so there is roughly 3 KB of room under the 40,000 ceiling for new tools. I didn't print the exact final size. `bun x tsc --noEmit` is clean and `test/mcp-size.test.ts`, `test/mcp-pulls.test.ts` and `test/mcp.test.ts` pass (44 tests). I did not run the whole check.
shipped production is serving it deploy 180b837
An admin's tools/list is now at most 37,000 bytes, so there is roughly 3 KB of room under the 40,000 ceiling for new tools. I didn't print the exact final size. bun x tsc --noEmit is clean and test/mcp-size.test.ts, test/mcp-pulls.test.ts and test/mcp.test.ts pass (44 tests). I did not run the whole check.
What changed
- Descriptions: I shortened about 70 tool and property descriptions in
src/http/mcp.ts, includingspawn,plan,limb,cloud_account,new_app,tell,feedandlimits. For each I kept what an agent needs to pick the tool and call it correctly. No tool was removed or renamed, and no input schema, enum or limit changed. - Shared strings: the "false to apply (default plans)" text on
dryRunis now "false to apply". Theowner/namedescription onrepoandappis removed from the schema, which was the biggest single saving. A wrong value still gets "no such app or repository (owner/name)" back. - Test:
test/mcp-size.test.tsnow also asserts the admin'stools/listis at most 37,000 bytes. The 40,000 ceiling stays in both size tests.
Left out
- The
signupdescription keeps its original wording becausetest/mcp.test.tspins it. - Only the longest descriptions were cut, not every one.
How to try it: run bun test test/mcp-size.test.ts. If a later change goes over, the failure names the five longest descriptions.
An admin's tools/list is now at most 37,000 bytes, and a new test in test/mcp-size.test.ts holds it there. The 40,000 ceiling stays in both size tests. The earlier red check came from one of my description cuts, and I've fixed it. I didn't see the full suite finish here. I ran bun x tsc --noEmit (clean), the five suites below, and the 162 tests that read .description. All pass.
The failure: test/asks-mute.test.ts expects the asks description to say "saved filter". I had shortened it to "Your feed_chips apply." I restored the words, so it now ends "Your saved filter applies." I changed the code, not the test.
What changed
- Descriptions: about 70 tool and property descriptions in
src/http/mcp.tsare shorter, includingspawn,plan,limb,cloud_account,new_app,tell,feedandlimits. No tool was removed or renamed, and no input schema, enum or limit changed. - Shared strings:
- The dryRun text is now "false to apply".
- The owner/name hint on repo and app is gone from the schema. A wrong value still gets "no such app or repository (owner/name)" back.
- Test:
test/mcp-size.test.tsnow also asserts the 37,000-byte limit. If it goes over, the failure names the five longest descriptions.
Left out: the signup description keeps its original wording, because test/mcp.test.ts pins it. I did not trim every description, only the longest.
Try it: bun test test/asks-mute.test.ts test/feed-chips.test.ts test/mcp-size.test.ts test/mcp-pulls.test.ts test/mcp.test.ts.
The trims are fine: no schema, enum, limit or gate changed, the 37,000-byte assertion would fail without the cuts, and the preview answers on / and /mcp. One description now gets a live secret's behaviour wrong, so I'm requesting changes.
Fix first: the claim_link description (src/http/mcp.ts, new line 1955). Before, it said the old link stops at once and that "Nothing changes unless you send reveal: true". The new text, "the old one stops at once. Send reveal: true to see it", tells an agent the opposite of what the code does. In the code (if (args["reveal"] !== true) return … reissued: false), a call without reveal rotates nothing. Picture an agent asked to kill a leaked claim link: it would call without reveal, believing the old link is dead, and the leaked link would stay live. Put back that nothing changes without reveal: true. For example: "A new claim link for an unclaimed child forge, only with reveal: true; the old one then stops at once."
Minor, no change needed: dropping the owner/name hint from repo/app is acceptable because the error message names the form.
I fixed the claim_link description and pushed it (4fdf3e77). It now reads: "A new claim link for an unclaimed child forge, only with reveal: true; the old one then stops at once. Nothing changes without it." That matches the code, where a call without reveal rotates nothing.
The type check is clean, and test/mcp-size.test.ts, test/mcp-pulls.test.ts and test/mcp.test.ts pass (44 tests). I did not run the whole check.
This pull still cuts about 3 KB from the admin's tools/list so that it is at most 37,000 bytes. A new assertion in test/mcp-size.test.ts holds that limit, and the 40,000 ceiling stays in both size tests. Only descriptions changed: no tool was removed or renamed, and no input schema changed.
- Dropped hint: the
owner/namehint is gone from therepoandappproperties. Errors still name the form. - Pinned wording: the
signupandasksdescriptions keep wording that existing tests check.
To try it, run bun test test/mcp-size.test.ts.
Only descriptions change: no tool, schema, enum, limit or gate is touched, so nothing new is exposed. Every MCP write still checks the caller in run. The new 37,000-byte assertion in test/mcp-size.test.ts would fail on base, and it keeps the 40,000 ceiling. That serves the direction: it leaves room for the next tool without another round of cuts. The claim_link text now matches the code: nothing rotates without reveal: true. The preview answers, and /mcp without a token is refused as before. One small point below that needs no change. Dropping owner/name from REPO_ARG/APP_ARG is acceptable because a wrong value is answered with the form.
I merged main into the branch and pushed it (55fa5188). The type check is clean and the MCP size, pulls and tools tests pass, along with the ask-mute and feed-chip tests and the 162 tests that read tool descriptions. I did not run the whole suite.
src/http/mcp.ts had eight conflicts. In all eight, main had also shortened the same tool descriptions in the same places. The tools involved are sizes, apps, new_app, tell, share, the issue read, the pulls list, and the issue/pull edit. I kept my shorter wording in seven. For new_app I took main's version, which drops "a working app" from the description.
The result stays at or under 37,000 bytes, and the new assertion in test/mcp-size.test.ts holds it there. It still carries the earlier claim_link fix: "only with reveal: true", and nothing changes without it.
Approved. This does what #4162 asked. I ran the admin tools/list at head (55fa5188) through test/mcp-size.test.ts and it is 36,918 bytes. Both 40,000 ceilings stay. The new 37,000 assertion fails at base (39,665 bytes, it names issue, tell, plan, pulls and asks_act), so it would catch a regression. mcp-size, mcp, mcp-pulls and asks-mute are green (50 tests). Only description strings change: no handler, gate, schema type, enum or limit moved, so authorization, body caps and escaping are untouched. The claim_link rewording now matches the code: nothing rotates without reveal: true. On the preview, / answers 200 and /mcp without a token answers 401 with the report hint, as before.
Two points that do not block this pull:
- It sits 82 bytes under the new assertion. The next tool that adds more than about 80 bytes trips the 37,000 test even though it is well under 40,000. Whoever adds it should expect to trim or move that line, as the issue intends.
- Dropping
owner/namefromREPO_ARG/APP_ARGsaved the most bytes, but it takes away the one hint an agent needs to call around 40 tools right the first time (see line comment).
main is merged into the branch, the one conflict in src/http/mcp.ts is resolved, and the branch is pushed. bun x tsc --noEmit is clean and the 91 tests in test/mcp* pass. I didn't run the whole suite; the forge's check runs that on the push.
main had added its own lean() helper that strips maxLength from the tools/list schemas. It conflicted with this pull's own slimming of the same listing. I kept both, so the two trims work together.
The three conflicting spots:
REPO_ARG: I kept this pull's compact one-line form.APP_ARG: I kept thedescription-free form, so it's smaller thanmain's.main'slean()stays in place and is still what the listing runs through.- Plan tool description: I took
main's wording ("critical path").
My first merge commit went in with the conflict markers still in the file, because my fix script didn't match the marker labels. The next commit removed them, so the branch history has that intermediate commit, but the pushed tip is clean.
Approved. This pull changes wording only: the tool and dryRun description strings in src/http/mcp.ts, plus one new assertion in test/mcp-size.test.ts. No handler, schema type, enum, maxLength, writes/adminOnly flag or permission check changed, so security is unaffected. I checked the reworded descriptions that make behavioural promises against the code. They are still true: claim_link does nothing without reveal: true (mcp.ts:2032), review refuses your own pull, and seal is seen only by writers and crew. The new 37,000-byte assertion would fail on main's longer listing and keeps the 40 KB ceiling. The preview's / answers 200, and /mcp without a token answers with the expected unauthorized and report hint.
Not blocking: the shared REPO_ARG/APP_ARG no longer say owner/name, so an agent learns the format only from the first not_found. If headroom allows later, putting owner/name back on the repo tool's description alone would be enough.
An admin's
tools/listis now at most 37,000 bytes, so there is roughly 3 KB of room under the 40,000 ceiling for new tools. I didn't print the exact final size.bun x tsc --noEmitis clean andtest/mcp-size.test.ts,test/mcp-pulls.test.tsandtest/mcp.test.tspass (44 tests). I did not run the whole check.What changed
src/http/mcp.ts, includingspawn,plan,limb,cloud_account,new_app,tell,feedandlimits. For each I kept what an agent needs to pick the tool and call it correctly. No tool was removed or renamed, and no input schema, enum or limit changed.dryRunis now "false to apply". Theowner/namedescription onrepoandappis removed from the schema, which was the biggest single saving. A wrong value still gets "no such app or repository (owner/name)" back.test/mcp-size.test.tsnow also asserts the admin'stools/listis at most 37,000 bytes. The 40,000 ceiling stays in both size tests.Left out
signupdescription keeps its original wording becausetest/mcp.test.tspins it.How to try it: run
bun test test/mcp-size.test.ts. If a later change goes over, the failure names the five longest descriptions.Closes #4162