1use crate::ToolDefinition;
2use crate::parse_tool_input_schema;
3use serde_json::Value as JsonValue;
4use serde_json::json;
5
6pub fn parse_mcp_tool(tool: &rmcp::model::Tool) -> Result<ToolDefinition, serde_json::Error> {
7 let mut serialized_input_schema = serde_json::Value::Object(tool.input_schema.as_ref().clone());
8
9 if let serde_json::Value::Object(obj) = &mut serialized_input_schema
13 && obj.get("properties").is_none_or(serde_json::Value::is_null)
14 {
15 obj.insert(
16 "properties".to_string(),
17 serde_json::Value::Object(serde_json::Map::new()),
18 );
19 }
20
21 let input_schema = parse_tool_input_schema(&serialized_input_schema)?;
22 let structured_content_schema = tool
23 .output_schema
24 .as_ref()
25 .map(|output_schema| serde_json::Value::Object(output_schema.as_ref().clone()))
26 .unwrap_or_else(|| JsonValue::Object(serde_json::Map::new()));
27
28 Ok(ToolDefinition {
29 name: tool.name.to_string(),
30 description: tool.description.clone().map(Into::into).unwrap_or_default(),
31 input_schema,
32 output_schema: Some(mcp_call_tool_result_output_schema(
33 structured_content_schema,
34 )),
35 defer_loading: false,
36 })
37}
38
39pub fn mcp_call_tool_result_output_schema(structured_content_schema: JsonValue) -> JsonValue {
40 json!({
41 "type": "object",
42 "properties": {
43 "content": {
44 "type": "array",
45 "items": {
46 "type": "object"
47 }
48 },
49 "structuredContent": structured_content_schema,
50 "isError": {
51 "type": "boolean"
52 },
53 "_meta": {
54 "type": "object"
55 }
56 },
57 "required": ["content"],
58 "additionalProperties": false
59 })
60}
61
62#[cfg(test)]
63#[path = "mcp_tool_tests.rs"]
64mod tests;