Protocolo de Contexto do Modelo (MCP)
Mapa da documentação: Visão geral e arquitetura · Cliente · Gerenciador dinâmico · Criação de servidor · Segurança · Testes
MCP oferece a uma aplicação de IA uma maneira padrão de descobrir e usar capacidades pertencentes a outro processo ou serviço. Um servidor pode publicar:
- ferramentas que executam ações;
- recursos que retornam contexto legível;
- prompts que fornecem modelos de mensagem reutilizáveis; e
- sugestões de conclusão que ajudam um cliente a preencher argumentos de prompt ou recurso.
ADK-Rust é geralmente o cliente MCP. McpToolset transforma ferramentas MCP descobertas em valores Tool ADK-Rust normais, para que um LlmAgent possa selecioná-las e chamá-las. O framework também expõe recursos, prompts, conclusão, assinaturas, elicitação e o ciclo de vida da tarefa negociada. Para a criação de servidor MCP e trabalho avançado de protocolo, ADK-Rust re-exporta a versão exata rmcp SDK que utiliza.
ADK-Rust 2 atualmente usa rmcp 2.2, o SDK oficial do Rust alinhado com a especificação 2025-11-25 MCP.
Arquitetura
Existem duas camadas separadas:
McpToolsetpossui uma conexão de cliente MCP inicializada. Ele descobre as capacidades do servidor e as adapta a ADK-Rust.McpServerManagerpossui um registro mutável de servidores stdio locais. Ele inicia, monitora, reinicia, atualiza, habilita, desabilita, persiste e agrega essas conexões.
O gerenciador não concede aprovação de ferramenta. Ele preserva autoApprove ao ler uma configuração compatível, mas a aplicação deve aplicar sua política normal de autorização e aprovação ADK-Rust.
Instalação
O suporte a stdio local MCP é opcional:
[dependencies]
adk-tool = { version = "2.0.0", features = ["mcp"] }
Adicione Streamable HTTP ao conectar-se a serviços remotos:
adk-tool = { version = "2.0.0", features = ["mcp", "http-transport"] }
Callbacks de amostragem legados exigem o recurso separado mcp-sampling. O projeto MCP descontinuou amostragem, raízes e log através do SEP-2577; use esses APIs apenas ao manter uma implantação compatível.
Conectar um 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 mantém os esquemas de entrada e saída do servidor intactos. Cada adaptador de modelo normaliza uma cópia para seu provedor ao construir a requisição do modelo. Isso permite que o mesmo servidor MCP funcione com Gemini, OpenAI, Anthropic e outros provedores sem danificar o esquema de origem.
Usar o protocolo além das ferramentas
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?;
Os métodos de conveniência retornam uma lista vazia quando um servidor mais antigo não implementa a listagem de recursos ou prompts. Operações contra um recurso ou prompt declarado retornam um erro quando a chamada remota falha.
Gerenciamento dinâmico de servidor
Use McpServerManager quando a aplicação precisar de uma frota de processos filhos MCP locais em vez de uma conexão 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()?;
O registro em tempo de execução suporta:
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?;
Quando dois servidores publicam o mesmo nome de ferramenta, o conjunto de ferramentas agregado prefixa ambos os nomes como {server_id}__{tool_name}. Nomes únicos permanecem inalterados.
O monitor de saúde detecta uma conexão MCP fechada. Um RestartPolicy configurado controla a repetição limitada com backoff exponencial. Isso é supervisão de conexão, não uma verificação de saúde em nível de aplicação: use uma ferramenta de domínio ou uma sonda de serviço separada quando precisar verificar o banco de dados de apoio do servidor ou API externo.
Execute o exemplo determinístico:
cargo run --manifest-path examples/mcp_manager/Cargo.toml
Ele inicia um servidor filho MCP Rust real e exercita descoberta, uma chamada de ferramenta, adição/habilitação/atualização/desabilitação/remoção em tempo de execução, persistência de configuração e desligamento. Ele não baixa pacotes nem requer uma chave API.
Streamable Remoto 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?;
O construtor aplica timeouts de requisição, cabeçalhos personalizados, tokens de portador, cabeçalhos de chave API personalizados e recuperação limitada quando uma sessão HTTP expira.
OAuth2Config implementa uma requisição de token de credenciais de cliente OAuth 2.0 fixa. É útil para um servidor com um endpoint de token conhecido. Não é o fluxo de autorização MCP completo: ele não realiza descoberta de metadados de recurso protegido, descoberta de servidor de autorização, autorização de navegador, PKCE ou negociação de indicador de recurso. Use o APIs de autorização de rmcp ou um componente de identidade externo quando a implantação exigir esse fluxo.
Elicitação
Um servidor MCP pode precisar de informações que os argumentos da ferramenta não incluíram. Nesse caso, ele pode enviar uma requisição de elicitação de volta ao cliente. A aplicação decide como mostrar a requisição a uma pessoa e se deve aceitá-la, recusá-la ou cancelá-la.
let toolset = McpToolset::with_elicitation_handler(
transport,
Arc::new(MyElicitationHandler),
).await?;
ADK-Rust anuncia tanto a elicitação de formulário quanto a URL. Um erro ou pânico do handler é convertido em uma recusa para que a conexão MCP permaneça utilizável. Valide os valores retornados e aplique as regras de consentimento na aplicação antes de aceitar uma requisição consequencial.
Veja examples/mcp_elicitation para um servidor completo e cliente interativo.
Tarefas MCP de longa duração
MCP 2025-11-25 pode mover uma chamada de ferramenta para uma tarefa de protocolo. ADK-Rust usa o fluxo de tarefas apenas quando o servidor negociou tasks.requests.tools.call e a ferramenta declara suporte de tarefa obrigatório ou 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 o modo de tarefa, ADK-Rust:
- envia
tools/callcom metadados oficiais da tarefa; - recebe a tarefa criada;
- consulta
tasks/getusando o intervalo sugerido pelo servidor; - lê o payload final através de
tasks/result; e - chama
tasks/cancelquando seu timeout local ou limite de consulta é atingido.
input_required é retornado como um erro tipado porque uma chamada de ferramenta ADK comum ainda não possui um canal de retomada neutro ao protocolo para fornecer essa entrada ausente. Projete essa interação explicitamente no fluxo de trabalho proprietário.
Mapa de capacidades
| MCP capacidade | ADK-Rust 2 superfície | Notas |
|---|---|---|
| Descoberta e chamadas de Tool | McpToolset, Toolset | Schemas brutos; resultados multimodais e estruturados preservados |
| Filtragem de Tool | with_filter, with_tools | Filtrar antes da exposição ao model |
| Recursos e modelos | list/read methods | Método-não-encontrado tratado para servidores mais antigos |
| Prompts | list/get methods | Mapas de argumentos tipados |
| Conclusão | prompt/resource completion methods | Retorna CompletionInfo oficial |
| Assinaturas de recursos | subscribe/unsubscribe methods | Notificações exigem um manipulador de cliente apropriado |
| Elicitação | ElicitationHandler | Formulário e modos URL |
| Tarefas | McpTaskConfig | Ciclo de vida de tarefas de chamada de ferramenta negociadas |
| stdio local | TokioChildProcess | Direto ou gerenciado pelo gerente |
| Transmissível HTTP | McpHttpClientBuilder | Timeouts, cabeçalhos, injeção de autenticação, recuperação de sessão |
| Registro local dinâmico | McpServerManager | Adicionar/atualizar/habilitar/desabilitar/remover/salvar/monitorar/reiniciar |
| Autoria e extensões de servidor | adk_tool::mcp::rmcp | Re-exportação exata SDK para uso avançado |
| Amostragem, raízes, registro | Recurso de compatibilidade / rmcp | Descontinuado upstream via SEP-2577 |
Escolhendo o limite
Use um Rust FunctionTool quando a capacidade pertencer ao mesmo processo e lançamento. Use MCP quando outro programa, equipe, linguagem, limite de segurança ou implantação possuir a capacidade e deve publicar seu próprio contrato.
Para implantações em produção:
- exponha o menor conjunto de ferramentas útil;
- separe ações somente leitura e ações com consequências;
- mantenha segredos fora dos argumentos de linha de comando e dos arquivos
mcp.jsoncommitados; - autentique servidores HTTP remotos e restrinja as credenciais;
- trate descrições de ferramentas e conteúdo retornado pelo servidor como entrada não confiável;
- mantenha a autorização e aprovação ADK-Rust em torno da execução da ferramenta;
- limite os tempos limite de conexão, ferramenta e tarefa; e
- registre chamadas de ferramentas, aprovações, erros e mudanças no ciclo de vida do servidor.
Limites atuais
McpServerManagergerencia processos filhos stdio locais. Serviços HTTP remotos usamMcpHttpClientBuildere configuração de propriedade do aplicativo.- Verificações de saúde do gerenciador detectam conexões MCP fechadas; elas não chamam uma ferramenta de saúde de nível de negócio.
- Mutações de registro são serializadas enquanto um filho completa seu handshake MCP.
autoApproveé compatibilidade de configuração, não aplicação de autorização.- O auxiliar OAuth integrado são credenciais de cliente, não o fluxo completo de descoberta e autorização de usuário MCP OAuth.
Esses limites são declarados para que as decisões de implantação permaneçam explícitas.