SpyBara
Go Premium

agent-sdk/mcp.md 2026-11-01 23:57 UTC to 2026-11-02 23:57 UTC

No changes for this document in this history range.

2026
Mon 9 23:02

MCP を使用して外部ツールに接続する

MCP サーバーを設定してエージェントを外部ツールで拡張します。トランスポートタイプ、大規模なツールセット向けのツール検索、認証、エラーハンドリングについて説明します。

Model Context Protocol(MCP)は、AI エージェントを外部ツールおよびデータソースに接続するためのオープンスタンダードです。MCP を使用すると、エージェントはデータベースをクエリし、Slack や GitHub などの API と統合し、カスタムツール実装を記述することなく他のサービスに接続できます。

MCP サーバーはローカルプロセスとして実行したり、HTTP 経由で接続したり、SDK アプリケーション内で直接実行したりできます。

[!NOTE]

このページは Agent SDK の MCP 設定について説明しています。Claude Code CLI に MCP サーバーを追加してすべてのプロジェクトで読み込むには、MCP インストールスコープを参照してください。

クイックスタート

この例は、HTTP トランスポートを使用して Claude Code ドキュメンテーションMCP サーバーに接続し、allowedToolsとワイルドカードを使用してサーバーからすべてのツールを許可します。

import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Use the docs MCP server to explain what hooks are in Claude Code",
  options: {
    mcpServers: {
      "claude-code-docs": {
        type: "http",
        url: "https://code.claude.com/docs/mcp"
      }
    },
    allowedTools: ["mcp__claude-code-docs__*"]
  }
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage


async def main():
    options = ClaudeAgentOptions(
        mcp_servers={
            "claude-code-docs": {
                "type": "http",
                "url": "https://code.claude.com/docs/mcp",
            }
        },
        allowed_tools=["mcp__claude-code-docs__*"],
    )

    async for message in query(
        prompt="Use the docs MCP server to explain what hooks are in Claude Code",
        options=options,
    ):
        if isinstance(message, ResultMessage) and message.subtype == "success":
            print(message.result)


asyncio.run(main())

エージェントはドキュメンテーションサーバーに接続し、hooks に関する情報を検索して、結果を返します。

MCP サーバーを追加する

query() を呼び出す際にコード内で MCP サーバーを設定するか、settingSources 経由で読み込まれる .mcp.json ファイルで設定できます。

コード内でサーバーを追加する

mcpServers オプションで MCP サーバーを直接渡します。この例では /Users/me/projects 用のローカルファイルシステム MCP サーバーを起動します。そのパスをマシン上のディレクトリに置き換えてください。

import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "List files in my project",
  options: {
    mcpServers: {
      filesystem: {
        command: "npx",
        args: ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
      }
    },
    allowedTools: ["mcp__filesystem__*"]
  }
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage


async def main():
    options = ClaudeAgentOptions(
        mcp_servers={
            "filesystem": {
                "command": "npx",
                "args": [
                    "-y",
                    "@modelcontextprotocol/server-filesystem",
                    "/Users/me/projects",
                ],
            }
        },
        allowed_tools=["mcp__filesystem__*"],
    )

    async for message in query(prompt="List files in my project", options=options):
        if isinstance(message, ResultMessage) and message.subtype == "success":
            print(message.result)


asyncio.run(main())

設定ファイルからサーバーを追加する

プロジェクトルートに .mcp.json ファイルを作成します。このファイルは project 設定ソースが有効な場合に読み込まれます。デフォルトの query() オプションでは有効になっています。settingSources を明示的に設定する場合は、このファイルを読み込むために "project" を含めてください。/Users/me/projects をマシン上のディレクトリに置き換えてください。

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
    }
  }
}

接続タイミング

Claude Code はセッション開始時に MCP サーバーへの接続を開始し、最初のターンの待機(存在する場合)が終了すると init メッセージ を送信します。最初のターンがサーバーをどれだけ待機するかは、そのサーバーをどこで設定したかによって異なります。permissionPromptToolName を設定した場合、最初のターンは、どこで設定したかに関わらず、常にそのツールのサーバーを MCP_TIMEOUT まで待機します。

options.mcpServers のサーバーについては、最初の列でそのタイプを確認すると、最初のターンがそのサーバーをどれだけ待機するかがわかります。

