use async_trait::async_trait;
use pmcp::types::ToolInfo;
use pmcp::ToolHandler;
use serde::Deserialize;
use serde_json::{json, Value};
use super::{create_tester, default_timeout, internal_err};
#[derive(Deserialize)]
struct TestCheckInput {
url: String,
#[serde(default)]
strict: bool,
#[serde(default = "default_timeout")]
timeout: u64,
}
pub struct TestCheckTool;
#[async_trait]
impl ToolHandler for TestCheckTool {
async fn handle(&self, args: Value, _extra: pmcp::RequestHandlerExtra) -> pmcp::Result<Value> {
let params: TestCheckInput = serde_json::from_value(args)
.map_err(|e| pmcp::Error::validation(format!("Invalid arguments: {e}")))?;
let mut tester = create_tester(¶ms.url, params.timeout)?;
let report = tester
.run_conformance_tests(params.strict, None)
.await
.map_err(internal_err)?;
serde_json::to_value(&report).map_err(internal_err)
}
fn metadata(&self) -> Option<ToolInfo> {
Some(ToolInfo::new(
"test_check",
Some("Run MCP protocol compliance checks against a remote server".to_string()),
json!({
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "MCP server URL to test"
},
"strict": {
"type": "boolean",
"description": "Enable strict compliance mode (warnings become failures)",
"default": false
},
"timeout": {
"type": "integer",
"description": "Timeout in seconds",
"default": 30
}
},
"required": ["url"]
}),
))
}
}