Protocolo de Contexto del Modelo (MCP)
Mapa de la documentación: Visión general y arquitectura · Cliente · Gestor dinámico · Creación de servidores · Seguridad · Pruebas
MCP proporciona a una aplicación de IA una forma estándar de descubrir y utilizar capacidades propiedad de otro proceso o servicio. Un servidor puede publicar:
- tools que realizan acciones;
- resources que devuelven contexto legible;
- prompts que proporcionan plantillas de mensajes reutilizables; y
- sugerencias de completion que ayudan a un cliente a rellenar argumentos de prompt o resource.
ADK-Rust es usualmente el MCP client. McpToolset convierte las herramientas MCP descubiertas en valores ADK-Rust Tool normales, para que un LlmAgent pueda seleccionarlas y llamarlas. El framework también expone recursos, prompts, completado, suscripciones, elicitación y el ciclo de vida de la tarea negociada. Para la autoría de servidores MCP y el trabajo de protocolo avanzado, ADK-Rust re-exporta la versión exacta de rmcp SDK que utiliza.
ADK-Rust 2 actualmente utiliza rmcp 2.2, el SDK oficial de Rust alineado con la especificación MCP 2025-11-25.
Arquitectura
Hay dos capas separadas:
McpToolsetposee una conexión de cliente MCP inicializada. Descubre las capacidades del servidor y las adapta a ADK-Rust.McpServerManagerposee un registro cambiante de servidores stdio locales. Inicia, monitorea, reinicia, actualiza, habilita, deshabilita, persiste y agrega esas conexiones.
El gestor no concede la aprobación de herramientas. Preserva autoApprove al leer una configuración compatible, pero la aplicación debe aplicar su política normal de autorización y aprobación ADK-Rust.
Instalación
El soporte local de stdio MCP es opcional:
[dependencies]
adk-tool = { version = "2.0.0", features = ["mcp"] }
Añada Streamable HTTP al conectarse a servicios remotos:
adk-tool = { version = "2.0.0", features = ["mcp", "http-transport"] }
Las devoluciones de llamada de muestreo heredadas requieren la característica separada mcp-sampling. El proyecto MCP ha desaprobado el muestreo, las raíces y el registro a través de SEP-2577; utilice esos APIs solo al mantener una implementación compatible.
Conectar un servidor 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 mantiene intactos los esquemas de entrada y salida del servidor. Cada adaptador de modelo normaliza una copia para su proveedor cuando construye la solicitud del modelo. Eso permite que el mismo servidor MCP funcione con Gemini, OpenAI, Anthropic y otros proveedores sin dañar el esquema fuente.
Usar el protocolo más allá de las herramientas
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?;
Los métodos de conveniencia devuelven una lista vacía cuando un servidor antiguo no implementa la lista de recursos o prompts. Las operaciones contra un recurso o prompt declarado devuelven un error cuando la llamada remota falla.
Gestión dinámica de servidores
Usa McpServerManager cuando la aplicación necesita una flota de procesos hijo MCP locales en lugar de una conexión estática.
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()?;
El registro en tiempo de ejecución soporta:
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?;
Cuando dos servidores publican el mismo nombre de herramienta, el conjunto de herramientas agregado prefija ambos nombres como {server_id}__{tool_name}. Los nombres únicos permanecen sin cambios.
El monitor de salud detecta una conexión MCP cerrada. Un RestartPolicy configurado controla el reintento limitado con retroceso exponencial. Esto es supervisión de conexión, no una verificación de salud a nivel de aplicación: use una herramienta de dominio o una sonda de servicio separada cuando necesite verificar la base de datos de respaldo del servidor o el API externo.
Ejecute el ejemplo determinista:
cargo run --manifest-path examples/mcp_manager/Cargo.toml
Inicia un servidor hijo Rust MCP real y ejercita el descubrimiento, una llamada a herramienta, la adición/habilitación/actualización/deshabilitación/eliminación en tiempo de ejecución, la persistencia de la configuración y el apagado. No descarga paquetes ni requiere una clave API.
HTTP Remoto Transmitible
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?;
El constructor aplica tiempos de espera de solicitud, encabezados personalizados, tokens de portador, encabezados de clave API personalizados y recuperación limitada cuando una sesión HTTP expira.
OAuth2Config implementa una solicitud fija de token OAuth 2.0 de credenciales de cliente.
Es útil para un servidor con un endpoint de token conocido. No es el flujo de autorización MCP completo: no realiza descubrimiento de metadatos de recursos protegidos, descubrimiento de servidor de autorización, autorización de navegador, PKCE o negociación de indicadores de recursos. Utilice el APIs de autorización de rmcp o un componente de identidad externo cuando la implementación requiera ese flujo.
Elicitación
Un servidor MCP puede necesitar información que los argumentos de la herramienta no incluyeron. En ese caso, puede enviar una solicitud de elicitación de vuelta al cliente. La aplicación decide cómo mostrar la solicitud a una persona y si aceptarla, rechazarla o cancelarla.
let toolset = McpToolset::with_elicitation_handler(
transport,
Arc::new(MyElicitationHandler),
).await?;
ADK-Rust anuncia tanto la forma como la obtención URL. Un error o pánico del manejador se convierte en un rechazo para que la conexión MCP permanezca utilizable. Valide los valores devueltos y aplique las reglas de consentimiento en la aplicación antes de aceptar una solicitud consecuente.
Consulte examples/mcp_elicitation para un servidor completo y un cliente interactivo.
Tareas MCP de larga duración
MCP 2025-11-25 puede mover una llamada a herramienta a una tarea de protocolo. ADK-Rust utiliza el
flujo de tareas solo cuando el servidor negoció tasks.requests.tools.call y la
herramienta declara soporte de tarea requerido u opcional.
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),
);
Para el modo de tarea, ADK-Rust:
- envía
tools/callcon metadatos oficiales de la tarea; - recibe la tarea creada;
- sondea
tasks/getutilizando el intervalo sugerido por el servidor; - lee la carga útil final a través de
tasks/result; y - llama
tasks/cancelcuando se alcanza su tiempo de espera local o límite de sondeo.
input_required se devuelve como un error tipado porque una ADK tool call ordinaria aún no tiene un canal de reanudación neutral al protocolo para proporcionar esa entrada faltante. Diseñe esa interacción explícitamente en el flujo de trabajo propietario.
Mapa de capacidades
| MCP capacidad | ADK-Rust para exponer | Notas |
|---|---|---|
| Descubrimiento y llamadas a herramientas | McpToolset, Toolset | Esquemas sin procesar; resultados multimodales y estructurados preservados |
| Tool filtering | with_filter, with_tools | Filtrar antes de la exposición al model |
| Recursos y plantillas | list/read methods | Method-not-found manejado para servidores antiguos |
| Prompts | métodos list/get | Mapas de argumentos tipados |
| Finalización | métodos de finalización de prompt/recurso | Devuelve CompletionInfo oficial |
| Suscripciones de recursos | métodos de suscripción/cancelación de suscripción | Las notificaciones requieren un controlador de cliente apropiado |
| Elicitación | ElicitationHandler | Forma y URL modos |
| Tareas | McpTaskConfig | Ciclo de vida de la tarea de llamada a herramienta negociada |
| Local stdio | TokioChildProcess | Directo o gestionado por el administrador |
| Transmisible HTTP | McpHttpClientBuilder | Tiempos de espera, encabezados, inyección de autenticación, recuperación de sesión |
| Registro local dinámico | McpServerManager | Añadir/actualizar/habilitar/deshabilitar/eliminar/guardar/monitorizar/reiniciar |
| Creación de servidores y extensiones | adk_tool::mcp::rmcp | Re-exportación exacta SDK para uso avanzado |
| Muestreo, raíces, registro | característica de compatibilidad / rmcp | Obsoleto en la fuente a través de SEP-2577 |
Elección del límite
Usa un Rust FunctionTool cuando la capacidad pertenece al mismo proceso y lanzamiento. Usa MCP cuando otro programa, equipo, lenguaje, límite de seguridad o despliegue posee la capacidad y debería publicar su propio contrato.
Para despliegues de producción:
- expón el conjunto de herramientas útil más pequeño;
- separa las acciones de solo lectura y las acciones consecuentes;
- mantén los secretos fuera de los argumentos de línea de comandos y los archivos
mcp.jsonconfirmados; - autentica servidores remotos HTTP y limita las credenciales estrictamente;
- trata las descripciones de herramientas y el contenido devuelto por el servidor como entrada no confiable;
- retén la autorización y aprobación ADK-Rust en torno a la ejecución de herramientas;
- limita los tiempos de espera de conexión, herramientas y tareas; y
- registra las llamadas a herramientas, aprobaciones, errores y cambios en el ciclo de vida del servidor.
Límites actuales
McpServerManagergestiona procesos hijo stdio locales. Los servicios remotos HTTP utilizanMcpHttpClientBuildery configuración propiedad de la aplicación.- Las comprobaciones de estado del gestor detectan conexiones MCP cerradas; no invocan una herramienta de estado a nivel de negocio.
- Las mutaciones del registro se serializan mientras un hijo completa su handshake MCP.
autoApprovees compatibilidad de configuración, no aplicación de autorización.- El asistente OAuth integrado son credenciales de cliente, no el flujo completo de descubrimiento MCP OAuth y autorización de usuario.
Estos límites se establecen para que las decisiones de despliegue sigan siendo explícitas.