Skip to main content

objectiveai_sdk/mcp/tool/
tool.rs

1//! MCP Tool definition.
2
3use indexmap::IndexMap;
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7/// A tool that an MCP server exposes for invocation.
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
9#[schemars(rename = "mcp.tool.Tool")]
10pub struct Tool {
11    /// The programmatic name of the tool.
12    pub name: String,
13    /// A human-readable display name.
14    #[serde(skip_serializing_if = "Option::is_none")]
15    #[schemars(extend("omitempty" = true))]
16    pub title: Option<String>,
17    /// A human-readable description of the tool.
18    #[serde(skip_serializing_if = "Option::is_none")]
19    #[schemars(extend("omitempty" = true))]
20    pub description: Option<String>,
21    /// Icons for the tool.
22    #[serde(skip_serializing_if = "Option::is_none")]
23    #[schemars(extend("omitempty" = true))]
24    pub icons: Option<Vec<super::super::shared::Icon>>,
25    /// JSON Schema defining the expected input parameters.
26    /// Must have `type: "object"` at the root level.
27    #[serde(rename = "inputSchema")]
28    pub input_schema: ToolSchemaObject,
29    /// JSON Schema defining the structure of the tool's output
30    /// (returned in `structuredContent`).
31    #[serde(skip_serializing_if = "Option::is_none")]
32    #[schemars(extend("omitempty" = true))]
33    #[serde(rename = "outputSchema")]
34    pub output_schema: Option<ToolSchemaObject>,
35    /// Additional tool metadata.
36    #[serde(skip_serializing_if = "Option::is_none")]
37    #[schemars(extend("omitempty" = true))]
38    pub annotations: Option<super::ToolAnnotations>,
39    /// Execution-related properties.
40    #[serde(skip_serializing_if = "Option::is_none")]
41    #[schemars(extend("omitempty" = true))]
42    pub execution: Option<super::ToolExecution>,
43    /// Extension metadata.
44    #[serde(skip_serializing_if = "Option::is_none")]
45    #[schemars(extend("omitempty" = true))]
46    pub _meta: Option<IndexMap<String, serde_json::Value>>,
47}
48
49impl Tool {
50    /// Returns a key identifying this tool, scoped to its connection.
51    pub fn tool_key(&self, connection_tool_key: &str) -> String {
52        format!("{connection_tool_key}-{}", self.name)
53    }
54}
55
56/// The type of a JSON Schema used by MCP tools.
57#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, JsonSchema)]
58#[serde(rename_all = "lowercase")]
59#[schemars(rename = "mcp.tool.ToolSchemaType")]
60pub enum ToolSchemaType {
61    Object,
62}
63
64/// JSON Schema for tool input/output. Must have `type: "object"`.
65#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
66#[schemars(rename = "mcp.tool.ToolSchemaObject")]
67pub struct ToolSchemaObject {
68    /// Always "object".
69    pub r#type: ToolSchemaType,
70    /// Property definitions.
71    #[serde(skip_serializing_if = "Option::is_none")]
72    #[schemars(extend("omitempty" = true))]
73    pub properties: Option<IndexMap<String, serde_json::Value>>,
74    /// Required property names.
75    #[serde(skip_serializing_if = "Option::is_none")]
76    #[schemars(extend("omitempty" = true))]
77    pub required: Option<Vec<String>>,
78    /// Additional schema fields.
79    #[serde(flatten)]
80    pub extra: IndexMap<String, serde_json::Value>,
81}