Claude Media
Agent SDKのMCP接頭辞を外す — CLAUDE_AGENT_SDK_MCP_NO_PREFIXの使い方

Agent SDKのMCP接頭辞を外す — CLAUDE_AGENT_SDK_MCP_NO_PREFIXの使い方

CLAUDE_AGENT_SDK_MCP_NO_PREFIXを1にすると、SDKで作ったMCPサーバーのツール名からmcp__サーバー名__が消えます。設定の渡し方と、権限ルール・フックへの影響を確認します。

CLAUDE_AGENT_SDK_MCP_NO_PREFIX は、Agent SDKで作ったMCPサーバーのツール名から mcp__<サーバー名>__ の接頭辞を外す環境変数です。1 を設定すると、ツールは定義したときの名前のままClaudeに見えます。対象はSDKで作ったMCPサーバーだけで、外部のMCPサーバーには触れません。

ただし、環境変数の一覧ページにこの変数の説明は1行しかありません。接頭辞を外した結果どこが変わるかは、ツール名を文字列で書く側、つまり権限ルールとフックのマッチャーの仕様から読み取ることになります。この記事では、まず接頭辞つきの名前の組み立てと、権限・フックでの書き方を押さえ、そのうえで変数を有効にしたときの影響を見ます。

接頭辞つきのツール名はどう組み立てられるか

MCPのツールは mcp__<サーバー名>__<ツール名> という名前でClaudeに渡されます。権限ルールもフックも、この文字列をそのまま照合に使います。サーバーの出どころによって、<サーバー名> の部分の形が違います。

出どころ名前の例
設定ファイルや createSdkMcpServer() のサーバー名前の例mcp__github__search_repositories
プラグイン同梱のサーバー名前の例mcp__plugin_my-plugin_db__query
claude.aiのコネクター名前の例mcp__claude_ai_<server>__<tool>

プラグイン同梱のサーバーでは、サーバー名の位置にプラグイン名が入ります。サーバーのキーだけを書いたルールやマッチャー、たとえば mcp__db__.* は、このサーバーのツールに当たりません。接頭辞は単なる飾りではなく、ルールが「どのサーバーか」を特定する手がかりとして使われています。

権限ルールでMCPツールを指定する書き方

権限ルールでは、サーバー単位とツール単位の指定が次の形でできます。

  • mcp__puppeteer は、puppeteer サーバーの全ツールに当たる
  • mcp__puppeteer__* も同じく、そのサーバーの全ツールに当たる
  • mcp__puppeteer__puppeteer_navigate は、そのサーバーの特定のツールだけに当たる

許可ルールと拒否ルールでは、ワイルドカードの扱いが違います。拒否と確認のルールは、ツール名の位置にglobを書けます。mcp__* と書けば、全サーバーのMCPツールが対象です。許可ルールのglobは、リテラルの mcp__<server>__ の後ろにしか置けません。mcp__github__get_* は通りますが、mcp__* のような先頭からのglobは警告つきで読み飛ばされ、何も自動承認しません。

もう1つの制約が引数の指定です。mcp__ で始まるルールに括弧を付けた書き方は、設定ファイルの読み込み時に読み飛ばされます。MCPツールの引数で絞りたい場合は、--disallowedTools に拒否ルールを渡します。

SDKの allowedTools は、自動承認するツールの一覧です。Claudeが使えるツールをこの一覧に限る設定ではありません。一覧にないツールは、permissionMode と canUseTool の判定に回ります。ツールを使えなくしたいときは disallowedTools を使います。canUseTool は許可ルールで承認済みの呼び出しには呼ばれないので、すべての呼び出しを検査するなら PreToolUse フックを使います。

フックのマッチャーでMCPツールを指定する書き方

フックの matcher は、含まれる文字によって評価方法が変わります。英数字、_、-、空白、,、| だけで書かれたマッチャーは、完全一致の文字列として扱われます。それ以外の文字を含むと、先頭や末尾を固定しない正規表現として評価されます。

