Publier un serveur MCP
ADK-Rust consomme des serveurs MCP via McpToolset, mais il nâenveloppe pas chaque
SDK API cÎté serveur. Les auteurs de serveurs utilisent le SDK officiel rmcp réexporté par
adk_tool::mcp::rmcp afin que les types de protocole client et serveur restent alignés.
Pour un crate de serveur autonome, dĂ©pendre directement de la mĂȘme version de
rmcp est également approprié :
[dependencies]
rmcp = { version = "2.2", features = ["transport-io", "schemars"] }
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
Serveur stdio minimal
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?;
Le fixture examples/mcp_manager déterministe utilise cette structure de serveur et est
compilé et exécuté par les contrÎles de vérification MCP.
Publier des capacitĂ©s honnĂȘtes
Nâannoncez une capacitĂ© que lorsque le gestionnaire lâimplĂ©mente. Un client utilise la rĂ©ponse dâinitialisation pour dĂ©terminer sâil peut appeler des ressources, des invites, la complĂ©tion, lâĂ©licitation, des abonnements ou des tĂąches.
Pour les outils capables de gérer des tùches, déclarez la prise en charge des tùches de
lâoutil et annoncez tasks.requests.tools.call. Le client peut refuser un outil nĂ©cessitant des tĂąches lorsque le
serveur nâa pas nĂ©gociĂ© la prise en charge des tĂąches.
Les outils sont des frontiÚres de sécurité
Les descriptions et le schéma JSON aident le modÚle à formuler un appel ; ils ne constituent ni une validation des entrées ni une autorisation. Un serveur doit :
- valider chaque entrée indépendamment du modÚle ;
- rĂ©soudre lâidentitĂ© et le pĂ©rimĂštre du locataire Ă la frontiĂšre du serveur ;
- autoriser lâaction et la ressource spĂ©cifiques ;
- séparer les opérations de lecture des écritures ayant des conséquences ;
- éviter de renvoyer des secrets ou des données non bornées ;
- rendre explicites les nouvelles tentatives et lâidempotence pour les effets de bord ; et
- consigner suffisamment dâĂ©lĂ©ments probants pour expliquer le rĂ©sultat.
Choisir un transport
Utilisez stdio lorsque le client possĂšde le processus enfant local. Utilisez Streamable HTTP lorsquâil sâagit dâun service dĂ©ployĂ© indĂ©pendamment. Les dĂ©ploiements distants nĂ©cessitent Ă©galement une authentification, des limites de requĂȘtes, une stratĂ©gie de session, de lâobservabilitĂ© et une sonde de santĂ© au niveau de lâapplication.
Consultez la documentation officielle de rmcp pour les routeurs de serveur, les ressources, les invites, les gestionnaires personnalisĂ©s, les transports, lâautorisation et lâextension APIs.