サーバータイプ 最初のターンを遅延させるか 最初のターン待機タイムアウト
stdio サーバー、またはキャッシュされたツールリストのない HTTP/SSE サーバー はい、接続されるまで MCP_TIMEOUT、デフォルトは 30 秒。接続はその期限で失敗します
キャッシュされたツールリストを持つリモートサーバー(Claude Code が以前の接続から保存) いいえ。キャッシュされたツールは最初のターンから利用可能 なし。最初のツール呼び出しで接続し、その遅延接続には独自のタイムアウトがあります
インプロセス SDK サーバー はい、接続してツールをリストするまで MCP_TIMEOUT、デフォルトは 30 秒。接続試行ごと。接続はその期限で失敗します

サーバーがキャッシュされたツールリストを持つのは、MCP 検出キャッシュ がオンの場合のみです。

.mcp.json などの 設定ファイル やプラグインから読み込まれたサーバーは、init メッセージでまだ pending と表示されることがよくあります。最初のターンがこれらのサーバーをどれだけ待機するかは、options.mcpServers とツール検索によって異なります。

  • options.mcpServers に stdio、HTTP、または SSE サーバーが含まれる場合:最初のターンは、保留中の設定ファイルおよびプラグインのサーバーも MCP_TIMEOUT まで待機します。
  • それ以外で、ANTHROPIC_BASE_URL が ゲートウェイ を指しており、ENABLE_TOOL_SEARCH が設定されていない場合:最初のターンは、保留中のすべての設定ファイルおよびプラグインのサーバーを最大 2 秒間待機します。
  • それ以外で、ツール検索 がオン(デフォルト)の場合:最初のターンは最大 2 秒間待機しますが、対象は alwaysLoad: true を設定した保留中のサーバー、または 名前を指定した 保留中のサーバーのみです。残りのサーバーはバックグラウンドで接続を続け、接続後に Claude は それらのツールに到達します。
  • それ以外で、ツール検索がオフの場合:最初のターンは、保留中のすべての設定ファイルおよびプラグインのサーバーを最大 2 秒間待機します。ツール検索がオフになるのは、ENABLE_TOOL_SEARCH の値またはモデル によってオフになる場合、または disallowedTools などを通じて ToolSearch ツールを除外した場合です。

名前を指定したサーバー

サーバーの名前を指定するには、mcp__github__list_issues や mcp__github__* など、そのサーバーのツールのいずれかを allowedTools または settings オプションの permissions.allow ルールに列挙します。mcp_tool フック も、プロンプト送信、ツール使用、権限、サブエージェント、タスク、elicitation、または worktree のイベントで設定した場合、呼び出すサーバーの名前を指定したことになります。v2.1.284 より前では、サーバーの名前を指定しても最初のターンの待機には影響しませんでした。

最初のターンの待機を自分で設定する

最初のターンの待機を自分で選択するには、env オプション で CLAUDE_CODE_MCP_STARTUP_WAIT_MS を設定します。たとえば CLAUDE_CODE_MCP_STARTUP_WAIT_MS: "5000" です。すると最初のターンは、ツール検索がオンかどうかに関わらず、保留中の設定ファイルおよびプラグインのサーバーを最大でそのミリ秒数だけ待機します。同じ上限が、options.mcpServers の stdio、HTTP、および SSE サーバーに対する MCP_TIMEOUT の待機も置き換えます。

設定した値に関わらず(0 を含む)、次の 3 つの待機が適用されます。

  • permissionPromptToolName サーバー:MCP_TIMEOUT まで。
  • インプロセス SDK サーバー:接続試行ごとに MCP_TIMEOUT まで。
  • まだ接続中の 名前を指定したサーバー:少なくとも最大 2 秒間。そのため、2000 未満の値を設定してもその待機は短くなりません。

変数を 0 に設定すると、それ以外のすべてのサーバーの待機をスキップします。待機が終了した時点でまだ保留中のサーバーは、バックグラウンドで接続を続けます。CLAUDE_CODE_MCP_STARTUP_WAIT_MS には Claude Code v2.1.274 以降が必要です。

スタートアップでサーバーを待機させる

次の 2 つの設定は、Claude Code が init メッセージを送信する前に、スタートアップ自体を待機させます。

  • MCP_CONNECTION_NONBLOCKING を 0 に設定:スタートアップは接続バッチ全体を待機します(デフォルトで最大 5 秒)。この上限を変更するには、MCP_CONNECT_TIMEOUT_MS をミリ秒単位で設定します。上限に達した時点でまだ保留中のサーバーは、バックグラウンドで接続を続けます。
  • サーバーの設定で alwaysLoad: true:スタートアップは同じ上限までそのサーバーのツールを待機するため、最初のターンではそれらのツールが完全なスキーマで利用可能になり、ツール検索の遅延から除外されます。キャッシュされたツールリストを持つリモートサーバーは、接続することもスタートアップを保留することもなく、それらのツールを提供します。

