diff --git a/examples/mcp_client_handle_message.rs b/examples/mcp_client_handle_message.rs index afa1857..b0e5379 100644 --- a/examples/mcp_client_handle_message.rs +++ b/examples/mcp_client_handle_message.rs @@ -122,18 +122,9 @@ fn handle_message(message_payload: &str) -> std::result::Result<(), AppError> { ServerResult::ListToolsResult(list_tools_result) => { dbg!(list_tools_result); } - #[cfg(any(feature = "2025_03_26", feature = "2024_11_05"))] ServerResult::CallToolResult(call_tool_result) => { dbg!(call_tool_result); } - #[cfg(feature = "draft")] - ServerResult::CallToolUnstructuredResult(call_tool_unstructured_result) => { - dbg!(call_tool_unstructured_result); - } - #[cfg(feature = "draft")] - ServerResult::CallToolStructuredResult(call_tool_structured_result) => { - dbg!(call_tool_structured_result); - } ServerResult::CompleteResult(complete_result) => { dbg!(complete_result); } diff --git a/src/generated_schema.rs b/src/generated_schema.rs index e2348fa..13a295c 100644 --- a/src/generated_schema.rs +++ b/src/generated_schema.rs @@ -33,3 +33,7 @@ pub use mcp_schema::*; #[cfg(all(feature = "schema_utils", feature = "draft"))] #[path = "generated_schema/draft/schema_utils.rs"] pub mod schema_utils; + +#[path = "generated_schema/protocol_version.rs"] +mod protocol_version; +pub use protocol_version::*; diff --git a/src/generated_schema/2024_11_05/mcp_schema.rs b/src/generated_schema/2024_11_05/mcp_schema.rs index 9dfad90..b8c8cba 100644 --- a/src/generated_schema/2024_11_05/mcp_schema.rs +++ b/src/generated_schema/2024_11_05/mcp_schema.rs @@ -6,7 +6,7 @@ /// /// Generated from : /// Hash : UNKNOWN -/// Generated at : 2025-05-20 20:52:14 +/// Generated at : 2025-05-26 21:28:07 /// ---------------------------------------------------------------------------- /// /// MCP Protocol Version diff --git a/src/generated_schema/2024_11_05/schema_utils.rs b/src/generated_schema/2024_11_05/schema_utils.rs index 244b751..85803ce 100644 --- a/src/generated_schema/2024_11_05/schema_utils.rs +++ b/src/generated_schema/2024_11_05/schema_utils.rs @@ -15,7 +15,7 @@ pub enum MessageTypes { /// Implements the `Display` trait for the `MessageTypes` enum, /// allowing it to be converted into a human-readable string. impl Display for MessageTypes { - /// Formats the `MessageTypes` enum variant as a string. + /// Formats the `MessageTypes` enum variant as a string. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, @@ -1071,6 +1071,7 @@ impl FromStr for ServerJsonrpcResponse { /// To determine standard and custom results from the server side /// Custom results (CustomResult) are of type serde_json::Value and can be deserialized into any custom type. +#[allow(clippy::large_enum_variant)] #[derive(::serde::Serialize, Clone, Debug)] #[serde(untagged)] pub enum ResultFromServer { diff --git a/src/generated_schema/2025_03_26/mcp_schema.rs b/src/generated_schema/2025_03_26/mcp_schema.rs index 1bd75f3..275dc48 100644 --- a/src/generated_schema/2025_03_26/mcp_schema.rs +++ b/src/generated_schema/2025_03_26/mcp_schema.rs @@ -6,7 +6,7 @@ /// /// Generated from : /// Hash : UNKNOWN -/// Generated at : 2025-05-20 20:52:15 +/// Generated at : 2025-05-26 21:28:07 /// ---------------------------------------------------------------------------- /// /// MCP Protocol Version diff --git a/src/generated_schema/draft/mcp_schema.rs b/src/generated_schema/draft/mcp_schema.rs index c58be77..74b248b 100644 --- a/src/generated_schema/draft/mcp_schema.rs +++ b/src/generated_schema/draft/mcp_schema.rs @@ -6,7 +6,7 @@ /// /// Generated from : /// Hash : UNKNOWN -/// Generated at : 2025-05-20 20:52:15 +/// Generated at : 2025-05-26 21:28:08 /// ---------------------------------------------------------------------------- /// /// MCP Protocol Version @@ -249,57 +249,16 @@ pub struct CallToolRequestParams { pub arguments: ::std::option::Option<::serde_json::Map<::std::string::String, ::serde_json::Value>>, pub name: ::std::string::String, } -/**The server's response to a tool call. -Any errors that originate from the tool SHOULD be reported inside the result -object, with isError set to true, _not_ as an MCP protocol-level error -response. Otherwise, the LLM would not be able to see that an error occurred -and self-correct. -However, any errors in _finding_ the tool, an error indicating that the -server does not support tool calls, or any other exceptional conditions, -should be reported as an MCP error response.*/ +///The server's response to a tool call. /// ///
JSON schema /// /// ```json ///{ -/// "description": "The server's response to a tool call.\n\nAny errors that originate from the tool SHOULD be reported inside the result\nobject, with isError set to true, _not_ as an MCP protocol-level error\nresponse. Otherwise, the LLM would not be able to see that an error occurred\nand self-correct.\n\nHowever, any errors in _finding_ the tool, an error indicating that the\nserver does not support tool calls, or any other exceptional conditions,\nshould be reported as an MCP error response.", -/// "anyOf": [ -/// { -/// "$ref": "#/definitions/CallToolUnstructuredResult" -/// }, -/// { -/// "$ref": "#/definitions/CallToolStructuredResult" -/// } -/// ] -///} -/// ``` -///
-#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)] -#[serde(untagged)] -pub enum CallToolResult { - UnstructuredResult(CallToolUnstructuredResult), - StructuredResult(CallToolStructuredResult), -} -impl ::std::convert::From for CallToolResult { - fn from(value: CallToolUnstructuredResult) -> Self { - Self::UnstructuredResult(value) - } -} -impl ::std::convert::From for CallToolResult { - fn from(value: CallToolStructuredResult) -> Self { - Self::StructuredResult(value) - } -} -///Tool result for tools that do declare an outputSchema. -/// -///
JSON schema -/// -/// ```json -///{ -/// "description": "Tool result for tools that do declare an outputSchema.", +/// "description": "The server's response to a tool call.", /// "type": "object", /// "required": [ -/// "structuredContent" +/// "content" /// ], /// "properties": { /// "_meta": { @@ -308,7 +267,7 @@ impl ::std::convert::From for CallToolResult { /// "additionalProperties": {} /// }, /// "content": { -/// "description": "If the Tool defines an outputSchema, this field MAY be present in the result.\nTools should use this field to provide compatibility with older clients that do not support structured content.\nClients that support structured content should ignore this field.", +/// "description": "A list of content objects that represent the unstructured result of the tool call.", /// "type": "array", /// "items": { /// "anyOf": [ @@ -328,11 +287,11 @@ impl ::std::convert::From for CallToolResult { /// } /// }, /// "isError": { -/// "description": "Whether the tool call ended in an error.\n\nIf not set, this is assumed to be false (the call was successful).", +/// "description": "Whether the tool call ended in an error.\n\nIf not set, this is assumed to be false (the call was successful).\n\nAny errors that originate from the tool SHOULD be reported inside the result\nobject, with isError set to true, _not_ as an MCP protocol-level error\nresponse. Otherwise, the LLM would not be able to see that an error occurred\nand self-correct.\n\nHowever, any errors in _finding_ the tool, an error indicating that the\nserver does not support tool calls, or any other exceptional conditions,\nshould be reported as an MCP error response.", /// "type": "boolean" /// }, /// "structuredContent": { -/// "description": "An object containing structured tool output.\n\nIf the Tool defines an outputSchema, this field MUST be present in the result, and contain a JSON object that matches the schema.", +/// "description": "An optional JSON object that represents the structured result of the tool call.", /// "type": "object", /// "additionalProperties": {} /// } @@ -341,134 +300,32 @@ impl ::std::convert::From for CallToolResult { /// ``` ///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)] -pub struct CallToolStructuredResult { - /**If the Tool defines an outputSchema, this field MAY be present in the result. - Tools should use this field to provide compatibility with older clients that do not support structured content. - Clients that support structured content should ignore this field.*/ - #[serde(default, skip_serializing_if = "::std::vec::Vec::is_empty")] - pub content: ::std::vec::Vec, +pub struct CallToolResult { + ///A list of content objects that represent the unstructured result of the tool call. + pub content: ::std::vec::Vec, /**Whether the tool call ended in an error. - If not set, this is assumed to be false (the call was successful).*/ - #[serde(rename = "isError", default, skip_serializing_if = "::std::option::Option::is_none")] - pub is_error: ::std::option::Option, - ///This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses. - #[serde(rename = "_meta", default, skip_serializing_if = "::std::option::Option::is_none")] - pub meta: ::std::option::Option<::serde_json::Map<::std::string::String, ::serde_json::Value>>, - /**An object containing structured tool output. - If the Tool defines an outputSchema, this field MUST be present in the result, and contain a JSON object that matches the schema.*/ - #[serde(rename = "structuredContent")] - pub structured_content: ::serde_json::Map<::std::string::String, ::serde_json::Value>, -} -///CallToolStructuredResultContentItem -/// -///
JSON schema -/// -/// ```json -///{ -/// "anyOf": [ -/// { -/// "$ref": "#/definitions/TextContent" -/// }, -/// { -/// "$ref": "#/definitions/ImageContent" -/// }, -/// { -/// "$ref": "#/definitions/AudioContent" -/// }, -/// { -/// "$ref": "#/definitions/EmbeddedResource" -/// } -/// ] -///} -/// ``` -///
-#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)] -#[serde(untagged)] -pub enum CallToolStructuredResultContentItem { - TextContent(TextContent), - ImageContent(ImageContent), - AudioContent(AudioContent), - EmbeddedResource(EmbeddedResource), -} -impl ::std::convert::From for CallToolStructuredResultContentItem { - fn from(value: TextContent) -> Self { - Self::TextContent(value) - } -} -impl ::std::convert::From for CallToolStructuredResultContentItem { - fn from(value: ImageContent) -> Self { - Self::ImageContent(value) - } -} -impl ::std::convert::From for CallToolStructuredResultContentItem { - fn from(value: AudioContent) -> Self { - Self::AudioContent(value) - } -} -impl ::std::convert::From for CallToolStructuredResultContentItem { - fn from(value: EmbeddedResource) -> Self { - Self::EmbeddedResource(value) - } -} -///Tool result for tools that do not declare an outputSchema. -/// -///
JSON schema -/// -/// ```json -///{ -/// "description": "Tool result for tools that do not declare an outputSchema.", -/// "type": "object", -/// "required": [ -/// "content" -/// ], -/// "properties": { -/// "_meta": { -/// "description": "This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses.", -/// "type": "object", -/// "additionalProperties": {} -/// }, -/// "content": { -/// "description": "A list of content objects that represent the result of the tool call.\n\nIf the Tool does not define an outputSchema, this field MUST be present in the result.", -/// "type": "array", -/// "items": { -/// "anyOf": [ -/// { -/// "$ref": "#/definitions/TextContent" -/// }, -/// { -/// "$ref": "#/definitions/ImageContent" -/// }, -/// { -/// "$ref": "#/definitions/AudioContent" -/// }, -/// { -/// "$ref": "#/definitions/EmbeddedResource" -/// } -/// ] -/// } -/// }, -/// "isError": { -/// "description": "Whether the tool call ended in an error.\n\nIf not set, this is assumed to be false (the call was successful).", -/// "type": "boolean" -/// } -/// } -///} -/// ``` -///
-#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)] -pub struct CallToolUnstructuredResult { - /**A list of content objects that represent the result of the tool call. - If the Tool does not define an outputSchema, this field MUST be present in the result.*/ - pub content: ::std::vec::Vec, - /**Whether the tool call ended in an error. - If not set, this is assumed to be false (the call was successful).*/ + If not set, this is assumed to be false (the call was successful). + Any errors that originate from the tool SHOULD be reported inside the result + object, with isError set to true, _not_ as an MCP protocol-level error + response. Otherwise, the LLM would not be able to see that an error occurred + and self-correct. + However, any errors in _finding_ the tool, an error indicating that the + server does not support tool calls, or any other exceptional conditions, + should be reported as an MCP error response.*/ #[serde(rename = "isError", default, skip_serializing_if = "::std::option::Option::is_none")] pub is_error: ::std::option::Option, ///This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses. #[serde(rename = "_meta", default, skip_serializing_if = "::std::option::Option::is_none")] pub meta: ::std::option::Option<::serde_json::Map<::std::string::String, ::serde_json::Value>>, + ///An optional JSON object that represents the structured result of the tool call. + #[serde( + rename = "structuredContent", + default, + skip_serializing_if = "::std::option::Option::is_none" + )] + pub structured_content: ::std::option::Option<::serde_json::Map<::std::string::String, ::serde_json::Value>>, } -///CallToolUnstructuredResultContentItem +///CallToolResultContentItem /// ///
JSON schema /// @@ -493,28 +350,28 @@ pub struct CallToolUnstructuredResult { ///
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)] #[serde(untagged)] -pub enum CallToolUnstructuredResultContentItem { +pub enum CallToolResultContentItem { TextContent(TextContent), ImageContent(ImageContent), AudioContent(AudioContent), EmbeddedResource(EmbeddedResource), } -impl ::std::convert::From for CallToolUnstructuredResultContentItem { +impl ::std::convert::From for CallToolResultContentItem { fn from(value: TextContent) -> Self { Self::TextContent(value) } } -impl ::std::convert::From for CallToolUnstructuredResultContentItem { +impl ::std::convert::From for CallToolResultContentItem { fn from(value: ImageContent) -> Self { Self::ImageContent(value) } } -impl ::std::convert::From for CallToolUnstructuredResultContentItem { +impl ::std::convert::From for CallToolResultContentItem { fn from(value: AudioContent) -> Self { Self::AudioContent(value) } } -impl ::std::convert::From for CallToolUnstructuredResultContentItem { +impl ::std::convert::From for CallToolResultContentItem { fn from(value: EmbeddedResource) -> Self { Self::EmbeddedResource(value) } @@ -1192,86 +1049,6 @@ pub struct CompleteResultCompletion { ///An array of completion values. Must not exceed 100 items. pub values: ::std::vec::Vec<::std::string::String>, } -///ContentList -/// -///
JSON schema -/// -/// ```json -///{ -/// "type": "array", -/// "items": { -/// "anyOf": [ -/// { -/// "$ref": "#/definitions/TextContent" -/// }, -/// { -/// "$ref": "#/definitions/ImageContent" -/// }, -/// { -/// "$ref": "#/definitions/AudioContent" -/// }, -/// { -/// "$ref": "#/definitions/EmbeddedResource" -/// } -/// ] -/// } -///} -/// ``` -///
-#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)] -#[serde(transparent)] -pub struct ContentList(pub ::std::vec::Vec); -///ContentListItem -/// -///
JSON schema -/// -/// ```json -///{ -/// "anyOf": [ -/// { -/// "$ref": "#/definitions/TextContent" -/// }, -/// { -/// "$ref": "#/definitions/ImageContent" -/// }, -/// { -/// "$ref": "#/definitions/AudioContent" -/// }, -/// { -/// "$ref": "#/definitions/EmbeddedResource" -/// } -/// ] -///} -/// ``` -///
-#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)] -#[serde(untagged)] -pub enum ContentListItem { - TextContent(TextContent), - ImageContent(ImageContent), - AudioContent(AudioContent), - EmbeddedResource(EmbeddedResource), -} -impl ::std::convert::From for ContentListItem { - fn from(value: TextContent) -> Self { - Self::TextContent(value) - } -} -impl ::std::convert::From for ContentListItem { - fn from(value: ImageContent) -> Self { - Self::ImageContent(value) - } -} -impl ::std::convert::From for ContentListItem { - fn from(value: AudioContent) -> Self { - Self::AudioContent(value) - } -} -impl ::std::convert::From for ContentListItem { - fn from(value: EmbeddedResource) -> Self { - Self::EmbeddedResource(value) - } -} ///A request from the server to sample an LLM via the client. The client has full discretion over which model to select. The client should also inform the user before beginning sampling, to allow them to inspect the request (human in the loop) and decide whether to approve it. /// ///
JSON schema @@ -5412,10 +5189,7 @@ impl ::std::convert::From for ServerRequest { /// "$ref": "#/definitions/ListToolsResult" /// }, /// { -/// "$ref": "#/definitions/CallToolUnstructuredResult" -/// }, -/// { -/// "$ref": "#/definitions/CallToolStructuredResult" +/// "$ref": "#/definitions/CallToolResult" /// }, /// { /// "$ref": "#/definitions/CompleteResult" @@ -5434,8 +5208,7 @@ pub enum ServerResult { ListPromptsResult(ListPromptsResult), GetPromptResult(GetPromptResult), ListToolsResult(ListToolsResult), - CallToolUnstructuredResult(CallToolUnstructuredResult), - CallToolStructuredResult(CallToolStructuredResult), + CallToolResult(CallToolResult), CompleteResult(CompleteResult), Result(Result), } @@ -5474,14 +5247,9 @@ impl ::std::convert::From for ServerResult { Self::ListToolsResult(value) } } -impl ::std::convert::From for ServerResult { - fn from(value: CallToolUnstructuredResult) -> Self { - Self::CallToolUnstructuredResult(value) - } -} -impl ::std::convert::From for ServerResult { - fn from(value: CallToolStructuredResult) -> Self { - Self::CallToolStructuredResult(value) +impl ::std::convert::From for ServerResult { + fn from(value: CallToolResult) -> Self { + Self::CallToolResult(value) } } impl ::std::convert::From for ServerResult { @@ -5793,7 +5561,7 @@ pub struct TextResourceContents { /// "type": "string" /// }, /// "outputSchema": { -/// "description": "An optional JSON Schema object defining the structure of the tool's output.\n\nIf set, a CallToolResult for this Tool MUST contain a structuredContent field whose contents validate against this schema.\nIf not set, a CallToolResult for this Tool MUST contain a content field.", +/// "description": "An optional JSON Schema object defining the structure of the tool's output returned in \nthe structuredContent field of a CallToolResult.", /// "type": "object", /// "required": [ /// "type" @@ -6049,15 +5817,14 @@ pub struct ToolListChangedNotificationParams { #[serde(flatten, default, skip_serializing_if = "::std::option::Option::is_none")] pub extra: ::std::option::Option<::serde_json::Map<::std::string::String, ::serde_json::Value>>, } -/**An optional JSON Schema object defining the structure of the tool's output. -If set, a CallToolResult for this Tool MUST contain a structuredContent field whose contents validate against this schema. -If not set, a CallToolResult for this Tool MUST contain a content field.*/ +/**An optional JSON Schema object defining the structure of the tool's output returned in +the structuredContent field of a CallToolResult.*/ /// ///
JSON schema /// /// ```json ///{ -/// "description": "An optional JSON Schema object defining the structure of the tool's output.\n\nIf set, a CallToolResult for this Tool MUST contain a structuredContent field whose contents validate against this schema.\nIf not set, a CallToolResult for this Tool MUST contain a content field.", +/// "description": "An optional JSON Schema object defining the structure of the tool's output returned in \nthe structuredContent field of a CallToolResult.", /// "type": "object", /// "required": [ /// "type" diff --git a/src/generated_schema/draft/schema_utils.rs b/src/generated_schema/draft/schema_utils.rs index a440f96..22152cd 100644 --- a/src/generated_schema/draft/schema_utils.rs +++ b/src/generated_schema/draft/schema_utils.rs @@ -1422,11 +1422,11 @@ impl std::error::Error for CallToolError { } } -/// Conversion of `CallToolError` into a `CallToolUnstructuredResult` with an error. -impl From for CallToolUnstructuredResult { +/// Conversion of `CallToolError` into a `CallToolResult` with an error. +impl From for CallToolResult { fn from(value: CallToolError) -> Self { - // Convert `CallToolError` to a `CallToolUnstructuredResult` by using the `with_error` method - CallToolUnstructuredResult::with_error(value) + // Convert `CallToolError` to a `CallToolResult` by using the `with_error` method + CallToolResult::with_error(value) } } @@ -2543,13 +2543,8 @@ impl From for ResultFromServer { Self::ServerResult(value.into()) } } -impl From for ResultFromServer { - fn from(value: CallToolUnstructuredResult) -> Self { - Self::ServerResult(value.into()) - } -} -impl From for ResultFromServer { - fn from(value: CallToolStructuredResult) -> Self { +impl From for ResultFromServer { + fn from(value: CallToolResult) -> Self { Self::ServerResult(value.into()) } } @@ -2598,13 +2593,8 @@ impl From for MessageFromServer { MessageFromServer::ResultFromServer(value.into()) } } -impl From for MessageFromServer { - fn from(value: CallToolUnstructuredResult) -> Self { - MessageFromServer::ResultFromServer(value.into()) - } -} -impl From for MessageFromServer { - fn from(value: CallToolStructuredResult) -> Self { +impl From for MessageFromServer { + fn from(value: CallToolResult) -> Self { MessageFromServer::ResultFromServer(value.into()) } } @@ -3039,11 +3029,8 @@ impl ToMessage for ListToolsResult { ServerMessage::from_message(self, request_id) } } -impl FromMessage for ServerMessage { - fn from_message( - message: CallToolUnstructuredResult, - request_id: Option, - ) -> std::result::Result { +impl FromMessage for ServerMessage { + fn from_message(message: CallToolResult, request_id: Option) -> std::result::Result { let request_id = request_id.ok_or_else(|| RpcError::internal_error().with_message("request_id is None!".to_string()))?; Ok(ServerMessage::Response(ServerJsonrpcResponse::new( @@ -3052,25 +3039,7 @@ impl FromMessage for ServerMessage { ))) } } -impl ToMessage for CallToolUnstructuredResult { - fn to_message(self, request_id: Option) -> std::result::Result { - ServerMessage::from_message(self, request_id) - } -} -impl FromMessage for ServerMessage { - fn from_message( - message: CallToolStructuredResult, - request_id: Option, - ) -> std::result::Result { - let request_id = - request_id.ok_or_else(|| RpcError::internal_error().with_message("request_id is None!".to_string()))?; - Ok(ServerMessage::Response(ServerJsonrpcResponse::new( - request_id, - message.into(), - ))) - } -} -impl ToMessage for CallToolStructuredResult { +impl ToMessage for CallToolResult { fn to_message(self, request_id: Option) -> std::result::Result { ServerMessage::from_message(self, request_id) } @@ -3551,25 +3520,14 @@ impl TryFrom for ListToolsResult { } } } -impl TryFrom for CallToolUnstructuredResult { - type Error = RpcError; - fn try_from(value: ResultFromServer) -> std::result::Result { - let matched_type: ServerResult = value.try_into()?; - if let ServerResult::CallToolUnstructuredResult(result) = matched_type { - Ok(result) - } else { - Err(RpcError::internal_error().with_message("Not a CallToolUnstructuredResult".to_string())) - } - } -} -impl TryFrom for CallToolStructuredResult { +impl TryFrom for CallToolResult { type Error = RpcError; fn try_from(value: ResultFromServer) -> std::result::Result { let matched_type: ServerResult = value.try_into()?; - if let ServerResult::CallToolStructuredResult(result) = matched_type { + if let ServerResult::CallToolResult(result) = matched_type { Ok(result) } else { - Err(RpcError::internal_error().with_message("Not a CallToolStructuredResult".to_string())) + Err(RpcError::internal_error().with_message("Not a CallToolResult".to_string())) } } } @@ -3661,12 +3619,12 @@ impl TryFrom for LoggingMessageNotification { } } } -impl CallToolUnstructuredResultContentItem { - ///Create a CallToolUnstructuredResultContentItem::TextContent +impl CallToolResultContentItem { + ///Create a CallToolResultContentItem::TextContent pub fn text_content(text: ::std::string::String, annotations: ::std::option::Option) -> Self { TextContent::new(text, annotations).into() } - ///Create a CallToolUnstructuredResultContentItem::ImageContent + ///Create a CallToolResultContentItem::ImageContent pub fn image_content( data: ::std::string::String, mime_type: ::std::string::String, @@ -3674,7 +3632,7 @@ impl CallToolUnstructuredResultContentItem { ) -> Self { ImageContent::new(data, mime_type, annotations).into() } - ///Create a CallToolUnstructuredResultContentItem::AudioContent + ///Create a CallToolResultContentItem::AudioContent pub fn audio_content( data: ::std::string::String, mime_type: ::std::string::String, @@ -3682,23 +3640,23 @@ impl CallToolUnstructuredResultContentItem { ) -> Self { AudioContent::new(data, mime_type, annotations).into() } - ///Create a CallToolUnstructuredResultContentItem::EmbeddedResource + ///Create a CallToolResultContentItem::EmbeddedResource pub fn embedded_resource(resource: EmbeddedResourceResource, annotations: ::std::option::Option) -> Self { EmbeddedResource::new(resource, annotations).into() } /// Returns the content type as a string based on the variant of `CallToolResultContentItem`. pub fn content_type(&self) -> &str { match self { - CallToolUnstructuredResultContentItem::TextContent(text_content) => text_content.type_(), - CallToolUnstructuredResultContentItem::ImageContent(image_content) => image_content.type_(), - CallToolUnstructuredResultContentItem::AudioContent(audio_content) => audio_content.type_(), - CallToolUnstructuredResultContentItem::EmbeddedResource(embedded_resource) => embedded_resource.type_(), + CallToolResultContentItem::TextContent(text_content) => text_content.type_(), + CallToolResultContentItem::ImageContent(image_content) => image_content.type_(), + CallToolResultContentItem::AudioContent(audio_content) => audio_content.type_(), + CallToolResultContentItem::EmbeddedResource(embedded_resource) => embedded_resource.type_(), } } /// Converts the content to a reference to `TextContent`, returning an error if the conversion is invalid. pub fn as_text_content(&self) -> std::result::Result<&TextContent, RpcError> { match &self { - CallToolUnstructuredResultContentItem::TextContent(text_content) => Ok(text_content), + CallToolResultContentItem::TextContent(text_content) => Ok(text_content), _ => Err(RpcError::internal_error().with_message(format!( "Invalid conversion, \"{}\" is not a {}", self.content_type(), @@ -3709,7 +3667,7 @@ impl CallToolUnstructuredResultContentItem { /// Converts the content to a reference to `TextContent`, returning an error if the conversion is invalid. pub fn as_image_content(&self) -> std::result::Result<&ImageContent, RpcError> { match &self { - CallToolUnstructuredResultContentItem::ImageContent(image_content) => Ok(image_content), + CallToolResultContentItem::ImageContent(image_content) => Ok(image_content), _ => Err(RpcError::internal_error().with_message(format!( "Invalid conversion, \"{}\" is not a {}", self.content_type(), @@ -3720,7 +3678,7 @@ impl CallToolUnstructuredResultContentItem { /// Converts the content to a reference to `TextContent`, returning an error if the conversion is invalid. pub fn as_audio_content(&self) -> std::result::Result<&AudioContent, RpcError> { match &self { - CallToolUnstructuredResultContentItem::AudioContent(audio_content) => Ok(audio_content), + CallToolResultContentItem::AudioContent(audio_content) => Ok(audio_content), _ => Err(RpcError::internal_error().with_message(format!( "Invalid conversion, \"{}\" is not a {}", self.content_type(), @@ -3731,7 +3689,7 @@ impl CallToolUnstructuredResultContentItem { /// Converts the content to a reference to `TextContent`, returning an error if the conversion is invalid. pub fn as_embedded_resource(&self) -> std::result::Result<&EmbeddedResource, RpcError> { match &self { - CallToolUnstructuredResultContentItem::EmbeddedResource(embedded_resource) => Ok(embedded_resource), + CallToolResultContentItem::EmbeddedResource(embedded_resource) => Ok(embedded_resource), _ => Err(RpcError::internal_error().with_message(format!( "Invalid conversion, \"{}\" is not a {}", self.content_type(), @@ -3740,13 +3698,13 @@ impl CallToolUnstructuredResultContentItem { } } } - -impl CallToolUnstructuredResult { +impl CallToolResult { pub fn text_content(text: ::std::string::String, annotations: ::std::option::Option) -> Self { Self { content: vec![TextContent::new(text, annotations).into()], is_error: None, meta: None, + structured_content: None, } } pub fn image_content( @@ -3758,6 +3716,7 @@ impl CallToolUnstructuredResult { content: vec![ImageContent::new(data, mime_type, annotations).into()], is_error: None, meta: None, + structured_content: None, } } pub fn audio_content( @@ -3769,6 +3728,7 @@ impl CallToolUnstructuredResult { content: vec![AudioContent::new(data, mime_type, annotations).into()], is_error: None, meta: None, + structured_content: None, } } pub fn embedded_resource(resource: EmbeddedResourceResource, annotations: ::std::option::Option) -> Self { @@ -3776,17 +3736,19 @@ impl CallToolUnstructuredResult { content: vec![EmbeddedResource::new(resource, annotations).into()], is_error: None, meta: None, + structured_content: None, } } /// Create a `CallToolResult` with an error, containing an error message in the content pub fn with_error(error: CallToolError) -> Self { Self { - content: vec![CallToolUnstructuredResultContentItem::TextContent(TextContent::new( + content: vec![CallToolResultContentItem::TextContent(TextContent::new( error.to_string(), None, ))], is_error: Some(true), meta: None, + structured_content: None, } } /// Adds metadata to the `CallToolResult`, allowing additional context or information to be included diff --git a/src/generated_schema/protocol_version.rs b/src/generated_schema/protocol_version.rs new file mode 100644 index 0000000..e7acb05 --- /dev/null +++ b/src/generated_schema/protocol_version.rs @@ -0,0 +1,39 @@ +use std::fmt::Display; +#[derive(Debug, PartialEq, Eq)] +pub enum ProtocolVersion { + V2024_11_05, + V2025_03_26, + Draft, +} +impl Display for ProtocolVersion { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ProtocolVersion::V2024_11_05 => write!(f, "2024-11-05"), + ProtocolVersion::V2025_03_26 => write!(f, "2025-03-26"), + ProtocolVersion::Draft => write!(f, "DRAFT-2025-v2"), + } + } +} +#[derive(Debug)] +pub struct ParseProtocolVersionError { + details: String, +} +impl std::fmt::Display for ParseProtocolVersionError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Protocol version parse error: {}", self.details) + } +} +impl std::error::Error for ParseProtocolVersionError {} +impl TryFrom<&str> for ProtocolVersion { + type Error = ParseProtocolVersionError; + fn try_from(value: &str) -> Result { + match value { + "2024-11-05" => Ok(ProtocolVersion::V2024_11_05), + "2025-03-26" => Ok(ProtocolVersion::V2025_03_26), + "DRAFT-2025-v2" => Ok(ProtocolVersion::Draft), + other => Err(ParseProtocolVersionError { + details: other.to_string(), + }), + } + } +} diff --git a/tests/test_serialize.rs b/tests/test_serialize.rs index 69ba073..f2d6ee1 100644 --- a/tests/test_serialize.rs +++ b/tests/test_serialize.rs @@ -388,26 +388,6 @@ mod test_serialize { )); } - #[cfg(feature = "draft")] - #[test] - fn test_server_call_tool_result() { - let message: ServerMessage = ServerMessage::Response(ServerJsonrpcResponse::new( - RequestId::Integer(15), - ResultFromServer::ServerResult(ServerResult::CallToolUnstructuredResult(CallToolUnstructuredResult { - meta: None, - content: vec![], - is_error: None, - })), - )); - - let message: ServerMessage = re_serialize(message); - - assert!(matches!(message, ServerMessage::Response(server_message) - if matches!(&server_message.result, ResultFromServer::ServerResult(server_result) - if matches!(server_result, ServerResult::CallToolUnstructuredResult(_))) - )); - } - #[test] fn test_server_custom_result() { let custom_result: serde_json::Map = json!({