Skip to main content

rmcp/handler/server/wrapper/
json.rs

1use std::borrow::Cow;
2
3use schemars::JsonSchema;
4use serde::Serialize;
5
6use crate::{
7    handler::server::tool::IntoCallToolResult,
8    model::{CallToolResponse, CallToolResult},
9};
10
11/// Json wrapper for structured output
12///
13/// When used with tools, this wrapper indicates that the value should be
14/// serialized as structured JSON content with an associated schema.
15/// The framework will place the JSON in the `structured_content` field
16/// of the tool result rather than the regular `content` field.
17#[expect(clippy::exhaustive_structs, reason = "intentionally exhaustive")]
18pub struct Json<T>(pub T);
19
20// Implement JsonSchema for Json<T> to delegate to T's schema
21impl<T: JsonSchema> JsonSchema for Json<T> {
22    fn schema_name() -> Cow<'static, str> {
23        T::schema_name()
24    }
25
26    fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
27        T::json_schema(generator)
28    }
29}
30
31// Implementation for Json<T> to create structured content
32impl<T: Serialize + JsonSchema + 'static> IntoCallToolResult for Json<T> {
33    fn into_call_tool_result(self) -> Result<CallToolResponse, crate::ErrorData> {
34        let value = serde_json::to_value(self.0).map_err(|e| {
35            crate::ErrorData::internal_error(
36                format!("Failed to serialize structured content: {}", e),
37                None,
38            )
39        })?;
40
41        Ok(CallToolResult::structured(value).into())
42    }
43}