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

GET /api/v1/openapi.json answers the OpenAPI document, the same as /contract/openapi.json #4159

Merged opened this

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

Merged

`GET /api/v1/openapi.json` now answers 308 to `/contract/openapi.json` with `cache-control: public, max-age=86400`. The new test and the existing mcp, standards and here-manifest tests pass (65 tests). `bun x tsc --noEmit` could not run here: it fails with "Cannot find type definition file for 'bun'", so the type check is unverified locally.

shipped production is serving it deploy d5b2fe2

opened this

GET /api/v1/openapi.json now answers 308 to /contract/openapi.json with cache-control: public, max-age=86400. The new test and the existing mcp, standards and here-manifest tests pass (65 tests). bun x tsc --noEmit could not run here: it fails with "Cannot find type definition file for 'bun'", so the type check is unverified locally.

  • Where the redirect lives: I put it in src/http/api.ts next to /api/v1/here. /api/ has its own router, so a route in src/http/mcp.ts was never reached.
  • Where the address is named: /llms.txt now has one line under "For agents with an account" saying GET <origin>/api/v1/openapi.json redirects to /contract/openapi.json.
  • Test: in test/mcp.test.ts, it asserts the 308, the location and cache-control headers, and a 200 from the target.

I left the here-manifest's docs field pointing at /llms.txt, because an existing test pins that value.

Closes #4149

commented

GET /api/v1/openapi.json now answers 308 to /contract/openapi.json with cache-control: public, max-age=86400. The new test and the existing mcp, standards and here-manifest tests pass (65 tests). bun x tsc --noEmit could not run here: it fails with "Cannot find type definition file for 'bun'", so the type check is unverified locally.

  • Where the redirect lives: I put it in src/http/api.ts next to /api/v1/here. /api/ has its own router, so a route in src/http/mcp.ts was never reached.
  • Where the address is named: /llms.txt now has one line under "For agents with an account" saying GET <origin>/api/v1/openapi.json redirects to /contract/openapi.json.
  • Test: in test/mcp.test.ts, it asserts the 308, the location and cache-control headers, and a 200 from the target.

I left the here-manifest's docs field pointing at /llms.txt, because an existing test pins that value.

Approved

Does what #4149 asks and nothing more. On the preview, GET /api/v1/openapi.json answers 308 with location: /contract/openapi.json and cache-control: public, max-age=86400. Every security-floor header is still on the response (CSP, nosniff, referrer-policy, HSTS). Following the redirect gives 200 application/json. /llms.txt names the address once.

Security: the route is a fixed, read-only, public redirect. It reads no input, the location is a relative constant so it cannot become an open redirect, and it returns no per-caller data, so the public cache is safe. The test asserts the status, location, cache-control and the target's 200, and it would fail without the route. The src/web/ change is one line of text in llms.txt with no markup, so DESIGN.md does not come into it. There is no page action that the terminal would need to mirror.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs