ftl_sdk_rs/
tool.rs

1use serde_json::Value;
2
3use crate::types::{ToolError, ToolResult};
4
5/// Trait that all FTL Core tools must implement
6///
7/// This trait defines a single computational tool optimized for WebAssembly
8/// performance. FTL Core follows the "1 tool per server" architecture for
9/// maximum efficiency.
10pub trait Tool: Clone {
11    /// The name of the tool (used in MCP tool calls)
12    fn name(&self) -> &'static str;
13
14    /// Human-readable description of what the tool does
15    fn description(&self) -> &'static str;
16
17    /// JSON schema for the tool's input parameters
18    ///
19    /// Return a JSON object describing the expected input structure.
20    /// Example:
21    /// ```json
22    /// {
23    ///   "type": "object",
24    ///   "properties": {
25    ///     "text": {
26    ///       "type": "string",
27    ///       "description": "The text to process"
28    ///     }
29    ///   },
30    ///   "required": ["text"]
31    /// }
32    /// ```
33    fn input_schema(&self) -> Value;
34
35    /// Execute the tool with the provided arguments
36    ///
37    /// This is where your tool's core logic goes. The arguments are validated
38    /// against your input schema before this method is called.
39    fn call(&self, arguments: &Value) -> Result<ToolResult, ToolError>;
40
41    /// Optional: Custom server name (defaults to tool name)
42    fn server_name(&self) -> String {
43        format!("ftl-{}", self.name())
44    }
45
46    /// Optional: Server version (defaults to "0.0.1")
47    fn server_version(&self) -> &'static str {
48        "0.0.1"
49    }
50
51    /// Optional: Additional server capabilities
52    fn capabilities(&self) -> Value {
53        serde_json::json!({
54            "tools": {}
55        })
56    }
57}
58
59/// Information about a tool for MCP tool listing
60#[derive(Debug)]
61pub struct ToolInfo {
62    pub name: String,
63    pub description: String,
64    pub input_schema: Value,
65}
66
67impl<T: Tool> From<&T> for ToolInfo {
68    fn from(tool: &T) -> Self {
69        Self {
70            name: tool.name().to_string(),
71            description: tool.description().to_string(),
72            input_schema: tool.input_schema(),
73        }
74    }
75}