vtcode_utility_tool_specs/
mcp_tool.rs1use rmcp::model::Tool;
2use serde_json::Value;
3
4#[derive(Clone, Debug, PartialEq)]
5pub struct ParsedMcpTool {
6 pub name: String,
7 pub description: String,
8 pub input_schema: Value,
9 pub output_schema: Option<Value>,
10}
11
12#[must_use]
13pub fn parse_mcp_tool(tool: &Tool) -> ParsedMcpTool {
14 ParsedMcpTool {
15 name: tool.name.to_string(),
16 description: tool.description.clone().unwrap_or_default().to_string(),
17 input_schema: serde_json::to_value(&tool.input_schema).unwrap_or(Value::Null),
18 output_schema: tool.output_schema.as_ref().and_then(|schema| serde_json::to_value(schema).ok()),
19 }
20}
21
22#[cfg(test)]
23mod tests {
24 use super::{ParsedMcpTool, parse_mcp_tool};
25 use rmcp::model::Tool;
26 use serde_json::json;
27 use std::sync::Arc;
28
29 #[test]
30 fn parse_mcp_tool_preserves_name_description_and_input_schema() {
31 let input_schema = Arc::new(
32 serde_json::from_value(json!({
33 "type": "object",
34 "properties": {
35 "query": {"type": "string"}
36 }
37 }))
38 .expect("json object"),
39 );
40 let tool = Tool::new("search-docs", "Search documentation", input_schema);
41
42 let parsed = parse_mcp_tool(&tool);
43 assert_eq!(
44 parsed,
45 ParsedMcpTool {
46 name: "search-docs".to_string(),
47 description: "Search documentation".to_string(),
48 input_schema: json!({
49 "type": "object",
50 "properties": {
51 "query": {"type": "string"}
52 }
53 }),
54 output_schema: None,
55 }
56 );
57 }
58
59 #[test]
60 fn parse_mcp_tool_defaults_missing_description() {
61 let input_schema = Arc::new(serde_json::from_value(json!({})).expect("json object"));
62 let tool = Tool::new_with_raw("search-docs", None, input_schema);
63
64 let parsed = parse_mcp_tool(&tool);
65 assert_eq!(parsed.description, "");
66 assert_eq!(parsed.input_schema, json!({}));
67 assert_eq!(parsed.output_schema, None);
68 }
69
70 #[test]
71 fn parse_mcp_tool_captures_output_schema() {
72 let input_schema = Arc::new(serde_json::from_value(json!({})).expect("json object"));
73 let output_schema = Arc::new(
74 serde_json::from_value(json!({
75 "type": "object",
76 "properties": {
77 "answer": {"type": "string"}
78 },
79 "required": ["answer"]
80 }))
81 .expect("json object"),
82 );
83 let mut tool = Tool::new_with_raw("ask_question", None, input_schema);
84 tool.output_schema = Some(output_schema);
85
86 let parsed = parse_mcp_tool(&tool);
87 assert_eq!(
88 parsed.output_schema,
89 Some(json!({
90 "type": "object",
91 "properties": {
92 "answer": {"type": "string"}
93 },
94 "required": ["answer"]
95 }))
96 );
97 }
98}