Skip to content

Commit 27d9ccb

Browse files
committed
refactor: update examples and tests to use new MCP server API
- Update with_mcp_server example to use McpServerExt::from_rmcp - Update test_session_id_in_mcp_tools to use McpServer::builder - Update mcp_integration proxy test for new API - Refactor sacp-rmcp to use McpServerExt extension trait
1 parent fcec6af commit 27d9ccb

5 files changed

Lines changed: 64 additions & 68 deletions

File tree

src/sacp-conductor/tests/mcp_integration/proxy.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use sacp::Component;
44
use sacp::ProxyToConductor;
5-
use sacp::mcp_server::{McpServerConnect, McpServiceRegistry};
5+
use sacp::mcp_server::McpServer;
66
use schemars::JsonSchema;
77
use serde::{Deserialize, Serialize};
88

@@ -24,7 +24,7 @@ struct ProxyComponent;
2424

2525
impl Component for ProxyComponent {
2626
async fn serve(self, client: impl Component) -> Result<(), sacp::Error> {
27-
let test_server = McpServerConnect::new()
27+
let test_server = McpServer::builder("test")
2828
.instructions("A simple test MCP server with an echo tool")
2929
.tool_fn(
3030
"echo",
@@ -35,11 +35,12 @@ impl Component for ProxyComponent {
3535
})
3636
},
3737
|f, args, cx| Box::pin(f(args, cx)),
38-
);
38+
)
39+
.build();
3940

4041
ProxyToConductor::builder()
4142
.name("proxy-component")
42-
.provide_mcp(McpServiceRegistry::default().with_mcp_server("test", test_server)?)
43+
.with_mcp_server(test_server)
4344
.serve(client)
4445
.await
4546
}

src/sacp-conductor/tests/test_session_id_in_mcp_tools.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
1111
use sacp::Component;
1212
use sacp::ProxyToConductor;
13-
use sacp::mcp_server::{McpServerConnect, McpServiceRegistry};
13+
use sacp::mcp_server::McpServer;
1414
use sacp_conductor::Conductor;
1515
use schemars::JsonSchema;
1616
use serde::{Deserialize, Serialize};
@@ -30,7 +30,7 @@ struct EchoOutput {
3030
/// Create a proxy that provides an MCP server with a session_id echo tool
3131
fn create_echo_proxy() -> Result<sacp::DynComponent, sacp::Error> {
3232
// Create MCP server with an echo tool that returns the session_id
33-
let mcp_server = McpServerConnect::new()
33+
let mcp_server = McpServer::builder("echo_server".to_string())
3434
.instructions("Test MCP server with session_id echo tool")
3535
.tool_fn(
3636
"echo",
@@ -41,24 +41,22 @@ fn create_echo_proxy() -> Result<sacp::DynComponent, sacp::Error> {
4141
})
4242
},
4343
|f, args, cx| Box::pin(f(args, cx)),
44-
);
45-
46-
// Create registry with the server
47-
let registry = McpServiceRegistry::default().with_mcp_server("echo_server", mcp_server)?;
44+
)
45+
.build();
4846

4947
// Create proxy component
50-
Ok(sacp::DynComponent::new(ProxyWithEchoServer { registry }))
48+
Ok(sacp::DynComponent::new(ProxyWithEchoServer { mcp_server }))
5149
}
5250

5351
struct ProxyWithEchoServer {
54-
registry: McpServiceRegistry<ProxyToConductor>,
52+
mcp_server: McpServer<ProxyToConductor>,
5553
}
5654