init メッセージは、Claude Code が送信した時点での各サーバーのステータスを報告します。

MCP ツールを許可する

MCP ツールは Claude が使用する前に明示的な権限が必要です。権限がない場合、Claude はツールが利用可能であることは認識しますが、呼び出すことはできません。

ツール命名規則

MCP ツールの名前は mcp__<server-name>__<tool-name> です。ここで <server-name> は、mcpServers 内のキーなど、サーバーを登録する際の名前です。

サーバー名に含まれる . やスペースなどの文字は _ に置き換えられます。次の表は、2 つのサーバーキーについて list_issues ツールの完全な名前を示しています。

mcpServers 内のキー ツールの完全な名前
github mcp__github__list_issues
my.server mcp__my_server__list_issues

allowedTools および MCP 権限ルール では、ツールの完全な名前を使用してください。プラグイン が提供するサーバーの場合、<server-name> は プラグインスコープの形式 になり、plugin_ で始まります。

allowedTools で自動承認

allowedTools を使用して特定の MCP ツールを事前承認し、Claude が権限プロンプトなしで使用できるようにします。

const _ = {
  options: {
    mcpServers: {
      // your servers
    },
    allowedTools: [
      "mcp__github__*", // All tools from the github server
      "mcp__db__query", // Only the query tool from db server
      "mcp__slack__send_message" // Only send_message from slack server
    ]
  }
};
options = ClaudeAgentOptions(
    mcp_servers={
        # your servers
    },
    allowed_tools=[
        "mcp__github__*",  # All tools from the github server
        "mcp__db__query",  # Only the query tool from db server
        "mcp__slack__send_message",  # Only send_message from slack server
    ],
)

ワイルドカード(*)を使用すると、各ツールを個別にリストアップすることなく、サーバーのすべてのツールを許可できます。

[!NOTE]

MCP アクセスには権限モードより allowedTools を優先してください。 permissionMode: "acceptEdits" は MCP ツールを自動承認しません(ファイル編集とファイルシステム Bash コマンドのみ)。permissionMode: "bypassPermissions" は MCP ツールを自動承認しますが、他のほとんどのセーフティプロンプトも無効にするため、必要以上に広範です。残存するプロンプトについては 権限の評価方法 を参照してください。allowedTools のワイルドカードは、必要な MCP サーバーのみに権限を付与し、それ以上のものは付与しません。完全な比較については 権限モード を参照してください。

利用可能なツールを検出

MCP サーバーが提供するツールを確認するには、サーバーのドキュメントを確認するか、system init メッセージの tools 配列を検査します。MCP ツール名は mcp__ で始まります。

Claude Code は options.mcpServers で渡されたサーバーの 最初のターン接続待機 後に init メッセージを出力するため、tools 配列には、その時点で接続されている各サーバーの mcp__ ツール、および キャッシュされたツールリスト を持つサーバーのツール(初回使用時に接続)がリストされます。接続されていない他のサーバーのツールは存在しません。各サーバーのステータスを読み取る方法については エラーハンドリング を参照してください。

このフィルターは MCP ツール名を出力します。

import { query } from "@anthropic-ai/claude-agent-sdk";

const options = {
  mcpServers: {
    // your servers
  },
};

