Notion MCP × Claude Code が Invalid redirect_uri で繋がらない原因と回避策

Claude Code から Notion の HTTP MCP に繋ごうとすると Invalid redirect_uri for OAuth client で失敗する。原因は CIMD ドキュメントと認可URLの redirect_uri 不一致で、ユーザー側では直せない。stdio 版 + Internal Integration Token に切り替えれば回避できる(2026-04 時点)。

s1mlogs1mlog
28 April, 2026
Notion MCP × Claude Code が Invalid redirect_uri で繋がらない原因と回避策

結論: Claude Code から Notion の HTTP MCP に繋ごうとして Invalid redirect_uri for OAuth client が出る場合、原因は Claude Code 側のバグで、ユーザー側で根本対処はできない(2026-04 時点)。回避策は stdio 版の @notionhq/notion-mcp-server + Internal Integration Token に切り替えること。

要約

  • 事象: claude mcp add --transport http notion https://mcp.notion.com/mcp で追加して /mcp から認可しようとすると失敗する
  • 原因: Claude Code が認可URLに付ける redirect_uri がポート付き (http://localhost:3118/callback) なのに、CIMD ドキュメントに登録されている redirect_uris はポート無し (http://localhost/callback)。Notion 側は CIMD と完全一致でしか受け付けないので弾かれる
  • --callback-port オプションは「ローカルで listen するポート」しか変えず、認可URLの redirect_uri には反映されない(罠)
  • 追跡先: anthropics/claude-code #37747(2026-04-28 時点 OPEN)
  • 回避策: stdio 版に切り替え、Notion の Internal Integration Token を使う

環境

  • Claude Code 2.1.119
  • macOS(cache パスは macOS 前提で記述)
  • Notion MCP: https://mcp.notion.com/mcp (リモート HTTP)
  • 確認日: 2026-04-28

症状

Claude Code に Notion MCP を HTTP で追加する。

claude mcp add --transport http notion https://mcp.notion.com/mcp

追加直後はサーバー側に認可済みではないので、/mcp で認可フローが開く。Notion のログイン画面に進むところで以下が表示される。

Invalid redirect_uri for OAuth client

同じ Claude Code から Slack や Google Drive の HTTP MCP は同じ手順で問題なく繋がる。Notion 固有の挙動だと切り分けられる。

ログを読む

MCP 認可フローの送受信は Claude Code が JSON Lines でキャッシュしている。macOS だとパスはここ。

~/Library/Caches/claude-cli-nodejs/<project-id>/mcp-logs-<server-name>/<timestamp>.jsonl

Notion の場合は mcp-logs-notion。最新ファイルを開くと、Claude Code が組み立てた認可URLが入っている。クエリパラメータをデコードすると以下のようになっている。

client_id=https://claude.ai/oauth/claude-code-client-metadata
redirect_uri=http://localhost:3118/callback
response_type=code
scope=...
state=...

ポイントは redirect_uri にポート 3118 が付いていること。これが Notion 側で弾かれている直接の原因になる。

CIMD ドキュメントを直接見にいく

client_id が URL になっているのは Client ID Metadata Document(CIMD)方式の OAuth クライアントだからで、その URL の中身がそのままクライアントメタデータになる。curl で叩いてみる。

curl -s https://claude.ai/oauth/claude-code-client-metadata | jq .

redirect_uris の値はこうなっている。

{
  "redirect_uris": [
    "http://localhost/callback",
    "http://127.0.0.1/callback"
  ],
  ...
}

ポートが入っていない。Notion の認可サーバーは送られてきた redirect_uri を CIMD の redirect_uris と完全一致で照合する。送信側が http://localhost:3118/callback、登録側が http://localhost/callback なので一致せず、Invalid redirect_uri for OAuth client でリジェクトされる、という流れになっている。

Notion MCP の OAuth で起きている redirect_uri 不一致を示す図。Claude Code は localhost:3118 のコールバックを認可URLに乗せるが、CIMD 側の登録値はポート無し。Notion 認可サーバーは完全一致でチェックするため reject され、Invalid redirect_uri for OAuth client が表示される。

--callback-port で直る? → 直らない

Claude Code には --callback-port オプションがある。もしこれが認可URL生成に使われているなら、CIMD 側の値(ポート無し)に合わせて 80 や空文字を渡せば直りそうに見える。が、実際にはこれは ローカルでコールバックを listen するポートを変えるだけで、認可URLの redirect_uri パラメータには反映されない。

仮に --callback-port 80 にしても、認可URLは依然として元のポート(3118)が付いた状態で生成される。Notion 側が見ているのは認可URLの redirect_uri なので、ローカルの listen ポートをいくらいじっても挙動は変わらない。

GitHub Issue

同じ症状でハマっている人がいないか探したら、すぐにヒットした。

タイトルがそのまま今回の現象を要約している。Claude Code が CIMD の redirect_uris にポート付きの値を含めるか、認可URLにポート無しの redirect_uri を載せるかのどちらかで直るが、いずれもクライアント側(Anthropic)の修正が必要で、ユーザーの設定では避けられない。

2026-04-28 時点で OPEN のまま。修正されたら本記事の前提も変わるので、コメント欄や issue の更新も合わせて確認することをおすすめする。

回避策: stdio 版 + Internal Integration Token

HTTP 版が直るまで詰まるかというと、そうでもない。Notion 公式の stdio 版 MCP サーバーInternal Integration Tokenを組み合わせれば、OAuth フローを完全に回避できる。

1. Notion 側で Internal Integration を作る

  1. Notion 統合管理ページにアクセス
  2. 「新しい統合」を作成、Type は Internal
  3. 連携対象のワークスペースを選び、必要な権限(Read/Update/Insert content など)を付与
  4. 発行された secret_xxxx 形式の Integration Token を控える
  5. 連携したいページ・データベースを開いて、右上の「接続」から作成した統合を許可する

2. Claude Code に stdio 版を追加する

HTTP 版は一旦削除しておく。

claude mcp remove notion

stdio 版を追加する。Token は環境変数で渡す。

claude mcp add notion \
  -e OPENAPI_MCP_HEADERS='{"Authorization":"Bearer secret_xxxxxxxxxxxx","Notion-Version":"2022-06-28"}' \
  -- npx -y @notionhq/notion-mcp-server

/mcpnotionconnected になっていれば成功。OAuth フロー自体を通らないので、CIMD 不一致問題の影響を受けない。

注意: Internal Integration Token はそのワークスペース全体に対する強い権限を持つ。.bashrc.zshrc に直書きしない、リポジトリにコミットしない、共有用 PC では使わない、などの基本的な扱いを守る。

教訓: CIMD と DCR の違い

MCP の OAuth でクライアント登録の方式は大きく 2 種類ある。

方式

クライアント登録

変更柔軟性

CIMD(Client ID Metadata Document)

client_id が URL になっていて、その URL から取得できるドキュメントがそのまま登録情報

クライアント側がドキュメントを書き換えるまで固定

DCR(Dynamic Client Registration)

サーバーに対してクライアントが動的に登録 API を叩いて発行を受ける

登録時にサーバー側が値を受け取って保存するので、サーバー側の許容によっては柔軟

今回は CIMD 方式かつサーバー側が完全一致を強制している組み合わせなので、ユーザー側でできることが限られる。サーバーが「localhost ベースなら任意ポートを許可する」という緩い実装なら同じバグでも刺さらなかったが、Notion はそうではないということ。

同じパターンで OAuth が詰まったときは、まず ~/Library/Caches/claude-cli-nodejs/.../mcp-logs-* の認可URLと client_id が指す CIMD ドキュメントの redirect_uris を見比べると、原因の切り分けが速い。

参考