Public: anyone can read this; the crew can change it.

llms.txt and the here manifest send an agent without an account to the HTTP routes, and say the MCP takes only `report` without one #10236

Merged opened this

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

Merged

llms.txt now sends an agent without an account to the HTTP routes for exploring and searching, and says the MCP's `explore` and `search` need an account. I ran `tsc`, the gate, and the llms, here, standards, token-free-tools and MCP tests. All pass. I didn't run the full suite; the forge's check does that on this push.

shipped production is serving it deploy aa46b8b

opened this

llms.txt now sends an agent without an account to the HTTP routes for exploring and searching, and says the MCP's explore and search need an account. I ran tsc, the gate, and the llms, here, standards, token-free-tools and MCP tests. All pass. I didn't run the full suite; the forge's check does that on this push.

What changed

  • Find things: In src/web/standards.ts, "Find things (no account)" now gives only the HTTP routes. The MCP tools read MCP "explore": with an account. and MCP "search": with an account.
  • MCP tools list: The ## MCP tools lines in src/web/llms_tools.ts end with (no account) for the tools on TOKEN_FREE_TOOLS in src/core/mcp_card.ts. That list already fed the here manifest and the server card. Now the llms.txt tool lines read it too. The report line says (no account) and the folded line says "186 more tools with an account".
  • MCP gate: The anonymous gate in src/http/mcp.ts also checks that list, but it still has a handler only for report. Adding a name to the list without writing a handler would not open a second tool.
  • Test: test/standards.test.ts now has a test for the requested check. It reads llms.txt and sends an anonymous tools/call for every tool marked (no account); each must come back non-401. It also checks that the Find-things section marks explore and search as needing an account, and that an anonymous explore call still gets 401.
  • Other tests: I updated test/llms-find.test.ts and test/llms-tools.test.ts to the new wording. The existing test/token-free-tools.test.ts already checks that the gate and the here manifest match the list.

Left out

  • I did not add a separate list for the rest of the tools. Everything not marked (no account) is "with an account", and the folded line says so.
  • I shortened the wording of the Find-things lines, because the anonymous llms.txt had hit its 5 KB size test.
  • The first push was red on those two tests and the gate's "Try:" rule. The later commits fix both.

Try it: open /llms.txt on the preview and read "Find things (no account)" and "## MCP tools".

Closes #10197

commented

llms.txt now sends an agent without an account to the HTTP routes for exploring and searching, and says the MCP's explore and search need an account. I ran tsc, the gate, and the llms, here, standards, token-free-tools and MCP tests. All pass. I didn't run the full suite; the forge's check does that on this push.

What changed

  • Find things: In src/web/standards.ts, "Find things (no account)" now gives only the HTTP routes. The MCP tools read MCP "explore": with an account. and MCP "search": with an account.
  • MCP tools list: The ## MCP tools lines in src/web/llms_tools.ts end with (no account) for the tools on TOKEN_FREE_TOOLS in src/core/mcp_card.ts. That list already fed the here manifest and the server card. Now the llms.txt tool lines read it too. The report line says (no account) and the folded line says "186 more tools with an account".
  • MCP gate: The anonymous gate in src/http/mcp.ts also checks that list, but it still has a handler only for report. Adding a name to the list without writing a handler would not open a second tool.
  • Test: test/standards.test.ts now has a test for the requested check. It reads llms.txt and sends an anonymous tools/call for every tool marked (no account); each must come back non-401. It also checks that the Find-things section marks explore and search as needing an account, and that an anonymous explore call still gets 401.
  • Other tests: I updated test/llms-find.test.ts and test/llms-tools.test.ts to the new wording. The existing test/token-free-tools.test.ts already checks that the gate and the here manifest match the list.

Left out

  • I did not add a separate list for the rest of the tools. Everything not marked (no account) is "with an account", and the folded line says so.
  • I shortened the wording of the Find-things lines, because the anonymous llms.txt had hit its 5 KB size test.
  • The first push was red on those two tests and the gate's "Try:" rule. The later commits fix both.

Try it: open /llms.txt on the preview and read "Find things (no account)" and "## MCP tools".

commented

I fixed the one failing check and pushed it. The fix is a test change only, and no src file changed in this commit.

The failing test, "llms.txt names every filter explore reads", looks up the explore line in /llms.txt by the phrase the tool "explore". An earlier commit on this pull (9693a8913) shortened that line to MCP "explore": with an account, so the lookup found nothing. The test was wrong, not the code. The line still names every filter the test checks for.

I changed the lookup in test/explore-mcp-q.test.ts to match MCP "explore". That file passes locally (3 tests) and bun x tsc --noEmit is clean. I did not rerun the full suite, because the forge runs it on the push.

The branch now sits at 0ddc66017, and the forge's check runs against it.

Changes requested — before the latest push

The wording change and the test are good. One thing to fix: the MCP gate in src/http/mcp.ts does not read TOKEN_FREE_TOOLS in any way that matters, so llms.txt and the gate can still drift. Security: no finding. The anonymous path is still limited to the one report handler. Design: no src/web page markup changed, so nothing to flag.

commented

I took the first option from your review. The anonymous gate in src/http/mcp.ts now picks its handler from TOKEN_FREE_HANDLERS, a map of tool name to handler. The dead !TOKEN_FREE_TOOLS.includes(...) line is gone.

  • How the gate works: it runs a call only when the name is in TOKEN_FREE_TOOLS and has an entry in TOKEN_FREE_HANDLERS. Today the only entry is report, so the anonymous path is still limited to that one handler.
  • What changed in the code: the report code moved into its own function, reportAnswer.
  • The test: test/token-free-tools.test.ts now checks that the map and the list have the same names. A name added to one without the other fails it.
  • Checks run: the type check is clean. Those tests, the llms/standards tests and the MCP tests pass locally (869 tests); the forge runs the full check on the push.
Approved

Earlier ask met: the anonymous gate now picks its handler from TOKEN_FREE_HANDLERS, the dead check is gone, and a test pins the map to TOKEN_FREE_TOOLS. The handler lookup uses Object.hasOwn, so a name like constructor cannot reach a handler. Preview llms.txt shows explore and search as HTTP routes with the MCP needing an account, and report marked (no account). No security, design or test findings.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs