Skip to main content
Skip to content

GitHub Copilot SDK での MCP サーバーの使用

Copilot SDK は MCP サーバー (モデル コンテキスト プロトコル) と統合して、アシスタントの機能を外部ツールで拡張できます。 MCP サーバーは個別のプロセスとして実行され、会話中に呼び出すことができるCopilotツール (関数) を公開します。

メモ

これは進化する機能です。 進行中のディスカッションについては 、問題 #36 を参照してください。

MCP とは

モデル コンテキスト プロトコル (MCP) は、AI アシスタントを外部のツールやデータ ソースに接続するためのオープンな標準です。 MCP サーバーは次のことができます。

  • コードまたはスクリプトを実行する
  • データベースのクエリ
  • ファイル システムにアクセスする
  • 外部 API を呼び出す
  • その他

サーバーの種類

SDK では、次の 2 種類の MCP サーバーがサポートされています。

タイプ説明ユースケース(事例)
Local/Stdioサブプロセスとして実行され、stdin/stdout 経由で通信するローカル ツール、ファイル アクセス、カスタム スクリプト
HTTP/SSEHTTP 経由でアクセスされるリモート サーバー共有サービス、クラウドでホストされるツール

コンフィギュレーション

構成とライフサイクルを確認

session.rpc.mcp.listConfigured() は、パラメーターなしのパッシブ インベントリ読み取りです。 サーバーの起動や再起動、認証、サンドボックス ポリシーの適用、サーバーの起動の待機は行われません。 構成の検出とポリシーのフィルター処理によって、表示されるサーバーとその enabled 値が決まります。

この試験的な RPC には、対応する SDK/ランタイム リリースが必要です。 以前のプレリリース応答では、 live を省略することができました。必要なライフサイクル コントラクトを使用する SDK では、その古い応答形状はサポートされていません。 外部ランタイムを指定するときは、SDK に合わせて更新します。 プロトコルの全体的なバージョンは変更されず、この試験的なコントラクトのリビジョンを示すものではありません。

すべてのエントリに live.statusが含まれます。 具体化されたランタイム サーバーがない構成済みサーバーは、true が not_configured の場合でも、既存のenabled状態を報告します。 明示的に停止されたランタイム サーバーは、stopped を報告します。 実体化されたサーバーは、pending、connected、needs-auth、failed など、実際のライフサイクルを報告します。障害には、利用可能な場合は live.error が含まれます。

構成とライフサイクルは異なる事実を説明します。 古い接続が維持されている間にサーバーの URL、認証、または構成ソースが変更された場合でも、インベントリはその接続の実際のライフサイクルを報告します。 connected ステータスは、最新の構成が適用されたことを意味するわけではありません。 このオブザベーションはランタイムに属します。クライアントは、サーバー名のみに基づいてキャッシュされた状態を置き換えてはなりません。

インベントリは、グラフの同時置換を制限された回数再試行し、一貫性のあるスナップショットを取得できない場合はエラーを返します。 グラフ競合を隠すために live を省略することは決してありません。

名前のみの startServer または restartServer は、最初に listを呼び出さずにコールド セッションが再開された後、要求されたサーバーのみを解決して初期化します。 これには、ユーザーとプラグインの構成、およびgithubMcpToolConfigを通じて構成された組み込みのGitHub サーバーが含まれます。 他の構成済みサーバーを起動したり、無効化された状態、認証要件、サンドボックス ポリシー、または構成ソースの優先順位をオーバーライドしたりすることはありません。

Node.js/ TypeScript

import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
const session = await client.createSession({
    model: "gpt-5",
    mcpServers: {
        // Local MCP server (stdio)
        "my-local-server": {
            type: "local",
            command: "node",
            args: ["./mcp-server.js"],
            env: { DEBUG: "true" },
            cwd: "./servers",
            tools: ["*"],  // "*" = all tools, [] = none, or list specific tools
            timeout: 30000,
        },
        // Remote MCP server (HTTP)
        "github": {
            type: "http",
            url: "https://api.githubcopilot.com/mcp/",
            headers: { "Authorization": "Bearer ${TOKEN}" },
            tools: ["*"],
        },
    },
});

Python

import asyncio
from copilot import CopilotClient
from copilot.session import PermissionHandler

