Skip to main content

agent_client_protocol/mcp_server/
tool.rs

1//! MCP tool trait for defining tools.
2
3use schemars::JsonSchema;
4use serde::{Serialize, de::DeserializeOwned};
5
6use crate::role::Role;
7
8use super::McpConnectionTo;
9
10/// Trait for defining MCP tools.
11///
12/// Implement this trait to create a tool that can be registered with an MCP server.
13/// The tool's input and output types must implement JSON Schema for automatic
14/// documentation.
15///
16/// # Example
17///
18/// ```rust,ignore
19/// use agent_client_protocol::mcp_server::{McpTool, McpContext};
20/// use schemars::JsonSchema;
21/// use serde::{Deserialize, Serialize};
22///
23/// #[derive(JsonSchema, Deserialize)]
24/// struct EchoInput {
25///     message: String,
26/// }
27///
28/// #[derive(JsonSchema, Serialize)]
29/// struct EchoOutput {
30///     echoed: String,
31/// }
32///
33/// struct EchoTool;
34///
35/// impl<R: agent_client_protocol::role::Role> McpTool<R> for EchoTool {
36///     type Input = EchoInput;
37///     type Output = EchoOutput;
38///
39///     fn name(&self) -> String {
40///         "echo".to_string()
41///     }
42///
43///     fn description(&self) -> String {
44///         "Echoes back the input message".to_string()
45///     }
46///
47///     async fn call_tool(
48///         &self,
49///         input: EchoInput,
50///         _context: McpContext<R>,
51///     ) -> Result<EchoOutput, agent_client_protocol::Error> {
52///         Ok(EchoOutput {
53///             echoed: format!("Echo: {}", input.message),
54///         })
55///     }
56/// }
57/// ```
58pub trait McpTool<R: Role>: Send + Sync {
59    /// The type of input the tool accepts.
60    type Input: JsonSchema + DeserializeOwned + Send + 'static;
61
62    /// The type of output the tool produces.
63    type Output: JsonSchema + Serialize + Send + 'static;
64
65    /// The name of the tool
66    fn name(&self) -> String;
67
68    /// A description of what the tool does
69    fn description(&self) -> String;
70
71    /// A human-readable title for the tool
72    fn title(&self) -> Option<String> {
73        None
74    }
75
76    /// Define the tool's behavior. You can implement this with an `async fn`.
77    fn call_tool(
78        &self,
79        input: Self::Input,
80        context: McpConnectionTo<R>,
81    ) -> impl Future<Output = Result<Self::Output, crate::Error>> + Send;
82}