pmcp_server/tools/
test_check.rs1use async_trait::async_trait;
7use pmcp::types::ToolInfo;
8use pmcp::ToolHandler;
9use serde::Deserialize;
10use serde_json::{json, Value};
11
12use super::{create_tester, default_timeout, internal_err};
13
14#[derive(Deserialize)]
16struct TestCheckInput {
17 url: String,
19 #[serde(default)]
21 strict: bool,
22 #[serde(default = "default_timeout")]
24 timeout: u64,
25}
26
27pub struct TestCheckTool;
32
33#[async_trait]
34impl ToolHandler for TestCheckTool {
35 async fn handle(&self, args: Value, _extra: pmcp::RequestHandlerExtra) -> pmcp::Result<Value> {
36 let params: TestCheckInput = serde_json::from_value(args)
37 .map_err(|e| pmcp::Error::validation(format!("Invalid arguments: {e}")))?;
38
39 let mut tester = create_tester(¶ms.url, params.timeout)?;
40
41 let report = tester
42 .run_conformance_tests(params.strict, None)
43 .await
44 .map_err(internal_err)?;
45
46 serde_json::to_value(&report).map_err(internal_err)
47 }
48
49 fn metadata(&self) -> Option<ToolInfo> {
50 Some(ToolInfo::new(
51 "test_check",
52 Some("Run MCP protocol compliance checks against a remote server".to_string()),
53 json!({
54 "type": "object",
55 "properties": {
56 "url": {
57 "type": "string",
58 "description": "MCP server URL to test"
59 },
60 "strict": {
61 "type": "boolean",
62 "description": "Enable strict compliance mode (warnings become failures)",
63 "default": false
64 },
65 "timeout": {
66 "type": "integer",
67 "description": "Timeout in seconds",
68 "default": 30
69 }
70 },
71 "required": ["url"]
72 }),
73 ))
74 }
75}