Skip to main content

mocopr_core/protocol/
handler.rs

1//! Protocol message handlers
2
3use super::*;
4use crate::{Error, Result};
5use async_trait::async_trait;
6
7/// Trait for handling MCP protocol messages
8#[async_trait]
9pub trait MessageHandler: Send + Sync {
10    /// Handle an initialize request
11    async fn handle_initialize(&self, request: InitializeRequest) -> Result<InitializeResponse>;
12
13    /// Handle an initialized notification
14    async fn handle_initialized(&self, _notification: InitializedNotification) -> Result<()> {
15        Ok(())
16    }
17
18    /// Handle a ping request
19    async fn handle_ping(&self, request: PingRequest) -> Result<PingResponse> {
20        Ok(PingResponse {
21            message: request.message,
22        })
23    }
24
25    /// Handle resources/list request
26    async fn handle_resources_list(
27        &self,
28        _request: ResourcesListRequest,
29    ) -> Result<ResourcesListResponse> {
30        Err(Error::MethodNotFound("resources/list".to_string()))
31    }
32
33    /// Handle resources/read request
34    async fn handle_resources_read(
35        &self,
36        _request: ResourcesReadRequest,
37    ) -> Result<ResourcesReadResponse> {
38        Err(Error::MethodNotFound("resources/read".to_string()))
39    }
40
41    /// Handle resources/subscribe request
42    async fn handle_resources_subscribe(
43        &self,
44        _request: ResourcesSubscribeRequest,
45    ) -> Result<ResourcesSubscribeResponse> {
46        Err(Error::MethodNotFound("resources/subscribe".to_string()))
47    }
48
49    /// Handle resources/unsubscribe request
50    async fn handle_resources_unsubscribe(
51        &self,
52        _request: ResourcesUnsubscribeRequest,
53    ) -> Result<ResourcesUnsubscribeResponse> {
54        Err(Error::MethodNotFound("resources/unsubscribe".to_string()))
55    }
56
57    /// Handle tools/list request
58    async fn handle_tools_list(&self, _request: ToolsListRequest) -> Result<ToolsListResponse> {
59        Err(Error::MethodNotFound("tools/list".to_string()))
60    }
61
62    /// Handle tools/call request
63    async fn handle_tools_call(&self, _request: ToolsCallRequest) -> Result<ToolsCallResponse> {
64        Err(Error::MethodNotFound("tools/call".to_string()))
65    }
66
67    /// Handle prompts/list request
68    async fn handle_prompts_list(
69        &self,
70        _request: PromptsListRequest,
71    ) -> Result<PromptsListResponse> {
72        Err(Error::MethodNotFound("prompts/list".to_string()))
73    }
74
75    /// Handle prompts/get request
76    async fn handle_prompts_get(&self, _request: PromptsGetRequest) -> Result<PromptsGetResponse> {
77        Err(Error::MethodNotFound("prompts/get".to_string()))
78    }
79
80    /// Handle logging/setLevel request
81    async fn handle_logging_set_level(
82        &self,
83        _request: LoggingSetLevelRequest,
84    ) -> Result<LoggingSetLevelResponse> {
85        Ok(LoggingSetLevelResponse {
86            meta: ResponseMetadata { _meta: None },
87        })
88    }
89
90    /// Handle sampling/createMessage request (client capability)
91    async fn handle_sampling_create_message(
92        &self,
93        _request: CreateMessageRequest,
94    ) -> Result<CreateMessageResponse> {
95        Err(Error::MethodNotFound("sampling/createMessage".to_string()))
96    }
97
98    /// Handle roots/list request (client capability)
99    async fn handle_roots_list(&self, _request: RootsListRequest) -> Result<RootsListResponse> {
100        Err(Error::MethodNotFound("roots/list".to_string()))
101    }
102
103    /// Handle progress notification
104    async fn handle_progress_notification(
105        &self,
106        _notification: ProgressNotification,
107    ) -> Result<()> {
108        Ok(())
109    }
110
111    /// Handle logging notification
112    async fn handle_logging_notification(&self, _notification: LoggingNotification) -> Result<()> {
113        Ok(())
114    }
115
116    /// Handle cancelled notification
117    async fn handle_cancelled_notification(
118        &self,
119        _notification: CancelledNotification,
120    ) -> Result<()> {
121        Ok(())
122    }
123
124    /// Handle resources updated notification
125    async fn handle_resources_updated_notification(
126        &self,
127        _notification: ResourcesUpdatedNotification,
128    ) -> Result<()> {
129        Ok(())
130    }
131
132    /// Handle tools updated notification
133    async fn handle_tools_updated_notification(
134        &self,
135        _notification: ToolsListChangedNotification,
136    ) -> Result<()> {
137        Ok(())
138    }
139
140    /// Handle prompts updated notification
141    async fn handle_prompts_updated_notification(
142        &self,
143        _notification: PromptsListChangedNotification,
144    ) -> Result<()> {
145        Ok(())
146    }
147
148    /// Handle roots updated notification
149    async fn handle_roots_updated_notification(
150        &self,
151        _notification: RootsListChangedNotification,
152    ) -> Result<()> {
153        Ok(())
154    }
155
156    /// Handle custom/unknown requests
157    async fn handle_custom_request(
158        &self,
159        method: &str,
160        _params: Option<serde_json::Value>,
161    ) -> Result<serde_json::Value> {
162        Err(Error::MethodNotFound(method.to_string()))
163    }
164
165    /// Handle custom/unknown notifications
166    async fn handle_custom_notification(
167        &self,
168        method: &str,
169        _params: Option<serde_json::Value>,
170    ) -> Result<()> {
171        // By default, ignore unknown notifications
172        tracing::debug!("Received unknown notification: {}", method);
173        Ok(())
174    }
175}
176
177/// Default implementation of MessageHandler
178pub struct DefaultMessageHandler {
179    /// Information about the server implementation
180    pub server_info: Implementation,
181    /// Capabilities supported by the server
182    pub capabilities: ServerCapabilities,
183}
184
185impl DefaultMessageHandler {
186    /// Creates a new default message handler with the specified server info and capabilities
187    pub fn new(server_info: Implementation, capabilities: ServerCapabilities) -> Self {
188        Self {
189            server_info,
190            capabilities,
191        }
192    }
193}
194
195#[async_trait]
196impl MessageHandler for DefaultMessageHandler {
197    async fn handle_initialize(&self, request: InitializeRequest) -> Result<InitializeResponse> {
198        // Validate protocol version
199        if !Protocol::is_version_supported(&request.protocol_version) {
200            return Err(Error::InvalidRequest(format!(
201                "Unsupported protocol version: {}",
202                request.protocol_version
203            )));
204        }
205
206        Ok(InitializeResponse {
207            protocol_version: Protocol::latest_version().to_string(),
208            capabilities: self.capabilities.clone(),
209            server_info: self.server_info.clone(),
210            instructions: None,
211        })
212    }
213}
214
215/// Builder for creating message handlers with chained configuration
216pub struct MessageHandlerBuilder {
217    server_info: Option<Implementation>,
218    capabilities: ServerCapabilities,
219}
220
221impl MessageHandlerBuilder {
222    /// Creates a new message handler builder with default settings
223    pub fn new() -> Self {
224        Self {
225            server_info: None,
226            capabilities: ServerCapabilities::default(),
227        }
228    }
229
230    /// Sets the server information for the message handler
231    pub fn with_server_info(mut self, name: String, version: String) -> Self {
232        self.server_info = Some(Implementation { name, version });
233        self
234    }
235
236    /// Enables logging capabilities in the server
237    pub fn with_logging(mut self) -> Self {
238        self.capabilities = self.capabilities.with_logging();
239        self
240    }
241
242    /// Configures resource handling capabilities
243    ///
244    /// * `list_changed` - Whether the server supports resource list change notifications
245    /// * `subscribe` - Whether the server supports resource subscription
246    pub fn with_resources(mut self, list_changed: bool, subscribe: bool) -> Self {
247        self.capabilities = self.capabilities.with_resources(list_changed, subscribe);
248        self
249    }
250
251    /// Configures tool capabilities
252    ///
253    /// * `list_changed` - Whether the server supports tool list change notifications
254    pub fn with_tools(mut self, list_changed: bool) -> Self {
255        self.capabilities = self.capabilities.with_tools(list_changed);
256        self
257    }
258
259    /// Configures prompt capabilities
260    ///
261    /// * `list_changed` - Whether the server supports prompt list change notifications
262    pub fn with_prompts(mut self, list_changed: bool) -> Self {
263        self.capabilities = self.capabilities.with_prompts(list_changed);
264        self
265    }
266
267    /// Builds the message handler with the configured settings
268    pub fn build(self) -> Result<DefaultMessageHandler> {
269        let server_info = self
270            .server_info
271            .ok_or_else(|| Error::InvalidRequest("Server info is required".to_string()))?;
272
273        Ok(DefaultMessageHandler::new(server_info, self.capabilities))
274    }
275}
276
277impl Default for MessageHandlerBuilder {
278    fn default() -> Self {
279        Self::new()
280    }
281}