Files
crank/apps/mcp-server/src/jsonrpc.rs
T
2026-03-25 20:02:23 +03:00

64 lines
1.6 KiB
Rust

use serde_json::{Value, json};
pub const CURRENT_PROTOCOL_VERSION: &str = "2025-11-25";
pub const DEFAULT_PROTOCOL_VERSION: &str = "2025-03-26";
pub const SUPPORTED_PROTOCOL_VERSIONS: &[&str] = &[
DEFAULT_PROTOCOL_VERSION,
"2025-06-18",
CURRENT_PROTOCOL_VERSION,
];
pub fn request_id(message: &Value) -> Value {
message.get("id").cloned().unwrap_or(Value::Null)
}
pub fn method_name(message: &Value) -> Option<&str> {
message.get("method").and_then(Value::as_str)
}
pub fn params(message: &Value) -> Value {
message
.get("params")
.cloned()
.unwrap_or_else(|| Value::Object(Default::default()))
}
pub fn is_notification(message: &Value) -> bool {
method_name(message).is_some() && message.get("id").is_none()
}
pub fn is_request(message: &Value) -> bool {
method_name(message).is_some() && message.get("id").is_some()
}
pub fn is_response(message: &Value) -> bool {
method_name(message).is_none()
&& (message.get("result").is_some() || message.get("error").is_some())
}
pub fn jsonrpc_result(id: Value, result: Value) -> Value {
json!({
"jsonrpc": "2.0",
"id": id,
"result": result
})
}
pub fn jsonrpc_error(id: Value, code: i64, message: impl Into<String>) -> Value {
json!({
"jsonrpc": "2.0",
"id": id,
"error": {
"code": code,
"message": message.into()
}
})
}
pub fn negotiated_protocol_version(requested: &str) -> Option<&'static str> {
SUPPORTED_PROTOCOL_VERSIONS
.iter()
.copied()
.find(|version| *version == requested)
}