1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6pub enum McpProtocolVersion {
7 #[serde(rename = "2025-03-26")]
8 V1,
9}
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct Request {
14 pub jsonrpc: String,
15 #[serde(skip_serializing_if = "Option::is_none")]
16 pub id: Option<Value>,
17 pub method: String,
18 pub params: Value,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct Response {
24 pub jsonrpc: String,
25 #[serde(skip_serializing_if = "Option::is_none")]
26 pub id: Option<Value>,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 pub result: Option<Value>,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub error: Option<Error>,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct Error {
36 pub code: ErrorCode,
37 pub message: String,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 pub data: Option<Value>,
40}
41
42#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
44#[serde(transparent)]
45pub struct ErrorCode(pub i32);
46
47impl ErrorCode {
48 pub const PARSE_ERROR: ErrorCode = ErrorCode(-32700);
49 pub const INVALID_REQUEST: ErrorCode = ErrorCode(-32600);
50 pub const METHOD_NOT_FOUND: ErrorCode = ErrorCode(-32601);
51 pub const INVALID_PARAMS: ErrorCode = ErrorCode(-32602);
52 pub const INTERNAL_ERROR: ErrorCode = ErrorCode(-32603);
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct InitializeRequest {
58 #[serde(rename = "protocolVersion")]
59 pub protocol_version: McpProtocolVersion,
60 #[serde(rename = "clientInfo")]
61 pub client_info: ClientInfo,
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize)]
66pub struct InitializeResponse {
67 #[serde(rename = "protocolVersion")]
68 pub protocol_version: McpProtocolVersion,
69 pub capabilities: Value,
70 #[serde(rename = "serverInfo")]
71 pub server_info: ServerInfo,
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct ClientInfo {
77 pub name: String,
78 pub version: String,
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize)]
83pub struct ServerInfo {
84 pub name: String,
85 pub version: String,
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct ListToolsRequest {}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct ListToolsResponse {
95 pub tools: Vec<Tool>,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize)]
100pub struct Tool {
101 pub name: String,
102 #[serde(skip_serializing_if = "Option::is_none")]
103 pub description: Option<String>,
104 #[serde(rename = "inputSchema")]
105 pub input_schema: Value,
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize)]
110pub struct CallToolRequest {
111 pub name: String,
112 pub arguments: Value,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct CallToolResponse {
118 pub content: Vec<Content>,
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct Content {
124 #[serde(rename = "type")]
125 pub content_type: String,
126 pub text: String,
127}
128
129impl Response {
130 pub fn success(id: Value, result: Value) -> Self {
132 Self {
133 jsonrpc: "2.0".to_string(),
134 id: Some(id),
135 result: Some(result),
136 error: None,
137 }
138 }
139
140 pub fn error(id: Value, code: ErrorCode, message: String, data: Option<Value>) -> Self {
142 Self {
143 jsonrpc: "2.0".to_string(),
144 id: Some(id),
145 result: None,
146 error: Some(Error {
147 code,
148 message,
149 data,
150 }),
151 }
152 }
153
154 pub fn error_without_id(code: ErrorCode, message: String, data: Option<Value>) -> Self {
156 Self {
157 jsonrpc: "2.0".to_string(),
158 id: None,
159 result: None,
160 error: Some(Error {
161 code,
162 message,
163 data,
164 }),
165 }
166 }
167}