モデルコンテキストプロトコル (MCP)
ドキュメントマップ: 概要とアーキテクチャ · クライアント · 動的マネージャー · サーバー作成 · セキュリティ · テスト
MCPは、AIアプリケーションが別のプロセスまたはサービスによって所有される機能を発見し、利用するための標準的な方法を提供します。サーバーは次を公開できます。
- アクションを実行するツール;
- 読み取り可能なコンテキストを返すリソース;
- 再利用可能なメッセージテンプレートを提供するプロンプト;
- クライアントがプロンプトまたはリソースの引数を入力するのを支援する補完候補。
ADK-Rustは通常、MCPのクライアントです。McpToolsetは、発見したMCPツールを通常のADK-Rust Tool値に変換するため、LlmAgentはそれらを選択して呼び出すことができます。フレームワークは、リソース、プロンプト、補完、サブスクリプション、情報要求、およびネゴシエーションされたタスクのライフサイクルも公開します。MCPサーバーの作成と高度なプロトコル処理のために、ADK-Rustは使用する正確なrmcp SDKバージョンを再エクスポートします。
ADK-Rust 2は、公式のRust SDKであるrmcp 3.1を使用します。クライアントはMCP 2025-11-25を通知し、従来のハンドシェイクを介して2026-07-28サーバーに接続します。examples/mcp_protocol_revisionsは、同梱サーバーに対して両方のリビジョンとSEP-2663タスク拡張を実演します。
アーキテクチャ
2つの独立した層があります。
McpToolsetは、初期化済みのMCPクライアント接続を1つ管理します。サーバーの機能を検出し、それらをADK-Rustに適応させます。McpServerManagerは、ローカルstdioサーバーの変化するレジストリを管理します。これらの接続を起動、監視、再起動、更新、有効化、無効化、永続化し、集約します。
マネージャーはツールの承認を付与しません。互換性のある設定を読み取る際には autoApprove を保持しますが、アプリケーションは通常の ADK-Rust 認証および承認ポリシーを適用する必要があります。
インストール
ローカル stdio MCP のサポートはオプトインです。
[dependencies]
adk-tool = { version = "2.1.0", features = ["mcp"] }
リモートサービスに接続する際は Streamable HTTP を追加します。
adk-tool = { version = "2.1.0", features = ["mcp", "http-transport"] }
レガシーサンプリングコールバックには、別個の mcp-sampling 機能が必要です。MCP プロジェクトでは SEP-2577 によりサンプリング、ルート、ロギングが非推奨になっています。互換性のあるデプロイメントを保守する場合にのみ、これらの APIs を使用してください。
1 つのローカルサーバーに接続する
use adk_tool::{
McpToolset,
mcp::rmcp::{ServiceExt, transport::TokioChildProcess},
};
use std::sync::Arc;
use tokio::process::Command;
let command = Command::new("./target/release/company-mcp");
let client = ().serve(TokioChildProcess::new(command)?).await?;
let toolset = McpToolset::new(client)
.with_name("company_tools")
.with_tools(&["find_customer", "read_order", "request_refund"]);
let agent = LlmAgentBuilder::new("support")
.model(model)
.toolset(Arc::new(toolset.clone()))
.build()?;
// Keep the token when the application owns the process lifecycle.
let shutdown = toolset.cancellation_token().await;
// ... run the agent ...
shutdown.cancel();
McpToolset は、サーバーの入力および出力スキーマをそのまま保持します。各モデルアダプターは、モデルリクエストを構築する際に、プロバイダー用にコピーを正規化します。これにより、同じ MCP サーバーを、ソーススキーマを損なうことなく Gemini、OpenAI、Anthropic、その他のプロバイダーで利用できます。
ツール以外でプロトコルを使用する
use serde_json::json;
let resources = toolset.list_resources().await?;
let templates = toolset.list_resource_templates().await?;
let contents = toolset.read_resource("company://policy/refunds").await?;
let prompts = toolset.list_prompts().await?;
let prompt = toolset
.get_prompt(
"investigate_order",
Some(serde_json::Map::from_iter([
("order_id".to_string(), json!("ORD-1042")),
])),
)
.await?;
let suggestions = toolset
.complete_prompt_argument("investigate_order", "order_id", "ORD-", None)
.await?;
toolset.subscribe_resource("company://inventory/sku-42").await?;
// ... receive notifications in a custom ClientHandler ...
toolset.unsubscribe_resource("company://inventory/sku-42").await?;
古いサーバーがリソースまたはプロンプトの一覧表示を実装していない場合、便利なメソッドは空のリストを返します。宣言されたリソースまたはプロンプトに対する操作は、リモート呼び出しが失敗するとエラーを返します。
動的なサーバー管理
静的な接続を 1 つ確立するのではなく、ローカルの MCP 子プロセス群を管理する必要がある場合は、McpServerManager を使用します。
use adk_tool::mcp::manager::{McpServerConfig, McpServerManager};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
let manager = Arc::new(McpServerManager::from_json_file("mcp.json")?
.with_name("product_mcp_servers")
.with_health_check_interval(Duration::from_secs(15))
.with_grace_period(Duration::from_secs(2)));
let outcomes = manager.start_all().await;
for (server_id, outcome) in outcomes {
if let Err(error) = outcome {
eprintln!("{server_id} did not start: {error}");
}
}
manager.start_monitoring();
let agent = LlmAgentBuilder::new("operator")
.model(model)
.toolset(manager.clone())
.build()?;
ランタイムレジストリは次をサポートします。
manager.add_server("billing".into(), billing_config).await?;
manager.start_server("billing").await?;
manager.update_server("billing", replacement_config).await?;
manager.disable_server("billing").await?;
manager.enable_server("billing").await?;
manager.save_json_file("mcp.json").await?;
manager.remove_server("billing").await?;
manager.shutdown().await?;
2 つのサーバーが同じツール名を公開すると、集約されたツールセットは両方の名前に {server_id}__{tool_name} を付加します。一意の名前は変更されません。
ヘルスモニターは、切断された MCP 接続を検出します。設定された
RestartPolicy により、指数バックオフを伴う回数制限付きの再試行が制御されます。これは
接続の監視であり、アプリケーションレベルのヘルスチェックではありません。サーバーの背後にある
データベースや外部 API を検証する必要がある場合は、ドメインツールまたは別のサービスプローブを
使用してください。
決定論的な例を実行します。
cargo run --manifest-path examples/mcp_manager/Cargo.toml
実際の Rust MCP 子サーバーを起動し、検出、ツール呼び出し、 実行時の追加/有効化/更新/無効化/削除、設定の永続化、シャットダウンを実行します。パッケージを ダウンロードせず、API キーも必要ありません。
リモートストリーミング可能な HTTP
use adk_tool::{McpAuth, McpHttpClientBuilder};
use std::time::Duration;
let toolset = McpHttpClientBuilder::new("https://mcp.example.com/mcp")
.with_auth(McpAuth::bearer(std::env::var("MCP_TOKEN")?))
.header("X-Tenant-ID", "tenant-42")
.timeout(Duration::from_secs(30))
.reinit_on_expired_session(true)
.connect()
.await?;
ビルダーは、リクエストのタイムアウト、カスタムヘッダー、ベアラートークン、カスタム API-キーのヘッダー、および HTTP セッションの期限切れ時の回数制限付きリカバリを 適用します。
OAuth2Config は、固定された OAuth 2.0 クライアント資格情報トークン要求を実装します。
既知のトークンエンドポイントを持つサーバーに便利です。これは完全な
MCP 認可フローではありません。保護されたリソースのメタデータ検出、認可サーバーの検出、
ブラウザー認可、PKCE、リソースインジケーターのネゴシエーションは実行しません。そのフローが必要な
デプロイでは、rmcp の認可 APIs または外部の
アイデンティティコンポーネントを使用してください。
情報要求
MCP サーバーは、ツールの引数に含まれていない情報を必要とする場合があります。その 場合、サーバーはクライアントに情報要求を送り返すことができます。アプリケーションは、その要求を 利用者にどのように表示するか、また受け入れるか、拒否するか、キャンセルするかを決定します。
let toolset = McpToolset::with_elicitation_handler(
transport,
Arc::new(MyElicitationHandler),
).await?;
ADK-Rust はフォームと URL の引き出しの両方を提供します。ハンドラーのエラーまたはパニックは拒否に変換されるため、MCP 接続は引き続き利用可能です。結果として返された値を検証し、影響の大きいリクエストを受け入れる前に、アプリケーションで同意ルールを適用してください。
完全なサーバーと対話型クライアントについては、examples/mcp_elicitation を参照してください。
長時間実行される MCP タスク
MCP 2025-11-25 は、ツール呼び出しをプロトコルタスクに移行できます。ADK-Rust は、サーバーが tasks.requests.tools.call をネゴシエートし、ツールが必須または任意のタスクサポートを宣言している場合にのみ、タスクフローを使用します。
use adk_tool::McpTaskConfig;
use std::time::Duration;
let toolset = McpToolset::new(client).with_task_support(
McpTaskConfig::enabled()
.poll_interval(Duration::from_secs(1))
.timeout(Duration::from_secs(120))
.max_attempts(120),
);
タスクモードでは、ADK-Rust は次の処理を行います。
- 公式のタスクメタデータを含む
tools/callを送信する。 - 作成されたタスクを受信する。
- サーバーが推奨する間隔を使用して
tasks/getをポーリングする。 tasks/resultを通じて最終ペイロードを読み取る。- ローカルのタイムアウトまたはポーリング上限に達した場合に
tasks/cancelを呼び出す。
input_required は型付きエラーとして返されます。通常の ADK ツール呼び出しには、現在のところ、不足している入力を提供するためのプロトコルに依存しない再開チャネルがないためです。このやり取りは、それを所有するワークフロー内で明示的に設計してください。
機能マップ
| MCP 能力 | ADK-Rust 2 サーフェス | 注記 |
|---|---|---|
| ツールの検出と呼び出し | McpToolset, Toolset | 生のスキーマ、マルチモーダルおよび構造化された結果を保持 |
| ツールのフィルタリング | with_filter, with_tools | モデルに公開する前にフィルタリング |
| リソースとテンプレート | list/read メソッド | 古いサーバー向けにメソッド未検出を処理 |
| プロンプト | list/get メソッド | 型付き引数マップ |
| 補完 | prompt/resource 補完メソッド | 公式の CompletionInfo を返す |
| リソースのサブスクリプション | subscribe/unsubscribe メソッド | 通知には適切なクライアントハンドラーが必要 |
| 誘出 | ElicitationHandler | フォームおよび URL モード |
| タスク | McpTaskConfig | 交渉型ツール呼び出しタスクのライフサイクル |
| ローカル stdio | TokioChildProcess | 直接またはマネージャー所有 |
| ストリーム可能な HTTP | McpHttpClientBuilder | タイムアウト、ヘッダー、認証の注入、セッションの復旧 |
| 動的ローカルレジストリ | McpServerManager | 追加/更新/有効化/無効化/削除/保存/監視/再起動 |
| サーバーの作成と拡張 | adk_tool::mcp::rmcp | 高度な用途向けの SDK の正確な再エクスポート |
| サンプリング、ルート、ロギング | 互換性機能 / rmcp | SEP-2577 を通じて上流で非推奨 |
境界の選択
機能が同じプロセスおよびリリースに属する場合は、Rust FunctionTool を使用します。別のプログラム、チーム、言語、セキュリティ境界、またはデプロイメントが機能を所有し、独自のコントラクトを公開すべき場合は、MCP を使用します。
本番環境へのデプロイメントでは、次の点に従います。
- 有用なツールセットを最小限にする。
- 読み取り専用のアクションと、結果に影響するアクションを分離する。
- コマンドライン引数およびコミット済みの
mcp.jsonファイルにシークレットを含めない。 - リモート HTTP サーバーを認証し、認証情報の範囲を厳密に限定する。
- ツールの説明およびサーバーから返されるコンテンツを、信頼できない入力として扱う。
- ツール実行に対する ADK-Rust の認可および承認を維持する。
- 接続、ツール、タスクのタイムアウトに上限を設ける。
- ツール呼び出し、承認、エラー、サーバーのライフサイクルの変更を記録する。
現在の制限
McpServerManagerはローカルの stdio 子プロセスを管理します。リモート HTTP サービスでは、McpHttpClientBuilderとアプリケーション所有の構成を使用します。- Manager のヘルスチェックは、切断された MCP 接続を検出しますが、ビジネスレベルのヘルスツールは呼び出しません。
- レジストリの変更は、子プロセスが MCP ハンドシェイクを完了するまでシリアル化されます。
autoApproveは構成の互換性に関するものであり、認可の強制ではありません。- 組み込みの OAuth ヘルパーはクライアント認証情報であり、完全な MCP OAuth のディスカバリーおよびユーザー認可フローではありません。
これらの制限は、デプロイメントに関する判断を明示的に保つために記載されています。