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}