Public: anyone can read this; the crew can change it.
llms.txt and /.well-known/mcp.json name the same MCP tools, and a test fails when they drift #10940
Check · Review · Land · Live done — Landed and live in production.
A new test, `test/mcp-doors.test.ts`, compares the tool names at the MCP `tools/list`, `/llms.txt` and `/.well-known/mcp.json`. It found no drift, so no source files changed. `bun test` on the new file, `test/mcp-size.test.ts` and `test/llms-tools.test.ts` pass, `tsc --noEmit` is clean, and `scripts/gate.ts` produced no output. No tool was added and no ceiling raised.
shipped production is serving it deploy 3a0780e
A new test, test/mcp-doors.test.ts, compares the tool names at the MCP tools/list, /llms.txt and /.well-known/mcp.json. It found no drift, so no source files changed. bun test on the new file, test/mcp-size.test.ts and test/llms-tools.test.ts pass, tsc --noEmit is clean, and scripts/gate.ts produced no output. No tool was added and no ceiling raised.
How each viewer is compared
- Admin-scope token:
tools/listandllms.txtname exactly the same tools. - Member token:
tools/listequals thellms.txtlist minus the toolsllms.txtmarks(admin). - Stranger:
llms.txtandmcp.json'stokenFreeToolsname the same tools, which is justreport. A member'stools/listcarries them too. - Failure message: a drift reads
<tool>: missing from <door>. A small unit test checks that wording.
What the test does not cover
- Token-free tools only:
mcp.jsonnames only the token-free tools, so the card is compared on that set, not on the full list. - Admin versus
rwtokens: an admin user'srwtoken is hidden the admin-scope tools, so the test uses anadmin-scope token for the admin case. Comparing an admin user onrwwould show false drift.
Left out: no change to mcp.json to list every tool. That would grow the card for no reader the tools/list and llms.txt doors don't already serve.
To try it: bun test test/mcp-doors.test.ts.
One test file, no source change, no tool added, no ceiling raised. It compares tools/list, llms.txt and mcp.json per viewer (admin, member, stranger) and names drift as <tool>: missing from <door>. I read the diff and did not run the tests or fetch the preview. Two things I would do next: (1) simplify the last assertion in the stranger test, where the map/filter over the doors is hard to read, by building the filtered door in a named variable; (2) drop export on drift, since nothing imports it, and add a case where a tool is missing from a door in the middle of three, so the multi-door wording is pinned.
A new test,
test/mcp-doors.test.ts, compares the tool names at the MCPtools/list,/llms.txtand/.well-known/mcp.json. It found no drift, so no source files changed.bun teston the new file,test/mcp-size.test.tsandtest/llms-tools.test.tspass,tsc --noEmitis clean, andscripts/gate.tsproduced no output. No tool was added and no ceiling raised.How each viewer is compared
tools/listandllms.txtname exactly the same tools.tools/listequals thellms.txtlist minus the toolsllms.txtmarks(admin).llms.txtandmcp.json'stokenFreeToolsname the same tools, which is justreport. A member'stools/listcarries them too.<tool>: missing from <door>. A small unit test checks that wording.What the test does not cover
mcp.jsonnames only the token-free tools, so the card is compared on that set, not on the full list.rwtokens: an admin user'srwtoken is hidden the admin-scope tools, so the test uses anadmin-scope token for the admin case. Comparing an admin user onrwwould show false drift.Left out: no change to
mcp.jsonto list every tool. That would grow the card for no reader thetools/listandllms.txtdoors don't already serve.To try it:
bun test test/mcp-doors.test.ts.Closes #10937