async def main():
    client = CopilotClient()
    await client.start()

    session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="gpt-5", mcp_servers={
        # Local MCP server (stdio)
        "my-local-server": {
            "type": "local",
            "command": "python",
            "args": ["./mcp_server.py"],
            "env": {"DEBUG": "true"},
            "cwd": "./servers",
            "tools": ["*"],
            "timeout": 30000,
        },
        # Remote MCP server (HTTP)
        "github": {
            "type": "http",
            "url": "https://api.githubcopilot.com/mcp/",
            "headers": {"Authorization": "Bearer ${TOKEN}"},
            "tools": ["*"],
        },
    })

    response = await session.send_and_wait("List my recent GitHub notifications")
    print(response.data.content)

    await client.stop()

asyncio.run(main())

Go

package main

import (
    "context"
    "log"
    copilot "github.com/github/copilot-sdk/go"
)

func main() {
    ctx := context.Background()
    client := copilot.NewClient(nil)
    if err := client.Start(ctx); err != nil {
        log.Fatal(err)
    }
    defer client.Stop()

    session, err := client.CreateSession(ctx, &copilot.SessionConfig{
        Model: "gpt-5",
        MCPServers: map[string]copilot.MCPServerConfig{
            "my-local-server": copilot.MCPStdioServerConfig{
                Command: "node",
                Args:    []string{"./mcp-server.js"},
                Tools:   []string{"*"},
            },
        },
    })
    if err != nil {
        log.Fatal(err)
    }
    defer session.Disconnect()

    // Use the session...
}

.NET

using GitHub.Copilot;

await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5",
    McpServers = new Dictionary<string, McpServerConfig>
    {
        ["my-local-server"] = new McpStdioServerConfig
        {
            Command = "node",
            Args = new List<string> { "./mcp-server.js" },
            Tools = new List<string> { "*" },
        },
    },
});

セッションごとに構成されたサーバーを無効にする

disabledMcpServersを、セッションで実行してはならない MCP サーバー名に正確に設定します。 この設定のスコープは、個々の作成要求または再開要求です。グローバル MCP 設定またはサーバー構成は変更されません。

const session = await client.createSession({
    mcpServers: {
        filesystem: { type: "local", command: "npx", args: ["-y", "@modelcontextprotocol/server-filesystem", "."] },
        github: { type: "http", url: "https://api.githubcopilot.com/mcp/" },
    },
    disabledMcpServers: ["github"],
});
SDK構成プロパティ
Node.jsdisabledMcpServers
Pythondisabled_mcp_servers
GoDisabledMCPServers
.NETDisabledMcpServers
JavasetDisabledMcpServers(...)
Rustwith_disabled_mcp_servers(...)

セッションの作成と コールド 再開では、無効になっているサーバーは起動されず、ランタイムは認証を開始しません。 常駐履歴書は、ランタイムが既に生成したサーバーを元に戻すことはできません。 名前は正確に一致します。

プロンプトの一覧表示と取得

実験用に生成された MCP 名前空間は、ワイヤ JSON-RPC メソッド session.mcp.prompts.list および session.mcp.prompts.getを公開します。 以下の言語固有の SDK アクセサーを使用して呼び出します。 これらのメソッドは、現在のセッション内の 1 つの接続されたサーバーを対象とします。複数のサーバーからの結果を結合しません。

SDKプロンプトを一覧表示するプロンプトを取得する
Node.jssession.rpc.mcp.prompts.list(...)session.rpc.mcp.prompts.get(...)
Pythonsession.rpc.mcp.prompts.list(...)session.rpc.mcp.prompts.get(...)
Gosession.RPC.MCP.Prompts().List(...)session.RPC.MCP.Prompts().Get(...)
.NETsession.Rpc.Mcp.Prompts.ListAsync(...)session.Rpc.Mcp.Prompts.GetAsync(...)
Javasession.getRpc().mcp.prompts.list(...)session.getRpc().mcp.prompts.get(...)
Rustsession.rpc().mcp().prompts().list(...)session.rpc().mcp().prompts().get(...)

一覧表示には serverName が必要であり、オプションの不透明な cursor を指定できます。 各呼び出しは、タイプ別のプロンプト定義の 1 ページとオプションの nextCursor を返します。 別のリスト呼び出しでそのカーソルを渡して、次のページを要求します。 定義には、名前、省略可能なタイトルと説明、および引数の定義が含まれます。 省略引数フラグ required は、false とは異なります。

