fix(auth): loopback redirect URIs must match on any port (RFC 8252 §7.3) #5
Labels
No labels
waiting-on-julian
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
jlxq0/carddav-mcp#5
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Symptom
Claude Code CLI cannot complete Dynamic Client Registration:
Observed against
caldav-mcpand diagnosed there;src/oauth_redirect.rsis copy-pasted across all five Rust MCP servers, so this repo has the same defect.Cause
is_allowed_redirect_uri(src/oauth_redirect.rs:23) requires exact string equality against the allowlist. The allowlist carrieshttp://localhost:8787/callback. Claude Code CLI does not use 8787: it binds a random free port per session (the observed attempt usedhttp://localhost:3118/callback) and only consults a fixed port if every random draw fails.MCP_OAUTH_CALLBACK_PORToverrides it, but nothing sets that by default. No static entry can match, so native loopback clients are permanently locked out.RFC 8252 §7.3:
validate_redirect_urialready implements the loopback carve-out for the scheme check — cleartexthttpis permitted on loopback hosts only. The port half of the same rule was never written.Fix
When an allowlist entry is a loopback
httpURI, compare scheme + host + path and ignore the port. Non-loopback entries keep exact matching: the port is a meaningful part of anhttpsor private-scheme callback and relaxing it there would be a real hole.Tests:
http://localhost:8787/callbackallowlisted acceptshttp://localhost:3118/callbackhttp://localhost:3118/other— path still mattershttp://127.0.0.1:3118/callbackunless127.0.0.1is listed separately — RFC 8252 relaxes the port, not the hosthttps://claude.ai/api/mcp/auth_callbackstill rejectshttps://claude.ai:8443/api/mcp/auth_callbackBefore trusting the new tests, break the matcher and watch them go red.
Scope
Sibling issue with the full diagnosis: jlxq0/caldav-mcp#2
Also affected: jmap-mcp, m365-mcp, typst-mcp, caldav-mcp.
No deployment manifest change is required — the existing allowlists already carry a loopback entry, which starts matching once the rule is right.