Protocole de Contexte de ModĂšle (MCP)
Plan de la documentation : Vue d'ensemble et architecture · Client · Gestionnaire dynamique · Création de serveurs · Sécurité · Tests
MCP offre à une application d'IA un moyen standard de découvrir et d'utiliser les capacités détenues par un autre processus ou service. Un serveur peut publier :
- tools qui effectuent des actions ;
- resources qui retournent un contexte lisible ;
- prompts qui fournissent des modÚles de messages réutilisables ; et
- completion suggestions qui aident un client Ă remplir les arguments de prompt ou de resource.
ADK-Rust est généralement le client MCP. McpToolset transforme les tools MCP découverts en valeurs normales ADK-Rust Tool, de sorte qu'un LlmAgent puisse les sélectionner et les appeler. Le framework expose également les resources, les prompts, la completion, les abonnements, l'élicitation et le cycle de vie négocié des tùches. Pour la création de serveurs MCP et les travaux de protocole avancés, ADK-Rust ré-exporte la version exacte du SDK rmcp qu'il utilise.
ADK-Rust 2 utilise actuellement rmcp 2.2, le Rust SDK officiel aligné sur la spécification MCP 2025-11-25.
Architecture
Il y a deux couches distinctes :
McpToolsetpossÚde une connexion client MCP initialisée. Il découvre les capacités du serveur et les adapte à ADK-Rust.McpServerManagerpossÚde un registre évolutif de serveurs stdio locaux. Il démarre, surveille, redémarre, met à jour, active, désactive, persiste et agrÚge ces connexions.
Le gestionnaire n'accorde pas l'approbation des outils. Il préserve autoApprove lors de la lecture d'une configuration compatible, mais l'application doit appliquer sa politique normale d'autorisation et d'approbation ADK-Rust.
Installation
Le support local stdio MCP est optionnel :
[dependencies]
adk-tool = { version = "2.0.0", features = ["mcp"] }
Ajoutez le HTTP streamable lors de la connexion Ă des services distants :
adk-tool = { version = "2.0.0", features = ["mcp", "http-transport"] }
Les rappels d'échantillonnage hérités nécessitent la fonctionnalité mcp-sampling distincte. Le projet MCP a déprécié l'échantillonnage, les racines et la journalisation via SEP-2577 ; utilisez ces API uniquement lors du maintien d'un déploiement compatible.
Connecter un serveur local
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 maintient les schĂ©mas d'entrĂ©e et de sortie du serveur intacts. Chaque adaptateur de modĂšle normalise une copie pour son fournisseur lorsqu'il construit la requĂȘte de modĂšle. Cela permet au mĂȘme serveur MCP de fonctionner avec Gemini, OpenAI, Anthropic et d'autres fournisseurs sans endommager le schĂ©ma source.
Utiliser le protocole au-delĂ des outils
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?;
Les méthodes de commodité renvoient une liste vide lorsqu'un serveur plus ancien n'implémente pas la liste des ressources ou des invites. Les opérations sur une ressource ou une invite déclarée renvoient une erreur lorsque l'appel distant échoue.
Gestion dynamique des serveurs
Utilisez McpServerManager lorsque l'application a besoin d'une flotte de processus enfants MCP locaux plutĂŽt que d'une connexion statique unique.
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()?;
Le registre d'exécution prend en charge :
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?;
Lorsque deux serveurs publient le mĂȘme nom d'outil, l'ensemble d'outils agrĂ©gĂ© prĂ©fixe les deux noms comme {server_id}__{tool_name}. Les noms uniques restent inchangĂ©s.
Le moniteur de santé détecte une connexion MCP fermée. Une RestartPolicy configurée contrÎle les tentatives limitées avec un backoff exponentiel. Il s'agit d'une supervision de connexion, pas d'une vérification de santé au niveau de l'application : utilisez un outil de domaine ou une sonde de service séparée lorsque vous devez vérifier la base de données de support du serveur ou une API externe.
Exécutez l'exemple déterministe :
cargo run --manifest-path examples/mcp_manager/Cargo.toml
Il dĂ©marre un vĂ©ritable serveur enfant Rust MCP et exerce la dĂ©couverte, un appel d'outil, l'ajout/l'activation/la mise Ă jour/la dĂ©sactivation/la suppression Ă l'exĂ©cution, la persistance de la configuration et l'arrĂȘt. Il ne tĂ©lĂ©charge pas de paquets et ne nĂ©cessite pas de clĂ© API.
HTTP distant et streamable
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?;
Le constructeur applique des dĂ©lais d'attente de requĂȘte, des en-tĂȘtes personnalisĂ©s, des jetons d'authentification (bearer tokens), des en-tĂȘtes de clĂ© API personnalisĂ©s et une rĂ©cupĂ©ration limitĂ©e lorsqu'une session HTTP expire.
OAuth2Config implĂ©mente une requĂȘte de jeton client-credentials OAuth 2.0 fixe. Il est utile pour un serveur avec un token endpoint connu. Ce n'est pas le flux d'autorisation MCP complet : il n'effectue pas la dĂ©couverte de mĂ©tadonnĂ©es de ressource protĂ©gĂ©e, la dĂ©couverte de serveur d'autorisation, l'autorisation de navigateur, le PKCE, ou la nĂ©gociation d'indicateur de ressource. Utilisez les APIs d'autorisation de rmcp ou un composant d'identitĂ© externe lorsque le dĂ©ploiement requiert ce flux.
Ălicitation
Un serveur MCP peut avoir besoin d'informations que les arguments de l'outil n'incluaient pas. Dans ce cas, il peut envoyer une requĂȘte d'Ă©licitation au client. L'application dĂ©cide comment afficher la requĂȘte Ă une personne et si elle doit l'accepter, la refuser ou l'annuler.
let toolset = McpToolset::with_elicitation_handler(
transport,
Arc::new(MyElicitationHandler),
).await?;
ADK-Rust propose la sollicitation de formulaires et d'URL. Une erreur de gestionnaire ou un panic est converti en refus afin que la connexion MCP reste utilisable. Validez les valeurs renvoyĂ©es et appliquez les rĂšgles de consentement dans l'application avant d'accepter une requĂȘte consĂ©cutive.
Consultez examples/mcp_elicitation pour un serveur complet et un client interactif.
Tùches MCP de longue durée
MCP 2025-11-25 peut déplacer un appel d'outil vers une tùche de protocole. ADK-Rust utilise le flux de tùches uniquement lorsque le serveur a négocié tasks.requests.tools.call et que l'outil déclare un support de tùche requis ou optionnel.
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),
);
Pour le mode tĂąche, ADK-Rust :
- envoie
tools/callavec les métadonnées de tùche officielles ; - reçoit la tùche créée ;
- interroge
tasks/geten utilisant l'intervalle suggéré par le serveur ; - lit la charge utile finale via
tasks/result; et - appelle
tasks/cancellorsque son délai d'attente local ou sa limite d'interrogation est atteint.
input_required est renvoyé comme une erreur typée car un appel d'outil ADK ordinaire n'a pas encore de canal de reprise neutre au niveau du protocole pour fournir cette entrée manquante. Concevez cette interaction explicitement dans le flux de travail propriétaire.
Mappage des capacités
| Capacité MCP | ADK-Rust 2 surface | Notes |
|---|---|---|
| Découverte et appels d'outils | McpToolset, Toolset | Schémas bruts ; résultats multimodaux et structurés préservés |
| Filtrage d'outils | with_filter, with_tools | Filtrer avant l'exposition au modĂšle |
| Ressources et modÚles | list/read methods | Méthode non trouvée gérée pour les serveurs plus anciens |
| Prompts | list/get methods | Mappages d'arguments typés |
| Complétion | prompt/resource completion methods | Retourne l'CompletionInfo officielle |
| Abonnements aux ressources | subscribe/unsubscribe methods | Les notifications nécessitent un gestionnaire de client approprié |
| Ălicitation | ElicitationHandler | Modes formulaire et URL |
| Tùches | McpTaskConfig | Cycle de vie des tùches d'appel d'outil négocié |
| Local stdio | TokioChildProcess | Direct ou géré par un responsable |
| Streamable HTTP | McpHttpClientBuilder | DĂ©lais d'attente, en-tĂȘtes, injection d'authentification, rĂ©cupĂ©ration de session |
| Registre local dynamique | McpServerManager | Ajouter/mettre à jour/activer/désactiver/supprimer/enregistrer/surveiller/redémarrer |
| Création de serveur et extensions | adk_tool::mcp::rmcp | Ré-exportation exacte du SDK pour une utilisation avancée |
| Sampling, roots, logging | fonctionnalité de compatibilité / rmcp | Déprécié en amont via SEP-2577 |
Choisir la limite
Utilisez un FunctionTool Rust lorsque la capacitĂ© appartient au mĂȘme processus et Ă la mĂȘme version. Utilisez MCP lorsqu'un autre programme, Ă©quipe, langage, limite de sĂ©curitĂ© ou dĂ©ploiement possĂšde la capacitĂ© et doit publier son propre contrat.
Pour les déploiements en production :
- exposer l'ensemble d'outils utiles le plus restreint ;
- séparer les actions en lecture seule et les actions à conséquences ;
- garder les secrets hors des arguments de ligne de commande et des fichiers
mcp.jsonvalidés ; - authentifier les serveurs HTTP distants et limiter strictement la portée des identifiants ;
- traiter les descriptions d'outils et le contenu retourné par le serveur comme des entrées non fiables ;
- maintenir l'autorisation et l'approbation ADK-Rust autour de l'exécution d'outils ;
- limiter les délais de connexion, d'outil et de tùche ; et
- enregistrer les appels d'outils, les approbations, les erreurs et les changements de cycle de vie du serveur.
Limites actuelles
McpServerManagergÚre les processus enfants stdio locaux. Les services HTTP distants utilisentMcpHttpClientBuilderet une configuration appartenant à l'application.- Les vérifications de santé du gestionnaire détectent les connexions MCP fermées ; elles n'appellent pas un outil de santé de niveau métier.
- Les mutations de registre sont sérialisées pendant qu'un enfant complÚte son handshake MCP.
autoApproveest la compatibilité de configuration, et non l'application de l'autorisation.- L'aide OAuth intégrée est des identifiants de client, et non le flux complet de découverte OAuth MCP et d'autorisation utilisateur.
Ces limites sont énoncées afin que les décisions de déploiement restent explicites.