5755
impl Component for ProxyWithEchoServer {
5856
async fn serve(self, client: impl Component) -> Result<(), sacp::Error> {
5957
ProxyToConductor::builder()
6058
.name("echo-proxy")
61-
.provide_mcp(self.registry)
59+
.with_handler(self.mcp_server)
6260
.serve(client)
6361
.await
6462
}

src/sacp-rmcp/examples/with_mcp_server.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use rmcp::{
1515
tool, tool_handler, tool_router,
1616
};
1717
use sacp::ProxyToConductor;
18-
use sacp::mcp_server::McpServiceRegistry;
19-
use sacp_rmcp::McpServiceRegistryRmcpExt;
18+
use sacp::mcp_server::McpServer;
19+
use sacp_rmcp::McpServerExt;
2020
use serde::{Deserialize, Serialize};
2121
use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
2222

@@ -84,14 +84,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
8484

8585
tracing::info!("MCP server proxy starting");
8686

87+
// Create an MCP server from the rmcp service
88+
let mcp_server = McpServer::from_rmcp("example", ExampleMcpServer::new);
89+
8790
// Set up the proxy connection with our MCP server
8891
// ProxyToConductor already has proxy behavior built into its default_message_handler
8992
ProxyToConductor::builder()
9093
.name("mcp-server-proxy")
91-
// Register the MCP server named "example"
92-
.provide_mcp(
93-
McpServiceRegistry::default().with_rmcp_server("example", ExampleMcpServer::new)?,
94-
)
94+
// Register the MCP server as a handler
95+
.with_handler(mcp_server)
9596
// Start serving
9697
.connect_to(sacp::ByteStreams::new(
9798
tokio::io::stdout().compat_write(),

src/sacp-rmcp/src/lib.rs

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
//!
66
//! ## Usage
77
//!
8-
//! Create an MCP server from an rmcp service:
8+
//! Create an MCP server from an rmcp service using the extension trait:
99
//!
1010
//! ```ignore
1111
//! use sacp::mcp_server::McpServer;
12-
//! use sacp_rmcp::RmcpServer;
12+
//! use sacp_rmcp::McpServerExt;
1313
//!
14-
//! let server = McpServer::new(RmcpServer::new("my-server", || MyRmcpService::new()));
14+
//! let server = McpServer::from_rmcp("my-server", MyRmcpService::new);
1515
//!
1616
//! // Use as a handler
1717
//! ProxyToConductor::builder()
@@ -21,60 +21,56 @@
2121
//! ```
2222
2323
use rmcp::ServiceExt;
24-
use sacp::mcp_server::{McpContext, McpServerConnect};
25-
use sacp::{ByteStreams, Component, DynComponent, JrRole};
24+
use sacp::mcp_server::{McpContext, McpServer, McpServerConnect};
25+
use sacp::{Agent, ByteStreams, Component, DynComponent, HasEndpoint, JrRole};
2626
use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
2727

28-
/// Wrapper that implements [`McpServerConnect`] for rmcp services.
29-
///
30-
/// Use this to integrate existing rmcp-based MCP servers with the SACP framework.
31-
///
32-
/// # Example
33-
///
34-
/// ```ignore
35-
/// use sacp::mcp_server::McpServer;
36-
/// use sacp_rmcp::RmcpServer;
37-
///
38-
/// // Create an MCP server from an rmcp service factory
39-
/// let server = McpServer::new(RmcpServer::new("my-server", || MyRmcpService::new()));
40-
/// ```
41-
pub struct RmcpServer<F> {
42-
name: String,
43-
make_service: F,
44-
}
45-
46-
impl<F> RmcpServer<F> {
47-
/// Create a new rmcp server wrapper.
28+
pub trait McpServerExt<Role: JrRole>
29+
where
30+
Role: HasEndpoint<Agent>,
31+
{
32+
/// Create an MCP server from something that implements the [`McpServerConnect`] trait.
4833
///
49-
/// # Parameters
34+
/// # See also
5035
///
51-
/// - `name`: The name of the server (used in session responses).
52-
/// - `make_service`: A function that creates a new rmcp service instance.
53-
/// This is called for each new connection.
54-
pub fn new(name: impl ToString, make_service: F) -> Self {
55-
Self {
56-
name: name.to_string(),
57-
make_service,
36+
/// See [`Self::builder`] to construct MCP servers from Rust code.
37+
fn from_rmcp<S>(
38+
name: impl ToString,
39+
new_fn: impl Fn() -> S + Send + Sync + 'static,
40+
) -> McpServer<Role>
41+
where
42+
S: rmcp::Service<rmcp::RoleServer>,
43+
{
44+
struct RmcpServer<F> {
45+
name: String,
46+
new_fn: F,
5847
}
59-
}
60-
}
6148

62-
impl<Role, F, S> McpServerConnect<Role> for RmcpServer<F>
63-
where
64-
Role: JrRole,
65-
F: Fn() -> S + Send + Sync + 'static,
66-
S: rmcp::Service<rmcp::RoleServer>,
67-
{
68-
fn name(&self) -> String {
69-
self.name.clone()
70-
}
49+
impl<Role, F, S> McpServerConnect<Role> for RmcpServer<F>
50+
where
51+
Role: JrRole,
52+
F: Fn() -> S + Send + Sync + 'static,
53+
S: rmcp::Service<rmcp::RoleServer>,
54+
{
55+
fn name(&self) -> String {
56+
self.name.clone()
57+
}
7158

72-
fn connect(&self, _cx: McpContext<Role>) -> DynComponent {
73-
let service = (self.make_service)();
74-
DynComponent::new(RmcpServerComponent { service })
59+
fn connect(&self, _cx: McpContext<Role>) -> DynComponent {
60+
let service = (self.new_fn)();
61+
DynComponent::new(RmcpServerComponent { service })
62+
}
63+
}
64+
65+
McpServer::new(RmcpServer {
66+
name: name.to_string(),
67+
new_fn,
68+
})
7569
}
7670
}
7771

72+
impl<Role: JrRole> McpServerExt<Role> for McpServer<Role> where Role: HasEndpoint<Agent> {}
73+
7874
/// Component wrapper for rmcp services.
7975
struct RmcpServerComponent<S> {
8076
service: S,

src/sacp/src/mcp_server/server.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ where
4444
Role: HasEndpoint<Agent>,
4545
{
4646
/// Create an empty server with no content.
47-
pub fn builder(name: String) -> McpServerBuilder<Role> {
48-
McpServerBuilder::new(name)
47+
pub fn builder(name: impl ToString) -> McpServerBuilder<Role> {
48+
McpServerBuilder::new(name.to_string())
4949
}
5050

5151
/// Create an MCP server from something that implements the [`McpServerConnect`] trait.

0 commit comments

Comments
 (0)