mcp_core/tools/
test_tool.rsuse async_trait::async_trait;
use crate::{error::McpError, server};
use super::{Tool, ToolContent, ToolProvider, ToolResult};
pub struct TestTool;
impl TestTool {
pub fn new() -> Self {
TestTool
}
}
#[async_trait]
impl ToolProvider for TestTool {
async fn get_tool(&self) -> Tool {
Tool {
name: "test_tool".to_string(),
description: "Test Tool".to_string(),
input_schema: serde_json::from_str(
r#"{
"type": "object",
"properties": {
"test": {
"type": "string",
"description": "Test property"
}
},
"required": ["test"]
}"#,
)
.unwrap(),
}
}
async fn execute(&self, arguments: serde_json::Value) -> Result<ToolResult, McpError> {
Ok(ToolResult {
content: vec![],
is_error: false,
})
}
}
pub struct PingTool;
impl PingTool {
pub fn new() -> Self {
PingTool
}
}
#[async_trait]
impl ToolProvider for PingTool {
async fn get_tool(&self) -> Tool {
Tool {
name: "ping_tool".to_string(),
description: "Ping Tool".to_string(),
input_schema: serde_json::from_str(
r#"{
"type": "object",
"properties": {
"server": {
"type": "string",
"description": "Server to ping"
}
},
"required": ["server"]
}"#,
)
.unwrap(),
}
}
async fn execute(&self, arguments: serde_json::Value) -> Result<ToolResult, McpError> {
let server = arguments
.get("server")
.and_then(|s| s.as_str())
.unwrap_or("localhost");
let res = reqwest::get(format!("http://{}", server))
.await
.map_err(|e| McpError::ToolExecutionError(e.to_string()))?;
let body = res
.text()
.await
.map_err(|e| McpError::ToolExecutionError(e.to_string()))?;
Ok(ToolResult {
content: vec![ToolContent::Text { text: body }],
is_error: false,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
protocol::{RequestHandler, ServerCapabilities},
server::{config::ServerConfig, McpServer},
};
use serde_json::{json, Value};
struct TestHandler;
#[async_trait]
impl RequestHandler for TestHandler {
async fn handle_request(
&self,
method: &str,
params: Option<Value>,
) -> Result<Value, McpError> {
Ok(json!({"success": true}))
}
async fn handle_notification(
&self,
_method: &str,
_params: Option<Value>,
) -> Result<(), McpError> {
Ok(())
}
fn get_capabilities(&self) -> ServerCapabilities {
ServerCapabilities {
name: "Test".to_string(),
version: "1.0".to_string(),
protocol_version: "1.0".to_string(),
capabilities: vec!["test".to_string()],
}
}
}
#[tokio::test]
async fn test_custom_handler() {
let handler = TestHandler;
let server = McpServer::new(ServerConfig::default(), handler);
let response = server
.process_request("test", Some(json!({})))
.await
.unwrap();
assert_eq!(response, json!({"success": true}));
}
}