Publicar um servidor MCP

ADK-Rust consome servidores MCP por meio de McpToolset, mas não encapsula todo SDK API do lado do servidor. Os autores de servidores usam o SDK oficial de rmcp reexportado por adk_tool::mcp::rmcp para que os tipos de protocolo do cliente e do servidor permaneçam alinhados.

Para um crate de servidor independente, depender diretamente da mesma versão de rmcp também é apropriado:

[dependencies]
rmcp = { version = "2.2", features = ["transport-io", "schemars"] }
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }

Servidor stdio mínimo

use rmcp::{
    ServerHandler,
    handler::server::{router::tool::ToolRouter, wrapper::Parameters},
    model::{ServerCapabilities, ServerInfo},
    schemars, tool, tool_handler, tool_router,
};
use serde::Deserialize;

#[derive(Debug, Deserialize, schemars::JsonSchema)]
struct LookupInput {
    order_id: String,
}

#[derive(Debug, Clone)]
struct OrderServer {
    tool_router: ToolRouter<Self>,
}

#[tool_router]
impl OrderServer {
    #[tool(description = "Read one order by its public order ID")]
    async fn read_order(
        &self,
        Parameters(input): Parameters<LookupInput>,
    ) -> String {
        format!("Order {} is ready for investigation", input.order_id)
    }
}

#[tool_handler]
impl ServerHandler for OrderServer {
    fn get_info(&self) -> ServerInfo {
        ServerInfo::new(ServerCapabilities::builder().enable_tools().build())
            .with_instructions("Read-only order investigation tools")
    }
}

let service = rmcp::ServiceExt::serve(
    OrderServer { tool_router: OrderServer::tool_router() },
    rmcp::transport::io::stdio(),
).await?;
service.waiting().await?;

O fixture determinístico examples/mcp_manager usa este formato de servidor e é compilado e executado pelos gates de verificação de MCP.

Publique capacidades honestas

Anuncie uma capacidade somente quando o handler a implementar. Um cliente usa a resposta de inicialização para decidir se pode chamar recursos, prompts, conclusão, elicitação, assinaturas ou tarefas.

Para ferramentas compatíveis com tarefas, declare o suporte a tarefas da ferramenta e anuncie tasks.requests.tools.call. O cliente pode rejeitar uma ferramenta que exige tarefas quando o servidor não negociou suporte a tarefas.

As ferramentas são limites de segurança

As descrições e o Schema JSON ajudam o modelo a formar uma chamada; não são validação de entrada nem autorização. Um servidor deve:

  • validar cada entrada independentemente do modelo;
  • resolver a identidade e o escopo do locatário no limite do servidor;
  • autorizar a ação e o recurso específicos;
  • separar operações de leitura de gravações consequenciais;
  • evitar retornar segredos ou dados sem limites;
  • tornar explícitos os efeitos colaterais de novas tentativas e a idempotência; e
  • registrar evidências suficientes para explicar o resultado.

Escolha um transporte

Use stdio quando o cliente for o proprietário do processo filho local. Use Streamable HTTP quando o servidor for um serviço implantado de forma independente. Implantações remotas também precisam de autenticação, limites de solicitações, política de sessões, observabilidade e uma sonda de integridade no nível da aplicação.

Consulte a documentação oficial do rmcp para obter informações sobre roteadores de servidor, recursos, prompts, manipuladores personalizados, transportes, autorização, e extensão APIs.