for await (const message of query({ prompt: "...", options })) {
  if (message.type === "system" && message.subtype === "init") {
    const mcpTools = message.tools.filter((name) => name.startsWith("mcp__"));
    console.log("Available MCP tools:", mcpTools);
  }
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, SystemMessage


async def main():
    options = ClaudeAgentOptions(
        mcp_servers={
            # your servers
        },
    )
    async for message in query(prompt="...", options=options):
        if isinstance(message, SystemMessage) and message.subtype == "init":
            mcp_tools = [t for t in message.data.get("tools", []) if t.startswith("mcp__")]
            print("Available MCP tools:", mcp_tools)


asyncio.run(main())

Claude にサーバーから利用可能なツールをリストアップするよう依頼することもできます。

トランスポートタイプ

MCP サーバーはさまざまなトランスポートプロトコルを使用してエージェントと通信します。サーバーのドキュメントを確認して、どのトランスポートがサポートされているかを確認してください。

  • ドキュメントに実行するコマンド(npx @modelcontextprotocol/server-filesystem など)が記載されている場合は、stdio を使用します
  • ドキュメントにURL が記載されている場合は、HTTP または SSE を使用します
  • コード内で独自のツールを構築している場合は、SDK MCP サーバーを使用します

stdio サーバー

stdin/stdout を介して通信するローカルプロセスです。同じマシン上で実行する MCP サーバーに使用します。.mcp.json 形式の場合は、設定ファイルからサーバーを追加するに示されているのと同じフィールドを使用します。コード内では、コマンドとその引数を渡します。/Users/me/projects をマシン上のディレクトリに置き換えます。

const _ = {
  options: {
    mcpServers: {
      filesystem: {
        command: "npx",
        args: ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
      }
    },
    allowedTools: ["mcp__filesystem__read_file", "mcp__filesystem__list_directory"]
  }
};
options = ClaudeAgentOptions(
    mcp_servers={
        "filesystem": {
            "command": "npx",
            "args": [
                "-y",
                "@modelcontextprotocol/server-filesystem",
                "/Users/me/projects",
            ],
        }
    },
    allowed_tools=["mcp__filesystem__read_file", "mcp__filesystem__list_directory"],
)

HTTP/SSE サーバー

クラウドホストされた MCP サーバーとリモート API には HTTP または SSE を使用します。.mcp.json 形式の場合は、リモートサーバーの HTTP ヘッダーの例と同じフィールドを使用し、SSE サーバーの場合は "type": "sse" を使用します。コード内では、サーバーの URL を渡します。

const _ = {
  options: {
    mcpServers: {
      "remote-api": {
        type: "sse",
        url: "https://api.example.com/mcp/sse",
        headers: {
          Authorization: `Bearer ${process.env.API_TOKEN}`
        }
      }
    },
    allowedTools: ["mcp__remote-api__*"]
  }
};
options = ClaudeAgentOptions(
    mcp_servers={
        "remote-api": {
            "type": "sse",
            "url": "https://api.example.com/mcp/sse",
            "headers": {"Authorization": f"Bearer {os.environ['API_TOKEN']}"},
        }
    },
    allowed_tools=["mcp__remote-api__*"],
)

ストリーム可能な HTTP トランスポートの場合は、代わりに "type": "http" を使用します。.mcp.json およびその他の JSON 設定ファイルでは、"streamable-http" は "http" のエイリアスとして受け入れられます。SDK の McpHttpServerConfig タイプは "http" のみを宣言しているため、コード内で渡すサーバーには "http" を使用します。

SDK MCP サーバー

別のサーバープロセスを実行する代わりに、アプリケーションコード内でカスタムツールを直接定義します。実装の詳細については、カスタムツールガイドを参照してください。

initialize 制御リクエストによって登録された SDK MCP サーバーは、Claude Code がリクエストを処理するとすぐに接続を開始します。

MCP ツール検索

多くの MCP ツールを設定している場合、ツール定義はコンテキストウィンドウの大部分を消費する可能性があります。ツール検索はコンテキストからツール定義を保留し、各ターンで Claude が必要とするツールのみを読み込むことでこの問題を解決します。

ツール検索はデフォルトで有効になっています。設定オプション、ベストプラクティス、およびカスタム SDK ツールでのツール検索の使用については、ツール検索を参照してください。

認証

ほとんどの MCP サーバーは、外部サービスにアクセスするために認証が必要です。サーバー設定で環境変数を通じて認証情報を渡します。

環境変数を通じて認証情報を渡す

env フィールドを使用して、API キー、トークン、およびその他の認証情報を MCP サーバーに渡します。

[tab] In code

const _ = {
  options: {
    mcpServers: {
      "api-server": {
        command: "npx",
        args: ["-y", "@your-org/api-mcp-server"],
        env: {
          API_KEY: process.env.API_KEY
        }
      }
    },
    allowedTools: ["mcp__api-server__*"]
  }
};
options = ClaudeAgentOptions(
    mcp_servers={
        "api-server": {
            "command": "npx",
            "args": ["-y", "@your-org/api-mcp-server"],
            "env": {"API_KEY": os.environ["API_KEY"]},
        }
    },
    allowed_tools=["mcp__api-server__*"],
)

[tab] .mcp.json

{
  "mcpServers": {
    "api-server": {
      "command": "npx",
      "args": ["-y", "@your-org/api-mcp-server"],
      "env": {
        "API_KEY": "${API_KEY}"
      }
    }
  }
}

${API_KEY} 構文は、実行時に環境変数を展開します。

リモートサーバーの HTTP ヘッダー

HTTP および SSE サーバーの場合、サーバー設定で認証ヘッダーを直接渡します。

[tab] In code

const _ = {
  options: {
    mcpServers: {
      "secure-api": {
        type: "http",
        url: "https://api.example.com/mcp",
        headers: {
          Authorization: `Bearer ${process.env.API_TOKEN}`
        }
      }
    },
    allowedTools: ["mcp__secure-api__*"]
  }
};
options = ClaudeAgentOptions(
    mcp_servers={
        "secure-api": {
            "type": "http",
            "url": "https://api.example.com/mcp",
            "headers": {"Authorization": f"Bearer {os.environ['API_TOKEN']}"},
        }
    },
    allowed_tools=["mcp__secure-api__*"],
)

[tab] .mcp.json

{
  "mcpServers": {
    "secure-api": {
      "type": "http",
      "url": "https://api.example.com/mcp",
      "headers": {
        "Authorization": "Bearer ${API_TOKEN}"
      }
    }
  }
}

${API_TOKEN} 構文は、実行時に環境変数を展開します。

リモートサーバーの完全な動作例(ヘッダーで認証されたもの)については、リポジトリから問題を一覧表示するを参照してください。

OAuth2 認証

MCP 仕様は認可のために OAuth 2.1 をサポートしています。SDK はブラウザを開いたり、対話的な OAuth フローを実行したりしません。設定されたサーバーが認可チャレンジを返し、Claude Code が送信できるトークンを持っていない場合、SDK はそのサーバーを needs-auth または failed として報告します。

  • needs-auth:Claude Code がそのサーバーに使用できるサインインを見つけられませんでした。headers でトークンを渡すか、実行前に同じマシン上で対話型の Claude Code セッションからサインインしてください。
  • failed(McpServerStatus エントリの error が Couldn't read the stored credentials または A request to MCP server で始まる場合):Claude Code が認証情報ストアを読み取れませんでした。対処方法については、Couldn't read the stored credentials for MCP server を参照してください。Claude Code v2.1.307 より前では、Mac のログインキーチェーンがロックされている場合、ステータスは代わりに needs-auth でした。

いずれの場合も、エージェント実行はそのサーバーのツールなしで続行されます。システム初期化メッセージの mcp_servers 配列は、発行されたときにそのサーバーに対して pending を表示する場合があります。サーバーが認証情報を必要とするかどうかを確認するには、TypeScript SDK で mcpServerStatus() をポーリングするか、Python で get_mcp_status() をポーリングします。

認証情報を提供するには、アプリケーション内で OAuth フローを完了し、結果のアクセストークンをサーバーの headers に渡します。

// After completing OAuth flow in your app.
// Implement getAccessTokenFromOAuthFlow for your OAuth provider.
const accessToken = await getAccessTokenFromOAuthFlow();

const options = {
  mcpServers: {
    "oauth-api": {
      type: "http",
      url: "https://api.example.com/mcp",
      headers: {
        Authorization: `Bearer ${accessToken}`
      }
    }
  },
  allowedTools: ["mcp__oauth-api__*"]
};
# After completing OAuth flow in your app.
# Implement get_access_token_from_oauth_flow for your OAuth provider.
access_token = await get_access_token_from_oauth_flow()

options = ClaudeAgentOptions(
    mcp_servers={
        "oauth-api": {
            "type": "http",
            "url": "https://api.example.com/mcp",
            "headers": {"Authorization": f"Bearer {access_token}"},
        }
    },
    allowed_tools=["mcp__oauth-api__*"],
)

例

リポジトリから問題を一覧表示する

この例は、リモート GitHub MCP サーバー に接続して、最近の問題を一覧表示します。この例には、MCP 接続とツール呼び出しを検証するためのデバッグログが含まれています。

実行する前に、クエリしたいリポジトリへの読み取りアクセス権を持つ GitHub 個人用アクセストークン を作成し、環境変数として設定してください。

export GITHUB_TOKEN=YOUR_GITHUB_PAT
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "List the 3 most recent issues in anthropics/claude-code",
  options: {
    mcpServers: {
      github: {
        type: "http",
        url: "https://api.githubcopilot.com/mcp/",
        headers: {
          Authorization: `Bearer ${process.env.GITHUB_TOKEN}`
        }
      }
    },
    allowedTools: ["mcp__github__list_issues"]
  }
})) {
  // Verify MCP server connected successfully
  if (message.type === "system" && message.subtype === "init") {
    console.log("MCP servers:", message.mcp_servers);
  }

  // Log when Claude calls an MCP tool
  if (message.type === "assistant") {
    for (const block of message.message.content) {
      if (block.type === "tool_use" && block.name.startsWith("mcp__")) {
        console.log("MCP tool called:", block.name);
      }
    }
  }

  // Print the final result
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}
import asyncio
import os
from claude_agent_sdk import (
    query,
    ClaudeAgentOptions,
    ResultMessage,
    SystemMessage,
    AssistantMessage,
)


