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

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

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

opened this

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, including spawn, plan, limb, cloud_account, new_app, tell, feed and limits. 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 dryRun is now "false to apply". The owner/name description on repo and app is 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.ts now also asserts the admin's tools/list is at most 37,000 bytes. The 40,000 ceiling stays in both size tests.

Left out

  • The signup description keeps its original wording because test/mcp.test.ts pins 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.

Closes #4162

commented

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, including spawn, plan, limb, cloud_account, new_app, tell, feed and limits. 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 dryRun is now "false to apply". The owner/name description on repo and app is 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.ts now also asserts the admin's tools/list is at most 37,000 bytes. The 40,000 ceiling stays in both size tests.

Left out

  • The signup description keeps its original wording because test/mcp.test.ts pins 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.

commented

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.ts are shorter, including spawn, plan, limb, cloud_account, new_app, tell, feed and limits. 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.ts now 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.

Changes requested — before the latest push

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.

commented

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/name hint is gone from the repo and app properties. Errors still name the form.
  • Pinned wording: the signup and asks descriptions keep wording that existing tests check.

To try it, run bun test test/mcp-size.test.ts.

Approved — before the latest push

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.

commented

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 — before the latest push

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/name from REPO_ARG/APP_ARG saved 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).
commented

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 the description-free form, so it's smaller than main's. main's lean() 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

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.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs