techne-mcp 0.1.0

Messages and data structures of the Model Context Protocol
Documentation
pub mod client;
pub mod server;

pub use client::Client;
pub use server::Server;
pub use skema::Schema;

pub use bytes::Bytes;
pub use serde::de::IgnoredAny as Ignored;
pub use serde_json::{Map, Value, json};

use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};

use std::io;

pub const VERSION: &str = "2025-06-18";
pub const JSONRPC: &str = "2.0";

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Message<R, N, T = Value> {
    Request(Request<R>),
    Notification(Notification<N>),
    Response(Response<T>),
    Error(Error),
}

impl<R, N, T> Message<R, N, T> {
    pub fn request(id: Id, payload: R) -> Self {
        Self::Request(Request::new(id, payload))
    }

    pub fn notification(payload: N) -> Self {
        Self::Notification(Notification::new(payload))
    }

    pub fn response(id: Id, result: T) -> Self {
        Self::Response(Response::new(id, result))
    }

    pub fn error(id: Option<Id>, payload: ErrorKind) -> Self {
        Self::Error(Error::new(id, payload))
    }

    pub fn deserialize(json: &[u8]) -> Result<Self, Error>
    where
        R: DeserializeOwned,
        N: DeserializeOwned,
        T: DeserializeOwned,
    {
        #[derive(Deserialize)]
        #[serde(untagged)]
        enum JsonRpc<R, N, T> {
            Message(Message<R, N, T>),
            Other { method: String },
        }

        match serde_json::from_slice(json) {
            Ok(JsonRpc::Message(message)) => Ok(message),
            Ok(JsonRpc::Other { method }) => Err(Error::method_not_found(method)),
            Err(error) => Err(Error::invalid_json(error.to_string())),
        }
    }
}

impl<R, N> Message<R, N> {
    pub fn decode<A: DeserializeOwned>(self) -> serde_json::Result<Message<R, N, A>> {
        Ok(match self {
            Self::Request(message) => Message::Request(message),
            Self::Notification(notification) => Message::Notification(notification),
            Self::Response(response) => Message::Response(Response::new(
                response.id,
                serde_json::from_value(response.result)?,
            )),
            Self::Error(error) => Message::Error(error),
        })
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Request<T> {
    jsonrpc: String,
    pub id: Id,
    #[serde(flatten)]
    pub payload: T,
}

impl<T> Request<T> {
    pub fn new(id: Id, payload: T) -> Self {
        Self {
            jsonrpc: JSONRPC.to_owned(),
            id,
            payload,
        }
    }

    pub fn serialize(&self) -> serde_json::Result<Bytes>
    where
        T: Serialize,
    {
        serde_json::to_vec(self).map(Bytes::from_owner)
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Response<T = serde_json::Value> {
    jsonrpc: String,
    pub id: Id,
    pub result: T,
}

impl<T> Response<T> {
    pub fn new(id: Id, result: T) -> Self {
        Self {
            jsonrpc: JSONRPC.to_owned(),
            id,
            result,
        }
    }

    pub fn serialize(&self) -> serde_json::Result<Bytes>
    where
        T: Serialize,
    {
        serde_json::to_vec(self).map(Bytes::from_owner)
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Notification<T> {
    jsonrpc: String,
    #[serde(flatten)]
    pub payload: T,
}

impl<T> Notification<T> {
    pub fn new(payload: T) -> Self {
        Self {
            jsonrpc: JSONRPC.to_owned(),
            payload,
        }
    }

    pub fn serialize(&self) -> serde_json::Result<Bytes>
    where
        T: Serialize,
    {
        serde_json::to_vec(self).map(Bytes::from_owner)
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Error {
    jsonrpc: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    id: Option<Id>,
    #[serde(rename = "error")]
    payload: ErrorKind,
}

impl Error {
    pub fn new(id: Option<Id>, payload: ErrorKind) -> Self {
        Self {
            jsonrpc: JSONRPC.to_owned(),
            id,
            payload,
        }
    }

    pub fn method_not_found(method: String) -> Self {
        Self::new(
            None,
            ErrorKind::new(-32601, format!("Unknown method: {method}")),
        )
    }

    pub fn invalid_json(message: String) -> Self {
        Self::new(None, ErrorKind::new(-32700, message))
    }

    pub fn serialize(&self) -> serde_json::Result<Bytes> {
        serde_json::to_vec(self).map(Bytes::from_owner)
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ErrorKind {
    code: i64,
    message: String,
}

impl ErrorKind {
    fn new(code: i64, message: String) -> Self {
        Self { code, message }
    }

    pub fn invalid_params(message: String) -> Self {
        Self::new(-32602, message)
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        self.payload.fmt(f)
    }
}

impl std::fmt::Display for ErrorKind {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "{message} ({code})",
            message = self.message,
            code = self.code
        )
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)]
pub struct Id(u64);

impl Id {
    pub fn increment(&mut self) -> Self {
        let current = *self;
        self.0 += 1;
        current
    }
}

pub fn from_value<T: DeserializeOwned>(value: Value) -> io::Result<T> {
    Ok(serde_json::from_value(value)?)
}