Files
mcp-memory/server/src/mcp.rs
T

82 lines
2.2 KiB
Rust

use schemars::JsonSchema;
use serde_json::json;
pub fn success(id: serde_json::Value, result: serde_json::Value) -> serde_json::Value {
json!({
"jsonrpc": "2.0",
"id": id,
"result": result
})
}
pub fn error(id: serde_json::Value, code: i32, message: &str) -> serde_json::Value {
json!({
"jsonrpc": "2.0",
"id": id,
"error": {
"code": code,
"message": message
}
})
}
pub fn tool_def<T: JsonSchema>(name: &str, fallback_desc: &str) -> serde_json::Value {
let schema = schemars::schema_for!(T);
let schema_val = serde_json::to_value(&schema).unwrap_or_default();
let desc = schema_val.get("description")
.and_then(|d| d.as_str())
.unwrap_or(fallback_desc)
.to_string();
// MCP expects standard JSON schema. Schemars returns draft-07.
json!({
"name": name,
"description": desc,
"inputSchema": schema_val
})
}
#[cfg(test)]
mod tests {
use super::*;
use schemars::JsonSchema;
use serde::Serialize;
#[derive(JsonSchema, Serialize)]
struct DummyTool {
name: String,
age: i32,
}
#[test]
fn test_success_response() {
let res = success(json!(1), json!({"status": "ok"}));
assert_eq!(res["jsonrpc"], "2.0");
assert_eq!(res["id"], 1);
assert_eq!(res["result"]["status"], "ok");
}
#[test]
fn test_error_response() {
let err = error(json!(2), -32603, "internal error");
assert_eq!(err["jsonrpc"], "2.0");
assert_eq!(err["id"], 2);
assert_eq!(err["error"]["code"], -32603);
assert_eq!(err["error"]["message"], "internal error");
}
#[test]
fn test_tool_def_generation() {
let def = tool_def::<DummyTool>("dummy", "A dummy tool");
assert_eq!(def["name"], "dummy");
assert_eq!(def["description"], "A dummy tool");
assert!(def["inputSchema"].is_object());
let schema = def["inputSchema"].as_object().unwrap();
let properties = schema["properties"].as_object().unwrap();
assert!(properties.contains_key("name"));
assert!(properties.contains_key("age"));
}
}