プロンプトを取得するには、serverName と promptName が必要です。さらに、値が文字列である省略可能な arguments ディクショナリを指定できます。 arguments省略すると、MCP 要求の引数は存在しません。{}渡すと、明示的に空のディクショナリが送信されます。 ランタイムは、サーバーに対してこの区別を保持します。 結果には、省略可能な説明と、型指定されたロールと不透明な JSON contentを含む順序付けされたメッセージが含まれます。 各コンテンツ ブロックの type を解釈する前に確認してください。コンテンツはテキストにフラット化されません。 入れ子になったリソース、注釈、メタデータ、見慣れないコンテンツ タイプ、その他のコンテンツ フィールドは、JSON 構造を保持します。 型指定された記述子、メッセージ、および結果エンベロープのサーバー拡張機能は、additionalProperties配下にあります。 additionalPropertiesという名前のサーバー拡張機能自体は、そのマップ内のエントリとして保持され、そのマップにマージされません。 プロトコルの最上位 resultType: "complete" 識別子はランタイムによって処理されます。SDK フィールドまたはサーバー拡張機能として返されません。 1 MiB キャプチャ制限を超える stdio 応答フレームを含め、ランタイムが未加工の応答を保持できない場合、要求は明示的に失敗します。

返されたプロンプト メッセージは、モデルに自動的に送信されたり、ツールの実行や参照先リソースのフェッチに使用されたりしません。 アプリケーションが結果の使用方法を決定します。 その結果を生成するときに、MCP サーバーは、複数のラウンドトリップ継続を通じてサンプリングまたはエリシテーションを要求できます。 これらの要求では、他の MCP 操作と同じ構成済みホスト レスポンダーが使用されます。プロンプトの取得では、追加のアクセス許可が付与されたり、ホストの決定がバイパスされたりすることはありません。 レスポンダーが存在しないかレスポンダーエラーがある場合、要求は失敗し、elicitation decline は変更されずにサーバーに返されます。 状態のみの継続では、どちらのレスポンダーも呼び出されません。

既存の mcp.prompts.list_changed セッション イベントが発生した後で、名前付きサーバーのプロンプトをもう一度一覧表示して、アプリケーションのビューを更新します。

MCP の起動前にサンドボックス ポリシーを適用する

検出されたルート構成、プラグイン、または明示的に構成された MCP サーバーが起動する前に、構築時にサンドボックス ポリシーを適用するには、createSession を resumeSession または sandboxConfig に渡します。 session.rpc.options.update({ sandboxConfig })と同じ構成を受け入れます。

const sandboxConfig = {
    enabled: true,
    sandboxMcpServers: true,
    userPolicy: { network: { allowOutbound: false } },
};
const session = await client.createSession({
    onPermissionRequest: approveAll,
    sandboxConfig,
});

コールド再開時に構成を再入力します。省略すると、常駐セッションの現在のポリシーを保持します。 常駐再開は、既に開始されているプロセスを元に戻すことはできません。 マネージド ポリシー検証では、オプションの更新と同じダイレクト ホスト セマンティクスが使用されます。競合する要求は、サンドボックス化されていないセッションにフォールバックするのではなく、作成または再開に失敗し、JSON-RPC エラーでは managed_sandbox_policy_conflict が data.code に設定されます。 ランタイムは、この明示的なホスト構成に設定由来の sandboxConfigSource を割り当てません。

後で同一の options.update({ sandboxConfig }) があっても、管理ポリシーによって構成が正規化された場合を含め、MCP サーバーは再起動されません。 別の有効な MCP サンドボックス ポリシーでは、通常の再起動動作が保持されます。

ConnectResult (version) によって返されるランタイム server.connectを、アプリケーションがこの機能に必要な最小ランタイム リリースと照らして確認します。 SDK プロトコルのバージョンは、機能ごとの対応可否を示すシグナルではありません。 古いランタイムは不明な作成/再開フィールドを無視するため、それらのフィールドをサポートするアプリケーションはオープン時に sandboxConfig を送信し、フォローアップ オプションの更新でそれを繰り返すことができます。 この更新プログラムは、サポートされているランタイムでは無害ですが、古いランタイムは更新が到着する前に MCP を起動できます。最初のプロセスからの封じ込めが必須の場合は、サポートされるランタイム バージョンを必須にしてください。

ツールの構成

tools フィールドを使用して、MCP サーバーで使用できるツールを制御できます。

すべてのツールを許可する