ここに落とし穴があります。mcp__memory のようにサーバー名だけを書くと、完全一致の文字列として比べられ、どのツールにも当たりません。サーバー単位で絞るには mcp__memory__.* と、末尾に .* を付けます。ハイフンを含むサーバー名も同じ書き方です(mcp__brave-search__.*)。サーバーを問わず名前の頭が write のツールを拾うなら、mcp__.*__write.* と書けます。

許可ルールの mcp__puppeteer がサーバー全体を表すのに対し、フックの mcp__memory は何にも当たらない点は、2つを並べて初めて気づく違いです。

接頭辞を外す環境変数は何をするか

環境変数のリファレンスでは、この変数を次のように説明しています。

  • 1 を設定すると、SDK作成のMCPサーバーのツール名で mcp__<server>__ を省略する
  • ツールは元の名前を使う
  • 用途はSDK利用に限る

通常は、createSdkMcpServer() で作ったサーバーのツールは mcp__<server>__<tool> の形式でClaudeに渡されます。たとえばサーバー名が weather、ツール名が get_temperature なら、名前は mcp__weather__get_temperature です。変数を有効にすると、これが get_temperature になります。

くらべる

変数の有無でツール名がどう変わるか

既定

未設定

mcp__weather__get_temperature

接頭辞なし

CLAUDE_AGENT_SDK_MCP_NO_PREFIX=1

get_temperature

「SDK専用」という点は、MCPの設定ページの記述とも合います。"type": "sdk" のインプロセスサーバーを登録できるのはSDKを使うホストアプリだけで、.mcp.json などに書いた sdk 型のエントリは読み飛ばされます。したがって、claude コマンドの対話セッションでこの変数を立てても、効く対象がありません。

SDKに環境変数を渡す書き方

TypeScript版のSDKでは、query() のオプション env で環境変数を渡します。env を指定すると、サブプロセスの環境は process.env と混ざらず丸ごと置き換わります。PATH などを残すには、process.env を展開して足します。

