Skip to content

fix: 404 the whole /.well-known/* tree for MCP discovery probes#829

Merged
nadaverell merged 2 commits into
mainfrom
fix/mcp-wellknown-discovery-404
May 30, 2026
Merged

fix: 404 the whole /.well-known/* tree for MCP discovery probes#829
nadaverell merged 2 commits into
mainfrom
fix/mcp-wellknown-discovery-404

Conversation

@nadaverell
Copy link
Copy Markdown
Contributor

@nadaverell nadaverell commented May 30, 2026

Summary

The SPA catch-all route was answering /.well-known/* discovery probes with an HTML 200. Newer MCP HTTP clients (claude-code et al.) probe /.well-known/oauth-protected-resource, /.well-known/oauth-authorization-server, and the resource-scoped variants (e.g. /.well-known/oauth-protected-resource/mcp) per RFC 9728 / RFC 8414 / OIDC discovery. Getting an HTML 200 back instead of a proper JSON document or a 404 makes them treat it as a broken OAuth flow — they either abort MCP registration outright or infer a phantom authenticate step that doesn't exist.

Radar's MCP endpoint is unauthenticated when run locally. The fix replaces the two previously-hardcoded oauth-* paths with a single tree-wide handler that returns a clean 404 for the entire /.well-known/* subtree, so clients correctly infer "no auth handshake needed" and proceed with registration.

Scope


Note

Low Risk
Routing-only change for discovery URLs; no auth, API, or SPA behavior outside /.well-known paths.

Overview
MCP HTTP clients (e.g. Claude Code) probe /.well-known/* and /mcp/.well-known/* before MCP initialize. Without explicit handlers, those paths were answered by the SPA catch-all (200 + HTML) or the /mcp mount (405 on non-POST), which clients treat as a broken OAuth-protected server and surface phantom authenticate tools.

This change registers http.NotFoundHandler() for both subtrees in setupRoutes, before the /mcp mount and SPA /* fallback, so unauthenticated local MCP gets a spec-correct 404 and clients infer no OAuth handshake is required.

Reviewed by Cursor Bugbot for commit 3bbfa36. Bugbot is set up for automated code reviews on this repo. Configure here.

The SPA catch-all was answering OAuth/OIDC discovery probes with an HTML
200, which newer MCP HTTP clients parse as a broken auth flow — aborting
MCP registration or inferring a phantom authenticate step. Radar's MCP
endpoint is unauthenticated locally; a clean 404 across the whole
/.well-known/* tree (RFC 9728 / RFC 8414 / OIDC all probe there, at both
bare and resource-scoped paths) tells clients no auth handshake is needed.

Replaces the two hardcoded oauth-* paths with a tree-wide handler.
@nadaverell nadaverell requested a review from hisco as a code owner May 30, 2026 17:30
Smoke-tested with claude-code 2.1.158: with only /.well-known/*
covered, the chi `r.Mount("/mcp", ...)` answers `/mcp/.well-known/*`
with HTTP 405 because the MCP handler only accepts POST. Newer MCP
HTTP clients probe both forms — path-prefix (/mcp/.well-known/X) and
path-suffix (/.well-known/X/mcp) — per RFC 9728. A 405 there trips
the same `needs-auth` detection as the SPA's HTML 200.

Add the second handler and register BOTH before the /mcp Mount so
chi's radix tree resolves the more specific pattern to NotFound
instead of letting the MCP handler answer with 405.

Verified with a logging reverse-proxy: claude-code now makes zero
.well-known probes during MCP `initialize`; `mcp_servers.status`
goes straight to "connected" instead of stopping at "needs-auth".
@nadaverell nadaverell merged commit 6fa037a into main May 30, 2026
9 checks passed
@nadaverell nadaverell deleted the fix/mcp-wellknown-discovery-404 branch May 30, 2026 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant