agent_client_protocol/mcp_server/connect.rs
1use std::sync::Arc;
2
3use crate::{
4 DynConnectTo,
5 mcp_server::McpConnectionTo,
6 role::{self, Role},
7};
8
9/// Trait for types that can create MCP server connections.
10///
11/// Implement this trait to create custom MCP servers. Each call to [`connect`](Self::connect)
12/// should return a new [`ConnectTo`](crate::ConnectTo) that serves MCP requests for a single
13/// connection.
14///
15/// # Example
16///
17/// ```rust,ignore
18/// use agent_client_protocol::mcp_server::{McpServerConnect, McpConnectionTo};
19/// use agent_client_protocol::{DynConnectTo, role::Role};
20///
21/// struct MyMcpServer {
22/// name: String,
23/// }
24///
25/// impl<R: Role> McpServerConnect<R> for MyMcpServer {
26/// fn name(&self) -> String {
27/// self.name.clone()
28/// }
29///
30/// fn connect(&self, cx: McpConnectionTo<R>) -> DynConnectTo<role::mcp::Client> {
31/// // Create and return a component that handles MCP requests
32/// DynConnectTo::new(MyMcpComponent::new(cx))
33/// }
34/// }
35/// ```
36pub trait McpServerConnect<Counterpart: Role>: Send + Sync + 'static {
37 /// The name of the MCP server, used in ACP declarations when attached.
38 fn name(&self) -> String;
39
40 /// Create a component to service a new MCP connection.
41 ///
42 /// This is called each time an MCP client connects to this server. The returned
43 /// component will handle MCP protocol messages for that connection.
44 ///
45 /// Any communication primitives shared with the server's
46 /// [`RunWithConnectionTo`](crate::RunWithConnectionTo) task must be created
47 /// before the [`McpServer`](super::McpServer) is returned. The runner has no
48 /// separate readiness protocol and may continue asynchronous initialization
49 /// while connections and their messages are queued.
50 ///
51 /// [`McpConnectionTo`] distinguishes a direct MCP connection from an
52 /// ACP-attached connection and provides the corresponding host connection.
53 fn connect(&self, cx: McpConnectionTo<Counterpart>) -> DynConnectTo<role::mcp::Client>;
54}
55
56impl<Counterpart: Role, S: ?Sized + McpServerConnect<Counterpart>> McpServerConnect<Counterpart>
57 for Box<S>
58{
59 fn name(&self) -> String {
60 S::name(self)
61 }
62
63 fn connect(&self, cx: McpConnectionTo<Counterpart>) -> DynConnectTo<role::mcp::Client> {
64 S::connect(self, cx)
65 }
66}
67
68impl<Counterpart: Role, S: ?Sized + McpServerConnect<Counterpart>> McpServerConnect<Counterpart>
69 for Arc<S>
70{
71 fn name(&self) -> String {
72 S::name(self)
73 }
74
75 fn connect(&self, cx: McpConnectionTo<Counterpart>) -> DynConnectTo<role::mcp::Client> {
76 S::connect(self, cx)
77 }
78}