Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: enhance CallToolError API and add is_initialized_notification to Relevant Client Message Types #85

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
hashemix merged 1 commit into main from feat/improve-call-tool-error-api
Aug 29, 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
79 changes: 36 additions & 43 deletions Cargo.lock
View file Open in desktop

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ edition = "2021"
path = "src/rust-mcp-schema.rs"

[dependencies]
serde = { version = "1.0.219", features = ["derive"] }
serde_json = { version = "1.0.140" }
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0.143" }


[dev-dependencies]
Expand Down
3 changes: 3 additions & 0 deletions rust-toolchain.toml
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[toolchain]
channel = "1.88.0"
components = ["rustfmt", "clippy"]
2 changes: 1 addition & 1 deletion scripts/run_test.sh
View file Open in desktop
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_06_18", "2025_03_26", "2024_11_05", "draft")
SCHEMA_VERSION_FEATURES=("2025_06_18", "2025_03_26", "2024_11_05") #// TODO: add the "draft" tests back

# space-separated string
COMMON_FEATURES_STR="${COMMON_FEATURES[*]}"
Expand Down
4 changes: 2 additions & 2 deletions src/generated_schema/2024_11_05/mcp_schema.rs
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
/// modify or extend the implementations as needed, but please do so at your own risk.
///
/// Generated from : <https://github.com/modelcontextprotocol/specification.git>
/// Hash : 0695a497eb50a804fc0e88c18a93a21a675d6b3e
/// Generated at : 2025-07-27 15:33:20
/// Hash : a470342d05c345b580642821605b9c885bad237b
/// Generated at : 2025-08-29 19:12:22
/// ----------------------------------------------------------------------------
///
/// MCP Protocol Version
Expand Down
72 changes: 62 additions & 10 deletions src/generated_schema/2024_11_05/schema_utils.rs
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,11 @@ impl ClientMessage {
pub fn is_initialize_request(&self) -> bool {
matches!(self, Self::Request(request) if request.request.is_initialize_request())
}

/// Returns `true` if the message is an `InitializedNotification`
pub fn is_initialized_notification(&self) -> bool {
matches!(self, Self::Notification(notofication) if notofication.notification.is_initialized_notification())
}
}

impl From<ClientJsonrpcNotification> for ClientMessage {
Expand Down Expand Up @@ -519,7 +524,7 @@ impl TryFrom<NotificationFromClient> for ClientNotification {
}

impl NotificationFromClient {
/// Checks if the current notification is an `InitializedNotification` from the client, indicating that the client has been initialized.
/// Returns `true` if the message is an `InitializedNotification`
pub fn is_initialized_notification(&self) -> bool {
matches!(
self,
Expand Down Expand Up @@ -1318,10 +1323,15 @@ pub enum MessageFromClient {
}

impl MessageFromClient {
/// Returns `true` if the request is an `InitializeRequest`.
/// Returns `true` if the message is an `InitializeRequest`.
pub fn is_initialize_request(&self) -> bool {
matches!(self, Self::RequestFromClient(request) if request.is_initialize_request())
}

/// Returns `true` if the message is an `InitializedNotification`
pub fn is_initialized_notification(&self) -> bool {
matches!(self, Self::NotificationFromClient(notofication) if notofication.is_initialized_notification())
}
}

impl From<RequestFromClient> for MessageFromClient {
Expand Down Expand Up @@ -1450,12 +1460,60 @@ impl CallToolError {
}

/// Specific constructor to create a `CallToolError` for an `UnknownTool` error.
pub fn unknown_tool(tool_name: String) -> Self {
pub fn unknown_tool(tool_name: impl Into<String>) -> Self {
// Create a `CallToolError` from an `UnknownTool` error (wrapped in a `Box`).
CallToolError(Box::new(UnknownTool(tool_name)))
CallToolError(Box::new(UnknownTool(tool_name.into())))
}

pub fn invalid_arguments(tool_name: impl Into<String>, message: Option<impl Into<String>>) -> Self {
let tool_name = tool_name.into();
let message = message.map(|m| m.into());

let full_message = match message {
Some(msg) => format!("Invalid arguments for tool '{tool_name}': {msg}" ),
None => format!("Invalid arguments for tool '{tool_name}'"),
};
Self::from_message(full_message)
}

/// Creates a new `CallToolError` from a string message.
///
/// This is useful for generating ad-hoc or one-off errors without defining a custom error type.
/// Internally, it wraps the string in a lightweight error type that implements the `Error` trait.
///
/// # Examples
///
/// ```
/// let err = CallToolError::from_message("Something went wrong");
/// println!("{:?}", err);
/// ```
///
/// # Parameters
///
/// - `message`: Any type that can be converted into a `String` (e.g., `&str` or `String`)
///
/// # Returns
///
/// A `CallToolError` wrapping a dynamic error created from the provided message.
pub fn from_message(message: impl Into<String>) -> Self {
struct MsgError(String);
impl std::fmt::Debug for MsgError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl std::fmt::Display for MsgError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl std::error::Error for MsgError {}

CallToolError::new(MsgError(message.into()))
}
}


/// Converts a `CallToolError` into a `RpcError`.
///
/// The conversion creates an internal error variant of `RpcError`
Expand Down Expand Up @@ -1508,8 +1566,6 @@ impl<T: Into<String>> From<T> for TextContent {
}
}



#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
#[serde(untagged)]
#[allow(clippy::large_enum_variant)]
Expand Down Expand Up @@ -1568,8 +1624,6 @@ impl Display for ClientMessages {
}
}



#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
#[serde(untagged)]
#[allow(clippy::large_enum_variant)]
Expand Down Expand Up @@ -1628,8 +1682,6 @@ impl Display for ServerMessages {
}
}



#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
#[serde(untagged)]
#[allow(clippy::large_enum_variant)]
Expand Down
4 changes: 2 additions & 2 deletions src/generated_schema/2025_03_26/mcp_schema.rs
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
/// modify or extend the implementations as needed, but please do so at your own risk.
///
/// Generated from : <https://github.com/modelcontextprotocol/specification.git>
/// Hash : 0695a497eb50a804fc0e88c18a93a21a675d6b3e
/// Generated at : 2025-07-27 15:33:21
/// Hash : a470342d05c345b580642821605b9c885bad237b
/// Generated at : 2025-08-29 19:12:23
/// ----------------------------------------------------------------------------
///
/// MCP Protocol Version
Expand Down
Loading

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /