mcp_context_server/protocol/
response.rs1use serde::{Deserialize, Serialize};
2
3use super::request::RpcId;
4
5#[derive(Debug, Clone, Serialize)]
11pub struct JsonRpcResponse {
12 pub jsonrpc: String,
13 #[serde(skip_serializing_if = "Option::is_none")]
14 pub id: Option<RpcId>,
15 #[serde(skip_serializing_if = "Option::is_none")]
16 pub result: Option<serde_json::Value>,
17 #[serde(skip_serializing_if = "Option::is_none")]
18 pub error: Option<JsonRpcError>,
19}
20
21impl JsonRpcResponse {
22 pub fn success(id: Option<RpcId>, result: serde_json::Value) -> Self {
23 Self {
24 jsonrpc: "2.0".into(),
25 id,
26 result: Some(result),
27 error: None,
28 }
29 }
30
31 pub fn error(id: Option<RpcId>, error: JsonRpcError) -> Self {
32 Self {
33 jsonrpc: "2.0".into(),
34 id,
35 result: None,
36 error: Some(error),
37 }
38 }
39}
40
41#[derive(Debug, Clone, Serialize)]
43pub struct JsonRpcError {
44 pub code: i32,
45 pub message: String,
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub data: Option<serde_json::Value>,
48}
49
50impl JsonRpcError {
51 pub fn parse_error() -> Self {
52 Self { code: -32700, message: "Parse error".into(), data: None }
53 }
54
55 pub fn invalid_request() -> Self {
56 Self { code: -32600, message: "Invalid Request".into(), data: None }
57 }
58
59 pub fn invalid_request_with(detail: impl Into<String>) -> Self {
60 Self { code: -32600, message: detail.into(), data: None }
61 }
62
63 pub fn method_not_found(method: &str) -> Self {
64 Self {
65 code: -32601,
66 message: format!("Method not found: {method}"),
67 data: None,
68 }
69 }
70
71 pub fn invalid_params(detail: impl Into<String>) -> Self {
72 Self { code: -32602, message: detail.into(), data: None }
73 }
74
75 pub fn internal_error(detail: impl Into<String>) -> Self {
76 Self { code: -32603, message: detail.into(), data: None }
77 }
78}
79
80#[derive(Debug, Clone, Serialize)]
86pub struct ToolResult {
87 pub content: Vec<ToolResultContent>,
88 #[serde(rename = "isError", skip_serializing_if = "std::ops::Not::not")]
89 pub is_error: bool,
90}
91
92#[derive(Debug, Clone, Serialize)]
94pub struct ToolResultContent {
95 #[serde(rename = "type")]
96 pub content_type: String,
97 pub text: String,
98}
99
100impl ToolResult {
101 pub fn text(text: impl Into<String>) -> Self {
102 Self {
103 content: vec![ToolResultContent {
104 content_type: "text".into(),
105 text: text.into(),
106 }],
107 is_error: false,
108 }
109 }
110
111 pub fn error(text: impl Into<String>) -> Self {
112 Self {
113 content: vec![ToolResultContent {
114 content_type: "text".into(),
115 text: text.into(),
116 }],
117 is_error: true,
118 }
119 }
120}
121
122#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
128#[serde(rename_all = "snake_case")]
129pub enum McpErrorCode {
130 CacheMissing,
131 CacheInvalid,
132 InvalidQuery,
133 InvalidBudget,
134 IoError,
135 InternalError,
136}
137
138impl McpErrorCode {
139 pub fn json_rpc_code(&self) -> i32 {
144 match self {
145 Self::CacheMissing | Self::CacheInvalid => -32602,
146 Self::InvalidQuery | Self::InvalidBudget => -32602,
147 Self::IoError | Self::InternalError => -32603,
148 }
149 }
150}
151
152#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
154pub struct McpError {
155 pub code: McpErrorCode,
156 pub message: String,
157}
158
159#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
161pub struct McpErrorResponse {
162 pub error: McpError,
163}
164
165impl McpErrorResponse {
166 pub fn new(code: McpErrorCode, message: impl Into<String>) -> Self {
167 Self {
168 error: McpError {
169 code,
170 message: message.into(),
171 },
172 }
173 }
174
175 pub fn canonical(code: McpErrorCode) -> Self {
179 let message = match &code {
180 McpErrorCode::CacheMissing => "Cache does not exist",
181 McpErrorCode::CacheInvalid => "Cache exists but is invalid",
182 McpErrorCode::InvalidQuery => "Query is invalid",
183 McpErrorCode::InvalidBudget => "Budget is invalid",
184 McpErrorCode::IoError => "I/O error occurred",
185 McpErrorCode::InternalError => "Internal error",
186 };
187 Self::new(code, message)
188 }
189}
190
191impl From<McpErrorResponse> for JsonRpcError {
197 fn from(mcp: McpErrorResponse) -> Self {
198 Self {
199 code: mcp.error.code.json_rpc_code(),
200 message: mcp.error.message.clone(),
201 data: Some(serde_json::to_value(&mcp).expect("McpErrorResponse must serialize to JSON Value")),
202 }
203 }
204}
205
206impl From<McpErrorResponse> for ToolResult {
211 fn from(mcp: McpErrorResponse) -> Self {
212 let json = serde_json::to_string(&mcp).expect("McpErrorResponse must serialize to JSON string");
213 Self::error(format!("{json}\n"))
214 }
215}