"*"を使用して、MCP サーバーによって提供されるすべてのツールを有効にします。

tools: ["*"]

特定のツールを許可する

アクセスを制限するツール名の一覧を指定します。

tools: ["bash", "edit"]

エージェントで使用できるのは、一覧に示されているツールのみです。

すべてのツールを無効にする

空の配列を使用して、すべてのツールを無効にします。

tools: []

Notes

  • tools フィールドでは、使用できるツールを定義します。
  • 個別の allow または disallow 構成はありません。ツール アクセスは、この一覧を通じて直接制御されます。

クイック スタート: ファイルシステム MCP サーバー

公式の @modelcontextprotocol/server-filesystem MCP サーバーを使用した完全な作業例を次に示します。

import { CopilotClient } from "@github/copilot-sdk";

async function main() {
    const client = new CopilotClient();

    // Create session with filesystem MCP server
    const session = await client.createSession({
        mcpServers: {
            filesystem: {
                type: "local",
                command: "npx",
                args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
                tools: ["*"],
            },
        },
    });

    console.log("Session created:", session.sessionId);

    // The model can now use filesystem tools
    const result = await session.sendAndWait({
        prompt: "List the files in the allowed directory",
    });

    console.log("Response:", result?.data?.content);

    await session.disconnect();
    await client.stop();
}

main();

Output:

Session created: 18b3482b-bcba-40ba-9f02-ad2ac949a59a
Response: The allowed directory is `/tmp`, which contains various files
and subdirectories including temporary system files, log files, and
directories for different applications.

ヒント

MCP サーバー ディレクトリから任意の MCP サーバーを使用できます。 一般的なオプションには、 @modelcontextprotocol/server-github、 @modelcontextprotocol/server-sqlite、 @modelcontextprotocol/server-puppeteerなどがあります。

構成オプション

ローカル/stdio サーバー

財産タイプ必須説明
type
"local" または "stdio"Noサーバーの種類 (既定値はローカル)
commandstringはい実行するコマンド
argsstring[]はいコマンド引数
envobjectNo環境変数
cwdstringNo作業ディレクトリ
toolsstring[]Noすべてを有効にするツール (["*"] すべて有効), ([] なし)
timeoutnumberNoタイムアウト (ミリ秒)

リモート サーバー (HTTP/SSE)

財産タイプ必須説明
type
"http" または "sse"はいサーバーの種類
urlstringはいサーバー アドレス
headersobjectNoHTTP ヘッダー (認証用など)
oauthClientIdstringNo静的に構成された OAuth クライアントの空でないクライアント ID
oauthScopesstring[]No有効な RFC 6749 スコープ トークンの空でない配列。
oauthClientIdが必要です。protected-resource メタデータフォールバックの前に、サーバー チャレンジがスコープを省略するか、空のスコープを提供する場合に使用されます
oauthPublicClientbooleanNo構成された OAuth クライアントがパブリックであり、クライアント シークレットを必要としないかどうか
oauthGrantTypestringNo構成済みクライアントの OAuth grant type(例: client_credentials)
toolsstring[]No有効にするツール
timeoutnumberNoタイムアウト (ミリ秒)

リモートサーバーのOAuth所有権確認

認証試行ごとに 1 つの OAuth 所有モデルを選択します。

  1. ランタイム管理ループバック: リダイレクト URI なしで session.mcp.oauth.login を呼び出します。 ランタイムはローカル コールバック リスナーを開き、ディスカバリー、PKCE、状態検証、トークン交換、永続化、トークンの更新、再接続を担います。
  2. ランタイムで管理されるホストされたコールバック: 信頼されたパブリック HTTPS リダイレクト URI で session.mcp.oauth.login を呼び出します。 ホストはコールバックを受け取りますが、ランタイムは引き続き OAuth プロトコルと認証情報を所有します。
  3. ホストで管理される OAuth: SDK の MCP 認証要求ハンドラーを使用して、ホストが取得したアクセス トークンを返します。 ホストは認可と更新を保持しています。

ランタイムで管理されるホスト型コールバックを使用する認証の試行にホストマネージド OAuth ハンドラーを登録しないでください。 リモート サーバーが needs-auth 状態になるまで待ってから、生成された session.rpc.mcp.oauth.login メソッドをサーバー名とコールバック URI で直接呼び出してください。

{
    "serverName": "remote-mcp",
    "redirectUri": "https://agent.example.com/oauth/callback"
}

