Crie um cliente MCP
Uma aplicação ADK-Rust é um cliente MCP quando se conecta a um servidor, lê seu catálogo publicado e disponibiliza recursos selecionados para um agente ou fluxo de trabalho.
Instalação
[dependencies]
adk-tool = { version = "2.1.0", features = ["mcp"] }
Para HTTP remoto por streaming:
adk-tool = { version = "2.1.0", features = ["mcp", "http-transport"] }
Conexão stdio 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 shutdown = toolset.cancellation_token().await;
let agent = LlmAgentBuilder::new("support")
.model(model)
.toolset(Arc::new(toolset))
.build()?;
// Run the agent, then close the client-owned MCP session.
shutdown.cancel();
Use um caminho absoluto para o binário em produção. Evite tags de pacote como latest
na configuração de implantação, pois elas tornam as compilações e a recuperação
de incidentes não reproduzíveis.
Descoberta e filtragem de ferramentas
McpToolset converte cada ferramenta MCP publicada em um ADK-Rust Tool. Ele mantém
os esquemas de entrada e saída do servidor inalterados. O provedor de modelo
selecionado normaliza uma cópia do esquema ao criar sua solicitação.
O adaptador também preserva as anotações de ferramentas MCP. Um readOnlyHint marca a
ferramenta ADK como somente leitura e segura para execução concorrente; um idempotentHint
permite a reprodução segura após a reconexão, mas, por si só, não torna a ferramenta
elegível para despacho paralelo automático. A ausência de dicas mantém ambos os
comportamentos desabilitados.
Importante: as anotações MCP são dicas publicadas pelo servidor. Use os metadados de reprodução e despacho automáticos somente com servidores dentro do limite de confiança da aplicação.
let reviewed = McpToolset::new(client).with_filter(|name| {
matches!(name, "read_order" | "read_policy" | "request_replacement")
});
A filtragem controla a visibilidade para o modelo. Ela não substitui a autorização no momento da execução da ferramenta.
Recursos, prompts e conclusão
use serde_json::json;
let resources = toolset.list_resources().await?;
let templates = toolset.list_resource_templates().await?;
let policy = 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?;
A conclusão de modelos de recursos usa complete_resource_argument. Um servidor que
não implementa operações de listagem retorna uma lista vazia quando responde com
MCP MethodNotFound; outros erros de protocolo e transporte continuam sendo erros.
Assinaturas de recursos
use adk_tool::{AutoDeclineElicitationHandler, McpToolset, ResourceNotificationHandler};
use std::sync::Arc;
struct ResourceUpdates;
#[async_trait::async_trait]
impl ResourceNotificationHandler for ResourceUpdates {
async fn handle_resource_updated(
&self,
uri: &str,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
println!("Resource changed: {uri}");
Ok(())
}
async fn handle_resource_list_changed(
&self,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
println!("The resource catalog changed");
Ok(())
}
}
let toolset = McpToolset::with_handlers(
transport,
Arc::new(AutoDeclineElicitationHandler),
Arc::new(ResourceUpdates),
).await?;
toolset.subscribe_resource("company://inventory/sku-42").await?;
toolset.unsubscribe_resource("company://inventory/sku-42").await?;
McpToolset restaura as assinaturas ativas após sua atualização de conexão limitada.
McpServerManager também mantém as assinaturas durante reinicializações gerenciadas do processo.
Erros e panics do manipulador são registrados sem encerrar a conexão MCP.
Para HTTP Streamable, configure o mesmo manipulador com
McpHttpClientBuilder::with_resource_notification_handler antes de chamar
connect_with_elicitation.
Elicitação
A elicitação permite que um servidor solicite informações durante o tratamento de uma chamada de ferramenta. O aplicativo decide como apresentar a solicitação e se deve aceitá-la, recusá-la ou cancelá-la.
let toolset = McpToolset::with_elicitation_handler(
transport,
Arc::new(MyElicitationHandler),
).await?;
ADK-Rust anuncia a elicitação de formulário e URL. Uma falha ou panic do manipulador se torna uma recusa, preservando a sessão MCP. O aplicativo ainda deve validar os valores aceitos e aplicar a política de consentimento.
Consulte examples/mcp_elicitation para obter um par completo de cliente e servidor.
Tarefas negociadas
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),
);
O modo de tarefa é selecionado com base em dois fatos negociados:
- o servidor anuncia
tasks.requests.tools.call; e - a ferramenta declara o suporte a tarefas como obrigatório ou opcional.
ADK-Rust envia metadados da tarefa com tools/call, recebe a tarefa criada, consulta
tasks/get, lê tasks/result e chama tasks/cancel quando os limites locais são
excedidos. input_required é retornado como um erro tipado porque uma chamada de ferramenta ADK
comum ainda não fornece um canal de entrada neutro em relação ao protocolo para retomar tarefas.
HTTP Streamable remoto
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 oferece suporte a tokens bearer, a um cabeçalho de chave API personalizado e a credenciais de cliente fixas do 2.0 OAuth. Consulte Segurança e autorização antes de escolher um fluxo de autenticação.