82 lines
2.2 KiB
Rust
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"));
|
|
}
|
|
}
|