claude_utils/mcp/
protocol.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4// JSON-RPC 2.0 base types
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct JsonRpcRequest {
7    pub jsonrpc: String,
8    pub id: Option<Value>,
9    pub method: String,
10    #[serde(skip_serializing_if = "Option::is_none")]
11    pub params: Option<Value>,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct JsonRpcResponse {
16    pub jsonrpc: String,
17    pub id: Option<Value>,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub result: Option<Value>,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub error: Option<JsonRpcError>,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct JsonRpcError {
26    pub code: i32,
27    pub message: String,
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub data: Option<Value>,
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct JsonRpcNotification {
34    pub jsonrpc: String,
35    pub method: String,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub params: Option<Value>,
38}
39
40// MCP Protocol types
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct InitializeRequest {
43    pub protocol_version: String,
44    pub capabilities: ClientCapabilities,
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub client_info: Option<ClientInfo>,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct InitializeResponse {
51    pub protocol_version: String,
52    pub capabilities: ServerCapabilities,
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub server_info: Option<ServerInfo>,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct ClientCapabilities {
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub experimental: Option<Value>,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct ServerCapabilities {
65    #[serde(skip_serializing_if = "Option::is_none")]
66    pub tools: Option<ToolsCapability>,
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub resources: Option<ResourcesCapability>,
69    #[serde(skip_serializing_if = "Option::is_none")]
70    pub prompts: Option<PromptsCapability>,
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize)]
74pub struct ToolsCapability {}
75
76#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct ResourcesCapability {}
78
79#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct PromptsCapability {}
81
82#[derive(Debug, Clone, Serialize, Deserialize)]
83pub struct ClientInfo {
84    pub name: String,
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub version: Option<String>,
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct ServerInfo {
91    pub name: String,
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub version: Option<String>,
94}
95
96// Tool definitions
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct Tool {
99    pub name: String,
100    pub description: String,
101    pub input_schema: Value,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct ToolListResponse {
106    pub tools: Vec<Tool>,
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize)]
110pub struct ToolCallRequest {
111    pub name: String,
112    #[serde(skip_serializing_if = "Option::is_none")]
113    pub arguments: Option<Value>,
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct ToolCallResponse {
118    pub content: Vec<Content>,
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize)]
122#[serde(tag = "type")]
123pub enum Content {
124    #[serde(rename = "text")]
125    Text { text: String },
126    #[serde(rename = "image")]
127    Image {
128        data: String, // base64
129        mime_type: String,
130    },
131}
132
133// Error codes
134pub const PARSE_ERROR: i32 = -32700;
135pub const INVALID_REQUEST: i32 = -32600;
136pub const METHOD_NOT_FOUND: i32 = -32601;
137pub const INVALID_PARAMS: i32 = -32602;
138pub const INTERNAL_ERROR: i32 = -32603;
139
140// MCP methods
141pub const INITIALIZE: &str = "initialize";
142pub const INITIALIZED: &str = "initialized";
143pub const TOOLS_LIST: &str = "tools/list";
144pub const TOOLS_CALL: &str = "tools/call";
145
146// Helper functions
147pub fn create_error_response(id: Option<Value>, code: i32, message: String) -> JsonRpcResponse {
148    JsonRpcResponse {
149        jsonrpc: "2.0".to_string(),
150        id,
151        result: None,
152        error: Some(JsonRpcError {
153            code,
154            message,
155            data: None,
156        }),
157    }
158}
159
160pub fn create_success_response(id: Option<Value>, result: Value) -> JsonRpcResponse {
161    JsonRpcResponse {
162        jsonrpc: "2.0".to_string(),
163        id,
164        result: Some(result),
165        error: None,
166    }
167}