feat(meta): add _meta field to prompts, resources and paginated result (#558)
This commit is contained in:
parent
eb5a7f7408
commit
81411fc12d
14 changed files with 195 additions and 8 deletions
|
|
@ -18,6 +18,8 @@ pub struct PromptAttribute {
|
||||||
pub arguments: Option<Expr>,
|
pub arguments: Option<Expr>,
|
||||||
/// Optional icons for the prompt
|
/// Optional icons for the prompt
|
||||||
pub icons: Option<Expr>,
|
pub icons: Option<Expr>,
|
||||||
|
/// Optional metadata for the prompt
|
||||||
|
pub meta: Option<Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ResolvedPromptAttribute {
|
pub struct ResolvedPromptAttribute {
|
||||||
|
|
@ -26,6 +28,7 @@ pub struct ResolvedPromptAttribute {
|
||||||
pub description: Option<Expr>,
|
pub description: Option<Expr>,
|
||||||
pub arguments: Expr,
|
pub arguments: Expr,
|
||||||
pub icons: Option<Expr>,
|
pub icons: Option<Expr>,
|
||||||
|
pub meta: Option<Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResolvedPromptAttribute {
|
impl ResolvedPromptAttribute {
|
||||||
|
|
@ -36,6 +39,7 @@ impl ResolvedPromptAttribute {
|
||||||
arguments,
|
arguments,
|
||||||
title,
|
title,
|
||||||
icons,
|
icons,
|
||||||
|
meta,
|
||||||
} = self;
|
} = self;
|
||||||
let description = if let Some(description) = description {
|
let description = if let Some(description) = description {
|
||||||
quote! { Some(#description.into()) }
|
quote! { Some(#description.into()) }
|
||||||
|
|
@ -52,6 +56,11 @@ impl ResolvedPromptAttribute {
|
||||||
} else {
|
} else {
|
||||||
quote! { None }
|
quote! { None }
|
||||||
};
|
};
|
||||||
|
let meta = if let Some(meta) = meta {
|
||||||
|
quote! { Some(#meta) }
|
||||||
|
} else {
|
||||||
|
quote! { None }
|
||||||
|
};
|
||||||
let tokens = quote! {
|
let tokens = quote! {
|
||||||
pub fn #fn_ident() -> rmcp::model::Prompt {
|
pub fn #fn_ident() -> rmcp::model::Prompt {
|
||||||
rmcp::model::Prompt {
|
rmcp::model::Prompt {
|
||||||
|
|
@ -60,6 +69,7 @@ impl ResolvedPromptAttribute {
|
||||||
arguments: #arguments,
|
arguments: #arguments,
|
||||||
title: #title,
|
title: #title,
|
||||||
icons: #icons,
|
icons: #icons,
|
||||||
|
meta: #meta,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -114,6 +124,7 @@ pub fn prompt(attr: TokenStream, input: TokenStream) -> syn::Result<TokenStream>
|
||||||
arguments: arguments.clone(),
|
arguments: arguments.clone(),
|
||||||
title: attribute.title,
|
title: attribute.title,
|
||||||
icons: attribute.icons,
|
icons: attribute.icons,
|
||||||
|
meta: attribute.meta,
|
||||||
};
|
};
|
||||||
let prompt_attr_fn = resolved_prompt_attr.into_fn(prompt_attr_fn_ident.clone())?;
|
let prompt_attr_fn = resolved_prompt_attr.into_fn(prompt_attr_fn_ident.clone())?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use syn::{Expr, ImplItem, ItemImpl, parse_quote};
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
pub struct PromptHandlerAttribute {
|
pub struct PromptHandlerAttribute {
|
||||||
pub router: Option<Expr>,
|
pub router: Option<Expr>,
|
||||||
|
pub meta: Option<Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prompt_handler(attr: TokenStream, input: TokenStream) -> syn::Result<TokenStream> {
|
pub fn prompt_handler(attr: TokenStream, input: TokenStream) -> syn::Result<TokenStream> {
|
||||||
|
|
@ -40,6 +41,12 @@ pub fn prompt_handler(attr: TokenStream, input: TokenStream) -> syn::Result<Toke
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let meta = if let Some(meta) = attribute.meta {
|
||||||
|
quote! { Some(#meta) }
|
||||||
|
} else {
|
||||||
|
quote! { None }
|
||||||
|
};
|
||||||
|
|
||||||
// Add list_prompts implementation
|
// Add list_prompts implementation
|
||||||
let list_prompts_impl: ImplItem = parse_quote! {
|
let list_prompts_impl: ImplItem = parse_quote! {
|
||||||
async fn list_prompts(
|
async fn list_prompts(
|
||||||
|
|
@ -50,6 +57,7 @@ pub fn prompt_handler(attr: TokenStream, input: TokenStream) -> syn::Result<Toke
|
||||||
let prompts = #router_expr.list_all();
|
let prompts = #router_expr.list_all();
|
||||||
Ok(ListPromptsResult {
|
Ok(ListPromptsResult {
|
||||||
prompts,
|
prompts,
|
||||||
|
meta: #meta,
|
||||||
next_cursor: None,
|
next_cursor: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use syn::{Expr, ImplItem, ItemImpl};
|
||||||
#[darling(default)]
|
#[darling(default)]
|
||||||
pub struct ToolHandlerAttribute {
|
pub struct ToolHandlerAttribute {
|
||||||
pub router: Expr,
|
pub router: Expr,
|
||||||
|
pub meta: Option<Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ToolHandlerAttribute {
|
impl Default for ToolHandlerAttribute {
|
||||||
|
|
@ -16,13 +17,14 @@ impl Default for ToolHandlerAttribute {
|
||||||
self.tool_router
|
self.tool_router
|
||||||
})
|
})
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tool_handler(attr: TokenStream, input: TokenStream) -> syn::Result<TokenStream> {
|
pub fn tool_handler(attr: TokenStream, input: TokenStream) -> syn::Result<TokenStream> {
|
||||||
let attr_args = NestedMeta::parse_meta_list(attr)?;
|
let attr_args = NestedMeta::parse_meta_list(attr)?;
|
||||||
let ToolHandlerAttribute { router } = ToolHandlerAttribute::from_list(&attr_args)?;
|
let ToolHandlerAttribute { router, meta } = ToolHandlerAttribute::from_list(&attr_args)?;
|
||||||
let mut item_impl = syn::parse2::<ItemImpl>(input.clone())?;
|
let mut item_impl = syn::parse2::<ItemImpl>(input.clone())?;
|
||||||
let tool_call_fn = quote! {
|
let tool_call_fn = quote! {
|
||||||
async fn call_tool(
|
async fn call_tool(
|
||||||
|
|
@ -34,13 +36,24 @@ pub fn tool_handler(attr: TokenStream, input: TokenStream) -> syn::Result<TokenS
|
||||||
#router.call(tcc).await
|
#router.call(tcc).await
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let result_meta = if let Some(meta) = meta {
|
||||||
|
quote! { Some(#meta) }
|
||||||
|
} else {
|
||||||
|
quote! { None }
|
||||||
|
};
|
||||||
|
|
||||||
let tool_list_fn = quote! {
|
let tool_list_fn = quote! {
|
||||||
async fn list_tools(
|
async fn list_tools(
|
||||||
&self,
|
&self,
|
||||||
_request: Option<rmcp::model::PaginatedRequestParam>,
|
_request: Option<rmcp::model::PaginatedRequestParam>,
|
||||||
_context: rmcp::service::RequestContext<rmcp::RoleServer>,
|
_context: rmcp::service::RequestContext<rmcp::RoleServer>,
|
||||||
) -> Result<rmcp::model::ListToolsResult, rmcp::ErrorData> {
|
) -> Result<rmcp::model::ListToolsResult, rmcp::ErrorData> {
|
||||||
Ok(rmcp::model::ListToolsResult::with_all_items(#router.list_all()))
|
Ok(rmcp::model::ListToolsResult{
|
||||||
|
tools: #router.list_all(),
|
||||||
|
meta: #result_meta,
|
||||||
|
next_cursor: None,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let tool_call_fn = syn::parse2::<ImplItem>(tool_call_fn)?;
|
let tool_call_fn = syn::parse2::<ImplItem>(tool_call_fn)?;
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ where
|
||||||
let tools = self.tool_router.list_all();
|
let tools = self.tool_router.list_all();
|
||||||
Ok(ServerResult::ListToolsResult(ListToolsResult {
|
Ok(ServerResult::ListToolsResult(ListToolsResult {
|
||||||
tools,
|
tools,
|
||||||
next_cursor: None,
|
..Default::default()
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
ClientRequest::GetPromptRequest(request) => {
|
ClientRequest::GetPromptRequest(request) => {
|
||||||
|
|
@ -125,7 +125,7 @@ where
|
||||||
let prompts = self.prompt_router.list_all();
|
let prompts = self.prompt_router.list_all();
|
||||||
Ok(ServerResult::ListPromptsResult(ListPromptsResult {
|
Ok(ServerResult::ListPromptsResult(ListPromptsResult {
|
||||||
prompts,
|
prompts,
|
||||||
next_cursor: None,
|
..Default::default()
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
rest => self.service.handle_request(rest, context).await,
|
rest => self.service.handle_request(rest, context).await,
|
||||||
|
|
|
||||||
|
|
@ -828,6 +828,8 @@ macro_rules! paginated_result {
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
pub struct $t {
|
pub struct $t {
|
||||||
|
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
|
||||||
|
pub meta: Option<Meta>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub next_cursor: Option<Cursor>,
|
pub next_cursor: Option<Cursor>,
|
||||||
pub $i_item: $t_item,
|
pub $i_item: $t_item,
|
||||||
|
|
@ -838,6 +840,7 @@ macro_rules! paginated_result {
|
||||||
items: $t_item,
|
items: $t_item,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
meta: None,
|
||||||
next_cursor: None,
|
next_cursor: None,
|
||||||
$i_item: items,
|
$i_item: items,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,7 @@ mod tests {
|
||||||
mime_type: Some("text/plain".to_string()),
|
mime_type: Some("text/plain".to_string()),
|
||||||
size: Some(100),
|
size: Some(100),
|
||||||
icons: None,
|
icons: None,
|
||||||
|
meta: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
let json = serde_json::to_string(&resource_link).unwrap();
|
let json = serde_json::to_string(&resource_link).unwrap();
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use base64::engine::{Engine, general_purpose::STANDARD as BASE64_STANDARD};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
AnnotateAble, Annotations, Icon, RawEmbeddedResource, RawImageContent,
|
AnnotateAble, Annotations, Icon, Meta, RawEmbeddedResource, RawImageContent,
|
||||||
content::{EmbeddedResource, ImageContent},
|
content::{EmbeddedResource, ImageContent},
|
||||||
resource::ResourceContents,
|
resource::ResourceContents,
|
||||||
};
|
};
|
||||||
|
|
@ -25,6 +25,9 @@ pub struct Prompt {
|
||||||
/// Optional list of icons for the prompt
|
/// Optional list of icons for the prompt
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub icons: Option<Vec<Icon>>,
|
pub icons: Option<Vec<Icon>>,
|
||||||
|
/// Optional additional metadata for this prompt
|
||||||
|
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
|
||||||
|
pub meta: Option<Meta>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Prompt {
|
impl Prompt {
|
||||||
|
|
@ -44,6 +47,7 @@ impl Prompt {
|
||||||
description: description.map(Into::into),
|
description: description.map(Into::into),
|
||||||
arguments,
|
arguments,
|
||||||
icons: None,
|
icons: None,
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ pub struct RawResource {
|
||||||
/// Optional list of icons for the resource
|
/// Optional list of icons for the resource
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub icons: Option<Vec<Icon>>,
|
pub icons: Option<Vec<Icon>>,
|
||||||
|
/// Optional additional metadata for this resource
|
||||||
|
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
|
||||||
|
pub meta: Option<Meta>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Resource = Annotated<RawResource>;
|
pub type Resource = Annotated<RawResource>;
|
||||||
|
|
@ -95,6 +98,7 @@ impl RawResource {
|
||||||
mime_type: None,
|
mime_type: None,
|
||||||
size: None,
|
size: None,
|
||||||
icons: None,
|
icons: None,
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -115,6 +119,7 @@ mod tests {
|
||||||
mime_type: Some("text/plain".to_string()),
|
mime_type: Some("text/plain".to_string()),
|
||||||
size: Some(100),
|
size: Some(100),
|
||||||
icons: None,
|
icons: None,
|
||||||
|
meta: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let json = serde_json::to_string(&resource).unwrap();
|
let json = serde_json::to_string(&resource).unwrap();
|
||||||
|
|
|
||||||
|
|
@ -992,6 +992,14 @@
|
||||||
"description": "Represents a resource in the extension with metadata",
|
"description": "Represents a resource in the extension with metadata",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"description": "Optional additional metadata for this resource",
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Optional description of the resource",
|
"description": "Optional description of the resource",
|
||||||
"type": [
|
"type": [
|
||||||
|
|
|
||||||
|
|
@ -992,6 +992,14 @@
|
||||||
"description": "Represents a resource in the extension with metadata",
|
"description": "Represents a resource in the extension with metadata",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"description": "Optional additional metadata for this resource",
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Optional description of the resource",
|
"description": "Optional description of the resource",
|
||||||
"type": [
|
"type": [
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,14 @@
|
||||||
"description": "Represents a resource in the extension with metadata",
|
"description": "Represents a resource in the extension with metadata",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"description": "Optional additional metadata for this resource",
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"annotations": {
|
"annotations": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
|
|
@ -1031,6 +1039,13 @@
|
||||||
"ListPromptsResult": {
|
"ListPromptsResult": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"nextCursor": {
|
"nextCursor": {
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
|
|
@ -1051,6 +1066,13 @@
|
||||||
"ListResourceTemplatesResult": {
|
"ListResourceTemplatesResult": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"nextCursor": {
|
"nextCursor": {
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
|
|
@ -1071,6 +1093,13 @@
|
||||||
"ListResourcesResult": {
|
"ListResourcesResult": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"nextCursor": {
|
"nextCursor": {
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
|
|
@ -1096,6 +1125,13 @@
|
||||||
"ListToolsResult": {
|
"ListToolsResult": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"nextCursor": {
|
"nextCursor": {
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
|
|
@ -1472,6 +1508,14 @@
|
||||||
"description": "A prompt that can be used to generate text from a model",
|
"description": "A prompt that can be used to generate text from a model",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"description": "Optional additional metadata for this prompt",
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"arguments": {
|
"arguments": {
|
||||||
"description": "Optional arguments that can be passed to customize the prompt",
|
"description": "Optional arguments that can be passed to customize the prompt",
|
||||||
"type": [
|
"type": [
|
||||||
|
|
@ -1660,6 +1704,14 @@
|
||||||
"description": "A link to a resource that can be fetched separately",
|
"description": "A link to a resource that can be fetched separately",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"description": "Optional additional metadata for this resource",
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"annotations": {
|
"annotations": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
|
|
@ -1816,6 +1868,14 @@
|
||||||
"description": "Represents a resource in the extension with metadata",
|
"description": "Represents a resource in the extension with metadata",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"description": "Optional additional metadata for this resource",
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Optional description of the resource",
|
"description": "Optional description of the resource",
|
||||||
"type": [
|
"type": [
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,14 @@
|
||||||
"description": "Represents a resource in the extension with metadata",
|
"description": "Represents a resource in the extension with metadata",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"description": "Optional additional metadata for this resource",
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"annotations": {
|
"annotations": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
|
|
@ -1031,6 +1039,13 @@
|
||||||
"ListPromptsResult": {
|
"ListPromptsResult": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"nextCursor": {
|
"nextCursor": {
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
|
|
@ -1051,6 +1066,13 @@
|
||||||
"ListResourceTemplatesResult": {
|
"ListResourceTemplatesResult": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"nextCursor": {
|
"nextCursor": {
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
|
|
@ -1071,6 +1093,13 @@
|
||||||
"ListResourcesResult": {
|
"ListResourcesResult": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"nextCursor": {
|
"nextCursor": {
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
|
|
@ -1096,6 +1125,13 @@
|
||||||
"ListToolsResult": {
|
"ListToolsResult": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"nextCursor": {
|
"nextCursor": {
|
||||||
"type": [
|
"type": [
|
||||||
"string",
|
"string",
|
||||||
|
|
@ -1472,6 +1508,14 @@
|
||||||
"description": "A prompt that can be used to generate text from a model",
|
"description": "A prompt that can be used to generate text from a model",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"description": "Optional additional metadata for this prompt",
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"arguments": {
|
"arguments": {
|
||||||
"description": "Optional arguments that can be passed to customize the prompt",
|
"description": "Optional arguments that can be passed to customize the prompt",
|
||||||
"type": [
|
"type": [
|
||||||
|
|
@ -1660,6 +1704,14 @@
|
||||||
"description": "A link to a resource that can be fetched separately",
|
"description": "A link to a resource that can be fetched separately",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"description": "Optional additional metadata for this resource",
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"annotations": {
|
"annotations": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
|
|
@ -1816,6 +1868,14 @@
|
||||||
"description": "Represents a resource in the extension with metadata",
|
"description": "Represents a resource in the extension with metadata",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"description": "Optional additional metadata for this resource",
|
||||||
|
"type": [
|
||||||
|
"object",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Optional description of the resource",
|
"description": "Optional description of the resource",
|
||||||
"type": [
|
"type": [
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,10 @@ impl Counter {
|
||||||
#[prompt_router]
|
#[prompt_router]
|
||||||
impl Counter {
|
impl Counter {
|
||||||
/// This is an example prompt that takes one required argument, message
|
/// This is an example prompt that takes one required argument, message
|
||||||
#[prompt(name = "example_prompt")]
|
#[prompt(
|
||||||
|
name = "example_prompt",
|
||||||
|
meta = Meta(rmcp::object!({"meta_key": "meta_value"}))
|
||||||
|
)]
|
||||||
async fn example_prompt(
|
async fn example_prompt(
|
||||||
&self,
|
&self,
|
||||||
Parameters(args): Parameters<ExamplePromptArgs>,
|
Parameters(args): Parameters<ExamplePromptArgs>,
|
||||||
|
|
@ -161,8 +164,8 @@ impl Counter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tool_handler]
|
#[tool_handler(meta = Meta(rmcp::object!({"tool_meta_key": "tool_meta_value"})))]
|
||||||
#[prompt_handler]
|
#[prompt_handler(meta = Meta(rmcp::object!({"router_meta_key": "router_meta_value"})))]
|
||||||
impl ServerHandler for Counter {
|
impl ServerHandler for Counter {
|
||||||
fn get_info(&self) -> ServerInfo {
|
fn get_info(&self) -> ServerInfo {
|
||||||
ServerInfo {
|
ServerInfo {
|
||||||
|
|
@ -188,6 +191,7 @@ impl ServerHandler for Counter {
|
||||||
self._create_resource_text("memo://insights", "memo-name"),
|
self._create_resource_text("memo://insights", "memo-name"),
|
||||||
],
|
],
|
||||||
next_cursor: None,
|
next_cursor: None,
|
||||||
|
meta: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -226,6 +230,7 @@ impl ServerHandler for Counter {
|
||||||
Ok(ListResourceTemplatesResult {
|
Ok(ListResourceTemplatesResult {
|
||||||
next_cursor: None,
|
next_cursor: None,
|
||||||
resource_templates: Vec::new(),
|
resource_templates: Vec::new(),
|
||||||
|
meta: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ impl ServerHandler for SamplingDemoServer {
|
||||||
icons: None,
|
icons: None,
|
||||||
meta: None,
|
meta: None,
|
||||||
}],
|
}],
|
||||||
|
meta: None,
|
||||||
next_cursor: None,
|
next_cursor: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue