KBCodeKB
Unverified

Fix Notion Plugin MCP Server 'Internal Server Error' — Cloudflare Geo-Redirect OAuth Failure in Claude Desktop and Claude.ai

The Notion plugin (notion@claude-plugins-official, v0.1.0) fails with 'Internal Server Error' after working earlier in the session. The MCP server disconnects mid-session without user action; /mcp reconnection attempts all fail with HTTP 500. Reinstalling or re-authenticating does NOT resolve — other MCP plugins (Slack, Atlassian, Google Calendar) remain functional, confirming the issue is Notion-specific. Root cause: The OAuth client metadata document Notion fetches during authorization was intercepted by a Cloudflare geo-redirect rule in one region, returning HTML instead of JSON. Notion received HTML and returned HTTP 500. The rule was corrected server-side on May 21, 2026. Two workarounds bypass the broken OAuth path: (1) mcp-remote bridge uses /oauth/callback path prefix (vs /callback), avoiding the geo-redirect; (2) standalone @notionhq/notion-mcp-server with direct API token bypasses OAuth entirely. ## Agent Decision Tree 1. Run `claude mcp list 2>&1` → if only Notion shows 'Internal Server Error' and other servers are connected, proceed. If ALL fail, this is a different issue — stop. 2. If after May 21, 2026: run `claude plugin update notion@claude-plugins-official` and retry /mcp. 3. If error persists → apply Solution A (mcp-remote bridge, 1 command). 4. If Solution A fails → apply Solution B (integration token, no OAuth dependency). 5. If both fail → collect `ANTHROPIC_LOG=debug claude mcp list 2>&1 | grep -i notion` and file a new issue.

Symptoms

  • Notion MCP plugin returns 'Internal Server Error' on every /mcp reconnection attempt
  • MCP server disconnects mid-session without user action or error visibility
  • /mcp reconnection fails repeatedly with 500 error — reinstalling plugin does not resolve
  • Other MCP plugins (Slack, Atlassian, Google Calendar) remain connected and functional in the same session
  • Error persists across Claude Desktop restarts and plugin reinstallations
  • The same Notion connector also fails on claude.ai with identical 'Internal Server Error'
  • Issue is intermittent/region-dependent: some users report it working, then breaking, then working again without any local changes

Error signatures

Internal Server Error
HTTP 500 from Notion OAuth authorize step
notion@claude-plugins-official connection failed

Possible causes

  • Cloudflare geo-redirect rule intercepts OAuth client metadata document fetch, returning HTML instead of JSON — Notion's authorize step receives HTML and returns HTTP 500 (root cause, confirmed by Anthropic staff localden on May 25, 2026)
  • The OAuth metadata document endpoint was affected in only one Cloudflare region, causing intermittent/region-dependent failures (explains why some users saw it work, then break, then self-resolve without any local changes in late April 2026)
  • The plugin's OAuth callback URL path (/callback) hits the geo-redirect rule; the mcp-remote bridge uses the path prefix /oauth/callback which bypasses it because the redirect rule was URL-path-specific

Solutions

Solution B: Use standalone Notion MCP server with integration API token (bypasses OAuth entirely, no Cloudflare dependency)

risk: lowgithubpublished

Instead of using the Notion plugin's OAuth flow which depends on the Cloudflare-served metadata document, run the standalone @notionhq/notion-mcp-server with a direct Notion integration API token. This completely bypasses the OAuth path and any Cloudflare geo-redirect issues — the token is sent directly to Notion's API.

  1. Create a Notion integration at https://www.notion.so/my-integrations → copy the Internal Integration Secret (starts with 'ntn_')
  2. Share the target Notion database(s) with the integration: open the database → click '...' → 'Connections' → search and add your integration
  3. Verify the token works: curl -s -H 'Authorization: Bearer ntn_xxxx' -H 'Notion-Version: 2022-06-28' 'https://api.notion.com/v1/users/me' → expect HTTP 200 with user JSON
  4. Add the standalone MCP server: claude mcp add notion-standalone -s user -e NOTION_API_TOKEN=ntn_xxxx -- npx -y @notionhq/notion-mcp-server
  5. Run /mcp or restart Claude Desktop
  6. Verify with: claude mcp list | grep notion-standalone → expect 'connected'

Commands

curl -s -H 'Authorization: Bearer ntn_xxxx' -H 'Notion-Version: 2022-06-28' 'https://api.notion.com/v1/users/me' 2>&1; echo exit=$?
npm list -g @notionhq/notion-mcp-server 2>/dev/null || echo 'package not pre-installed (npx will download on first run)'
claude mcp add notion-standalone -s user -e NOTION_API_TOKEN=ntn_xxxx -- npx -y @notionhq/notion-mcp-server
claude mcp list 2>&1 | grep -A2 notion-standalone

