mcp_core/transport/
mod.rs

1//! Transport layer for the MCP protocol
2//! handles the serialization and deserialization of message
3//! handles send and receive of messages
4//! defines transport layer types
5
6use std::{future::Future, pin::Pin};
7
8use anyhow::Result;
9use async_trait::async_trait;
10use serde::{Deserialize, Serialize};
11
12mod client;
13pub use client::*;
14
15mod server;
16pub use server::*;
17
18use crate::protocol::RequestOptions;
19
20/// only JsonRpcMessage is supported for now
21/// https://spec.modelcontextprotocol.io/specification/basic/messages/
22pub type Message = JsonRpcMessage;
23
24#[async_trait()]
25pub trait Transport: Send + Sync + 'static {
26    /// open the transport
27    async fn open(&self) -> Result<()>;
28
29    /// Close the transport
30    async fn close(&self) -> Result<()>;
31
32    async fn poll_message(&self) -> Result<Option<Message>>;
33
34    fn request(
35        &self,
36        method: &str,
37        params: Option<serde_json::Value>,
38        options: RequestOptions,
39    ) -> Pin<Box<dyn Future<Output = Result<JsonRpcResponse>> + Send + Sync>>;
40
41    async fn send_notification(
42        &self,
43        method: &str,
44        params: Option<serde_json::Value>,
45    ) -> Result<()>;
46
47    async fn send_response(
48        &self,
49        id: RequestId,
50        result: Option<serde_json::Value>,
51        error: Option<JsonRpcError>,
52    ) -> Result<()>;
53}
54
55/// Request ID type
56pub type RequestId = u64;
57/// JSON RPC version type
58#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
59#[serde(transparent)]
60pub struct JsonRpcVersion(String);
61
62impl Default for JsonRpcVersion {
63    fn default() -> Self {
64        JsonRpcVersion("2.0".to_owned())
65    }
66}
67
68impl JsonRpcVersion {
69    pub fn as_str(&self) -> &str {
70        &self.0
71    }
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
75#[serde(deny_unknown_fields)]
76#[serde(untagged)]
77pub enum JsonRpcMessage {
78    Response(JsonRpcResponse),
79    Request(JsonRpcRequest),
80    Notification(JsonRpcNotification),
81}
82
83// json rpc types
84#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
85#[serde(deny_unknown_fields)]
86pub struct JsonRpcRequest {
87    pub id: RequestId,
88    pub method: String,
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub params: Option<serde_json::Value>,
91    pub jsonrpc: JsonRpcVersion,
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
95#[serde(rename_all = "camelCase")]
96#[serde(deny_unknown_fields)]
97#[serde(default)]
98pub struct JsonRpcNotification {
99    pub method: String,
100    #[serde(skip_serializing_if = "Option::is_none")]
101    pub params: Option<serde_json::Value>,
102    pub jsonrpc: JsonRpcVersion,
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
106#[serde(deny_unknown_fields)]
107#[serde(rename_all = "camelCase")]
108#[serde(default)]
109pub struct JsonRpcResponse {
110    /// The request ID this response corresponds to
111    pub id: RequestId,
112    /// The result of the request, if successful
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub result: Option<serde_json::Value>,
115    /// The error, if the request failed
116    #[serde(skip_serializing_if = "Option::is_none")]
117    pub error: Option<JsonRpcError>,
118    /// The JSON-RPC version
119    pub jsonrpc: JsonRpcVersion,
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
123#[serde(rename_all = "camelCase")]
124#[serde(default)]
125pub struct JsonRpcError {
126    /// Error code
127    pub code: i32,
128    /// Error message
129    pub message: String,
130    /// Optional additional error data
131    #[serde(skip_serializing_if = "Option::is_none")]
132    pub data: Option<serde_json::Value>,
133}