MCP tool not foundエラー — --permission-prompt-toolの原因と対処
--permission-prompt-toolで指定したMCPツールが見つからず非対話(headless)実行が終了する原因は、接続待ちとツール名の2通りに分かれます。切り分け方と直し方を示します。
このTipsでできること
--permission-prompt-tool を指定した非対話(headless)実行が、最初のツール呼び出しで次のエラーを出して終了することがあります。
Error: MCP tool mcp__permissions__approve (passed via --permission-prompt-tool) not found. Available MCP tools: none直すのは多くの場合、サーバーの接続待ちかツール名のどちらかです。この記事は、末尾の一覧からどちらかを見分ける方法、直し方、再開や無人実行で同じフラグを扱うときの注意を順に示します。
末尾の一覧で原因を2つに分ける
指定したツールが、最初の権限判断の時点で接続済みのMCPツールの中に無いと、このエラーになります。メッセージ末尾の Available MCP tools: には、そのとき接続済みだったMCPツールが並びます。
一覧の中身で見分ける
none、または目的外のサーバーだけ
そのツールを提供するはずのサーバーが、最初の権限判断までに接続を終えていません。起動が30秒の待ち時間を超えているか、サーバーが起動に失敗しています。
他のツール名は並んでいる
サーバーは接続しているのに、渡した名前のツールを公開していません。名前空間のスペルや、サーバー側のツール名の変更を疑います。
Claude Codeは、最初のプロンプトを処理する前に、--permission-prompt-tool が指すサーバーの接続を最大30秒(MCP_TIMEOUT の既定値)まで待ちます。この待ち合わせが入ったのはv2.1.206からです。それ以前は、起動の遅い健全なサーバーでも同じエラーで落ちていました。
直し方は3段階
上から順に確かめる
- 1
サーバーが接続しているか見る
--permission-prompt-toolを付けるのと同じディレクトリでclaude mcp listを実行し、目的のサーバーが接続済みと表示されるか確かめます。 - 2
ツール名を突き合わせる
渡す名前は
mcp__<サーバー名>__<ツール名>の形です。大文字小文字、ハイフンとアンダースコアまで、サーバーが公開している名前と1文字ずつ照らします。 - 3
起動に30秒以上かかるなら待ち時間を延ばす
MCP_TIMEOUTはミリ秒指定です。依存パッケージのダウンロードやコンテナ起動を伴うサーバーは、既定の30000に収まらないことがあります。
3段階目は、環境変数を付けて実行します。
MCP_TIMEOUT=60000 claude -p "タスクの内容" --permission-prompt-tool mcp__permissions__approveサーバーの追加方法やスコープから見直したい場合はClaude Code MCP設定ガイドを参照してください。名前空間の書き方はClaude Code MCP権限ルールにまとめています。
ツール名の真ん中は設定ファイルのキーで決まる
mcp__permissions__approve の permissions は、サーバー定義に付けたキーです。approve は、そのサーバーが公開するツール名です。設定ファイルのキーを perm に直して名前を渡し直し忘れると、サーバーは接続しているのに名前の不一致になります。
{
"mcpServers": {
"permissions": {
"command": "node",
"args": ["./approve-server.js"]
}
}
}このファイルを --mcp-config で渡す構成なら、実行は次の形になります。サーバー名のキー permissions とツール名 approve が、そのまま --permission-prompt-tool の値に現れます。
claude -p "タスクの内容" \
--mcp-config ./mcp.json \
--permission-prompt-tool mcp__permissions__approve--mcp-config を渡した -p 実行は、保留中のサーバーが接続するのを最初のターンの前に待ちます。ツール一覧のキャッシュを持つリモートサーバーは待ちの対象から外れ、system/init では pending と表示され、最初のツール呼び出しで接続します。
待ち時間を決める設定は3つある
起動待ちに関わる設定は複数あり、--permission-prompt-tool のサーバーに効くのは MCP_TIMEOUT だけです。
| 設定・版 | 内容 |
|---|---|
| v2.1.206 | 内容prompt toolのサーバーの接続を、最初のプロンプトの前に MCP_TIMEOUT まで待つ |
| v2.1.221 | 内容-p に --mcp-config を渡すと、保留中のサーバー全般を最初のターンの前に待つ。ツール一覧のキャッシュがあるサーバーは待たずに、最初の使用時に接続する |
| v2.1.274 | 内容CLAUDE_CODE_MCP_STARTUP_WAIT_MS で最初のターンの待ち時間を置き換える。0 で待たない |
CLAUDE_CODE_MCP_STARTUP_WAIT_MS を 0 にしても、--permission-prompt-tool のサーバーは MCP_TIMEOUT の待ちを維持します。起動の速さを優先して他のサーバーの待ちを切っても、このエラーの対策にはなりません。--allowedTools や mcp_tool フックで名指しされたMCPサーバーは、0 でも最大2秒は接続を待ちます(v2.1.284)。MCP_TIMEOUT と、混同しやすい MCP_TOOL_TIMEOUT の役割の違いはMCP_TIMEOUTとMCP_TOOL_TIMEOUTの違いで扱っています。
エラー後、非対話実行は終了コード1で止まる
このエラーが出た実行は、最初のツール呼び出しで終了コード1を返します。リクエスト自体は送られているのに、答えは1つも返りません。CIでは終了コードだけを見ると失敗の理由が分かりません。実行ログに残るエラーメッセージも、一緒に保存しておくと原因を追えます。
対比になるのが、承認役を指定しない -p 実行です。承認要求は拒否され、実行は続きます。承認役を指定したからこそ、その承認役が見つからないと実行ごと止まります。承認役の指定は、あるだけで安全側に倒れる設定ではなく、動いていることまで含めて前提になる設定です。
承認役を置けない無人実行は --permission-prompts none
--permission-prompt-tool は、承認を受け持つ相手(承認役)がいる前提のフラグです。スケジュール実行のように誰も答えられない場面では、v2.1.259で入った --permission-prompts none が使えます。v2.1.287の claude --help には、次の項目があります。
--permission-prompts <target> Who answers permission prompts with
--print: "host" (the SDK host or
--permission-prompt-tool) or "none"
(nobody: anything that would prompt is
denied automatically; the permission
mode still decides everything else)
(choices: "host", "none", default:
"host")既定は host で、承認要求はAgent SDKのホストか --permission-prompt-tool のツールに渡ります。none にすると、承認役を待たずに、承認が要る操作が自動で拒否されます。拒否のあと実行は続き、Claudeには「誰も承認できないので再試行しない」と伝わります。権限ルール、PermissionRequest フック、権限モードは先に判断するため、決まらなかった要求だけが拒否の対象です。
承認が要る操作をすべて拒否したいだけなら、権限モードの dontAsk も選べます。dontAsk は、承認が要る呼び出しをすべて拒否し、承認なしで通る操作は従来どおり動かします。ロックダウンしたCI向けの選択肢です。承認役のツールを用意して実際に承認させたいときだけ、--permission-prompt-tool が候補になります。
なお、この claude --help の一覧には --permission-prompt-tool 自体の項目が出ず、上の説明文の中に名前が現れるだけです。フラグの詳細は、公式のCLIリファレンスで確かめます。
--resumeでは毎回フラグを渡し直す
セッションを再開するときも、--permission-prompt-tool は指定し直します。これが効くのが、claude -p --resume や claude -p --continue でplanモードを再開する場面です。次の4条件がすべて成り立つと、planモードのまま再開します。
--permission-prompt-toolを渡し、--permission-prompts noneは渡さない(計画の承認を提示できるようにするため)--permission-modeと--dangerously-skip-permissionsを渡さない--fork-sessionを渡さない- channels経由の起動ではない
1つ目を満たさないと、planモードでの再開にはなりません。その場合は、新しい claude -p 実行が始まるのと同じ権限モードで再開します。
対話セッションの /tui でレンダラーを切り替えるときも、同じ性質が表に出ます。切り替えはClaude Codeのプロセスを再起動するので、--permission-prompt-tool のような起動フラグは再起動後に引き継げません。その結果、/tui fullscreen が「Cannot switch renderers in this session」で断られることがあります。v2.1.234より前は、制限を落としたまま再起動していました。同じ /tui でも、バックグラウンドの作業が動いているときは「Cannot switch renderers while work is running in the background」という別のメッセージになり、作業の終了を待てば切り替えられます。
似た別エラー「requires user interaction」
名前の近いエラーに、次のメッセージがあります。
MCP tool requires user interaction; not supported via --permission-prompt-tool見つからない場合との違い
tool not found
指定した承認ツールが接続済みのツールに無い状態です。サーバーの接続や名前を直せば解消します。
requires user interaction
承認ツールは見つかっています。ただし、承認先のMCPツールがサーバー側で「毎回人の承認が必要」と宣言しており、その経路で承認できません。
サーバー側の宣言は、tools/list の応答にある _meta["anthropic/requiresUserInteraction"] に、JSONのブール値 true を入れたものです。true 以外の値は無視されます。宣言されたツールは、一致する許可ルールがあってもプロンプトが出ます。「今後は確認しない」の選択肢も出ません。承認プロンプトは、承認が自動で通る権限モードの acceptEdits、auto、bypassPermissions でも毎回出ます。dontAsk モードでは、プロンプトを出さずに拒否します。
--permission-prompt-tool が allow を返しても、宣言付きのツールは拒否に変換されます。Agent SDKの canUseTool コールバックはこうした呼び出しを受け取れるので、アプリ側で利用者に承認を求める実装なら通せます。宣言を付けるのは、同意やアクセス許可の手順のように、承認そのものが目的のツールです。同じサーバーの他のツールは、通常の権限の扱いのままです。
CIだけで見つからないときは組織のMCP制御も確かめる
手元の対話セッションでは接続できるのに、CIの実行だけでこのエラーになる場合は、サーバーの起動遅延と名前の不一致に加えて、組織のMCP設定を確かめます。組織は allowedMcpServers と deniedMcpServers で、使えるサーバーを制限できます。許可されていないサーバーは使えないため、ツールが接続済みの一覧に現れません。クラウドセッションでは、セッションに届くこれらのエントリが、配信されるclaude.aiのコネクタも絞ります。サーバーの定義を直す前に、組織側の許可リストに載っているかを管理者に確かめる選択肢があります。組織のMCP制御の全体像はMCPセキュリティガイドにまとめています。
まとめ
一覧が none なら接続待ち、他のツールが並ぶなら名前の不一致です。まず claude mcp list で接続を見て、足りなければ MCP_TIMEOUT を延ばします。「requires user interaction」は別の経路の問題なので、メッセージの文言を確かめてから対処に入ります。