import { query, createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";
 
const weather = createSdkMcpServer({
  name: "weather",
  tools: [
    tool("get_temperature", "指定した都市の気温を返す",
      { city: z.string() },
      async ({ city }) => ({
        content: [{ type: "text", text: `${city}: 21度` }],
      })),
  ],
});
 
for await (const message of query({
  prompt: "東京の気温を教えて",
  options: {
    mcpServers: { weather },
    env: { ...process.env, CLAUDE_AGENT_SDK_MCP_NO_PREFIX: "1" },
    allowedTools: ["get_temperature"],
  },
})) {
  console.log(message);
}

上のコードの allowedTools は、接頭辞なしの名前を書く想定の一例です。この変数を使った許可ルールの例は仕様のページにないので、書き方が通るかどうかは、後述のinitメッセージで確かめてください。

設定ファイルの env キーに書く方法もあります。ただし、SDKのアプリでは、アプリ側のオプションがユーザーやプロジェクトの設定ファイルより優先されると説明されています。環境変数を確実に効かせたいなら、アプリのコードで env に入れるのが筋です。

ツール名が変わると影響を受ける場所

ツール名を文字列で指定している箇所は、すべて名前変更の影響を受ける候補です。ここまでに見た、接頭辞つきの名前を前提にした記述を並べます。

場所接頭辞つきを前提にした記述
allowedTools接頭辞つきを前提にした記述例: mcp__weather__get_temperature
disallowedTools接頭辞つきを前提にした記述mcp__server や mcp__server__* でサーバー単位、mcp__* で全MCPツールを除外
権限ルールのワイルドカード接頭辞つきを前提にした記述許可側は、リテラルの mcp__<server>__ の後にだけ使える
フックのマッチャー接頭辞つきを前提にした記述mcp__memory__.* のように、サーバー名の接頭辞でサーバー単位に絞る
toolAliases接頭辞つきを前提にした記述例: { Bash: 'mcp__workspace__bash' }

接頭辞は、これらの書き方が「サーバー単位でまとめて扱う」ための手がかりです。この変数を有効にした場合の挙動は仕様のページに書かれていないため、次の4点はルールの文法から導いた見立てです。

  • mcp__weather__* のようなサーバー単位の許可は、接頭辞のない名前には当たらない
  • 許可は、ツール名の完全一致を並べる形になる
  • 拒否も同様に、mcp__* では接頭辞のないツールを除外できない
  • フックのマッチャーは、ツール名そのものに合わせて書き直す

組み込みツールを置き換えるMCPツールの名前

toolAliases は、組み込みツールの名前をMCPツールの名前に対応づけ、Claudeが組み込みの代わりに自作の実装を呼ぶようにするオプションです。値には接頭辞つきの完全な名前を書きます(例は { Bash: 'mcp__workspace__bash' })。

置き換えたツールには、権限の扱いにも注意点があります。Claude Codeは、Bash 全体を拒否するルールを mcp__workspace__bash にも適用します。一方、Bash の許可ルールは mcp__workspace__bash に引き継がれません。許可を与えたいなら、置き換え後のMCPツールの名前でルールを書く必要があります。名前がそのまま権限判定の鍵になる例で、接頭辞を外す変数と組み合わせるなら、toolAliases の値がどの名前になるかも、後述のinitメッセージで確かめておく必要があります。

権限と信頼判断を名前に頼らない

接頭辞が消えると、名前から「どのサーバーのツールか」を読み取れなくなります。その意味で、SDKのリファレンスの注意書きが参考になります。信頼の判断は name や mcp__<server>__ の接頭辞でなく source に基づけと書かれています。フックの入力やコールバックの引数には、サーバー名と出どころを持つ mcp_server の情報が付きます。SDKで作ったサーバーの出どころは sdk です。

つまり、「接頭辞があるから安全」という前提はもともと置かないほうがよい、ということです。自作ツールを許可するかどうかは allowedTools に完全な名前を並べるか、canUseTool や PreToolUse フックで制御します。

接頭辞を外す前に確かめたいこと

この変数を使うかどうかは、次の点で決められます。

  1. 手元のツール名が他のツール名とぶつからないか。接頭辞はサーバーごとに名前空間を分ける役目を持っていたため、外すと別のサーバーや組み込みツールと同じ名前になる余地が生まれます(衝突したときの挙動は、権限・フック・環境変数のどのページにも記載がありません)
  2. 既存の許可ルール・拒否ルール・フックを書き直せるか
  3. 外す目的があるか。ツール名を短くしたい、既存プロンプトが元の名前を前提にしている、などの理由です

目的が見当たらないなら、既定の接頭辞つきのままのほうが、名前空間が分かれて扱いやすくなります。

実際のツール名を確かめる

変数を有効にしたあとは、Claudeに見えているツール名を直接確かめるのが確実です。SDKは、セッション開始時に type: "system"、subtype: "init" のメッセージを返し、その tools フィールドに利用可能なツール名の一覧が入ります。

for await (const message of query({ prompt: "ok", options })) {
  if (message.type === "system" && message.subtype === "init") {
    console.log(message.tools);
  }
}

変数を外した状態と有効にした状態で出力を比べれば、名前の変化と、許可ルールに書くべき文字列が分かります。許可を入れた状態で呼び出しが承認待ちに回るなら、ルールが名前に当たっていません。

よくあるつまずき

  • env を渡して PATH が消える: env は process.env を置き換えます。{ ...process.env, ... } の形にします
  • 対話の claude で効かない: この変数はSDKで作ったサーバー向けです。外部のMCPサーバーの名前は変わりません
  • ルールだけ古いまま: 名前を外してもルールの文字列は自動で直りません。許可・拒否・フックを同時に見直します

SDKでのツールの作り方はAgent SDKカスタムツールの作り方、接続方式の使い分けはAgent SDK MCP接続ガイドにあります。ツールが多いときの読み込みの扱いはAgent SDK Tool Searchの使い方で扱っています。環境変数の全体像はClaude Codeの設定の全項目の一覧から探せます。

まとめ

CLAUDE_AGENT_SDK_MCP_NO_PREFIX=1 は、SDK作成のMCPツール名から mcp__<server>__ を外すだけの小さなスイッチです。ただし、ツール名を前提にした許可・拒否・フックの文字列が全部影響を受けます。有効にしたら、initメッセージの tools で実際の名前を確認し、ルールを名前に合わせて書き直す流れになります。

この記事を共有:XはてブLinkedIn