Protocole de contexte des modĂšles (MCP)

Carte de la documentation : Vue d’ensemble et architecture · Client · Gestionnaire dynamique · CrĂ©ation de serveurs · SĂ©curitĂ© · Tests

MCP fournit Ă  une application d’IA un moyen standard de dĂ©couvrir et d’utiliser des capacitĂ©s dĂ©tenues par un autre processus ou service. Un serveur peut publier :

  • des outils qui effectuent des actions ;
  • des ressources qui renvoient un contexte lisible ;
  • des invites qui fournissent des modĂšles de messages rĂ©utilisables ; et
  • des suggestions de complĂ©tion qui aident un client Ă  renseigner les arguments d’une invite ou d’une ressource.

ADK-Rust est gĂ©nĂ©ralement le client MCP. McpToolset transforme les outils MCP dĂ©couverts en valeurs Tool ADK-Rust ordinaires, afin qu’un LlmAgent puisse les sĂ©lectionner et les appeler. Le framework expose Ă©galement les ressources, les invites, la complĂ©tion, les abonnements, la sollicitation d’informations et le cycle de vie nĂ©gociĂ© des tĂąches. Pour la crĂ©ation de serveurs MCP et les travaux avancĂ©s sur le protocole, ADK-Rust rĂ©exporte la version exacte de SDK rmcp qu’il utilise.

ADK-Rust 2 utilise rmcp 3.1, le SDK officiel de Rust. Le client annonce MCP 2025-11-25 et se connecte aux serveurs 2026-07-28 via leur procĂ©dure d’établissement de liaison historique. examples/mcp_protocol_revisions prĂ©sente les deux rĂ©visions ainsi que l’extension de tĂąches SEP-2663 avec un serveur intĂ©grĂ©.

Architecture

Rendering architecture


Il existe deux couches distinctes :

  1. McpToolset gÚre une connexion client MCP initialisée. Il découvre les capacités du serveur et les adapte à ADK-Rust.
  2. McpServerManager gÚre un registre évolutif de serveurs stdio locaux. Il démarre, surveille, redémarre, met à jour, active, désactive, conserve et agrÚge ces connexions.

Le gestionnaire n’accorde pas l’autorisation d’utiliser les outils. Il prĂ©serve autoApprove lors de la lecture d’une configuration compatible, mais l’application doit appliquer sa politique habituelle d’autorisation et d’approbation ADK-Rust.

Installation

La prise en charge de stdio local MCP est activée explicitement :

[dependencies]
adk-tool = { version = "2.1.0", features = ["mcp"] }

Ajoutez Streamable HTTP lors de la connexion Ă  des services distants :

adk-tool = { version = "2.1.0", features = ["mcp", "http-transport"] }

Les anciens rappels d’échantillonnage nĂ©cessitent la fonctionnalitĂ© distincte mcp-sampling. Le projet MCP a rendu obsolĂštes l’échantillonnage, les racines et la journalisation via SEP-2577 ; utilisez ces APIs uniquement pour maintenir 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 conserve les schĂ©mas d’entrĂ©e et de sortie du serveur tels quels. Chaque adaptateur de modĂšle normalise une copie pour son fournisseur lors de la construction de la requĂȘte du modĂšle. Cela permet au mĂȘme serveur MCP de fonctionner avec Gemini, OpenAI, Anthropic et d’autres fournisseurs sans altĂ©rer 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 pratiques renvoient une liste vide lorsqu’un serveur plus ancien n’implĂ©mente pas la liste des ressources ou des invites. Les opĂ©rations portant 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’un ensemble de processus enfants locaux MCP plutît que d’une seule connexion statique.

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 avec {server_id}__{tool_name}. Les noms uniques restent inchangĂ©s.

Le moniteur d’intĂ©gritĂ© dĂ©tecte une connexion MCP fermĂ©e. Un RestartPolicy configurĂ© contrĂŽle les tentatives limitĂ©es avec une temporisation exponentielle. Il s’agit d’une supervision de connexion, et non d’une vĂ©rification d’intĂ©gritĂ© au niveau de l’application : utilisez un outil de domaine ou une sonde de service distincte lorsque vous devez vĂ©rifier la base de donnĂ©es sous-jacente du serveur ou un 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 met Ă  l’épreuve 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 diffusé à distance

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 gĂ©nĂ©rateur applique des dĂ©lais d’expiration aux requĂȘtes, des en-tĂȘtes personnalisĂ©s, des jetons bearer, 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 Ă  identifiants client fixe OAuth 2.0. Il est utile pour un serveur possĂ©dant un point de terminaison de jeton connu. Il ne s’agit pas du flux d’autorisation MCP complet : il n’effectue pas la dĂ©couverte des mĂ©tadonnĂ©es de la ressource protĂ©gĂ©e, la dĂ©couverte du serveur d’autorisation, l’autorisation via navigateur, PKCE ou la nĂ©gociation d’indicateur de ressource. Utilisez l’autorisation APIs de rmcp ou un composant d’identitĂ© externe lorsque le dĂ©ploiement requiert ce flux.

Sollicitation

Un serveur MCP peut avoir besoin d’informations qui n’étaient pas incluses dans les arguments de l’outil. Dans ce cas, il peut renvoyer une demande de sollicitation au client. L’application dĂ©cide comment prĂ©senter la demande Ă  une personne et s’il convient de l’accepter, de la refuser ou de l’annuler.