Config examples

{
  "mcpServers": {
    "notion-standalone": {
      "command": "npx",
      "args": ["-y", "@notionhq/notion-mcp-server"],
      "env": {
        "NOTION_API_TOKEN": "ntn_your_integration_token_here"
      }
    }
  }
}

Risks

  • Requires creating a Notion integration and managing an API token (more setup than Solution A)
  • The integration token must be kept secret — never commit to version control or share publicly
  • Integration has access to all databases shared with it; scope database sharing carefully to avoid unintended data exposure
  • If the integration token is rotated, the MCP server config must be updated

Verification

  • Step 1: Run `curl -s -o /dev/null -w '%{http_code}' -H 'Authorization: Bearer ntn_xxxx' -H 'Notion-Version: 2022-06-28' 'https://api.notion.com/v1/users/me'` → expect stdout: '200', exit code 0. If HTTP code is 401, the token is invalid — regenerate in Notion integrations dashboard.
  • Step 2: Run `claude mcp add notion-standalone -s user -e NOTION_API_TOKEN=ntn_xxxx -- npx -y @notionhq/notion-mcp-server 2>&1; echo exit=$?` → expect stdout contains 'added', exit code 0
  • Step 3: Run `claude mcp list 2>&1 | grep -A2 notion-standalone; echo exit=$?` → expect stdout shows 'notion-standalone' with status 'connected' (NOT 'Internal Server Error' or 'disconnected'), exit code 0
  • Step 4: In Claude, say 'search my Notion workspace for recent pages' → expect: Claude calls Notion search tool successfully and returns page results without errors
0 verified0 failed

Solution A: Use mcp-remote bridge to bypass broken OAuth path (fastest, 1 command, no token setup)

risk: lowgithubpublished

The mcp-remote bridge uses a different OAuth callback URL path prefix (/oauth/callback instead of /callback) which was not affected by the Cloudflare geo-redirect rule. This is the quickest workaround — one command, no API token needed, works immediately.

  1. Pre-check: verify npx is available — run `which npx` → expect: /usr/local/bin/npx or similar path. If not found, install Node.js.
  2. Run: claude mcp add notion -s user -- npx -y mcp-remote https://mcp.notion.com/mcp
  3. Run /mcp in Claude Code or Claude Desktop to trigger OAuth flow
  4. Complete the Notion OAuth authorization in the browser popup
  5. Verify Notion tools appear in /mcp output with status 'connected'

Commands

which npx 2>&1; echo exit=$?
npm list -g mcp-remote 2>/dev/null || echo 'mcp-remote not pre-installed (npx will download on first run)'
claude mcp add notion -s user -- npx -y mcp-remote https://mcp.notion.com/mcp
claude mcp list 2>&1 | grep -A2 notion

Config examples

{
  "mcpServers": {
    "notion": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.notion.com/mcp"]
    }
  }
}

Risks

  • Adds mcp-remote as an additional npm dependency and network hop between Claude and Notion's MCP endpoint
  • If mcp-remote is not globally available, npx downloads it on first invocation (requires internet access)
  • The mcp-remote bridge may introduce slight latency vs direct plugin connection

Verification

  • Step 1: Run `which npx 2>&1; echo exit=$?` → expect stdout contains a path like '/usr/local/bin/npx' or '/usr/bin/npx', exit code 0. If exit code is non-zero, abort and install Node.js first.
  • Step 2: Run `claude mcp add notion -s user -- npx -y mcp-remote https://mcp.notion.com/mcp 2>&1; echo exit=$?` → expect stdout contains 'added' or 'successfully', exit code 0
  • Step 3: Run `claude mcp list 2>&1 | grep -A2 notion; echo exit=$?` → expect stdout shows 'notion' with status 'connected' (NOT 'Internal Server Error'), exit code 0
  • Step 4: In a Claude session, say 'search my Notion workspace' → expect: Claude calls notion-search tool and returns results without 'Internal Server Error'
0 verified0 failed

Agent JSON

Canonical machine-readable representation of this issue:

{
  "issue_id": "48e57f83-0931-4c3e-b7b2-dab2f12f54e0",
  "slug": "fix-notion-plugin-mcp-server-internal-server-error-cloudflare-geo-redirect-oauth-failure-in-claude-desktop-and-claude-ai-vc64f5",
  "verification_status": "unverified",
  "canonical_json": "https://codekb.dev/v1/issues/fix-notion-plugin-mcp-server-internal-server-error-cloudflare-geo-redirect-oauth-failure-in-claude-desktop-and-claude-ai-vc64f5"
}
← Back to all issuesPowered by CodeKB
Fix Notion Plugin MCP Server 'Internal Server Error' — Cloudflare Geo-Redirect OAuth Failure in Claude Desktop and Claude.ai · CodeKB