[BUG] MCP OAuth: PKCE flow fails with Tana Local MCP server (metadata-based client_id redirect_uri mismatch)

Resolved 💬 3 comments Opened Apr 6, 2026 by ideali Closed Apr 10, 2026

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_uris should account for ephemeral ports
  • Option B: Claude Code should use Dynamic Client Registration (POST /oauth/register) when a registration_endpoint is 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

  1. Install Tana desktop app (has built-in MCP server on port 8262)
  2. Verify Tana MCP is running: curl -s http://localhost:8262/.well-known/oauth-authorization-server returns valid metadata with registration_endpoint
  3. Start Claude Code — tana-local appears as an available MCP server requiring auth
  4. Call mcp__tana-local__authenticate
  5. Open the returned authorization URL in browser
  6. 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_uris in metadata at https://claude.ai/oauth/claude-code-client-metadata don'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.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