mcp_ectors/utils/
json_rpc.rs

1use mcp_spec::protocol::{ErrorData, JsonRpcError, JsonRpcRequest, JsonRpcResponse};
2use serde_json::{json, Value};
3use crate::messages::JSONRPC_VERSION;
4
5// JSON-RPC Error Codes
6pub const JSON_RPC_PARSE_ERROR: i32 = -32700;
7pub const JSON_RPC_INVALID_REQUEST: i32 = -32600;
8pub const JSON_RPC_METHOD_NOT_FOUND: i32 = -32601;
9pub const JSON_RPC_INVALID_PARAMS: i32 = -32602;
10pub const JSON_RPC_INTERNAL_ERROR: i32 = -32603;
11pub const JSON_RPC_APPLICATION_ERROR_START: i32 = -32000; // Range -32000 to -32099 for app-specific errors
12
13// MCP Error Codes
14pub const MCP_INVALID_REQUEST: i32 = 100;
15pub const MCP_INVALID_METHOD: i32 = 101;
16pub const MCP_INVALID_PARAMS: i32 = 102;
17pub const MCP_AUTH_ERROR: i32 = 103;
18pub const MCP_TIMEOUT_ERROR: i32 = 104;
19pub const MCP_INTERNAL_SERVER_ERROR: i32 = 105;
20pub const MCP_SERVICE_UNAVAILABLE: i32 = 106;
21pub const MCP_FORBIDDEN_ERROR: i32 = 107;
22
23
24/// Helper functions for JSON-RPC handling
25pub struct JsonRpcUtils;
26
27impl JsonRpcUtils {
28    /// Parses raw JSON into a JSON-RPC request
29    pub fn parse_request(json_str: &str) -> Result<JsonRpcRequest, JsonRpcError> {
30        serde_json::from_str(json_str).map_err(|e| JsonRpcUtils::invalid_request(Some(e.to_string())))
31    }
32
33    /// Parses raw JSON into a JSON-RPC message (handles requests and notifications)
34    pub fn parse_message(json_str: &str) -> Result<Value, JsonRpcError> {
35        serde_json::from_str(json_str).map_err(|e| JsonRpcUtils::invalid_request(Some(e.to_string())))
36    }
37
38    /// Serializes a JSON-RPC response into a string
39    pub fn serialize_response(response: &JsonRpcResponse) -> String {
40        serde_json::to_string(response).unwrap_or_else(|_| "{}".to_string())
41    }
42
43    /// Creates a generic JSON-RPC error response
44    pub fn error_response(id: Option<u64>, code: i32, message: &str, data: Option<Value>) -> JsonRpcError {
45        JsonRpcError {
46            jsonrpc: JSONRPC_VERSION.to_string(),
47            id: id,
48            error: ErrorData {
49                code,
50                message: message.to_string(),
51                data,
52            },
53        }
54    }
55
56    /// Returns a predefined error for invalid requests
57    pub fn invalid_request(detail: Option<String>) -> JsonRpcError {
58        JsonRpcError {
59           jsonrpc: JSONRPC_VERSION.to_owned(),
60            id: None,
61            error: ErrorData {
62                code: -32600, // Invalid Request
63                message: "Invalid JSON-RPC request".to_string(),
64                data: detail.map(|d| json!(d)),
65            
66            }
67        }
68    }
69
70    /// Returns a predefined error for method not found
71    pub fn method_not_found(id: u64, method: &str) -> JsonRpcError {
72        JsonRpcUtils::error_response(Some(id), -32601, &format!("Method '{}' not found", method), None)
73    }
74
75    /// Returns a predefined error for internal server errors
76    pub fn internal_error(id: Option<u64>, detail: Option<String>) -> JsonRpcError {
77        JsonRpcUtils::error_response(id, -1, "Internal server error", detail.map(|d| json!(d)))
78    }
79}