From 6790cc2e2a7c563a84e081ceb952b02d85053cc8 Mon Sep 17 00:00:00 2001 From: Dylan Anthony Date: Mon, 10 Nov 2025 11:31:12 -0700 Subject: [PATCH] Add _meta to tool definitions --- crates/rmcp-macros/src/tool.rs | 11 +++++++++++ crates/rmcp/src/model/tool.rs | 6 +++++- .../server_json_rpc_message_schema.json | 8 ++++++++ .../server_json_rpc_message_schema_current.json | 8 ++++++++ examples/servers/src/sampling_stdio.rs | 1 + 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/crates/rmcp-macros/src/tool.rs b/crates/rmcp-macros/src/tool.rs index 675ba6e1..fe389be0 100644 --- a/crates/rmcp-macros/src/tool.rs +++ b/crates/rmcp-macros/src/tool.rs @@ -77,6 +77,8 @@ pub struct ToolAttribute { pub annotations: Option, /// Optional icons for the tool pub icons: Option, + /// Optional metadata for the tool + pub meta: Option, } pub struct ResolvedToolAttribute { @@ -87,6 +89,7 @@ pub struct ResolvedToolAttribute { pub output_schema: Option, pub annotations: Expr, pub icons: Option, + pub meta: Option, } impl ResolvedToolAttribute { @@ -99,6 +102,7 @@ impl ResolvedToolAttribute { output_schema, annotations, icons, + meta, } = self; let description = if let Some(description) = description { quote! { Some(#description.into()) } @@ -120,6 +124,11 @@ impl ResolvedToolAttribute { } else { quote! { None } }; + let meta = if let Some(meta) = meta { + quote! { Some(#meta) } + } else { + quote! { None } + }; let doc_comment = format!("Generated tool metadata function for {name}"); let doc_attr: syn::Attribute = parse_quote!(#[doc = #doc_comment]); let tokens = quote! { @@ -133,6 +142,7 @@ impl ResolvedToolAttribute { output_schema: #output_schema, annotations: #annotations, icons: #icons, + meta: #meta, } } }; @@ -264,6 +274,7 @@ pub fn tool(attr: TokenStream, input: TokenStream) -> syn::Result { annotations: annotations_expr, title: attribute.title, icons: attribute.icons, + meta: attribute.meta, }; let tool_attr_fn = resolved_tool_attr.into_fn(tool_attr_fn_ident)?; // modify the the input function diff --git a/crates/rmcp/src/model/tool.rs b/crates/rmcp/src/model/tool.rs index 282d8aa3..c7309bbe 100644 --- a/crates/rmcp/src/model/tool.rs +++ b/crates/rmcp/src/model/tool.rs @@ -6,7 +6,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_json::Value; -use super::{Icon, JsonObject}; +use super::{Icon, JsonObject, Meta}; /// A tool that can be used by a model. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] @@ -32,6 +32,9 @@ pub struct Tool { /// Optional list of icons for the tool #[serde(skip_serializing_if = "Option::is_none")] pub icons: Option>, + /// Optional additional metadata for this tool + #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")] + pub meta: Option, } /// Additional properties describing a Tool to clients. @@ -150,6 +153,7 @@ impl Tool { output_schema: None, annotations: None, icons: None, + meta: None, } } diff --git a/crates/rmcp/tests/test_message_schema/server_json_rpc_message_schema.json b/crates/rmcp/tests/test_message_schema/server_json_rpc_message_schema.json index 663a6894..223989cb 100644 --- a/crates/rmcp/tests/test_message_schema/server_json_rpc_message_schema.json +++ b/crates/rmcp/tests/test_message_schema/server_json_rpc_message_schema.json @@ -2292,6 +2292,14 @@ "description": "A tool that can be used by a model.", "type": "object", "properties": { + "_meta": { + "description": "Optional additional metadata for this tool", + "type": [ + "object", + "null" + ], + "additionalProperties": true + }, "annotations": { "description": "Optional additional tool information.", "anyOf": [ diff --git a/crates/rmcp/tests/test_message_schema/server_json_rpc_message_schema_current.json b/crates/rmcp/tests/test_message_schema/server_json_rpc_message_schema_current.json index 663a6894..223989cb 100644 --- a/crates/rmcp/tests/test_message_schema/server_json_rpc_message_schema_current.json +++ b/crates/rmcp/tests/test_message_schema/server_json_rpc_message_schema_current.json @@ -2292,6 +2292,14 @@ "description": "A tool that can be used by a model.", "type": "object", "properties": { + "_meta": { + "description": "Optional additional metadata for this tool", + "type": [ + "object", + "null" + ], + "additionalProperties": true + }, "annotations": { "description": "Optional additional tool information.", "anyOf": [ diff --git a/examples/servers/src/sampling_stdio.rs b/examples/servers/src/sampling_stdio.rs index 4daa261c..29125d9b 100644 --- a/examples/servers/src/sampling_stdio.rs +++ b/examples/servers/src/sampling_stdio.rs @@ -123,6 +123,7 @@ impl ServerHandler for SamplingDemoServer { output_schema: None, annotations: None, icons: None, + meta: None, }], next_cursor: None, })