async def main():
    options = ClaudeAgentOptions(
        mcp_servers={
            "github": {
                "type": "http",
                "url": "https://api.githubcopilot.com/mcp/",
                "headers": {"Authorization": f"Bearer {os.environ['GITHUB_TOKEN']}"},
            }
        },
        allowed_tools=["mcp__github__list_issues"],
    )

    async for message in query(
        prompt="List the 3 most recent issues in anthropics/claude-code",
        options=options,
    ):
        # Verify MCP server connected successfully
        if isinstance(message, SystemMessage) and message.subtype == "init":
            print("MCP servers:", message.data.get("mcp_servers"))

        # Log when Claude calls an MCP tool
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if hasattr(block, "name") and block.name.startswith("mcp__"):
                    print("MCP tool called:", block.name)

        # Print the final result
        if isinstance(message, ResultMessage) and message.subtype == "success":
            print(message.result)


asyncio.run(main())

MCP servers: の行で、github の status が connected であることは、トークンが機能していることを確認します。Claude Code がサーバーの キャッシュされたツールリスト を持っている場合、ステータスは代わりに pending と表示され、サーバーは最初のツール呼び出しで接続します。ステータスが failed または needs-auth の場合は、サーバーが利用できないときに Claude がビルトインツールにフォールバックする可能性があるため、結果を信頼する前に エラーハンドリング を参照してください。

