mcp_ectors/messages/mcp/
mcp_messages.rs1use actix::prelude::*;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4use mcp_spec::protocol::JsonRpcResponse;
5use mcp_spec::protocol::JsonRpcRequest;
6pub const JSONRPC_VERSION: &str = "2.0";
7
8#[derive(Message)]
10#[rtype(result = "Result<JsonRpcResponse, ()>")]
11pub enum JsonRpcRequestMessage {
12 Initialize(InitializeRequest),
13 Ping(PingRequest),
14 Complete(CompleteRequest),
15 ListRoots(ListRootsRequest),
16 ListPrompts(ListPromptsRequest),
17 GetPrompt(GetPromptRequest),
18 ListResources(ListResourcesRequest),
19 ListResourceTemplates(ListResourceTemplatesRequest),
20 ReadResource(ReadResourceRequest),
21 Subscribe(SubscribeRequest),
22 Unsubscribe(UnsubscribeRequest),
23 CallTool(CallToolRequest),
24 ListTools(ListToolsRequest),
25 SetLevel(SetLevelRequest),
26 CreateMessage(CreateMessageRequest),
27}
28
29#[derive(Message)]
31#[rtype(result = "()")]
32pub enum JsonRpcNotificationMessage {
33 Initialized(InitializedNotification),
34 Cancelled(CancelledNotification),
35 Progress(ProgressNotification),
36 RootsListChanged(RootsListChangedNotification),
37 LoggingMessage(LoggingMessageNotification),
38 ResourceListChanged(ResourceListChangedNotification),
39 ResourceUpdated(ResourceUpdatedNotification),
40 ToolListChanged(ToolListChangedNotification),
41 PromptListChanged(PromptListChangedNotification),
42}
43
44
45macro_rules! create_request {
48 ($struct_name:ident, $method:expr) => {
49 #[derive(Message, Debug, Clone, Serialize, Deserialize,)]
50 #[rtype(result = "Result<JsonRpcResponse, ()>")]
51 pub struct $struct_name {
52 pub request: JsonRpcRequest,
53 }
54
55 impl $struct_name {
56 pub const METHOD: &'static str = $method;
57 }
58 };
59}
60
61create_request!(InitializeRequest, "initialize");
63create_request!(InitializedNotificationRequest, "notifications/initialized");
64create_request!(PingRequest, "ping");
65create_request!(CompleteRequest, "completion/complete");
66create_request!(ListRootsRequest, "roots/list");
67create_request!(ListPromptsRequest, "prompts/list");
68create_request!(GetPromptRequest, "prompts/get");
69create_request!(ListResourcesRequest, "resources/list");
70create_request!(ListResourceTemplatesRequest, "resources/templates/list");
71create_request!(ReadResourceRequest, "resources/read");
72create_request!(SubscribeRequest, "resources/subscribe");
73create_request!(UnsubscribeRequest, "resources/unsubscribe");
74create_request!(CallToolRequest, "tools/call");
75create_request!(ListToolsRequest, "tools/list");
76create_request!(SetLevelRequest, "logging/setLevel");
77create_request!(CreateMessageRequest, "sampling/createMessage");
78
79macro_rules! create_notification {
82 ($struct_name:ident, $method:expr) => {
83 #[derive(Message, Debug, Clone, Serialize, Deserialize,)]
84 #[rtype(result = "()")]
85 pub struct $struct_name {
86 pub params: Option<Value>,
87 }
88
89 impl $struct_name {
90 pub const METHOD: &'static str = $method;
91 }
92 };
93}
94
95create_notification!(InitializedNotification, "notifications/initialized");
97create_notification!(CancelledNotification, "notifications/cancelled");
98create_notification!(ProgressNotification, "notifications/progress");
99create_notification!(RootsListChangedNotification, "notifications/roots/list_changed");
100create_notification!(LoggingMessageNotification, "notifications/message");
101create_notification!(ResourceListChangedNotification, "notifications/resources/list_changed");
102create_notification!(ResourceUpdatedNotification, "notifications/resources/updated");
103create_notification!(ToolListChangedNotification, "notifications/tools/list_changed");
104create_notification!(PromptListChangedNotification, "notifications/prompts/list_changed");
105
106#[derive(Debug, Clone)]
110pub enum McpMessage {
111 Request(JsonRpcRequest),
112 Response(JsonRpcResponse),
113 Notification(String, Option<Value>), }
115
116impl McpMessage {
117 pub fn from_json(value: Value) -> Result<Self, String> {
119 if let Some(jsonrpc) = value.get("jsonrpc") {
120 if jsonrpc != JSONRPC_VERSION {
121 return Err("Invalid JSON-RPC version".to_string());
122 }
123 }
124
125 if let Some(method) = value.get("method").and_then(|v| v.as_str()) {
126 if value.get("id").is_some() {
127 serde_json::from_value::<JsonRpcRequest>(value.clone())
129 .map(McpMessage::Request)
130 .map_err(|e| e.to_string())
131 } else {
132 let params = value.get("params").cloned();
134 Ok(McpMessage::Notification(method.to_string(), params))
135 }
136 } else if value.get("id").is_some() {
137 serde_json::from_value::<JsonRpcResponse>(value.clone())
139 .map(McpMessage::Response)
140 .map_err(|e| e.to_string())
141 } else {
142 Err("Unknown MCP message type".to_string())
143 }
144 }
145}