pmcp_server/tools/
test_generate.rs1use async_trait::async_trait;
7use mcp_tester::ScenarioGenerator;
8use pmcp::types::ToolInfo;
9use pmcp::ToolHandler;
10use serde::Deserialize;
11use serde_json::{json, Value};
12
13use super::{create_tester, default_timeout, internal_err};
14
15#[derive(Deserialize)]
17struct TestGenerateInput {
18 url: String,
20 #[serde(default = "default_timeout")]
22 timeout: u64,
23 #[serde(default = "default_true")]
25 all_tools: bool,
26 #[serde(default)]
28 with_resources: bool,
29 #[serde(default)]
31 with_prompts: bool,
32}
33
34const fn default_true() -> bool {
35 true
36}
37
38pub struct TestGenerateTool;
43
44#[async_trait]
45impl ToolHandler for TestGenerateTool {
46 async fn handle(&self, args: Value, _extra: pmcp::RequestHandlerExtra) -> pmcp::Result<Value> {
47 let params: TestGenerateInput = serde_json::from_value(args)
48 .map_err(|e| pmcp::Error::validation(format!("Invalid arguments: {e}")))?;
49
50 let mut tester = create_tester(¶ms.url, params.timeout)?;
51
52 let generator = ScenarioGenerator::new(
53 params.url,
54 params.all_tools,
55 params.with_resources,
56 params.with_prompts,
57 );
58
59 let scenario = generator
60 .create_scenario_struct(&mut tester)
61 .await
62 .map_err(internal_err)?;
63
64 serde_json::to_value(&scenario).map_err(internal_err)
65 }
66
67 fn metadata(&self) -> Option<ToolInfo> {
68 Some(ToolInfo::new(
69 "test_generate",
70 Some("Generate test scenarios from a remote MCP server's capabilities".to_string()),
71 json!({
72 "type": "object",
73 "properties": {
74 "url": {
75 "type": "string",
76 "description": "MCP server URL to discover capabilities from"
77 },
78 "timeout": {
79 "type": "integer",
80 "description": "Timeout in seconds",
81 "default": 30
82 },
83 "all_tools": {
84 "type": "boolean",
85 "description": "Include all discovered tools in the scenario",
86 "default": true
87 },
88 "with_resources": {
89 "type": "boolean",
90 "description": "Include resource testing in the scenario",
91 "default": false
92 },
93 "with_prompts": {
94 "type": "boolean",
95 "description": "Include prompt testing in the scenario",
96 "default": false
97 }
98 },
99 "required": ["url"]
100 }),
101 ))
102 }
103}