選択した静的、CIMD、または動的に登録された OAuth クライアントは、その正確な URI をアドバタイズする必要があります。 URI は HTTPS を使用する必要があり、クエリまたはフラグメントを含めてはなりません。 ブラウザーの操作が必要な場合、結果には authorizationUrl と authorizationIdが含まれます。 ユーザーのブラウザーで authorizationUrl を開き、ターゲット セッションで authorizationId を保持します。

承認サーバーがエンドポイントにリダイレクトしたら、生成された session.rpc.mcp.oauth.complete メソッドを呼び出します。

{
    "authorizationId": "<opaque-state>",
    "callbackUrl": "https://agent.example.com/oauth/callback?code=...&state=..."
}

構成されたパブリック リダイレクトのオリジンとパスに加えて、コールバックの元のクエリから callbackUrl を構築します。 内部サービス URL を渡したり、クライアントが指定した Forwarded または X-Forwarded-* ヘッダーを信頼したりしないでください。 ランタイムは、配信を受け入れる前に、配信元、ポート、パス、状態、および OAuth 応答を検証します。 トークン交換、永続化、および MCP の再接続は、その後非同期で続行されます。

拒否されたアクセス トークンをランタイムに返す

reason: "refresh"とruntimeRefreshSupported: trueを使用するホスト OAuth 要求の場合、ハンドラーは代替アクセス トークンを取得する代わりに{ "kind": "runtimeRefresh" }を返すことができます。 ランタイムは、元の承認操作内で既存の保存された付与を使用して非対話型更新を実行します。 新しい同意フローを開始したり、独立した authenticationStateChanged 更新 RPC を呼び出したりすることはありません。 置き換えでは、保存された許可の来歴が保持されるため、後でスコープ付き保存トークンの採用を引き続き利用できます。 ホストから直接提供されたトークンは、保存されたトークンとしてマークされず、その処理経路で上書きすることはできません。

保留中のリクエストがサポートを表明している場合にのみ、この応答を返します。 capability が欠落している場合は false であり、従来のトークン/取り消しコントラクトを保持します。 ハンドラーがその機能を持たない要求に対してハンドオフを返す場合、SDK は代わりに cancelled を送信するため、保留中の要求は開いたままになりません。 指定されたトークンはハンドオフよりも優先され、キャンセルはキャンセルのままです。

SDK能力ハンドオフの結果
Node.jsrequest.runtimeRefreshSupported{ kind: "runtimeRefresh" }
Pythonrequest["runtimeRefreshSupported"]{"kind": "runtimeRefresh"}
Go
MCPAuthRuntimeRefreshHandler 機能引数MCPAuthResultRuntimeRefresh()
.NETMcpAuthContext.RuntimeRefreshSupportedMcpAuthResult.RefreshInRuntime()
Java
McpAuthHandler.handleWithRuntimeRefresh 機能引数McpAuthResponse.runtimeRefresh()
RustMcpAuthHandler::handle_with_runtime_refreshMcpAuthResponse::RuntimeRefresh

応答の受諾は、更新、再接続、またはツールの完了ではなく、ハンドオフを示します。 受け入れられたハンドオフの場合、元のオーソリ予約がその最終結果に達すると、mcp.oauth_completed が 1 回生成されます。 その outcome は、既存の値のみを使用します。復旧に成功した場合は token の場合、取り消された場合または失敗した場合は cancelled の場合。 永続化された mcp.oauth_recovery_completed イベントは、同じ requestId と serverName を保持し、再接続を含む終了結果 ( succeeded、 cancelled、または failed) を区別します。 このイベントより前のSDKバージョンでは、これを不明なイベントの種類として受け取ります。

ランタイムが runtimeRefresh レスポンスを受け入れるまで、既存の応答は以前の意味を維持します。 ホスト { kind: "cancelled" } の応答が要求を拒否します。refresh 要求の場合、ランタイムはその後再認証を要求できます。 どのホストからも応答がない場合、ランタイムはキャッシュされた資格情報を含む通常のローカル OAuth 処理にフォールバックし、mcp.oauth_recovery_completed イベントを生成しません。 この変更は、ホスト cancelled 応答を Stop として再分類しません。 元の呼び出しは、runtimeRefresh ハンドオフが受理された場合にのみ維持されます。

