Skip to main content

sh_layer4/mcp_bridge/
protocol.rs

1//! MCP 协议定义
2//!
3//! Model Context Protocol 消息类型和常量。
4
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7
8/// MCP 协议版本
9pub const MCP_VERSION: &str = "2024-11-05";
10
11/// MCP 消息类型
12#[derive(Debug, Clone, Serialize, Deserialize)]
13#[serde(tag = "type", rename_all = "snake_case")]
14pub enum McpMessage {
15    /// 请求消息
16    Request(McpRequest),
17    /// 响应消息
18    Response(McpResponse),
19    /// 通知消息
20    Notification(McpNotification),
21    /// 错误消息
22    Error(McpError),
23}
24
25/// MCP 请求
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct McpRequest {
28    /// 请求 ID
29    pub id: RequestId,
30    /// 方法名
31    pub method: String,
32    /// 参数
33    #[serde(default)]
34    pub params: Option<Value>,
35}
36
37/// MCP 响应
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct McpResponse {
40    /// 对应的请求 ID
41    pub id: RequestId,
42    /// 结果
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub result: Option<Value>,
45    /// 错误
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub error: Option<McpErrorData>,
48}
49
50/// MCP 通知
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct McpNotification {
53    /// 方法名
54    pub method: String,
55    /// 参数
56    #[serde(default)]
57    pub params: Option<Value>,
58}
59
60/// MCP 错误
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct McpError {
63    /// 对应的请求 ID (可选)
64    #[serde(skip_serializing_if = "Option::is_none")]
65    pub id: Option<RequestId>,
66    /// 错误数据
67    pub error: McpErrorData,
68}
69
70/// MCP 错误数据
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct McpErrorData {
73    /// 错误码
74    pub code: i32,
75    /// 错误消息
76    pub message: String,
77    /// 额外数据
78    #[serde(skip_serializing_if = "Option::is_none")]
79    pub data: Option<Value>,
80}
81
82/// 请求 ID 类型
83#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
84#[serde(untagged)]
85pub enum RequestId {
86    String(String),
87    Number(i64),
88}
89
90impl Default for RequestId {
91    fn default() -> Self {
92        RequestId::Number(0)
93    }
94}
95
96// ========== MCP 方法常量 ==========
97
98/// 初始化
99pub const METHOD_INITIALIZE: &str = "initialize";
100/// 初始化完成通知
101pub const METHOD_INITIALIZED: &str = "notifications/initialized";
102/// 关闭
103pub const METHOD_SHUTDOWN: &str = "shutdown";
104/// 列出工具
105pub const METHOD_LIST_TOOLS: &str = "tools/list";
106/// 调用工具
107pub const METHOD_CALL_TOOL: &str = "tools/call";
108/// 列出资源
109pub const METHOD_LIST_RESOURCES: &str = "resources/list";
110/// 读取资源
111pub const METHOD_READ_RESOURCE: &str = "resources/read";
112/// 列出提示词
113pub const METHOD_LIST_PROMPTS: &str = "prompts/list";
114/// 获取提示词
115pub const METHOD_GET_PROMPT: &str = "prompts/get";
116
117// ========== MCP 标准类型 ==========
118
119/// 工具定义
120#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct ToolDefinition {
122    /// 工具名称
123    pub name: String,
124    /// 工具描述
125    #[serde(default)]
126    pub description: Option<String>,
127    /// 输入参数 Schema
128    #[serde(default)]
129    pub input_schema: Option<Value>,
130}
131
132/// 工具执行结果
133#[derive(Debug, Clone, Serialize, Deserialize)]
134pub struct ToolResult {
135    /// 是否错误
136    #[serde(default)]
137    pub is_error: bool,
138    /// 内容列表
139    pub content: Vec<ContentBlock>,
140}
141
142/// 内容块
143#[derive(Debug, Clone, Serialize, Deserialize)]
144#[serde(tag = "type", rename_all = "snake_case")]
145pub enum ContentBlock {
146    /// 文本内容
147    Text { text: String },
148    /// 图片内容
149    Image { data: String, mime_type: String },
150    /// 资源内容
151    Resource { resource: ResourceContent },
152}
153
154/// 资源内容
155#[derive(Debug, Clone, Serialize, Deserialize)]
156pub struct ResourceContent {
157    /// URI
158    pub uri: String,
159    /// MIME 类型
160    #[serde(default)]
161    pub mime_type: Option<String>,
162    /// 文本内容
163    #[serde(skip_serializing_if = "Option::is_none")]
164    pub text: Option<String>,
165    /// 二进制内容 (base64)
166    #[serde(skip_serializing_if = "Option::is_none")]
167    pub blob: Option<String>,
168}
169
170/// 初始化参数
171#[derive(Debug, Clone, Serialize, Deserialize)]
172pub struct InitializeParams {
173    /// 协议版本
174    #[serde(default = "default_protocol_version")]
175    pub protocol_version: String,
176    /// 客户端能力
177    pub capabilities: ClientCapabilities,
178    /// 客户端信息
179    #[serde(default)]
180    pub client_info: Option<Implementation>,
181}
182
183fn default_protocol_version() -> String {
184    MCP_VERSION.to_string()
185}
186
187/// 客户端能力
188#[derive(Debug, Clone, Default, Serialize, Deserialize)]
189pub struct ClientCapabilities {
190    /// 实验性功能
191    #[serde(default)]
192    pub experimental: Option<Value>,
193    /// 根目录支持
194    #[serde(default)]
195    pub roots: Option<RootsCapability>,
196    /// 采样支持
197    #[serde(default)]
198    pub sampling: Option<Value>,
199}
200
201/// 根目录能力
202#[derive(Debug, Clone, Default, Serialize, Deserialize)]
203pub struct RootsCapability {
204    /// 是否支持列表变更通知
205    #[serde(default)]
206    pub list_changed: Option<bool>,
207}
208
209/// 实现信息
210#[derive(Debug, Clone, Serialize, Deserialize)]
211pub struct Implementation {
212    /// 名称
213    pub name: String,
214    /// 版本
215    pub version: String,
216}
217
218/// 初始化结果
219#[derive(Debug, Clone, Serialize, Deserialize)]
220pub struct InitializeResult {
221    /// 协议版本
222    pub protocol_version: String,
223    /// 服务端能力
224    pub capabilities: ServerCapabilities,
225    /// 服务端信息
226    pub server_info: Implementation,
227    /// 指令
228    #[serde(skip_serializing_if = "Option::is_none")]
229    pub instructions: Option<String>,
230}
231
232/// 服务端能力
233#[derive(Debug, Clone, Default, Serialize, Deserialize)]
234pub struct ServerCapabilities {
235    /// 实验性功能
236    #[serde(default)]
237    pub experimental: Option<Value>,
238    /// 日志支持
239    #[serde(default)]
240    pub logging: Option<Value>,
241    /// 提示词支持
242    #[serde(default)]
243    pub prompts: Option<PromptsCapability>,
244    /// 资源支持
245    #[serde(default)]
246    pub resources: Option<ResourcesCapability>,
247    /// 工具支持
248    #[serde(default)]
249    pub tools: Option<ToolsCapability>,
250}
251
252/// 提示词能力
253#[derive(Debug, Clone, Default, Serialize, Deserialize)]
254pub struct PromptsCapability {
255    /// 是否支持列表变更通知
256    #[serde(default)]
257    pub list_changed: Option<bool>,
258}
259
260/// 资源能力
261#[derive(Debug, Clone, Default, Serialize, Deserialize)]
262pub struct ResourcesCapability {
263    /// 是否支持订阅
264    #[serde(default)]
265    pub subscribe: Option<bool>,
266    /// 是否支持列表变更通知
267    #[serde(default)]
268    pub list_changed: Option<bool>,
269}
270
271/// 工具能力
272#[derive(Debug, Clone, Default, Serialize, Deserialize)]
273pub struct ToolsCapability {
274    /// 是否支持列表变更通知
275    #[serde(default)]
276    pub list_changed: Option<bool>,
277}
278
279// ========== 错误码 ==========
280
281/// 标准错误码
282pub mod error_codes {
283    pub const PARSE_ERROR: i32 = -32700;
284    pub const INVALID_REQUEST: i32 = -32600;
285    pub const METHOD_NOT_FOUND: i32 = -32601;
286    pub const INVALID_PARAMS: i32 = -32602;
287    pub const INTERNAL_ERROR: i32 = -32603;
288
289    // MCP 特定错误码
290    pub const SERVER_NOT_INITIALIZED: i32 = -32002;
291    pub const UNKNOWN_ERROR: i32 = -32001;
292}
293
294#[cfg(test)]
295mod tests {
296    use super::*;
297
298    #[test]
299    fn test_serialize_request() {
300        let request = McpRequest {
301            id: RequestId::Number(1),
302            method: "tools/list".to_string(),
303            params: None,
304        };
305
306        let json = serde_json::to_string(&request).unwrap();
307        assert!(json.contains("tools/list"));
308    }
309
310    #[test]
311    fn test_deserialize_response() {
312        let json = r#"{"id":1,"result":{"tools":[]}}"#;
313        let response: McpResponse = serde_json::from_str(json).unwrap();
314        assert_eq!(response.id, RequestId::Number(1));
315    }
316
317    #[test]
318    fn test_tool_definition() {
319        let tool = ToolDefinition {
320            name: "test_tool".to_string(),
321            description: Some("A test tool".to_string()),
322            input_schema: None,
323        };
324
325        let json = serde_json::to_string(&tool).unwrap();
326        assert!(json.contains("test_tool"));
327    }
328
329    #[test]
330    fn test_content_block_text() {
331        let block = ContentBlock::Text {
332            text: "Hello".to_string(),
333        };
334
335        let json = serde_json::to_string(&block).unwrap();
336        assert!(json.contains("text"));
337        assert!(json.contains("Hello"));
338    }
339}