[BUG] MCP OAuth: PKCE flow fails with Tana Local MCP server (metadata-based client_id redirect_uri mismatch)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Claude Code cannot authenticate with Tana Local MCP server (HTTP transport at localhost:8262/mcp). The OAuth PKCE flow fails every time — calling mcp__tana-local__authenticate generates an authorization URL, but completing the flow always results in an error.
The root cause: Claude Code's client metadata at https://claude.ai/oauth/claude-code-client-metadata declares redirect_uris without ports:
{
"redirect_uris": [
"http://localhost/callback",
"http://127.0.0.1/callback"
]
}
But Claude Code starts its callback server on an ephemeral port (e.g., http://localhost:55611/callback). The MCP server rejects the redirect_uri mismatch.
What Should Happen?
Claude Code should successfully complete the OAuth PKCE flow with any MCP server that supports code_challenge_methods_supported: ["S256"]. Per RFC 8252 Section 7.3, loopback redirect URIs should match on any port.
Either:
- Option A: The client metadata
redirect_urisshould account for ephemeral ports - Option B: Claude Code should use Dynamic Client Registration (
POST /oauth/register) when aregistration_endpointis available, instead of relying on metadata-based client_id
Error Messages/Logs
{
"error": "invalid_request",
"error_description": "[{\"origin\":\"string\",\"code\":\"too_small\",\"minimum\":43,\"inclusive\":true,\"path\":[\"code_challenge\"],\"message\":\"Too small: expected string to have >=43 characters\"}]"
}
Note: the error says `code_challenge` but the actual issue is redirect_uri mismatch. Tana's Zod validation order causes a misleading error message.
Steps to Reproduce
Steps to Reproduce
- Install Tana desktop app (has built-in MCP server on port 8262)
- Verify Tana MCP is running:
curl -s http://localhost:8262/.well-known/oauth-authorization-serverreturns valid metadata withregistration_endpoint - Start Claude Code —
tana-localappears as an available MCP server requiring auth - Call
mcp__tana-local__authenticate - Open the returned authorization URL in browser
- Auth fails with the error above
What works (proving the issue is in the client_id flow):
# Dynamic Client Registration + PKCE = success
CLIENT=$(curl -s -X POST "http://localhost:8262/oauth/register" \
-H "Content-Type: application/json" \
-d '{"client_name":"test","redirect_uris":["http://localhost:19876/callback"],...}')
# ... full OAuth flow completes, access_token returned
Workaround
Stdio proxy that performs Dynamic Client Registration + PKCE token lifecycle, configured as a stdio MCP server in .mcp.json.
Environment
- Claude Code CLI (latest as of 2026-04-07)
- Tana Desktop (built-in MCP server v0.1.0, port 8262)
- macOS Darwin 25.5.0
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.92
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Other
Additional Information
Root Cause Analysis
Claude Code uses metadata-based client_id: https://claude.ai/oauth/claude-code-client-metadata
The metadata document declares:
{
"redirect_uris": [
"http://localhost/callback",
"http://127.0.0.1/callback"
]
}
But Claude Code starts a callback server on an ephemeral port (e.g., http://localhost:55611/callback). Tana's OAuth server rejects the redirect_uri mismatch, but surfaces a misleading code_challenge validation error.
Evidence
- Dynamic Client Registration with matching redirect_uri + PKCE -> works perfectly
- Metadata-based client_id + same PKCE params -> fails (redirect_uri port mismatch)
- The
redirect_urisin metadata athttps://claude.ai/oauth/claude-code-client-metadatadon't include ports
Suggested Fix
Option A: Update client metadata to include wildcard localhost ports per RFC 8252 Section 7.3 (loopback redirect URIs should match on any port).
Option B: Use Dynamic Client Registration (POST /oauth/register) when registration_endpoint is available, instead of metadata-based client_id.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