データベースをクエリする

この例は DBHub を使用して Postgres データベースをクエリします。エージェントはデータベーススキーマを自動的に検出し、SQL クエリを作成して、結果を返します。

DBHub の execute_sql ツールは、エージェントが発行する SQL(書き込みを含む)を実行します。ただし、DBHub 設定ファイル で readonly = true を設定すると、DBHub は INSERT、UPDATE、DELETE、および DDL ステートメントを拒否するため、エージェントが書き込みを発行した場合でも、この例はデータを変更できません。DBHub は設定を読み込むときにプロセス環境から ${DATABASE_URL} を解決するため、接続文字列はファイルの外に留まります。スクリプトの隣に次の dbhub.toml を作成してください。

[[sources]]
id = "production"
dsn = "${DATABASE_URL}"

[[tools]]
name = "execute_sql"
source = "production"
readonly = true

スクリプトは、接続文字列を直接渡す代わりに、DBHub が設定ファイルを指すようにします。実行する前に、DATABASE_URL 環境変数を接続文字列に設定してください。プレースホルダー値を独自のデータベース詳細に置き換えてください。

export DATABASE_URL=postgresql://user:password@localhost:5432/mydb
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  // Natural language query - Claude writes the SQL
  prompt: "How many users signed up last week? Break it down by day.",
  options: {
    mcpServers: {
      postgres: {
        command: "npx",
        // dbhub.toml sets readonly = true, so execute_sql rejects writes
        args: ["-y", "@bytebase/dbhub", "--config", "dbhub.toml"]
      }
    },
    allowedTools: ["mcp__postgres__execute_sql"]
  }
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage


async def main():
    options = ClaudeAgentOptions(
        mcp_servers={
            "postgres": {
                "command": "npx",
                # dbhub.toml sets readonly = true, so execute_sql rejects writes
                "args": [
                    "-y",
                    "@bytebase/dbhub",
                    "--config",
                    "dbhub.toml",
                ],
            }
        },
        allowed_tools=["mcp__postgres__execute_sql"],
    )

    # Natural language query - Claude writes the SQL
    async for message in query(
        prompt="How many users signed up last week? Break it down by day.",
        options=options,
    ):
        if isinstance(message, ResultMessage) and message.subtype == "success":
            print(message.result)


