Skip to main content

rmcp_server_builder/
providers.rs

1//! Provider traits for individual MCP capabilities.
2//!
3//! Each trait represents a single capability group that can be composed into a server.
4//! Blanket implementations ensure that any `ServerHandler` automatically implements
5//! all provider traits.
6
7use rmcp::{
8    handler::server::ServerHandler,
9    model::{
10        CallToolRequestParams, CallToolResult, CompleteRequestParams, CompleteResult, ErrorData,
11        GetPromptRequestParams, GetPromptResult, ListPromptsResult, ListResourceTemplatesResult,
12        ListResourcesResult, ListToolsResult, PaginatedRequestParams, ReadResourceRequestParams,
13        ReadResourceResult, ServerCapabilities, ServerInfo, SetLevelRequestParams,
14        SubscribeRequestParams, UnsubscribeRequestParams,
15    },
16    service::{RequestContext, RoleServer},
17};
18
19/// Provider for tools capability.
20///
21/// Implement this trait to provide tools to a composed server.
22pub trait ToolsProvider: Send + Sync + 'static {
23    /// List available tools.
24    fn list_tools(
25        &self,
26        request: Option<PaginatedRequestParams>,
27        context: RequestContext<RoleServer>,
28    ) -> impl Future<Output = Result<ListToolsResult, ErrorData>> + Send;
29
30    /// Execute a tool.
31    fn call_tool(
32        &self,
33        request: CallToolRequestParams,
34        context: RequestContext<RoleServer>,
35    ) -> impl Future<Output = Result<CallToolResult, ErrorData>> + Send;
36}
37
38/// Provider for prompts capability.
39///
40/// Implement this trait to provide prompts to a composed server.
41pub trait PromptsProvider: Send + Sync + 'static {
42    /// List available prompts.
43    fn list_prompts(
44        &self,
45        request: Option<PaginatedRequestParams>,
46        context: RequestContext<RoleServer>,
47    ) -> impl Future<Output = Result<ListPromptsResult, ErrorData>> + Send;
48
49    /// Get a specific prompt.
50    fn get_prompt(
51        &self,
52        request: GetPromptRequestParams,
53        context: RequestContext<RoleServer>,
54    ) -> impl Future<Output = Result<GetPromptResult, ErrorData>> + Send;
55}
56
57/// Provider for resources capability.
58///
59/// Implement this trait to provide resources to a composed server.
60pub trait ResourcesProvider: Send + Sync + 'static {
61    /// List available resources.
62    fn list_resources(
63        &self,
64        request: Option<PaginatedRequestParams>,
65        context: RequestContext<RoleServer>,
66    ) -> impl Future<Output = Result<ListResourcesResult, ErrorData>> + Send;
67
68    /// List resource templates.
69    fn list_resource_templates(
70        &self,
71        request: Option<PaginatedRequestParams>,
72        context: RequestContext<RoleServer>,
73    ) -> impl Future<Output = Result<ListResourceTemplatesResult, ErrorData>> + Send;
74
75    /// Read a resource.
76    fn read_resource(
77        &self,
78        request: ReadResourceRequestParams,
79        context: RequestContext<RoleServer>,
80    ) -> impl Future<Output = Result<ReadResourceResult, ErrorData>> + Send;
81
82    /// Subscribe to resource updates.
83    fn subscribe(
84        &self,
85        request: SubscribeRequestParams,
86        context: RequestContext<RoleServer>,
87    ) -> impl Future<Output = Result<(), ErrorData>> + Send;
88
89    /// Unsubscribe from resource updates.
90    fn unsubscribe(
91        &self,
92        request: UnsubscribeRequestParams,
93        context: RequestContext<RoleServer>,
94    ) -> impl Future<Output = Result<(), ErrorData>> + Send;
95}
96
97/// Provider for completion capability.
98///
99/// Implement this trait to provide completion suggestions to a composed server.
100pub trait CompletionProvider: Send + Sync + 'static {
101    /// Provide completion suggestions.
102    fn complete(
103        &self,
104        request: CompleteRequestParams,
105        context: RequestContext<RoleServer>,
106    ) -> impl Future<Output = Result<CompleteResult, ErrorData>> + Send;
107}
108
109/// Provider for logging capability.
110///
111/// Implement this trait to handle logging level changes.
112pub trait LoggingProvider: Send + Sync + 'static {
113    /// Set the logging level.
114    fn set_level(
115        &self,
116        request: SetLevelRequestParams,
117        context: RequestContext<RoleServer>,
118    ) -> impl Future<Output = Result<(), ErrorData>> + Send;
119}
120
121/// Provider for server info and initialization.
122///
123/// This is required for any composed server.
124pub trait ServerInfoProvider: Send + Sync + 'static {
125    /// Get the server info and capabilities.
126    fn get_info(&self) -> ServerInfo;
127
128    /// Get the base capabilities (before provider-based adjustments).
129    fn capabilities(&self) -> ServerCapabilities {
130        self.get_info().capabilities.clone()
131    }
132}
133
134// =============================================================================
135// Blanket implementations: ServerHandler -> Provider traits
136// =============================================================================
137
138impl<T: ServerHandler> ToolsProvider for T {
139    async fn list_tools(
140        &self,
141        request: Option<PaginatedRequestParams>,
142        context: RequestContext<RoleServer>,
143    ) -> Result<ListToolsResult, ErrorData> {
144        ServerHandler::list_tools(self, request, context).await
145    }
146
147    async fn call_tool(
148        &self,
149        request: CallToolRequestParams,
150        context: RequestContext<RoleServer>,
151    ) -> Result<CallToolResult, ErrorData> {
152        ServerHandler::call_tool(self, request, context).await
153    }
154}
155
156impl<T: ServerHandler> PromptsProvider for T {
157    async fn list_prompts(
158        &self,
159        request: Option<PaginatedRequestParams>,
160        context: RequestContext<RoleServer>,
161    ) -> Result<ListPromptsResult, ErrorData> {
162        ServerHandler::list_prompts(self, request, context).await
163    }
164
165    async fn get_prompt(
166        &self,
167        request: GetPromptRequestParams,
168        context: RequestContext<RoleServer>,
169    ) -> Result<GetPromptResult, ErrorData> {
170        ServerHandler::get_prompt(self, request, context).await
171    }
172}
173
174impl<T: ServerHandler> ResourcesProvider for T {
175    async fn list_resources(
176        &self,
177        request: Option<PaginatedRequestParams>,
178        context: RequestContext<RoleServer>,
179    ) -> Result<ListResourcesResult, ErrorData> {
180        ServerHandler::list_resources(self, request, context).await
181    }
182
183    async fn list_resource_templates(
184        &self,
185        request: Option<PaginatedRequestParams>,
186        context: RequestContext<RoleServer>,
187    ) -> Result<ListResourceTemplatesResult, ErrorData> {
188        ServerHandler::list_resource_templates(self, request, context).await
189    }
190
191    async fn read_resource(
192        &self,
193        request: ReadResourceRequestParams,
194        context: RequestContext<RoleServer>,
195    ) -> Result<ReadResourceResult, ErrorData> {
196        ServerHandler::read_resource(self, request, context).await
197    }
198
199    async fn subscribe(
200        &self,
201        request: SubscribeRequestParams,
202        context: RequestContext<RoleServer>,
203    ) -> Result<(), ErrorData> {
204        ServerHandler::subscribe(self, request, context).await
205    }
206
207    async fn unsubscribe(
208        &self,
209        request: UnsubscribeRequestParams,
210        context: RequestContext<RoleServer>,
211    ) -> Result<(), ErrorData> {
212        ServerHandler::unsubscribe(self, request, context).await
213    }
214}
215
216impl<T: ServerHandler> CompletionProvider for T {
217    async fn complete(
218        &self,
219        request: CompleteRequestParams,
220        context: RequestContext<RoleServer>,
221    ) -> Result<CompleteResult, ErrorData> {
222        ServerHandler::complete(self, request, context).await
223    }
224}
225
226impl<T: ServerHandler> LoggingProvider for T {
227    async fn set_level(
228        &self,
229        request: SetLevelRequestParams,
230        context: RequestContext<RoleServer>,
231    ) -> Result<(), ErrorData> {
232        ServerHandler::set_level(self, request, context).await
233    }
234}
235
236// Note: We intentionally do NOT provide a blanket impl of ServerInfoProvider for ServerHandler
237// because it would conflict with our explicit impl for Implementation.
238// Users must explicitly implement ServerInfoProvider or use Implementation/SimpleInfo.