はじめに / 対象と前提
想定読者は、Claude Code で社内の自前ホスト API などを MCP 経由で叩きたいが、ローカル起動の stdio 接続ではなく HTTP/SSE 経由のリモート MCP サーバーに OAuth で繋ぐ必要が出てきたエンジニア。
前提:
- Claude Code v2.x 系(
claude --versionで確認) - 接続先は OAuth 2.1(Authorization Code + PKCE)対応のリモート MCP サーバー
- stdio 接続の MCP サーバーは構築済み・利用経験ありを想定(初めての場合は先にローカル stdio 版で慣れておくのがおすすめ)
TL;DR
- リモート MCP サーバーの認証は、Claude Code が「ブラウザで認可 → localhost でコールバック受信 → トークン保存・自動更新」までワンストップでやってくれる
- ただし ポート競合・トークン失効・ブラウザが起動できない環境の3つで詰まりやすい
- 詰まったら
/mcpコマンドで接続状態を確認し、再認証すれば大抵直る
手順 / 動かし方
1. リモート MCP サーバーを HTTP transport で登録
claude mcp add --transport http my-remote-server https://mcp.example.com/mcp
.mcp.json はこういう形になる。
{
"mcpServers": {
"my-remote-server": {
"type": "http",
"url": "https://mcp.example.com/mcp"
}
}
}
2. 起動すると認証フローが自動で走る
該当ツールを呼ぶタイミングでサーバー側が OAuth 必須と判定すると、認可 URL が表示されるかブラウザが自動起動する。
$ claude
> このMCPサーバーは認証が必要です。ブラウザで認可してください:
https://auth.example.com/authorize?client_id=...&redirect_uri=http://localhost:PORT/callback&code_challenge=...
ブラウザで許可すると http://localhost:PORT/callback?code=... にリダイレクトされ、Claude Code が裏で立てている一時 HTTP サーバーがそれを受け取ってトークンに交換する。
3. 接続状態の確認
/mcp
を叩くと、サーバーごとの接続ステータス(Connected / Needs auth / Error)が一覧で出る。Needs auth になっていたら再度認可が必要というサイン。
ハマりどころ
1. localhost コールバック用のポートが埋まっている
redirect_uri が固定ポートを使う実装だと、他のローカルサーバー(Vite の開発サーバーなど)が同じポートを掴んでいる場合にコールバックが届かずタイムアウトする。
Error: OAuth callback timeout - no response received on http://localhost:PORT/callback
→ 認証前に lsof -i :PORT で空きを確認する。また複数の Claude Code セッションを同時に認証フローへ突入させない(セッションごとに一時サーバーを立てるため稀に競合する)。
2. リフレッシュトークン失効に気づかず 401 を食らう
しばらく使っていないマシン・セッションだと、保存済みアクセストークンだけでなくリフレッシュトークンの期限も切れていることがある。この場合エラーが OAuth 関連だとひと目で分からず、ツール呼び出し自体が失敗したように見える。
Error calling tool 'search_docs': 401 Unauthorized
→ ツール呼び出しが原因不明で 401 になったら、まず /mcp で該当サーバーのステータスを見る。Needs auth なら再認可、Connected なのに 401 ならサーバー側のスコープ変更を疑う。
3. ブラウザを起動できない環境(SSH越し・サンドボックス内)で止まる
リモートサーバーに SSH して、その中で Claude Code を動かしている場合、ブラウザを自動起動できずに認可フローが固まる。認可 URL を手元 PC のブラウザにコピペして開いても、リダイレクト先の localhost が SSH 越しの環境と一致せず失敗する。
→ ssh -L PORT:localhost:PORT でコールバックポートをローカルにフォワードしてから認可 URL を開く。どのポートが使われるかは事前にわからないので、表示された認可 URL 内の redirect_uri パラメータを見てフォワード先のポートを決めるのがコツ。
背景・補足
MCP の認証まわりは仕様追加により、OAuth 2.1(PKCE 必須)がリモートサーバーの標準になっている。stdio 接続では環境変数で API キーを渡すだけで済んでいたが、HTTP/SSE 経由でリモートに繋ぐ場合はブラウザを介した認可が前提になる分、上記のような「ローカル実行環境特有」のハマりどころが増える。
まとめ
- リモート MCP サーバーは
.mcp.jsonにtype: httpで登録するだけで動き出すが、OAuth 認証まわりは環境依存のハマりどころが多い - ポート競合・トークン失効・ブラウザ起動不可の3パターンは
/mcpコマンドでの状態確認から潰していくのが早い - SSH 越しなど特殊な実行環境では、コールバックポートのポートフォワードを忘れずに
- 挙動は Claude Code のバージョンで変わりうるので、詰まったら
claude --versionを確認する習慣をつけておくと安心