Skip to main content

origin_mcp_core/
protocol.rs

1//! The JSON-RPC 2.0 envelope MCP speaks.
2//!
3//! Only what this server needs: lifecycle, `tools/list`, and `tools/call`.
4
5use serde::{Deserialize, Serialize};
6
7/// Protocol revision this server announces.
8pub const PROTOCOL_VERSION: &str = "2025-06-18";
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct ServerInfo {
12    pub name: String,
13    pub version: String,
14}
15
16#[derive(Debug, Clone, Deserialize)]
17#[serde(rename_all = "camelCase")]
18pub struct InitializeParams {
19    pub protocol_version: String,
20    pub capabilities: serde_json::Value,
21    pub client_info: ClientInfo,
22}
23
24#[derive(Debug, Clone, Deserialize)]
25pub struct ClientInfo {
26    pub name: String,
27    pub version: String,
28}
29
30#[derive(Debug, Clone, Deserialize)]
31pub struct Request {
32    pub jsonrpc: String,
33    /// Absent for notifications, which take no response.
34    #[serde(default)]
35    pub id: Option<serde_json::Value>,
36    pub method: String,
37    #[serde(default)]
38    pub params: serde_json::Value,
39}
40
41#[derive(Debug, Clone, Serialize)]
42pub struct Response {
43    pub jsonrpc: &'static str,
44    pub id: serde_json::Value,
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub result: Option<serde_json::Value>,
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub error: Option<ResponseError>,
49}
50
51#[derive(Debug, Clone, Serialize)]
52pub struct ResponseError {
53    pub code: i32,
54    pub message: String,
55}
56
57/// JSON-RPC error codes, plus the one MCP-specific case this server produces.
58pub(crate) mod codes {
59    pub(crate) const PARSE_ERROR: i32 = -32700;
60    pub(crate) const INVALID_REQUEST: i32 = -32600;
61    pub(crate) const METHOD_NOT_FOUND: i32 = -32601;
62    pub(crate) const INVALID_PARAMS: i32 = -32602;
63}
64
65impl Response {
66    pub(crate) fn result(id: serde_json::Value, result: serde_json::Value) -> Self {
67        Self {
68            jsonrpc: "2.0",
69            id,
70            result: Some(result),
71            error: None,
72        }
73    }
74
75    pub(crate) fn error(id: serde_json::Value, code: i32, message: impl Into<String>) -> Self {
76        Self {
77            jsonrpc: "2.0",
78            id,
79            result: None,
80            error: Some(ResponseError {
81                code,
82                message: message.into(),
83            }),
84        }
85    }
86}