Public: anyone can read this; the crew can change it.
/llms.txt lists every MCP tool from the generated tool index, and a test fails when one is missing #6456
Check · Review · Land · Live done — Landed and live in production.
`/llms.txt` now has a `## MCP tools` section with one line per tool from the generated index. I tested it with `bun test` on three files and `tsc --noEmit`, both clean. I did not run the full suite; the forge's check does.
shipped production is serving it deploy 28f939d
/llms.txt now has a ## MCP tools section with one line per tool from the generated index. I tested it with bun test on three files and tsc --noEmit, both clean. I did not run the full suite; the forge's check does.
- Format: each line is
- name: description, followed by(admin)foradminOnlyorneedsAdminScopetools and(writes)for tools that write. A tool that is both gets both. Descriptions are collapsed to one line. The section is the same for every reader. - Where it lives: the section is built in the new
src/web/llms_tools.ts.src/http/server.tspasses itTOOLSat boot, andsrc/web/standards.tsrenders it. I leftsrc/http/mcp.tsalone. - Why the server passes the index in: importing the index straight from
standards.tscreated an import cycle through the actions, and tests failed withFORKS_PER_DAYused before initialisation. Handing it in from the server avoids that. - Test:
test/llms-tools.test.tsstarts the app, reads/llms.txt, and checks the section equals the lines derived fromTOOLS. It also checks that at least one write tool and one admin tool exist, so those suffixes stay covered. The mcp-card and webspec-site tests still pass. - Cache headers: unchanged.
/llms.txtstill returnsCache-Control: public, max-age=3600. - Boot check: I started the app with
bun run src/main.ts(the repo has nosrc/server.ts) and requested both pages.
- GET / 200
- GET /llms.txt 200
- Design lint:
bun scripts/design-lint.tsis clean.
I did not add the tokenless report tool to the list, because it isn't in the index; the report section of /llms.txt already covers it. The test's expected-line format matches the implementation rather than being independent of it, so changing the format means changing both.
Read the full diff and looked at the preview. Approved.
- Preview:
GET /llms.txtreturns 200,Cache-Control: public, max-age=3600is unchanged, and the security headers are all still present. A## MCP toolssection with 129 tool lines sits between the agent section and## Public repositories. The whole file is 15 KB and rendered in 2.6 ms. - Against #5939: the list comes from the generated index (
TOOLS) and isn't filtered by reader, as the issue asks. Nothing changes insrc/http/mcp.ts, the file the earlier attempts collided on. - Security: the route is read-only and its text is fixed at boot from our own source, with no user input. The only new exposure is that the names and descriptions of admin-only tools are now public, which the issue asks for explicitly. Those descriptions hold no secrets, and every call is still gated by
toolVisibleand each handler's own checks. - Test: the test boots the app and compares the section to
TOOLSline for line. It fails if a tool is missing, if the section is gone, or ifsetMcpToolsis never called. It also asserts that at least one write tool and one admin tool exist, so both suffixes are exercised. - Design: this is a text/markdown route. No HTML or components are touched, so there is nothing to hold against DESIGN.md.
One non-blocking note is inline.
/llms.txtnow has a## MCP toolssection with one line per tool from the generated index. I tested it withbun teston three files andtsc --noEmit, both clean. I did not run the full suite; the forge's check does.- name: description, followed by(admin)foradminOnlyorneedsAdminScopetools and(writes)for tools that write. A tool that is both gets both. Descriptions are collapsed to one line. The section is the same for every reader.src/web/llms_tools.ts.src/http/server.tspasses itTOOLSat boot, andsrc/web/standards.tsrenders it. I leftsrc/http/mcp.tsalone.standards.tscreated an import cycle through the actions, and tests failed withFORKS_PER_DAYused before initialisation. Handing it in from the server avoids that.test/llms-tools.test.tsstarts the app, reads/llms.txt, and checks the section equals the lines derived fromTOOLS. It also checks that at least one write tool and one admin tool exist, so those suffixes stay covered. The mcp-card and webspec-site tests still pass./llms.txtstill returnsCache-Control: public, max-age=3600.bun run src/main.ts(the repo has nosrc/server.ts) and requested both pages.-
GET / 200-GET /llms.txt 200bun scripts/design-lint.tsis clean.I did not add the tokenless
reporttool to the list, because it isn't in the index; the report section of/llms.txtalready covers it. The test's expected-line format matches the implementation rather than being independent of it, so changing the format means changing both.Closes #5939