MCP OAuth SDK sends empty User-Agent, causing 403 from WAF/Cloudflare-protected servers

Resolved 💬 4 comments Opened Apr 13, 2026 by railima Closed Jun 9, 2026

Bug description

Claude Code's MCP OAuth SDK does not send a User-Agent header (or sends an empty one) during the OAuth discovery and authentication flow. This causes 403 Forbidden responses from servers behind WAFs that block requests without a User-Agent (AWS WAF, Cloudflare bot protection, nginx rules, etc.).

The regular MCP HTTP transport correctly sends User-Agent: claude-code/<version> (cli), but the OAuth SDK that runs before the transport (during /.well-known discovery, DCR, and token exchange) does not.

Reproduction steps

  1. Deploy an MCP server behind any WAF that blocks empty User-Agent (this is a common default rule on AWS WAF, Cloudflare, etc.)
  2. Configure it in Claude Code: claude mcp add myserver --transport http https://myserver.example.com/mcp
  3. Restart Claude Code
  4. The OAuth flow fails with: SDK auth failed: HTTP 403: Invalid OAuth error response: SyntaxError: JSON Parse error: Unrecognized token '<'

Evidence

Tested against a staging server behind AWS ALB/WAF:

# With User-Agent (works):
curl https://myserver.example.com/.well-known/oauth-protected-resource
# → 200 {"resource":"...","authorization_servers":["..."]}

# Without User-Agent (blocked by WAF):
curl -H "User-Agent:" https://myserver.example.com/.well-known/oauth-protected-resource
# → 403 <html><head><title>403 Forbidden</title></head>...</html>

# Node.js fetch reproduces the same behavior:
node -e "fetch('https://myserver.example.com/.well-known/oauth-protected-resource', { headers: { 'User-Agent': '' } }).then(r => console.log(r.status))"
# → 403

The MCP server itself works correctly. We validated the full flow (token generation, authenticated connections, tool calls) via MCP Inspector with manual Bearer tokens.

Expected behavior

The OAuth SDK should send a proper User-Agent header (e.g., claude-code/<version> (cli)) on all HTTP requests, consistent with what the MCP HTTP transport already does.

Related issues

  • openai/codex#12859: identical bug in OpenAI Codex's rmcp HTTP client (no User-Agent on OAuth requests causes 403 from Cloudflare)
  • #34982: confirms the MCP transport itself sends User-Agent: claude-code/2.1.76 (cli), so the gap is specifically in the OAuth SDK

Environment

  • Claude Code version: latest (April 2026)
  • OS: Ubuntu Linux (also reproducible via curl on any OS)
  • MCP transport: Streamable HTTP
  • WAF: AWS ALB with standard bot protection rules (blocks empty User-Agent)

View original on GitHub ↗

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