1pub mod completion;
42pub mod content;
43pub mod elicitation;
44pub mod initialize;
45pub mod json_rpc;
46pub mod logging;
47pub mod meta;
48pub mod notifications;
49pub mod param_extraction;
50pub mod ping;
51pub mod prelude;
52pub mod prompts;
53pub mod resources;
54pub mod roots;
55pub mod sampling;
56pub mod schema;
57pub mod tools;
58pub mod traits;
59pub mod version;
60
61pub use content::{
63 BlobResourceContents, ContentBlock, ResourceContents, ResourceReference, TextResourceContents,
64};
65pub use meta::{Annotations, Meta};
67
68#[cfg(test)]
69mod compliance_test;
70
71pub use initialize::{
73 ClientCapabilities, Implementation, InitializeRequest, InitializeResult, ServerCapabilities,
74};
75pub use prompts::{
76 GetPromptRequest, GetPromptResult, ListPromptsRequest, ListPromptsResult, Prompt,
77 PromptArgument, PromptMessage,
78};
79pub use resources::{
80 ListResourcesRequest, ListResourcesResult, ReadResourceRequest, ReadResourceResult, Resource,
81 ResourceContent, ResourceSubscription, SubscribeRequest, UnsubscribeRequest,
82};
83pub use tools::{
84 CallToolRequest, CallToolResult, ListToolsRequest, ListToolsResult, Tool, ToolResult,
85 ToolSchema,
86};
87pub use version::McpVersion;
88pub use elicitation::{
91 ElicitAction, ElicitCreateParams, ElicitCreateRequest, ElicitResult, ElicitationBuilder,
92 ElicitationSchema, PrimitiveSchemaDefinition, StringFormat,
93};
94pub use json_rpc::{
95 JsonRpcError, JsonRpcMessage, JsonRpcNotification, JsonRpcRequest, JsonRpcResponse,
96 RequestParams, ResultWithMeta,
97};
98pub use meta::{
99 Cursor as MetaCursor, PaginatedResponse, ProgressResponse, ProgressToken, WithMeta,
100};
101pub use notifications::{
102 CancelledNotification, InitializedNotification, LoggingMessageNotification,
103 LoggingMessageNotificationParams, Notification, NotificationParams, ProgressNotification,
104 ProgressNotificationParams, PromptListChangedNotification, ResourceListChangedNotification,
105 ResourceUpdatedNotification, ResourceUpdatedNotificationParams, RootsListChangedNotification,
106 ToolListChangedNotification,
107};
108pub use ping::{EmptyParams, EmptyResult, PingRequest};
109pub use schema::JsonSchema;
110pub use traits::{
111 HasData, HasDataParam, HasMeta, HasMetaParam, HasProgressTokenParam, JsonRpcNotificationTrait,
112 JsonRpcRequestTrait, JsonRpcResponseTrait, Params, RpcResult,
113};
114
115pub use turul_mcp_json_rpc_server::{
117 RequestParams as LegacyRequestParams, ResponseResult, types::RequestId,
118};
119
120pub const MCP_VERSION: &str = "2025-06-18";
122
123pub type McpResult<T> = Result<T, McpError>;
125
126#[derive(Debug, thiserror::Error)]
128pub enum McpError {
129 #[error("Protocol version mismatch: expected {expected}, got {actual}")]
130 VersionMismatch { expected: String, actual: String },
131
132 #[error("Invalid capability: {0}")]
133 InvalidCapability(String),
134
135 #[error("Tool not found: {0}")]
136 ToolNotFound(String),
137
138 #[error("Resource not found: {0}")]
139 ResourceNotFound(String),
140
141 #[error("Prompt not found: {0}")]
142 PromptNotFound(String),
143
144 #[error("Invalid request: {message}")]
145 InvalidRequest { message: String },
146
147 #[error("Invalid parameters: {0}")]
148 InvalidParameters(String),
149
150 #[error("Missing required parameter: {0}")]
151 MissingParameter(String),
152
153 #[error("Invalid parameter type for '{param}': expected {expected}, got {actual}")]
154 InvalidParameterType {
155 param: String,
156 expected: String,
157 actual: String,
158 },
159
160 #[error("Parameter '{param}' value {value} is out of range: {constraint}")]
161 ParameterOutOfRange {
162 param: String,
163 value: String,
164 constraint: String,
165 },
166
167 #[error("Tool execution failed: {0}")]
168 ToolExecutionError(String),
169
170 #[error("Resource execution failed: {0}")]
171 ResourceExecutionError(String),
172
173 #[error("Prompt execution failed: {0}")]
174 PromptExecutionError(String),
175
176 #[error("Resource access denied: {0}")]
177 ResourceAccessDenied(String),
178
179 #[error("Configuration error: {0}")]
180 ConfigurationError(String),
181
182 #[error("Session error: {0}")]
183 SessionError(String),
184
185 #[error("Validation error: {0}")]
186 ValidationError(String),
187
188 #[error("IO error: {0}")]
189 IoError(#[from] std::io::Error),
190
191 #[error("Serialization error: {0}")]
192 SerializationError(#[from] serde_json::Error),
193
194 #[error("Transport error: {0}")]
195 TransportError(String),
196
197 #[error("JSON-RPC protocol error: {0}")]
198 JsonRpcProtocolError(String),
199}
200
201impl From<String> for McpError {
202 fn from(message: String) -> Self {
203 Self::ToolExecutionError(message)
204 }
205}
206
207impl From<&str> for McpError {
208 fn from(message: &str) -> Self {
209 Self::ToolExecutionError(message.to_string())
210 }
211}
212
213impl McpError {
214 pub fn missing_param(param: &str) -> Self {
216 Self::MissingParameter(param.to_string())
217 }
218
219 pub fn invalid_param_type(param: &str, expected: &str, actual: &str) -> Self {
221 Self::InvalidParameterType {
222 param: param.to_string(),
223 expected: expected.to_string(),
224 actual: actual.to_string(),
225 }
226 }
227
228 pub fn param_out_of_range(param: &str, value: &str, constraint: &str) -> Self {
230 Self::ParameterOutOfRange {
231 param: param.to_string(),
232 value: value.to_string(),
233 constraint: constraint.to_string(),
234 }
235 }
236
237 pub fn tool_execution(message: &str) -> Self {
239 Self::ToolExecutionError(message.to_string())
240 }
241
242 pub fn resource_execution(message: &str) -> Self {
244 Self::ResourceExecutionError(message.to_string())
245 }
246
247 pub fn prompt_execution(message: &str) -> Self {
249 Self::PromptExecutionError(message.to_string())
250 }
251
252 pub fn validation(message: &str) -> Self {
254 Self::ValidationError(message.to_string())
255 }
256
257 pub fn configuration(message: &str) -> Self {
259 Self::ConfigurationError(message.to_string())
260 }
261
262 pub fn transport(message: &str) -> Self {
264 Self::TransportError(message.to_string())
265 }
266
267 pub fn json_rpc_protocol(message: &str) -> Self {
269 Self::JsonRpcProtocolError(message.to_string())
270 }
271
272 pub fn to_error_object(&self) -> turul_mcp_json_rpc_server::error::JsonRpcErrorObject {
274 use turul_mcp_json_rpc_server::error::JsonRpcErrorObject;
275
276 match self {
277 McpError::InvalidRequest { message } => JsonRpcErrorObject::invalid_params(message),
279
280 McpError::InvalidParameters(msg) => JsonRpcErrorObject::invalid_params(msg),
282 McpError::MissingParameter(param) => JsonRpcErrorObject::invalid_params(&format!(
283 "Missing required parameter: {}",
284 param
285 )),
286 McpError::InvalidParameterType {
287 param,
288 expected,
289 actual,
290 } => JsonRpcErrorObject::invalid_params(&format!(
291 "Invalid parameter type for '{}': expected {}, got {}",
292 param, expected, actual
293 )),
294 McpError::ParameterOutOfRange {
295 param,
296 value,
297 constraint,
298 } => JsonRpcErrorObject::invalid_params(&format!(
299 "Parameter '{}' value {} is out of range: {}",
300 param, value, constraint
301 )),
302
303 McpError::ToolNotFound(name) => {
305 JsonRpcErrorObject::server_error(-32001, &format!("Tool not found: {}", name), None)
306 }
307 McpError::ResourceNotFound(uri) => JsonRpcErrorObject::server_error(
308 -32002,
309 &format!("Resource not found: {}", uri),
310 None,
311 ),
312 McpError::PromptNotFound(name) => JsonRpcErrorObject::server_error(
313 -32003,
314 &format!("Prompt not found: {}", name),
315 None,
316 ),
317
318 McpError::ToolExecutionError(msg) => JsonRpcErrorObject::server_error(
320 -32010,
321 &format!("Tool execution failed: {}", msg),
322 None,
323 ),
324 McpError::ResourceExecutionError(msg) => JsonRpcErrorObject::server_error(
325 -32012,
326 &format!("Resource execution failed: {}", msg),
327 None,
328 ),
329 McpError::PromptExecutionError(msg) => JsonRpcErrorObject::server_error(
330 -32013,
331 &format!("Prompt execution failed: {}", msg),
332 None,
333 ),
334 McpError::ResourceAccessDenied(uri) => JsonRpcErrorObject::server_error(
335 -32011,
336 &format!("Resource access denied: {}", uri),
337 None,
338 ),
339
340 McpError::ValidationError(msg) => JsonRpcErrorObject::server_error(
342 -32020,
343 &format!("Validation error: {}", msg),
344 None,
345 ),
346 McpError::InvalidCapability(cap) => JsonRpcErrorObject::server_error(
347 -32021,
348 &format!("Invalid capability: {}", cap),
349 None,
350 ),
351 McpError::VersionMismatch { expected, actual } => JsonRpcErrorObject::server_error(
352 -32022,
353 &format!(
354 "Protocol version mismatch: expected {}, got {}",
355 expected, actual
356 ),
357 None,
358 ),
359
360 McpError::ConfigurationError(msg) => JsonRpcErrorObject::server_error(
362 -32030,
363 &format!("Configuration error: {}", msg),
364 None,
365 ),
366 McpError::SessionError(msg) => {
367 JsonRpcErrorObject::server_error(-32031, &format!("Session error: {}", msg), None)
368 }
369
370 McpError::TransportError(msg) => {
372 JsonRpcErrorObject::server_error(-32040, &format!("Transport error: {}", msg), None)
373 }
374 McpError::JsonRpcProtocolError(msg) => JsonRpcErrorObject::server_error(
375 -32041,
376 &format!("JSON-RPC protocol error: {}", msg),
377 None,
378 ),
379
380 McpError::IoError(err) => {
382 JsonRpcErrorObject::internal_error(Some(format!("IO error: {}", err)))
383 }
384 McpError::SerializationError(err) => {
385 JsonRpcErrorObject::internal_error(Some(format!("Serialization error: {}", err)))
386 }
387 }
388 }
389
390 pub fn to_json_rpc_response(
392 &self,
393 id: Option<turul_mcp_json_rpc_server::RequestId>,
394 ) -> turul_mcp_json_rpc_server::JsonRpcError {
395 turul_mcp_json_rpc_server::JsonRpcError::new(id, self.to_error_object())
396 }
397
398 #[deprecated(note = "Use to_error_object() instead for cleaner architecture")]
400 pub fn to_json_rpc_error(&self) -> turul_mcp_json_rpc_server::error::JsonRpcErrorObject {
401 self.to_error_object()
402 }
403}
404
405impl turul_mcp_json_rpc_server::r#async::ToJsonRpcError for McpError {
407 fn to_error_object(&self) -> turul_mcp_json_rpc_server::error::JsonRpcErrorObject {
408 McpError::to_error_object(self)
410 }
411}