Skip to content

feat!: add new draft version and update 2025_03_26 #66

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,7 @@ latest = ["2025_03_26"]
2025_03_26 = []
# enabled mcp schema version 2024_11_05
2024_11_05 = []
# enabled draft mcp schema
draft = []
# Enables `schema_utils`, which provides utility types that simplify communication with MCP messages, improving ease of use while reducing potential mistakes ane errors when constructing messages.
schema_utils = []
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/rust-mcp-stack/rust-mcp-schema/ci.yml?style=for-the-badge" height="22">
](https://github.com/rust-mcp-stack/rust-mcp-schema/actions/workflows/ci.yml)

A type-safe implementation of the official Model Context Protocol (MCP) schema in Rust, supporting both the `2024_11_05` and `2025_03_26` versions.
A type-safe Rust implementation of the official Model Context Protocol (MCP) schema, supporting all official released versions including `2024_11_05`, `2025_03_26`, and `draft` version for early adoption.

The MCP schemas in this repository are [automatically generated](#how-are-schemas-generated) from the official Model Context Protocol, ensuring they are always up-to-date and aligned with the latest official specifications.

Expand Down Expand Up @@ -46,7 +46,7 @@ Focus on your app's logic while [rust-mcp-sdk](https://crates.io/crates/rust-mcp

- 🧩 Type-safe implementation of the MCP protocol specification.
- 💎 Auto-generated schemas are always synchronized with the official schema specifications.
- 📜 Includes both schema versions : `2024_11_05` and `2025_03_26`.
- 📜 Includes all official released versions : `2024_11_05` and `2025_03_26` and `draft` version for early adoption.
- 🛠 Complimentary schema utility module (schema_utils) to boost productivity and ensure development integrity.

## How can this crate be used?
Expand All @@ -68,10 +68,11 @@ For more information on the MCP architecture, refer to the [official documentati

## Schema Versions

This repository provides all versions of the schema, which can be selected using Cargo features:
This repository provides all official released versions the schema , including draft version, enabling you to prepare and adapt your applications ahead of upcoming official schema releases.

- [2024_11_05](src/generated_schema/2024_11_05)
- [2025_03_26](src/generated_schema/2025_03_26)
- [draft](src/generated_schema/draft)

### How to switch between different schema versions?

Expand Down
1 change: 0 additions & 1 deletion examples/mcp_client_handle_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ fn handle_message(message_payload: &str) -> std::result::Result<(), AppError> {
ServerResult::ListResourcesResult(list_resources_result) => {
dbg!(list_resources_result);
}
#[cfg(feature = "2024_11_05")]
ServerResult::ListResourceTemplatesResult(list_resource_templates_result) => {
dbg!(list_resource_templates_result);
}
Expand Down
1 change: 0 additions & 1 deletion examples/mcp_server_handle_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ fn handle_message(message_payload: &str) -> std::result::Result<(), AppError> {
dbg!(list_resources_request);
}

#[cfg(feature = "2024_11_05")]
ClientRequest::ListResourceTemplatesRequest(list_resource_templates_request) => {
dbg!(list_resource_templates_request);
}
Expand Down
2 changes: 1 addition & 1 deletion scripts/run_clippy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
COMMON_FEATURES=("schema_utils")

# schema versions features (passed to clippy one at a time)
SCHEMA_VERSION_FEATURES=("2025_03_26", "2024_11_05")
SCHEMA_VERSION_FEATURES=("2025_03_26", "2024_11_05", "draft")

# space-separated string
COMMON_FEATURES_STR="${COMMON_FEATURES[*]}"
Expand Down
2 changes: 1 addition & 1 deletion scripts/run_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
COMMON_FEATURES=("schema_utils")

# schema versions features (tested one at a time)
SCHEMA_VERSION_FEATURES=("2025_03_26", "2024_11_05")
SCHEMA_VERSION_FEATURES=("2025_03_26", "2024_11_05", "draft")

# space-separated string
COMMON_FEATURES_STR="${COMMON_FEATURES[*]}"
Expand Down
19 changes: 19 additions & 0 deletions src/generated_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#[cfg(feature = "2024_11_05")]
#[path = "generated_schema/2024_11_05/mcp_schema.rs"]
mod schema_2024_11_05;

#[cfg(feature = "2024_11_05")]
pub use schema_2024_11_05::*;

Expand All @@ -23,3 +24,21 @@ pub use schema_2025_03_26::*;
#[cfg(not(feature = "2024_11_05"))]
#[path = "generated_schema/2025_03_26/schema_utils.rs"]
pub mod schema_utils;

/// Schema Version : draft
#[cfg(feature = "draft")]
#[cfg(not(feature = "2024_11_05"))]
#[cfg(not(feature = "2025_03_26"))]
#[path = "generated_schema/draft/mcp_schema.rs"]
mod schema_draft;

#[cfg(feature = "draft")]
#[cfg(not(feature = "2024_11_05"))]
#[cfg(not(feature = "2025_03_26"))]
pub use schema_draft::*;

#[cfg(all(feature = "schema_utils", feature = "draft"))]
#[cfg(not(feature = "2024_11_05"))]
#[cfg(not(feature = "2025_03_26"))]
#[path = "generated_schema/draft/schema_utils.rs"]
pub mod schema_utils;
6 changes: 3 additions & 3 deletions src/generated_schema/2024_11_05/mcp_schema.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/// ----------------------------------------------------------------------------
/// This file is auto-generated by mcp-schema-gen v0.1.16.
/// This file is auto-generated by mcp-schema-gen v0.2.0.
/// WARNING:
/// It is not recommended to modify this file directly. You are free to
/// modify or extend the implementations as needed, but please do so at your own risk.
///
/// Generated from : <https://github.com/modelcontextprotocol/specification.git>
/// Hash : 72516795d9a7aacdcf9b87624feb05229e10c950
/// Generated at : 2025-04-04 20:01:25
/// Hash : 5da5bac89165d68cad24a211119e4c1b61178d5a
/// Generated at : 2025-04-26 18:56:03
/// ----------------------------------------------------------------------------
///
/// MCP Protocol Version
Expand Down
25 changes: 15 additions & 10 deletions src/generated_schema/2024_11_05/schema_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ fn detect_message_type(value: &serde_json::Value) -> MessageTypes {

/// Represents a generic MCP (Model Context Protocol) message.
/// This trait defines methods to classify and extract information from messages.
pub trait RPCMessage: MCPMessage {
pub trait RpcMessage: McpMessage {
fn request_id(&self) -> Option<&RequestId>;
fn jsonrpc(&self) -> &str;
}

pub trait MCPMessage {
pub trait McpMessage {
fn is_response(&self) -> bool;
fn is_request(&self) -> bool;
fn is_notification(&self) -> bool;
Expand Down Expand Up @@ -226,7 +226,7 @@ impl ClientMessage {
}
}

impl RPCMessage for ClientMessage {
impl RpcMessage for ClientMessage {
// Retrieves the request ID associated with the message, if applicable
fn request_id(&self) -> Option<&RequestId> {
match self {
Expand All @@ -251,8 +251,8 @@ impl RPCMessage for ClientMessage {
}
}

// Implementing the `MCPMessage` trait for `ClientMessage`
impl MCPMessage for ClientMessage {
// Implementing the `McpMessage` trait for `ClientMessage`
impl McpMessage for ClientMessage {
// Returns true if the message is a response type
fn is_response(&self) -> bool {
matches!(self, ClientMessage::Response(_))
Expand Down Expand Up @@ -738,7 +738,7 @@ impl ServerMessage {
}
}

impl RPCMessage for ServerMessage {
impl RpcMessage for ServerMessage {
// Retrieves the request ID associated with the message, if applicable
fn request_id(&self) -> Option<&RequestId> {
match self {
Expand Down Expand Up @@ -767,8 +767,8 @@ impl RPCMessage for ServerMessage {
}
}

// Implementing the `MCPMessage` trait for `ServerMessage`
impl MCPMessage for ServerMessage {
// Implementing the `McpMessage` trait for `ServerMessage`
impl McpMessage for ServerMessage {
// Returns true if the message is a response type
fn is_response(&self) -> bool {
matches!(self, ServerMessage::Response(_))
Expand Down Expand Up @@ -1183,7 +1183,7 @@ impl From<RpcError> for MessageFromServer {
}
}

impl MCPMessage for MessageFromServer {
impl McpMessage for MessageFromServer {
fn is_response(&self) -> bool {
matches!(self, MessageFromServer::ResultFromServer(_))
}
Expand Down Expand Up @@ -1288,7 +1288,7 @@ impl From<RpcError> for MessageFromClient {
}
}

impl MCPMessage for MessageFromClient {
impl McpMessage for MessageFromClient {
fn is_response(&self) -> bool {
matches!(self, MessageFromClient::ResultFromClient(_))
}
Expand Down Expand Up @@ -1442,6 +1442,11 @@ impl CallToolRequest {
}
}

#[deprecated(since = "0.4.0", note = "This trait was renamed to RpcMessage. Use RpcMessage instead.")]
pub type RPCMessage = ();
#[deprecated(since = "0.4.0", note = "This trait was renamed to McpMessage. Use McpMessage instead.")]
pub type MCPMessage = ();

/// BEGIN AUTO GENERATED
impl ::serde::Serialize for ClientJsonrpcRequest {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
Expand Down
42 changes: 37 additions & 5 deletions src/generated_schema/2025_03_26/mcp_schema.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/// ----------------------------------------------------------------------------
/// This file is auto-generated by mcp-schema-gen v0.1.16.
/// This file is auto-generated by mcp-schema-gen v0.2.0.
/// WARNING:
/// It is not recommended to modify this file directly. You are free to
/// modify or extend the implementations as needed, but please do so at your own risk.
///
/// Generated from : <https://github.com/modelcontextprotocol/specification.git>
/// Hash : 72516795d9a7aacdcf9b87624feb05229e10c950
/// Generated at : 2025-04-04 20:01:26
/// Hash : 5da5bac89165d68cad24a211119e4c1b61178d5a
/// Generated at : 2025-04-26 18:56:03
/// ----------------------------------------------------------------------------
///
/// MCP Protocol Version
Expand Down Expand Up @@ -594,6 +594,9 @@ impl ::std::convert::From<RootsListChangedNotification> for ClientNotification {
/// "$ref": "#/definitions/ListResourcesRequest"
/// },
/// {
/// "$ref": "#/definitions/ListResourceTemplatesRequest"
/// },
/// {
/// "$ref": "#/definitions/ReadResourceRequest"
/// },
/// {
Expand Down Expand Up @@ -630,6 +633,7 @@ pub enum ClientRequest {
InitializeRequest(InitializeRequest),
PingRequest(PingRequest),
ListResourcesRequest(ListResourcesRequest),
ListResourceTemplatesRequest(ListResourceTemplatesRequest),
ReadResourceRequest(ReadResourceRequest),
SubscribeRequest(SubscribeRequest),
UnsubscribeRequest(UnsubscribeRequest),
Expand All @@ -655,6 +659,11 @@ impl ::std::convert::From<ListResourcesRequest> for ClientRequest {
Self::ListResourcesRequest(value)
}
}
impl ::std::convert::From<ListResourceTemplatesRequest> for ClientRequest {
fn from(value: ListResourceTemplatesRequest) -> Self {
Self::ListResourceTemplatesRequest(value)
}
}
impl ::std::convert::From<ReadResourceRequest> for ClientRequest {
fn from(value: ReadResourceRequest) -> Self {
Self::ReadResourceRequest(value)
Expand Down Expand Up @@ -4237,6 +4246,10 @@ pub struct RequestParamsMeta {
/// "description": "A human-readable name for this resource.\n\nThis can be used by clients to populate UI elements.",
/// "type": "string"
/// },
/// "size": {
/// "description": "The size of the raw resource content, in bytes (i.e., before base64 encoding or any tokenization), if known.\n\nThis can be used by Hosts to display file sizes and estimate context window usage.",
/// "type": "integer"
/// },
/// "uri": {
/// "description": "The URI of this resource.",
/// "type": "string",
Expand All @@ -4261,6 +4274,10 @@ pub struct Resource {
/**A human-readable name for this resource.
This can be used by clients to populate UI elements.*/
pub name: ::std::string::String,
/**The size of the raw resource content, in bytes (i.e., before base64 encoding or any tokenization), if known.
This can be used by Hosts to display file sizes and estimate context window usage.*/
#[serde(default, skip_serializing_if = "::std::option::Option::is_none")]
pub size: ::std::option::Option<i64>,
///The URI of this resource.
pub uri: ::std::string::String,
}
Expand Down Expand Up @@ -5143,6 +5160,9 @@ impl ::std::convert::From<ListRootsRequest> for ServerRequest {
/// "$ref": "#/definitions/ListResourcesResult"
/// },
/// {
/// "$ref": "#/definitions/ListResourceTemplatesResult"
/// },
/// {
/// "$ref": "#/definitions/ReadResourceResult"
/// },
/// {
Expand All @@ -5169,6 +5189,7 @@ impl ::std::convert::From<ListRootsRequest> for ServerRequest {
pub enum ServerResult {
InitializeResult(InitializeResult),
ListResourcesResult(ListResourcesResult),
ListResourceTemplatesResult(ListResourceTemplatesResult),
ReadResourceResult(ReadResourceResult),
ListPromptsResult(ListPromptsResult),
GetPromptResult(GetPromptResult),
Expand All @@ -5187,6 +5208,11 @@ impl ::std::convert::From<ListResourcesResult> for ServerResult {
Self::ListResourcesResult(value)
}
}
impl ::std::convert::From<ListResourceTemplatesResult> for ServerResult {
fn from(value: ListResourceTemplatesResult) -> Self {
Self::ListResourceTemplatesResult(value)
}
}
impl ::std::convert::From<ReadResourceResult> for ServerResult {
fn from(value: ReadResourceResult) -> Self {
Self::ReadResourceResult(value)
Expand Down Expand Up @@ -5549,15 +5575,15 @@ received from untrusted servers.*/
///
/// ```json
///{
/// "description": "Additional properties describing a Tool to clients.\n\nNOTE: all properties in ToolAnnotations are **hints**. \nThey are not guaranteed to provide a faithful description of \ntool behavior (including descriptive properties like title).\n\nClients should never make tool use decisions based on ToolAnnotations\nreceived from untrusted servers.",
/// "description": "Additional properties describing a Tool to clients.\n\nNOTE: all properties in ToolAnnotations are **hints**.\nThey are not guaranteed to provide a faithful description of\ntool behavior (including descriptive properties like title).\n\nClients should never make tool use decisions based on ToolAnnotations\nreceived from untrusted servers.",
/// "type": "object",
/// "properties": {
/// "destructiveHint": {
/// "description": "If true, the tool may perform destructive updates to its environment.\nIf false, the tool performs only additive updates.\n\n(This property is meaningful only when readOnlyHint == false)\n\nDefault: true",
/// "type": "boolean"
/// },
/// "idempotentHint": {
/// "description": "If true, calling the tool repeatedly with the same arguments \nwill have no additional effect on the its environment.\n\n(This property is meaningful only when readOnlyHint == false)\n\nDefault: false",
/// "description": "If true, calling the tool repeatedly with the same arguments\nwill have no additional effect on the its environment.\n\n(This property is meaningful only when readOnlyHint == false)\n\nDefault: false",
/// "type": "boolean"
/// },
/// "openWorldHint": {
Expand Down Expand Up @@ -5850,6 +5876,11 @@ impl<'de> serde::Deserialize<'de> for ClientRequest {
let req = serde_json::from_value::<ListResourcesRequest>(value).map_err(serde::de::Error::custom)?;
Ok(ClientRequest::ListResourcesRequest(req))
}
"resources/templates/list" => {
let req =
serde_json::from_value::<ListResourceTemplatesRequest>(value).map_err(serde::de::Error::custom)?;
Ok(ClientRequest::ListResourceTemplatesRequest(req))
}
"resources/read" => {
let req = serde_json::from_value::<ReadResourceRequest>(value).map_err(serde::de::Error::custom)?;
Ok(ClientRequest::ReadResourceRequest(req))
Expand Down Expand Up @@ -5899,6 +5930,7 @@ impl ClientRequest {
ClientRequest::InitializeRequest(request) => request.method(),
ClientRequest::PingRequest(request) => request.method(),
ClientRequest::ListResourcesRequest(request) => request.method(),
ClientRequest::ListResourceTemplatesRequest(request) => request.method(),
ClientRequest::ReadResourceRequest(request) => request.method(),
ClientRequest::SubscribeRequest(request) => request.method(),
ClientRequest::UnsubscribeRequest(request) => request.method(),
Expand Down
Loading