techne_mcp/
lib.rs

1pub mod client;
2pub mod server;
3
4pub use client::Client;
5pub use server::Server;
6pub use skema::Schema;
7
8pub use bytes::Bytes;
9pub use serde::de::IgnoredAny as Ignored;
10pub use serde_json::{Map, Value, json};
11
12use serde::de::DeserializeOwned;
13use serde::{Deserialize, Serialize};
14
15use std::io;
16
17pub const VERSION: &str = "2025-06-18";
18pub const JSONRPC: &str = "2.0";
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
21#[serde(untagged)]
22pub enum Message<R, N, T = Value> {
23    Request(Request<R>),
24    Notification(Notification<N>),
25    Response(Response<T>),
26    Error(Error),
27}
28
29impl<R, N, T> Message<R, N, T> {
30    pub fn request(id: Id, payload: R) -> Self {
31        Self::Request(Request::new(id, payload))
32    }
33
34    pub fn notification(payload: N) -> Self {
35        Self::Notification(Notification::new(payload))
36    }
37
38    pub fn response(id: Id, result: T) -> Self {
39        Self::Response(Response::new(id, result))
40    }
41
42    pub fn error(id: Option<Id>, payload: ErrorKind) -> Self {
43        Self::Error(Error::new(id, payload))
44    }
45
46    pub fn deserialize(json: &[u8]) -> Result<Self, Error>
47    where
48        R: DeserializeOwned,
49        N: DeserializeOwned,
50        T: DeserializeOwned,
51    {
52        #[derive(Deserialize)]
53        #[serde(untagged)]
54        enum JsonRpc<R, N, T> {
55            Message(Message<R, N, T>),
56            Other { method: String },
57        }
58
59        match serde_json::from_slice(json) {
60            Ok(JsonRpc::Message(message)) => Ok(message),
61            Ok(JsonRpc::Other { method }) => Err(Error::method_not_found(method)),
62            Err(error) => Err(Error::invalid_json(error.to_string())),
63        }
64    }
65}
66
67impl<R, N> Message<R, N> {
68    pub fn decode<A: DeserializeOwned>(self) -> serde_json::Result<Message<R, N, A>> {
69        Ok(match self {
70            Self::Request(message) => Message::Request(message),
71            Self::Notification(notification) => Message::Notification(notification),
72            Self::Response(response) => Message::Response(Response::new(
73                response.id,
74                serde_json::from_value(response.result)?,
75            )),
76            Self::Error(error) => Message::Error(error),
77        })
78    }
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct Request<T> {
83    jsonrpc: String,
84    pub id: Id,
85    #[serde(flatten)]
86    pub payload: T,
87}
88
89impl<T> Request<T> {
90    pub fn new(id: Id, payload: T) -> Self {
91        Self {
92            jsonrpc: JSONRPC.to_owned(),
93            id,
94            payload,
95        }
96    }
97
98    pub fn serialize(&self) -> serde_json::Result<Bytes>
99    where
100        T: Serialize,
101    {
102        serde_json::to_vec(self).map(Bytes::from_owner)
103    }
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct Response<T = serde_json::Value> {
108    jsonrpc: String,
109    pub id: Id,
110    pub result: T,
111}
112
113impl<T> Response<T> {
114    pub fn new(id: Id, result: T) -> Self {
115        Self {
116            jsonrpc: JSONRPC.to_owned(),
117            id,
118            result,
119        }
120    }
121
122    pub fn serialize(&self) -> serde_json::Result<Bytes>
123    where
124        T: Serialize,
125    {
126        serde_json::to_vec(self).map(Bytes::from_owner)
127    }
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct Notification<T> {
132    jsonrpc: String,
133    #[serde(flatten)]
134    pub payload: T,
135}
136
137impl<T> Notification<T> {
138    pub fn new(payload: T) -> Self {
139        Self {
140            jsonrpc: JSONRPC.to_owned(),
141            payload,
142        }
143    }
144
145    pub fn serialize(&self) -> serde_json::Result<Bytes>
146    where
147        T: Serialize,
148    {
149        serde_json::to_vec(self).map(Bytes::from_owner)
150    }
151}
152
153#[derive(Debug, Clone, Serialize, Deserialize)]
154pub struct Error {
155    jsonrpc: String,
156    #[serde(default, skip_serializing_if = "Option::is_none")]
157    id: Option<Id>,
158    #[serde(rename = "error")]
159    payload: ErrorKind,
160}
161
162impl Error {
163    pub fn new(id: Option<Id>, payload: ErrorKind) -> Self {
164        Self {
165            jsonrpc: JSONRPC.to_owned(),
166            id,
167            payload,
168        }
169    }
170
171    pub fn method_not_found(method: String) -> Self {
172        Self::new(
173            None,
174            ErrorKind::new(-32601, format!("Unknown method: {method}")),
175        )
176    }
177
178    pub fn invalid_json(message: String) -> Self {
179        Self::new(None, ErrorKind::new(-32700, message))
180    }
181
182    pub fn serialize(&self) -> serde_json::Result<Bytes> {
183        serde_json::to_vec(self).map(Bytes::from_owner)
184    }
185}
186
187#[derive(Debug, Clone, Serialize, Deserialize)]
188pub struct ErrorKind {
189    code: i64,
190    message: String,
191}
192
193impl ErrorKind {
194    fn new(code: i64, message: String) -> Self {
195        Self { code, message }
196    }
197
198    pub fn invalid_params(message: String) -> Self {
199        Self::new(-32602, message)
200    }
201}
202
203impl std::fmt::Display for Error {
204    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
205        self.payload.fmt(f)
206    }
207}
208
209impl std::fmt::Display for ErrorKind {
210    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
211        write!(
212            f,
213            "{message} ({code})",
214            message = self.message,
215            code = self.code
216        )
217    }
218}
219
220#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)]
221pub struct Id(u64);
222
223impl Id {
224    pub fn increment(&mut self) -> Self {
225        let current = *self;
226        self.0 += 1;
227        current
228    }
229}
230
231pub fn from_value<T: DeserializeOwned>(value: Value) -> io::Result<T> {
232    Ok(serde_json::from_value(value)?)
233}