Modell-Kontext-Protokoll (MCP)
Dokumentationsübersicht: Übersicht und Architektur · Client · Dynamischer Manager · Server-Erstellung · Sicherheit · Testen
MCP bietet einer KI-Anwendung eine Standardmethode, um Funktionen zu entdecken und zu nutzen, die einem anderen Prozess oder Dienst gehören. Ein Server kann veröffentlichen:
- tools, die Aktionen ausführen;
- resources, die lesbaren Kontext zurückgeben;
- prompts, die wiederverwendbare Nachrichtenvorlagen bereitstellen; und
- completion-Vorschläge, die einem Client helfen, prompt- oder resource-Argumente auszufüllen.
ADK-Rust ist normalerweise der MCP client. McpToolset wandelt entdeckte MCP tools
in normale ADK-Rust Tool Werte, sodass ein LlmAgent sie auswählen und aufrufen kann.
Das Framework stellt auch Ressourcen, Prompts, Vervollständigungen, Abonnements,
Elicitation und den ausgehandelten Aufgabenlebenszyklus bereit. Für die Erstellung von MCP-Servern und
fortgeschrittene Protokollarbeiten re-exportiert ADK-Rust die exakte rmcp SDK-Version, die es
verwendet.
ADK-Rust 2 verwendet derzeit rmcp 2.2, das offizielle Rust SDK, das mit der
MCP 2025-11-25 Spezifikation übereinstimmt.
Architektur
Es gibt zwei separate Schichten:
McpToolsetbesitzt eine initialisierte MCP client-Verbindung. Es entdeckt die Fähigkeiten des Servers und passt sie an ADK-Rust an.McpServerManagerbesitzt ein sich änderndes Register lokaler stdio-Server. Es startet, überwacht, startet neu, aktualisiert, aktiviert, deaktiviert, persistiert und aggregiert diese Verbindungen.
Der Manager erteilt keine Tool-Genehmigung. Es bewahrt autoApprove beim
Lesen kompatibler Konfigurationen, aber die Anwendung muss ihre normale
ADK-Rust Autorisierungs- und Genehmigungsrichtlinie anwenden.
Installation
Lokale stdio MCP-Unterstützung ist optional:
[dependencies]
adk-tool = { version = "2.0.0", features = ["mcp"] }
Fügen Sie Streamable HTTP hinzu, wenn Sie sich mit Remote-Diensten verbinden:
adk-tool = { version = "2.0.0", features = ["mcp", "http-transport"] }
Legacy-Sampling-Callbacks erfordern die separate mcp-sampling-Funktion. Das MCP-Projekt hat Sampling, Roots und Logging über SEP-2577 als veraltet erklärt; verwenden Sie diese APIs nur, wenn Sie eine kompatible Bereitstellung aufrechterhalten.
Einen lokalen Server verbinden
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 hält die Eingabe- und Ausgabeschemata des Servers intakt. Jeder Modelladapter normalisiert eine Kopie für seinen Anbieter, wenn er die Modell-Anfrage erstellt. Das ermöglicht es demselben MCP-Server, mit Gemini, OpenAI, Anthropic und anderen Anbietern zu arbeiten, ohne das Quellschema zu beschädigen.
Das Protokoll über Tools hinaus verwenden
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?;
Die Komfortmethoden geben eine leere Liste zurück, wenn ein älterer Server die Auflistung von Ressourcen oder Prompts nicht implementiert. Operationen gegen eine deklarierte Ressource oder einen Prompt geben einen Fehler zurück, wenn der Remote-Aufruf fehlschlägt.
Dynamische Serververwaltung
Verwenden Sie McpServerManager, wenn die Anwendung eine Flotte lokaler MCP-Child-Prozesse anstelle einer statischen Verbindung benötigt.
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()?;
Die Laufzeitregistrierung unterstützt:
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?;
Wenn zwei Server denselben Tool-Namen veröffentlichen, präfixiert das aggregierte Toolset beide Namen als {server_id}__{tool_name}. Eindeutige Namen bleiben unverändert.
Der Health Monitor erkennt eine geschlossene MCP-Verbindung. Ein konfigurierter RestartPolicy steuert die begrenzte Wiederholung mit exponentiellem Backoff. Dies ist eine Verbindungsüberwachung, keine anwendungsbezogene Gesundheitsprüfung: Verwenden Sie ein Domänen-Tool oder eine separate Dienstsonde, wenn Sie die unterstützende Datenbank oder externe API des Servers überprüfen müssen.
Führen Sie das deterministische Beispiel aus:
cargo run --manifest-path examples/mcp_manager/Cargo.toml
Es startet einen echten Rust MCP Child-Server und übt Discovery, einen Tool-Aufruf, Laufzeit-Hinzufügen/Aktivieren/Aktualisieren/Deaktivieren/Entfernen, Konfigurationspersistenz und Herunterfahren. Es lädt keine Pakete herunter und benötigt keinen API-Schlüssel.
Remote Streamfähiges 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?;
Der Builder wendet Anforderungs-Timeouts, benutzerdefinierte Header, Bearer-Tokens, benutzerdefinierte API-Schlüssel-Header und begrenzte Wiederherstellung an, wenn eine HTTP-Sitzung abläuft.
OAuth2Config implementiert eine feste OAuth 2.0 Client-Credentials Token-Anforderung. Dies ist nützlich für einen Server mit einem bekannten Token-Endpunkt. Es ist nicht der vollständige MCP-Autorisierungsfluss: es führt keine Metadaten-Discovery für geschützte Ressourcen, Autorisierungsserver-Discovery, Browser-Autorisierung, PKCE oder Ressourcenindikator-Verhandlung durch. Verwenden Sie die Autorisierungs-APIs von rmcp oder eine externe Identitätskomponente, wenn die Bereitstellung diesen Fluss erfordert.
Erlangung
Ein MCP-Server benötigt möglicherweise Informationen, die die Tool-Argumente nicht enthielten. In diesem Fall kann er eine Elicitation-Anfrage an den Client zurücksenden. Die Anwendung entscheidet, wie die Anfrage einer Person angezeigt wird und ob sie angenommen, abgelehnt oder abgebrochen werden soll.
let toolset = McpToolset::with_elicitation_handler(
transport,
Arc::new(MyElicitationHandler),
).await?;
ADK-Rust bewirbt sowohl Formular- als auch URL-Elicitation. Ein Handler-Fehler oder Panic wird in eine Ablehnung umgewandelt, damit die MCP-Verbindung nutzbar bleibt. Validieren Sie die zurückgegebenen Werte und wenden Sie Zustimmungsregeln in der Anwendung an, bevor Sie eine Folgeanfrage akzeptieren.
Siehe examples/mcp_elicitation für einen vollständigen Server und interaktiven Client.
Langlaufende MCP-Aufgaben
MCP 2025-11-25 kann einen Tool-Aufruf in eine Protokollaufgabe verschieben. ADK-Rust verwendet den Aufgabenfluss nur, wenn der Server tasks.requests.tools.call ausgehandelt hat und das Tool erforderliche oder optionale Aufgabenunterstützung deklariert.
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),
);
Für den Aufgabenmodus, ADK-Rust:
- sendet
tools/callmit offiziellen Aufgabenmetadaten; - empfängt die erstellte Aufgabe;
- fragt
tasks/getunter Verwendung des vom Server vorgeschlagenen Intervalls ab; - liest die endgültige Nutzlast über
tasks/result; und - ruft
tasks/cancelauf, wenn das lokale Timeout oder das Abfragelimit erreicht ist.
input_required wird als typisierter Fehler zurückgegeben, da ein gewöhnlicher ADK-Tool-Aufruf
noch keinen protokollneutralen Fortsetzungskanal besitzt, um diese fehlende
Eingabe bereitzustellen. Gestalten Sie diese Interaktion explizit im übergeordneten Workflow.
Fähigkeitsübersicht
| MCP Fähigkeit | ADK-Rust 2 Oberfläche | Anmerkungen |
|---|---|---|
| Tool-Erkennung und -Aufrufe | McpToolset, Toolset | Rohe Schemata; multimodale und strukturierte Ergebnisse bleiben erhalten |
| Tool-Filterung | with_filter, with_tools | Filtern vor der Bereitstellung für das Modell |
| Ressourcen und Vorlagen | list/read methods | Method-not-found für ältere Server behandelt |
| Prompts | list/get-Methoden | Typisierte Argument-Maps |
| Vervollständigung | prompt-/Ressourcen-Vervollständigungsmethoden | Gibt offizielle CompletionInfo zurück |
| Ressourcen-Abonnements | Abonnieren/Abbestellen-Methoden | Benachrichtigungen erfordern einen geeigneten Client-Handler |
| Elicitation | ElicitationHandler | Form and URL modes |
| Aufgaben | McpTaskConfig | Verhandelter tool-call Aufgabenlebenszyklus |
| Lokales stdio | TokioChildProcess | Direkt oder Manager-gesteuert |
| Streamfähiges HTTP | McpHttpClientBuilder | Timeouts, headers, auth injection, session recovery |
| Dynamische lokale Registrierung | McpServerManager | Hinzufügen/Aktualisieren/Aktivieren/Deaktivieren/Entfernen/Speichern/Überwachen/Neustarten |
| Server-Erstellung und Erweiterungen | adk_tool::mcp::rmcp | Exakter SDK-Re-Export für fortgeschrittene Nutzung |
| Probenahme, Wurzeln, Protokollierung | Kompatibilitätsfunktion / rmcp | Upstream veraltet durch SEP-2577 |
Die Wahl der Grenze
Verwenden Sie ein Rust FunctionTool, wenn die Fähigkeit zum selben Prozess und Release gehört. Verwenden Sie MCP, wenn ein anderes Programm, Team, eine andere Sprache, Sicherheitsgrenze oder Bereitstellung die Fähigkeit besitzt und einen eigenen Vertrag veröffentlichen sollte.
Für Produktionsbereitstellungen:
- den kleinstmöglichen nützlichen Werkzeugsatz offenlegen;
- schreibgeschützte und folgenreiche Aktionen trennen;
- Geheimnisse von Kommandozeilenargumenten und festgeschriebenen
mcp.jsonDateien fernhalten; - entfernte HTTP-Server authentifizieren und Anmeldeinformationen eng fassen;
- Werkzeugbeschreibungen und vom Server zurückgegebenen Inhalt als nicht vertrauenswürdige Eingabe behandeln;
- ADK-Rust Autorisierung und Genehmigung rund um die Werkzeugausführung beibehalten;
- Verbindungs-, Werkzeug- und Aufgaben-Timeouts begrenzen; und
- Werkzeugaufrufe, Genehmigungen, Fehler und Server-Lebenszyklusänderungen aufzeichnen.
Aktuelle Grenzen
McpServerManagerverwaltet lokale stdio-Child-Prozesse. Remote-HTTP-Dienste verwendenMcpHttpClientBuilderund anwendungsseitige Konfiguration.- Manager-Integritätsprüfungen erkennen geschlossene MCP-Verbindungen; sie rufen kein Integritäts-Tool auf Geschäftsebene auf.
- Registry-Mutationen werden serialisiert, während ein Child seinen MCP-Handshake abschließt.
autoApproveist Konfigurationskompatibilität, nicht Autorisierungsdurchsetzung.- Der integrierte OAuth-Helfer sind Client-Anmeldeinformationen, nicht der vollständige MCP-OAuth- Erkennungs- und Benutzerautorisierungsfluss.
Diese Grenzen werden genannt, damit Bereitstellungsentscheidungen explizit bleiben.