Skip to main content

lilo_rm_core/
mcp.rs

1use serde::{Deserialize, Serialize};
2use serde_json::{Value, json};
3
4pub const MCP_PROTOCOL_VERSION: &str = "2025-06-18";
5
6#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
7pub struct JsonRpcRequest {
8    pub jsonrpc: String,
9    pub id: Option<Value>,
10    pub method: String,
11    #[serde(default)]
12    pub params: Option<Value>,
13}
14
15#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
16pub struct JsonRpcResponse {
17    pub jsonrpc: String,
18    pub id: Value,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub result: Option<Value>,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub error: Option<JsonRpcError>,
23}
24
25#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
26pub struct JsonRpcError {
27    pub code: i32,
28    pub message: String,
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub data: Option<Value>,
31}
32
33#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
34pub struct McpBridgeRequest {
35    pub line: String,
36}
37
38#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
39pub struct McpBridgeResponse {
40    pub line: Option<String>,
41}
42
43pub fn json_rpc_result(id: Value, result: Value) -> JsonRpcResponse {
44    JsonRpcResponse {
45        jsonrpc: "2.0".to_owned(),
46        id,
47        result: Some(result),
48        error: None,
49    }
50}
51
52pub fn json_rpc_failure(id: Value, error: JsonRpcError) -> JsonRpcResponse {
53    JsonRpcResponse {
54        jsonrpc: "2.0".to_owned(),
55        id,
56        result: None,
57        error: Some(error),
58    }
59}
60
61pub fn json_rpc_error(code: i32, message: impl Into<String>) -> JsonRpcError {
62    JsonRpcError {
63        code,
64        message: message.into(),
65        data: None,
66    }
67}
68
69pub fn tool_success<T>(text: String, structured: &T) -> Value
70where
71    T: Serialize,
72{
73    json!({
74        "content": [{"type": "text", "text": text}],
75        "structuredContent": serde_json::to_value(structured)
76            .expect("structured MCP result serializes")
77    })
78}
79
80pub fn tool_error(message: impl Into<String>) -> Value {
81    let message = message.into();
82    json!({
83        "content": [{"type": "text", "text": format!("ERROR: {message}")}],
84        "_meta": {
85            "rtm_tool_error": {
86                "is_error": true,
87                "message": message
88            }
89        }
90    })
91}