承認後、元の呼び出しは資格情報のインストール後に再試行でき、既存のセッション、構成、ポリシー、およびアクセス許可の制約を引き継いで再接続できます。 メイン ターンを停止するか、セッションを終了すると、元の承認予約が取り消されます。停止した呼び出しは、後で再試行したり、結果を発行したりすることはできません。 既に発行されているローテーション許可交換は、取り消し後にその置き換えの永続化を完了できますが、古い資格情報をインストールしたり、再接続したり、取り消された呼び出しを再開したりすることはできません。

使用できない保存済みの認可または失敗した更新は、対話型の再認証を要求せずに元の呼び出しを終了します。 再接続に失敗すると、呼び出しも終了します。トークンを正常に取得することは、ツールの成功の結果ではありません。

同時呼び出しは、まさにその進行中の認可試行に参加し、その最終結果を受け取ります。 接続されたサーバー、保持されているアクセス トークン、または後で成功した試行は、その人の試行が成功したことを示すものではありません。 残っている各呼び出しでは、再試行する前に、独自のカタログとツールのアクセス許可が再チェックされます。結合された失敗が発生しても、別の対話型承認は開始されません。

OAuth HTTP のタイムアウト時間は、完全なハンドオフや認可付与の保存処理ではなく、個々のリクエストに適用されます。 取り消しは、発行済みの exchange が確定する前に返ることができ、セッションの破棄は追跡中の決済ワーカーを待機します。 全体的な決済期限がないため、ホストはキャンセル、ハンドオフの受け入れ、または HTTP タイムアウトを、すべてのストレージ作業が完了したことを示す証拠として扱ってはなりません。

セッション単位のMCP診断

MCP 診断にオプトインするには、セッションを作成または再開するときに diagnostics: { sources: { mcp: { level: "debug" } } } を設定します。 既定では、すべてのソースが off に設定されます。 有効なレベルは、 error、 warning、 info、 debug、および traceです。 この設定は、クライアントのプロセス レベルの logLevelとは別です。

警告

診断エントリには、有効なすべてのレベルでユーザー指定またはサーバー提供のコンテンツを含めることができます。warning 以降にはサーバー stderr を含めることができます。一方、debug と trace には、さらに MCP ペイロード、ツール引数、パスを含めることができます。 すべてのエントリを機密として扱います。 エントリをテレメトリとして自動的にアップロードしたり、意図的なホスト アクションなしでエクスポートしたりしないでください。

生成された session.rpc.diagnostics API を使用すると、ホストはセッション スコープの、制約付きのインメモリ診断を構成して読み取ります。 MCP は、最初であり、現在サポートされている唯一のソースです。 読み取り時に sources: ["mcp"] を使用して明示的に選択します。読み取りではキャプチャは有効になりません。 出力サーフェスごとに 1 つの停止可能な読み取りループを使用し、カーソルを保持します。 読み取りループは、そのカーソルと表示を所有します。ランタイムは、キャプチャ、フィルター処理、保持、カーソルの有効期限、およびウェイクアップを所有します。

