OAuth callback port is already in useの原因と対処 — Claude Code
Claude CodeでリモートMCPサーバーにOAuthでサインインすると出るポート競合エラーの原因を整理し、lsofとnetstatで占有プロセスを特定して解消する手順を扱います。
リモートMCPサーバーへのOAuthサインインで「OAuth callback port <port> is already in use — another process may be holding it」と表示されたら、サインインの結果を受け取るためのローカルポートを別のプロセスが握っています。多くは固定コールバックポートの設定が原因です。メッセージに出ているコマンドで占有プロセスを見つけて止めるか、別のポートに切り替えれば解消します。
このエラーは何を意味しているか
リモートMCPサーバーにOAuthでサインインすると、Claude Codeはローカルで待ち受け用のリスナーを立て、ブラウザーからのコールバックを受け取ります。そのポートが別のプロセスに使われていると、サインインはここで失敗します。表示されるメッセージは次の形です。
OAuth callback port <port> is already in use — another process may be holding it. Run `lsof -ti:<port> -sTCP:LISTEN` to find it.<port>には実際の番号が入ります。Windowsでは提案されるコマンドがnetstat -ano | findstr :<port>に変わります。
エラーの発生源はMCPサーバーでもブラウザーでもなく、手元のマシン上のポート競合です。サーバー側の設定を疑う前に、まず自分の環境を見ます。
なぜ固定ポートのときに起きやすいのか
Claude Codeは、ポートを指定しない場合は空いているポートを自分で選びます。競合がほとんど起きないのはこのためです。エラーが目立つのは、次のどちらかで固定ポートを指定した場合です。
- 環境変数の
MCP_OAUTH_CALLBACK_PORT claude mcp addなどに渡す--callback-portフラグ
固定するのは、MCPサーバー側に「http://localhost:PORT/callback」の形のリダイレクトURIを事前登録する必要があるからです。登録した番号とClaude Codeの待ち受け番号が一致しなければならないので、空いているポートを自動で選ぶ挙動が使えなくなります。
# 固定コールバックポートでサーバーを追加する例
claude mcp add --transport http \
--callback-port 8080 \
my-server https://mcp.example.com/mcp設定ファイルに書く場合は、oauthオブジェクトのcallbackPortで同じ指定ができます。
claude mcp add-json my-server \
'{"type":"http","url":"https://mcp.example.com/mcp","oauth":{"callbackPort":8080}}'8080のような定番の番号を選ぶと、開発サーバーなど別の用途と衝突する可能性が上がります。どのプロセスが握っているかは環境ごとに違うため、次の節の手順で実物を確かめます。
占有しているプロセスを特定して止める
エラーメッセージのコマンドをそのまま実行します。macOSとLinuxの例です。
lsof -ti:8080 -sTCP:LISTEN-tを付けているので出力はプロセスIDだけになり、-sTCP:LISTENで待ち受け状態のものに絞られます。何も出なければ、その時点でポートは空いています。
プロセスIDから中身を知りたいときは、続けてpsで名前を確認します。止めてよいプロセスかどうかは、この名前を見て判断します。
ps -p <PID> -o pid,commandWindowsではnetstatで待ち受けているプロセスのPIDを探します。
netstat -ano | findstr :8080
tasklist /FI "PID eq <PID>"netstat -anoの最後の列がPIDです。tasklistで名前を引けます。
手順は「メッセージのコマンドで占有プロセスを見つけ、止めるか終わるのを待つ」です。止める操作はkill <PID>(Windowsはtaskkill /PID <PID>)などOS標準の方法で行います。ほかの作業で使っている開発サーバーやデータベースの可能性があるので、名前を確かめてから止めます。
解消したらサインインをやり直す
ポートが空いたら、サインインを最初からやり直します。例は/mcpでサーバーを選ぶやり方です。
/mcpシェルから直接実行したい場合はclaude mcp login <name>でも同じOAuthフローを動かせます。SSHセッションなどブラウザーが開けない環境では、認可URLが表示されます。手元のマシンでURLを開き、ブラウザーのアドレスバーに出たリダイレクトURL全体をプロンプトに貼り戻します。この貼り付けには対話的な端末が必要で、ssh -tで接続します。
別のプロセスがそのポートを必要とし続ける場合
他のプログラムがそのポートを恒常的に使うなら、止めても再び競合します。この場合の対処は、サーバー側に別のリダイレクトURIを登録し、そのポート番号をClaude Code側に設定し直すことです。
- MCPサーバーの開発者ポータルなどで、空いている別の番号の
http://localhost:PORT/callbackを登録する MCP_OAUTH_CALLBACK_PORTか--callback-portのうち、使っている方でその番号を指定する/mcpからサインインをやり直す
環境変数の例は次のとおりです。
export MCP_OAUTH_CALLBACK_PORT=8765
claudeMCP_OAUTH_CALLBACK_PORTは、事前設定済みの認証情報でMCPサーバーを追加するときに--callback-portの代わりに使える環境変数です。8765は例示用の番号で、実際にはサーバーに登録した番号に合わせます。どちらか一方だけを使い、番号がずれないようにします。
止めたのにまたエラーになるときの確認点
占有プロセスを止めて解決したはずなのに、同じエラーが戻ることがあります。多い原因は次の3つです。
- 止めたプロセスが自動で再起動している: 開発サーバーの監視機能やコンテナーのポート公開などが、止めた直後に同じポートを取り直すことがあります。サインインの直前に
lsof -ti:<port> -sTCP:LISTENをもう一度実行し、出力が空であることを見てから進めます - 番号を変えたのにサーバー側の登録を変えていない: 別のポートに切り替えても、MCPサーバーに登録済みのリダイレクトURIが元の番号のままだと、今度は不一致でサインインが失敗します。番号を変えたら、サーバー側の
http://localhost:PORT/callbackも同じ番号に直します - 環境変数とフラグの番号がずれている:
MCP_OAUTH_CALLBACK_PORT、--callback-port、設定ファイルのoauth.callbackPortのどれで指定しているか分からなくなり、片方だけ書き換えて古い番号が残ることがあります。どこで指定したかを控えておきます
エラーの見分け方
似たエラーが複数あるので、メッセージの文言で切り分けます。
| 表示 | 意味 | 見る場所 |
|---|---|---|
OAuth callback port <port> is already in use | 意味指定ポートを他プロセスが占有 | 見る場所lsofまたはnetstatで特定 |
| No available ports for OAuth redirect | 意味ローカルポートをそもそも待ち受けできない | 見る場所セキュリティソフトやサンドボックスの設定 |
| Incompatible auth server: does not support dynamic client registration | 意味サーバーが自動登録に非対応 | 見る場所事前設定済みの認証情報が必要 |
2行目の「No available ports」は、127.0.0.1での待ち受け自体が妨げられているときに出ます。原因の例はセキュリティソフトやサンドボックスの制限です。v2.1.268より前はOSが割り当てるポートへのフォールバックがなく、Claude Codeが自分で選ぶ範囲のポートがすべて使えない場合にも出ました。Windowsでは、Hyper-Vが予約したポート範囲が原因になることがあります。
3行目は、ポートではなくサーバー側の対応状況の問題です。詳しくはGitHub MCPサーバーのOAuth接続エラーが具体例になります。
リダイレクトURIの不一致と混同しない
固定ポートを使う設定では、ポートの競合とは別に「リダイレクトURIの不一致」でサインインが失敗する場合があります。v2.1.229のClaude Codeはhttp://127.0.0.1:PORT/callbackの形で送信しており、登録値を完全一致で照合するサーバーはこれを拒否しました。v2.1.231でlocalhostの形に戻っています。
v2.1.229を使っているなら、Claude Codeを更新するか、127.0.0.1形式のURIも一時的にサーバー側へ登録して回避できます。ポートが空いているのに失敗するときは、この不一致を確かめます。競合を解消してもエラーが変わるだけ、というケースの切り分けにもなります。
再発を減らす設定の考え方
同じ競合を繰り返さないために、次の点を確認しておきます。
- 固定ポートは、ほかのツールが既定で使わない番号を選ぶ
- 複数のMCPサーバーで同じ固定ポートを使い回さない。片方のサインインが終わるまでポートが使われる可能性があり、並行して認証すると競合することがある
- CIやスクリプトで固定ポートを環境変数から渡すときは、その番号をチーム内で一覧にしておく
2つ目は、ドキュメントに書かれた挙動ではなく、上の仕組みからの推論です。同じ番号を共有する構成では、サインインを1つずつ順番に行うと問題を避けられます。
ポートを固定せずに済むなら、それが最も競合しにくい構成です。サーバー側が動的クライアント登録に対応していれば、--callback-portなしで追加でき、空いているポートが自動で選ばれます。固定が必要かどうかは、サーバーのドキュメントでリダイレクトURIの事前登録を求められているかで決まります。
固定するか、Claude Codeに任せるかは、接続先のサーバーの対応で分かれます。
| サーバーの状況 | ポートの扱い | このエラーの起きやすさ |
|---|---|---|
| 動的クライアント登録に対応 | ポートの扱い指定せず、空いているポートの自動選択に任せる | このエラーの起きやすさ起きにくい |
| リダイレクトURIの事前登録が必要 | ポートの扱い登録した番号を--callback-portなどで固定する | このエラーの起きやすさ固定ポートの衝突で起きうる |
| 事前設定済みの認証情報を使う | ポートの扱いサーバーに登録した番号と揃えて固定する | このエラーの起きやすさ同上 |
判断の材料は、サーバーのドキュメントにリダイレクトURIの登録手順があるかどうかです。手順があるなら固定が必要で、その番号を他のツールと重ならないように選びます。
認証まわりのそのほかの不調は、次の記事が入口になります。
- MCPの追加コマンドやスコープの全体像はClaude Code MCP設定ガイド
- 401エラーで「OAuth not supported」と出る場合は「OAuth not supported」401エラーの原因と対処
- サインインが繰り返し求められる場合はClaude Codeで何度もログインを求められる原因と対処法
まとめ
このエラーの原因は、OAuthのコールバック用に固定したポートを別のプロセスが握っていることです。lsof -ti:<port> -sTCP:LISTEN(Windowsはnetstat -ano | findstr :<port>)で占有元を見つけ、止めてから/mcpでサインインをやり直します。そのポートが恒常的に必要なプロセスに使われているなら、サーバーに別のリダイレクトURIを登録し、MCP_OAUTH_CALLBACK_PORTか--callback-portの番号を合わせ直します。