Skip to main content

soma_gateway/gateway/manager/
mcp_projection.rs

1//! Projection of gateway routes into concrete `rmcp::model` types.
2//!
3//! [`super::mcp_routes`] returns loose route/descriptor structs — reused
4//! directly from `soma-mcp-proxy` (`GatewayToolRoute` etc. are type aliases
5//! for `soma_mcp_proxy::Mcp*Route`). A caller that wants to hand these routes
6//! to its own inbound MCP clients — rather than just tracking route names —
7//! needs real `rmcp::model` objects. `soma-mcp-proxy` already owns that exact
8//! conversion (`rmcp_tool_from_route` and friends, itself built on
9//! `soma-mcp-server`'s generic descriptor projection), so this module
10//! delegates to it instead of re-deriving the conversion, keeping a single
11//! owner for "route struct -> rmcp::model type" and keeping the gateway off
12//! `rmcp` server-side types.
13
14use rmcp::model::{Prompt, Resource, Tool};
15use soma_mcp_proxy::{rmcp_prompt_from_route, rmcp_resource_from_route, rmcp_tool_from_route};
16
17use super::{GatewayManager, GatewayManagerError};
18
19impl GatewayManager {
20    pub async fn rmcp_tool_routes(&self) -> Result<Vec<Tool>, GatewayManagerError> {
21        self.rmcp_tool_routes_for_subject(None).await
22    }
23
24    pub async fn rmcp_tool_routes_for_subject(
25        &self,
26        subject: Option<&str>,
27    ) -> Result<Vec<Tool>, GatewayManagerError> {
28        Ok(self
29            .tool_routes_for_subject(subject)
30            .await?
31            .iter()
32            .map(rmcp_tool_from_route)
33            .collect())
34    }
35
36    pub async fn rmcp_resource_routes(&self) -> Result<Vec<Resource>, GatewayManagerError> {
37        self.rmcp_resource_routes_for_subject(None).await
38    }
39
40    pub async fn rmcp_resource_routes_for_subject(
41        &self,
42        subject: Option<&str>,
43    ) -> Result<Vec<Resource>, GatewayManagerError> {
44        Ok(self
45            .resource_routes_for_subject(subject)
46            .await?
47            .iter()
48            .map(rmcp_resource_from_route)
49            .collect())
50    }
51
52    pub async fn rmcp_prompt_routes(&self) -> Result<Vec<Prompt>, GatewayManagerError> {
53        self.rmcp_prompt_routes_for_subject(None).await
54    }
55
56    pub async fn rmcp_prompt_routes_for_subject(
57        &self,
58        subject: Option<&str>,
59    ) -> Result<Vec<Prompt>, GatewayManagerError> {
60        Ok(self
61            .prompt_routes_for_subject(subject)
62            .await?
63            .iter()
64            .map(rmcp_prompt_from_route)
65            .collect())
66    }
67}
68
69#[cfg(test)]
70#[path = "mcp_projection_tests.rs"]
71mod tests;