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}
10
11#[must_use]
12pub fn parse_mcp_tool(tool: &Tool) -> ParsedMcpTool {
13 ParsedMcpTool {
14 name: tool.name.to_string(),
15 description: tool.description.clone().unwrap_or_default().to_string(),
16 input_schema: serde_json::to_value(&tool.input_schema).unwrap_or(Value::Null),
17 }
18}
19
20#[cfg(test)]
21mod tests {
22 use super::{ParsedMcpTool, parse_mcp_tool};
23 use rmcp::model::Tool;
24 use serde_json::json;
25 use std::sync::Arc;
26
27 #[test]
28 fn parse_mcp_tool_preserves_name_description_and_input_schema() {
29 let input_schema = Arc::new(
30 serde_json::from_value(json!({
31 "type": "object",
32 "properties": {
33 "query": {"type": "string"}
34 }
35 }))
36 .expect("json object"),
37 );
38 let tool = Tool::new("search-docs", "Search documentation", input_schema);
39
40 let parsed = parse_mcp_tool(&tool);
41 assert_eq!(
42 parsed,
43 ParsedMcpTool {
44 name: "search-docs".to_string(),
45 description: "Search documentation".to_string(),
46 input_schema: json!({
47 "type": "object",
48 "properties": {
49 "query": {"type": "string"}
50 }
51 }),
52 }
53 );
54 }
55
56 #[test]
57 fn parse_mcp_tool_defaults_missing_description() {
58 let input_schema = Arc::new(serde_json::from_value(json!({})).expect("json object"));
59 let tool = Tool::new_with_raw("search-docs", None, input_schema);
60
61 let parsed = parse_mcp_tool(&tool);
62 assert_eq!(parsed.description, "");
63 assert_eq!(parsed.input_schema, json!({}));
64 }
65}