asyncio.run(main())

エラーハンドリング

MCP サーバーは様々な理由で接続に失敗する可能性があります。サーバープロセスがインストールされていない、認証情報が無効である、またはリモートサーバーに到達できない場合があります。

Claude Code は各クエリの開始時に、サブタイプ init の system メッセージを発行します。このメッセージには各 MCP サーバーの接続ステータスが含まれます。status フィールドは "pending"、"connected"、"failed"、"needs-auth"、または "disabled" のいずれかです。Claude Code は options.mcpServers で渡されたサーバーの 最初のターン接続待機 の後に init メッセージを発行するため、待機時間内に接続したサーバーは "connected" を表示します。

init メッセージでは、"pending" をそれ自体で失敗として扱わないでください。これは以下のいずれかを意味する可能性があります。

  • サーバーはまだ接続されていません。Claude Code がそれを待つ時間 を参照してください
  • サーバーのツールリストは キャッシュから提供 され、最初の使用時に接続が確立されました
  • 接続期限が切れました。このようなサーバーはタイミングに応じて "pending" または "failed" を報告します

使用できないサーバーを検出するには、"failed" または "needs-auth" をチェックしてください。

import { query } from "@anthropic-ai/claude-agent-sdk";

try {
  for await (const message of query({
    prompt: "Process data",
    options: {
      mcpServers: {
        // Replace dataServer with your server configuration
        "data-processor": dataServer
      }
    }
  })) {
    if (message.type === "system" && message.subtype === "init") {
      const unavailableServers = message.mcp_servers.filter(
        (s) => s.status === "failed" || s.status === "needs-auth"
      );

      if (unavailableServers.length > 0) {
        console.warn("Unavailable MCP servers:", unavailableServers);
      }
    }

    if (message.type === "result" && message.subtype === "error_during_execution") {
      console.error("Execution failed");
    }
  }
} catch (error) {
  // A single-shot query() throws after yielding an error result. If the
  // failure was an error result, the error subtype branch above has
  // already run; a failure to start or reach the Claude Code process
  // yields no result message. MCP servers that fail to connect don't
  // throw: use the status check above, and note that servers still
  // "pending" at init need a later status check.
  console.log(`Session ended with an error: ${error}`);
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, SystemMessage, ResultMessage


async def main():
    # Replace data_server with your server configuration
    options = ClaudeAgentOptions(mcp_servers={"data-processor": data_server})

    try:
        async for message in query(prompt="Process data", options=options):
            if isinstance(message, SystemMessage) and message.subtype == "init":
                unavailable_servers = [
                    s
                    for s in message.data.get("mcp_servers", [])
                    if s.get("status") in ("failed", "needs-auth")
                ]

                if unavailable_servers:
                    print(f"Unavailable MCP servers: {unavailable_servers}")

            if (
                isinstance(message, ResultMessage)
                and message.subtype == "error_during_execution"
            ):
                print("Execution failed")
    except Exception as error:
        # A single-shot query() raises after yielding an error result. If the
        # failure was an error result, the error subtype branch above has
        # already run; a failure to start or reach the Claude Code process
        # yields no result message. MCP servers that fail to connect don't
        # raise: use the status check above, and note that servers still
        # "pending" at init need a later status check.
        print(f"Session ended with an error: {error}")


asyncio.run(main())

リモートサーバーのステータスは、"connected" を報告した後でも変わる可能性があります。セッション中に接続が切れると、Claude Code はサーバーを "pending" に戻して 再接続 します。その後、TypeScript で mcpServerStatus() を呼び出すか、Python で ClaudeSDKClient.get_mcp_status() を呼び出すと、あなた側で設定変更がなくても、以前に接続されていたサーバーに対して "pending" を報告できます。

5 回の再接続試行が失敗した後、サーバーは "failed" を報告するか、再度認可が必要な場合は "needs-auth" を報告します。一時的なエラーの後も Claude Code は バックグラウンドで再試行 を続けるため、"failed" の HTTP または SSE サーバーは、呼び出しを行わなくても "connected" に戻ることがあります。手動で再試行するには、TypeScript で reconnectMcpServer() を呼び出すか、Python で ClaudeSDKClient.reconnect_mcp_server() を呼び出してください。

トラブルシューティング

サーバーが「failed」ステータスを表示する

init メッセージをチェックして、どのサーバーが接続に失敗したかを確認します。

if (message.type === "system" && message.subtype === "init") {
  for (const server of message.mcp_servers) {
    if (server.status === "failed") {
      console.error(`Server ${server.name} failed to connect`);
    }
  }
}
if isinstance(message, SystemMessage) and message.subtype == "init":
    for server in message.data.get("mcp_servers", []):
        if server.get("status") == "failed":
            print(f"Server {server['name']} failed to connect")

"pending" ステータスはサーバーが失敗したことを意味しません。初期化時にカバーされるケースについては、エラーハンドリングを参照してください。セッションの後半で更新されたステータスを取得するには、TypeScript SDK でクエリの mcpServerStatus() メソッドを呼び出すか、Python で ClaudeSDKClient.get_mcp_status() を呼び出します。

一般的な原因:

  • 環境変数の欠落:必要なトークンと認証情報が設定されていることを確認します。stdio サーバーの場合、env フィールドがサーバーが期待する内容と一致していることを確認します。
  • サーバーがインストールされていない:npx コマンドの場合、パッケージが存在し、Node.js が PATH に含まれていることを確認します。
  • 無効な接続文字列:データベースサーバーの場合、接続文字列の形式を確認し、データベースがアクセス可能であることを確認します。
  • ネットワークの問題:リモート HTTP/SSE サーバーの場合、URL に到達可能であり、ファイアウォールが接続を許可していることを確認します。

ツールが呼び出されていない

Claude がツールを認識しているが使用していない場合、allowedTools で権限を付与していることを確認します。

const _ = {
  options: {
    mcpServers: {
      // your servers
    },
    allowedTools: ["mcp__servername__*"] // Auto-approve calls from this server
  }
};
options = ClaudeAgentOptions(
    mcp_servers={
        # your servers
    },
    allowed_tools=["mcp__servername__*"],  # Auto-approve calls from this server
)

SDK MCP サーバーからツールが欠落している

TypeScript SDK では、ツールの入力スキーマを JSON Schema に変換できない場合、createSdkMcpServer() で作成したサーバーは、ツールを一覧表示する際にそのツールを除外します。SDK はその時点で警告を出力します。Node.js では、この警告はコード CLAUDE_SDK_MCP_TOOL_SCHEMA_UNCONVERTIBLE を持つプロセス警告であり、次のテキストで始まります。

Tool "<name>" on SDK MCP server "<server>" was left out of the server's tool list, because its input schema cannot be converted to JSON Schema

警告の残りの部分では、変換エラーのメッセージがある場合はそのメッセージが示され、続いて確認および変更すべき点が示されます。

TypeScript Agent SDK v0.3.286 より前では、変換できないスキーマが 1 つあるだけで、この警告なしにサーバーのツール一覧全体が失敗していたため、そのサーバーのツールはいずれも Claude に届きませんでした。

接続タイムアウト

MCP サーバー接続はデフォルトで 30 秒後にタイムアウトします。実行中のツール呼び出しにかかる時間を変更するには、MCP_TOOL_TIMEOUT を設定します。サーバーの起動に時間がかかる場合、接続は失敗します。MCP_TIMEOUT 環境変数(ミリ秒単位)で接続制限を引き上げます。より多くの起動時間が必要なサーバーの場合、以下も検討してください。

  • 利用可能な場合は、より軽量なサーバーを使用する
  • エージェントを開始する前にサーバーをプリウォーミングする
  • 遅い初期化の原因についてサーバーログを確認する

TypeScript では、timeout を createSdkMcpServer() に渡すことで、単一の SDK MCP サーバー のツール呼び出し制限を設定できます。

ツール出力が最大許容トークン数を超える

SDK は Claude Code と同じ MCP 出力制限を適用します。画像コンテンツを含まない成功したツール結果が 25,000 トークンより大きい場合、Claude Code は出力をファイルに保存し、ツール結果をそのファイルパスを示すエラーメッセージに置き換えるため、エージェントは出力を部分的に読み戻すことができます。

トークン制限を変更するには、MAX_MCP_OUTPUT_TOKENS 環境変数を設定します。ツールが anthropic/maxResultSizeChars を宣言していない限り、50,000 文字を超える成功したテキスト結果は、トークン制限に関係なくファイルに保存されます。サーバーがこのアノテーションを宣言する方法を含む完全な動作については、MCP 出力制限と警告を参照してください。

関連リソース