import { approveAll, CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
const stop = new AbortController();
const appendLine = (line: string) => console.log(line);

await client.start();
const session = await client.createSession({
    onPermissionRequest: approveAll,
    diagnostics: { sources: { mcp: { level: "debug" } } },
});

try {
    let cursor: string | undefined;
    while (!stop.signal.aborted) {
        const page = await session.rpc.diagnostics.read({
            sources: ["mcp"],
            cursor,
            max: 100,
            waitMs: 30_000,
        });
        if (page.cursorStatus === "expired") {
            appendLine("MCP diagnostic entries were dropped.");
        }
        for (const entry of page.entries) {
            const detail = entry.details.data ? ` ${entry.details.data}` : "";
            appendLine(
                `${entry.timestamp} [${entry.level}] [${entry.source}:${entry.details.serverName}] ${entry.message}${detail}`,
            );
        }
        cursor = page.cursor;
    }
} finally {
    await session.disconnect();
    await client.stop();
}

中止シグナルは、現在の有界読み取りが完了した後にループを停止します。RPC 呼び出しに渡されません。 キャプチャを無効にすると、未処理の読み取りが再開されます。

MCP は必要時にのみ起動します。診断の有効化または読み取りはサーバーを起動しません。 セッションの作成時に mcpServers を構成してから、セッションを通常どおりに使用するか、インストール済みサーバーに対して session.rpc.mcp.startServer({ serverName }) を呼び出して、モデル要求を行わずに初期化のトラブルシューティングを行います。

各レコードには、source: "mcp"、タイムスタンプ、重大度、メッセージ、および非ルート エージェント用の省略可能な agentId があります。 型指定された details には、ライフサイクル、プロトコル、HTTP、または stderr カテゴリ、サーバー名、接続試行ごとに新しい connectionId 、オプションのプロトコルの方向と診断データが含まれます。 MCP の保持上限は、セッションあたり 1,024 レコードおよび 4 MiB に制限されます。 個々のエンコードされたレコードは 16 KiB に制限され、短縮されると truncated が付加されます。 既定では 100 個のレコードを読み取り、最大 500 個を受け入れ、他のリーダーのデータを消費しません。 期限切れのカーソルにある場合は、droppedCountを使用して既知の損失量を表示します。 読み取りが成功するたびに、空の読み取りであっても、カーソルとカーソルの状態が返されます。 レコードが到着しない場合でも、返されたカーソルを保持します。 カーソルはソース選択に属します。その選択を変更する場合は、カーソルを付けずに開始してください。 ソースが欠落している、空、重複している、またはサポートされていない場合は、形式が正しくないカーソルと無効な数値範囲が拒否されます。 レコードもキャプチャ設定もセッション履歴には保存されません。

session.rpc.diagnostics.configure({ sources: { mcp: { level: "off" } } })を呼び出して MCP キャプチャを無効にし、保持されているバッファーをクリアします。 構成では、明示的に名前が付けられたソースのみが更新され、有効なソース レベルが返されます。 空または不明なソース構成は拒否されます。今後、サポートされる別のソースを追加しても、既存の呼び出し元がそのソースに暗黙的にオプトインされることはありません。

ホストの読み取りループも停止します。ログ記録がオフの間は、読み取りは待機せずに直ちに返されます。 保留中の長いポーリングは、ログ記録が無効になると復帰します。 常駐状態からの再開時に diagnostics を省略すると、現在の構成が保持されます。コールド ロード セッションでは、新しいオプトインが必要です。 初期 off 状態から診断を有効にすると、すでに有効な MCP 接続のキャプチャを開始できます。 configure({ sources: { mcp: { level: "off" } } }) を使用して診断を無効にした後、再度有効にすると、同じライブ接続とその既存の接続 ID のキャプチャを再開できます。 診断が無効になったときに既に処理中だったレコードは破棄されます。

ランタイムは、エントリがこの API に到達する前に、構成済みの構造的に認識された資格情報を HTTP 診断から削除しますが、これは、任意のサーバーが提供するシークレットが存在しないという保証ではありません。 リクエストまたは応答ヘッダー マップは公開されません。 選択したメタデータ ( Content-Type、 Accept、 MCP-Protocol-Versionなど) のみがキャプチャの対象となりますが、その値はまだ信頼されておらず、機密性の高いコンテンツを含む可能性があります。 認証ヘッダー、Cookie、セッション ID、クエリ値、URL userinfo、フラグメントは省略されます。 URL パスはトラブルシューティングのために保持されるため、パス セグメントに資格情報を配置しないでください。 プロトコル ペイロードと stderr には、ユーザー コンテンツや任意のサーバー提供のシークレットが含まれることもあります。

Troubleshooting

ツールが表示されない、または呼び出されていない

  1. MCP サーバーが正しく起動されていることを確認する

    • コマンドと引数が正しいことを確認する
    • 起動時にサーバー プロセスがクラッシュしないことを確認する
    • stderr でエラー出力を探す
  2. ツールの構成を確認する

    • toolsが["*"]に設定されているか、必要な特定のツールが一覧表示されていることを確認します
    • 空の配列 [] は、ツールが有効になっていないこと
  3. リモート サーバーの接続を確認する

    • URL にアクセスできることを確認する
    • 認証ヘッダーが正しいことを確認する

一般的な問題

Issueソリューション
"MCP サーバーが見つかりません"コマンド パスが正しく、実行可能であることを確認する
"接続が拒否されました" (HTTP)URL を確認し、サーバーが実行されていることを確認します
"タイムアウトエラー"
timeout値を増やすか、サーバーのパフォーマンスを確認する
ツールは機能しますが、呼び出されませんプロンプトにツールの機能が明確に必要であることを確認する

デバッグの詳細なガイダンスについては、 MCP サーバー デバッグ ガイド を参照してください。

こちらも参照ください