Skip to main content

agentic_evolve_mcp/types/
message.rs

1//! JSON-RPC 2.0 message types for the MCP protocol.
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6/// JSON-RPC 2.0 protocol version.
7pub const JSONRPC_VERSION: &str = "2.0";
8
9/// Unique request identifier — can be string, number, or null.
10#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
11#[serde(untagged)]
12pub enum RequestId {
13    /// String identifier.
14    String(String),
15    /// Numeric identifier.
16    Number(i64),
17    /// Null identifier (for notifications that shouldn't have one).
18    Null,
19}
20
21impl std::fmt::Display for RequestId {
22    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23        match self {
24            RequestId::String(s) => write!(f, "{s}"),
25            RequestId::Number(n) => write!(f, "{n}"),
26            RequestId::Null => write!(f, "null"),
27        }
28    }
29}
30
31/// A JSON-RPC 2.0 request message.
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct JsonRpcRequest {
34    /// Must be "2.0".
35    pub jsonrpc: String,
36    /// Unique request identifier.
37    pub id: RequestId,
38    /// Method name to invoke.
39    pub method: String,
40    /// Optional parameters.
41    #[serde(default, skip_serializing_if = "Option::is_none")]
42    pub params: Option<Value>,
43}
44
45/// A JSON-RPC 2.0 success response.
46#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct JsonRpcResponse {
48    /// Must be "2.0".
49    pub jsonrpc: String,
50    /// Echoes the request id.
51    pub id: RequestId,
52    /// Result payload.
53    pub result: Value,
54}
55
56/// A JSON-RPC 2.0 error response.
57#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct JsonRpcError {
59    /// Must be "2.0".
60    pub jsonrpc: String,
61    /// Echoes the request id.
62    pub id: RequestId,
63    /// Error object.
64    pub error: JsonRpcErrorObject,
65}
66
67/// Error object within a JSON-RPC error response.
68#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct JsonRpcErrorObject {
70    /// Numeric error code.
71    pub code: i32,
72    /// Human-readable error message.
73    pub message: String,
74    /// Optional additional data.
75    #[serde(default, skip_serializing_if = "Option::is_none")]
76    pub data: Option<Value>,
77}
78
79/// A JSON-RPC 2.0 notification (no id, no response expected).
80#[derive(Debug, Clone, Serialize, Deserialize)]
81pub struct JsonRpcNotification {
82    /// Must be "2.0".
83    pub jsonrpc: String,
84    /// Method name.
85    pub method: String,
86    /// Optional parameters.
87    #[serde(default, skip_serializing_if = "Option::is_none")]
88    pub params: Option<Value>,
89}
90
91/// Union type for any JSON-RPC message.
92#[derive(Debug, Clone, Serialize, Deserialize)]
93#[serde(untagged)]
94pub enum JsonRpcMessage {
95    /// A request (has id + method).
96    Request(JsonRpcRequest),
97    /// A success response (has id + result).
98    Response(JsonRpcResponse),
99    /// An error response (has id + error).
100    Error(JsonRpcError),
101    /// A notification (has method, no id).
102    Notification(JsonRpcNotification),
103}
104
105impl JsonRpcResponse {
106    /// Create a new success response.
107    pub fn new(id: RequestId, result: Value) -> Self {
108        Self {
109            jsonrpc: JSONRPC_VERSION.to_string(),
110            id,
111            result,
112        }
113    }
114}
115
116impl JsonRpcError {
117    /// Create a new error response.
118    pub fn new(id: RequestId, code: i32, message: String) -> Self {
119        Self {
120            jsonrpc: JSONRPC_VERSION.to_string(),
121            id,
122            error: JsonRpcErrorObject {
123                code,
124                message,
125                data: None,
126            },
127        }
128    }
129}
130
131impl JsonRpcNotification {
132    /// Create a new notification.
133    pub fn new(method: String, params: Option<Value>) -> Self {
134        Self {
135            jsonrpc: JSONRPC_VERSION.to_string(),
136            method,
137            params,
138        }
139    }
140}