let toolset = McpToolset::with_elicitation_handler(
    transport,
    Arc::new(MyElicitationHandler),
).await?;

ADK-Rust annonce Ă  la fois l’interface et l’URL. Une erreur ou une panique du gestionnaire est convertie 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 ayant des consĂ©quences.

Voir examples/mcp_elicitation pour un serveur complet et un client interactif.

Tùches MCP de longue durée

MCP 2025-11-25 peut convertir un appel d’outil en tĂąche de protocole. ADK-Rust utilise le flux de tĂąche uniquement lorsque le serveur a nĂ©gociĂ© tasks.requests.tools.call et que l’outil dĂ©clare la prise en charge obligatoire ou facultative des tĂąches.

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),
);

En mode tĂąche, ADK-Rust :

  1. envoie tools/call avec les métadonnées officielles de la tùche ;
  2. reçoit la tùche créée ;
  3. interroge tasks/get en utilisant l’intervalle suggĂ©rĂ© par le serveur ;
  4. lit la charge utile finale via tasks/result ; et
  5. appelle tasks/cancel lorsque son dĂ©lai d’attente ou sa limite d’interrogations locale est atteinte.

input_required est renvoyĂ©e sous forme d’erreur typĂ©e, car un appel d’outil ADK ordinaire ne dispose pas encore d’un canal de reprise neutre vis-Ă -vis du protocole permettant de fournir cette entrĂ©e manquante. Concevez explicitement cette interaction dans le flux de travail qui en est responsable.

Carte des capacités

MCP capacitéADK-Rust 2 interfaceRemarques
DĂ©couverte et appels d’outilsMcpToolset, ToolsetSchĂ©mas bruts ; rĂ©sultats multimodaux et structurĂ©s prĂ©servĂ©s
Filtrage des outilswith_filter, with_toolsFiltrer avant l’exposition au modùle
Ressources et modĂšlesmĂ©thodes de liste/lectureGestion de l’absence de mĂ©thode pour les anciens serveurs
InvitesmĂ©thodes de liste/rĂ©cupĂ©rationCartes d’arguments typĂ©es
Complétionméthodes de complétion des invites/ressourcesRenvoie le CompletionInfo officiel
Abonnements aux ressourcesmĂ©thodes d’abonnement/dĂ©sabonnementLes notifications nĂ©cessitent un gestionnaire client appropriĂ©
SollicitationElicitationHandlerModes formulaire et URL
TĂąchesMcpTaskConfigCycle de vie des tĂąches d’appel d’outil nĂ©gociĂ©es
stdio localTokioChildProcessDirect ou géré par le gestionnaire
Streamable HTTPMcpHttpClientBuilderDĂ©lais d’expiration, en-tĂȘtes, injection d’authentification, rĂ©cupĂ©ration de session
Registre local dynamiqueMcpServerManagerAjouter/mettre à jour/activer/désactiver/supprimer/enregistrer/surveiller/redémarrer
Création et extensions du serveuradk_tool::mcp::rmcpRéexportation exacte de SDK pour une utilisation avancée
Échantillonnage, racines, journalisationfonctionnalitĂ© de compatibilitĂ© / rmcpObsolĂšte 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, une autre Ă©quipe, un autre langage, une autre limite de sĂ©curitĂ© ou un autre dĂ©ploiement possĂšde la capacitĂ© et doit publier son propre contrat.

Pour les déploiements en production :

  • exposez le plus petit ensemble d’outils utile ;
  • sĂ©parez les actions en lecture seule des actions ayant des consĂ©quences ;
  • gardez les secrets hors des arguments de ligne de commande et des fichiers mcp.json versionnĂ©s ;
  • authentifiez les serveurs HTTP distants et limitez strictement les identifiants ;
  • considĂ©rez les descriptions des outils et le contenu renvoyĂ© par les serveurs comme des entrĂ©es non fiables ;
  • maintenez l’autorisation et l’approbation ADK-Rust autour de l’exĂ©cution des outils ;
  • imposez des dĂ©lais d’expiration aux connexions, aux outils et aux tĂąches ; et
  • consignez les appels d’outils, les approbations, les erreurs et les changements du cycle de vie des serveurs.

Limites actuelles

  • McpServerManager gĂšre les processus enfants locaux via stdio. Les services HTTP distants utilisent McpHttpClientBuilder et une configuration gĂ©rĂ©e par l’application.
  • Les vĂ©rifications d’état du gestionnaire dĂ©tectent les connexions MCP fermĂ©es ; elles n’appellent pas d’outil d’état au niveau mĂ©tier.
  • Les modifications du registre sont sĂ©rialisĂ©es pendant qu’un processus enfant termine sa nĂ©gociation MCP.
  • autoApprove concerne la compatibilitĂ© de configuration, et non l’application des autorisations.
  • L’assistant OAuth intĂ©grĂ© correspond aux identifiants du client, et non au flux complet de dĂ©couverte et d’autorisation de l’utilisateur MCP OAuth.

Ces limites sont énoncées afin que les décisions de déploiement restent explicites.

Références

Protocole de contexte des modĂšles (MCP) - Documentation ADK-Rust | ADK-Rust