Skip to main content

yapi_core/mcp/
transport.rs

1//! The two MCP transports behind one type.
2
3use serde_json::Value;
4
5use super::http::HttpTransport;
6use super::jsonrpc::McpError;
7use super::stdio::StdioTransport;
8
9/// The largest message a transport accepts.
10pub const MAX_MESSAGE_BYTES: usize = 16 * 1024 * 1024;
11
12/// What a transport delivers to its client.
13#[derive(Debug)]
14pub enum Event {
15    /// A valid JSON-RPC message.
16    Message(Value),
17    /// A problem that does not end the connection, such as a malformed line.
18    Error(String),
19    /// The connection ended.
20    Closed,
21}
22
23/// Where a transport delivers its events.
24pub type Events = tokio::sync::mpsc::UnboundedSender<Event>;
25
26/// A connection to a server.
27pub enum Transport {
28    /// A server process on stdin and stdout.
29    Stdio(Box<StdioTransport>),
30    /// A streamable HTTP endpoint.
31    Http(HttpTransport),
32}
33
34impl Transport {
35    /// Opens the connection.
36    pub async fn start(&self, events: Events) -> Result<(), McpError> {
37        match self {
38            Transport::Stdio(stdio) => stdio.start(events).await,
39            Transport::Http(http) => http.start(events),
40        }
41    }
42
43    /// Sends one message.
44    pub async fn send(&self, message: &Value) -> Result<(), McpError> {
45        match self {
46            Transport::Stdio(stdio) => stdio.send(message).await,
47            Transport::Http(http) => http.send(message).await,
48        }
49    }
50
51    /// Closes the connection.
52    pub async fn close(&self) {
53        match self {
54            Transport::Stdio(stdio) => stdio.close().await,
55            Transport::Http(http) => http.close().await,
56        }
57    }
58
59    /// Records the negotiated protocol version, which HTTP sends as a header.
60    pub fn set_protocol_version(&self, version: &str) {
61        if let Transport::Http(http) = self {
62            http.set_protocol_version(version);
63        }
64    }
65
66    /// The end of a stdio server's stderr.
67    pub fn stderr(&self) -> Option<String> {
68        match self {
69            Transport::Stdio(stdio) => Some(stdio.stderr()),
70            Transport::Http(_) => None,
71        }
72    }
73}