Intent: a client refused by the API learns where to authenticate, as an MCP client does.
Seen: POST /mcp without a token answers 401 with www-authenticate: Bearer realm="forge", resource_metadata="<origin>/.well-known/oauth-protected-resource"; GET /api/v1/feed answers 401 with no such header.
Done:
[ ] every 401 the API answers (the shared unauthorized refusal) carries the same header, built by one function both doors call
[ ] a test: /api/v1/feed and one repository write without a token answer 401 with the header; /mcp is unchanged
Files: src/http/refusal.ts or wherever the 401 is built, src/http/mcp.ts (to share the builder), one test.
Risk: none to callers; only a header is added.
Intent: a client refused by the API learns where to authenticate, as an MCP client does.
Seen:
POST /mcpwithout a token answers 401 withwww-authenticate: Bearer realm="forge", resource_metadata="<origin>/.well-known/oauth-protected-resource";GET /api/v1/feedanswers 401 with no such header.Done:
unauthorizedrefusal) carries the same header, built by one function both doors call/api/v1/feedand one repository write without a token answer 401 with the header; /mcp is unchangedFiles: src/http/refusal.ts or wherever the 401 is built, src/http/mcp.ts (to share the builder), one test. Risk: none to callers; only a header is added.