claude-code - 💡(How to fix) Fix Hosted Notion MCP (DCR): client re-registers per session → repeated full re-auth (orphaned refresh tokens)

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Authenticating the hosted Notion MCP server (https://mcp.notion.com/mcp) via the official notion plugin works, but the session repeatedly drops and demands a full interactive browser re-auth (open URL + paste callback). Notion uses Dynamic Client Registration (RFC 7591), which is supposed to persist client credentials for reuse — but Claude Code appears to register a new OAuth client on many sessions/resumes instead of reusing the persisted one, orphaning the prior refresh token.

This is a follow-on to the now-closed #52961 (which moved Notion off the static claude.ai metadata client onto DCR). DCR fixed the Invalid redirect_uri error, but surfaced this persistence problem.

Error Message

This is a follow-on to the now-closed #52961 (which moved Notion off the static claude.ai metadata client onto DCR). DCR fixed the Invalid redirect_uri error, but surfaced this persistence problem.

  • Compounding idle drops: Connection error: SSE stream disconnected: TimeoutError (×11, ~every 5 min) → after 3 strikes Closing transport (max consecutive terminal errors)HTTP connection closed after ~900–1200s

Root Cause

Hypothesis

Because every workspace shares the one Claude Code-credentials keychain blob and (apparently) a single per-host Notion entry, concurrent workspaces race / last-writer-wins on that entry: when workspace A re-auths after an SSE teardown, it rewrites the Notion client/token, so workspace B's stored refresh token + client-info no longer match → Grant not found / No client info found → re-register (new client_id) → full re-auth. This compounds with the ~5-min SSE idle teardown that forces frequent reconnects.

RAW_BUFFERClick to expand / collapse

Description

Authenticating the hosted Notion MCP server (https://mcp.notion.com/mcp) via the official notion plugin works, but the session repeatedly drops and demands a full interactive browser re-auth (open URL + paste callback). Notion uses Dynamic Client Registration (RFC 7591), which is supposed to persist client credentials for reuse — but Claude Code appears to register a new OAuth client on many sessions/resumes instead of reusing the persisted one, orphaning the prior refresh token.

This is a follow-on to the now-closed #52961 (which moved Notion off the static claude.ai metadata client onto DCR). DCR fixed the Invalid redirect_uri error, but surfaced this persistence problem.

Environment

  • macOS (Darwin), zsh
  • Hosted Notion MCP via official notion plugin: { "type": "http", "url": "https://mcp.notion.com/mcp" } (no oauth block, unlike the slack plugin)
  • Runs under Conductor (headless/remote): logs show Skipping browser open (skipBrowserOpen=true), so every re-auth is a manual open-URL-and-paste
  • Many concurrent Conductor workspaces active (~40+ in ~/Library/Caches/claude-cli-nodejs/)

Evidence (mcp-logs-plugin-Notion-notion, one workspace, several days)

  • 5 distinct dynamically-registered client_ids across sessions (a new one each re-auth)
  • No client info found (×5), Cleared stored tokens (×5)
  • Token refresh failed with invalid_grant: Grant not foundRedirecting to authorization URLHTTP Connection failed: Unauthorized
  • Compounding idle drops: Connection error: SSE stream disconnected: TimeoutError (×11, ~every 5 min) → after 3 strikes Closing transport (max consecutive terminal errors)HTTP connection closed after ~900–1200s

Contrast — Slack hosted MCP (slack plugin, which does pin a fixed oauth.clientId + callbackPort): 1 client_id, 0 full re-auths, 0 logged transport teardowns over the same period.

Where credentials are stored (investigation)

  • Nothing in ~/.claude.json (no oauth/client/token keys) and no ~/.claude/*cred* file.
  • MCP OAuth state is in the macOS Keychain bundled inside the single Claude Code-credentials generic item — there is no per-host keychain item (mcp.notion.com, notion, etc. return nothing).

Hypothesis

Because every workspace shares the one Claude Code-credentials keychain blob and (apparently) a single per-host Notion entry, concurrent workspaces race / last-writer-wins on that entry: when workspace A re-auths after an SSE teardown, it rewrites the Notion client/token, so workspace B's stored refresh token + client-info no longer match → Grant not found / No client info found → re-register (new client_id) → full re-auth. This compounds with the ~5-min SSE idle teardown that forces frequent reconnects.

Ruled out

  • tengu_mcp_local_oauth_blocked_hosts does not include Notion (only microsoft365/gmail/gcal).
  • token_refresh_buffer_ms = 600000 (10 min) — in-session refresh works fine.

Ask

  1. Persist and reuse the DCR client registration (client_id/secret) + refresh token for mcp.notion.com across sessions; only re-register on a genuine invalid_client.
  2. Make per-host MCP OAuth entries concurrency-safe (merge, don't last-writer-wins clobber) so multiple simultaneous Claude Code instances / Conductor workspaces don't invalidate each other's grants.
  3. Consider a longer SSE keepalive / not tearing down the transport so aggressively on idle, to reduce reconnect churn that triggers the above.

Open question

Where is the DCR client info meant to be persisted, and why is No client info found hit on a stable workspace? If it's the shared Claude Code-credentials blob, is access serialized across concurrent processes?

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING