Skip to content

Added _meta field to prompts, resources and paginated results - #558

Merged
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field
Dec 4, 2025
Merged

Added _meta field to prompts, resources and paginated results#558
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field

Conversation

@pbezglasny

@pbezglasnypbezglasny commented Nov 24, 2025

Copy link
Copy Markdown
Contributor

Motivation and Context

MCP specifies _meta field for requested entities. Currently _meta field implemeted for tool, but missing for others.

This PR:

  • adds _meta field for Prompt, Resource
  • adds _meta field for PaginatedResult: ListToolsResult, ListPromptsResult, ListResourceTemplatesResult, ListPromptsResult.
  • adds the meta attribute to tool_handler and prompt_handler macros
  • updates Counter example to include example of usage new attributes(there is an issues with RustRover to parse attributes, but examples are working)

Format of meta attribute is the same as existed for tool.

let meta = ifletSome(meta) = meta {
quote!{Some(#meta)}
}else{
quote!{None}
};

In this case you need to provide Meta object, but we can update to something like

let meta = ifletSome(meta) = meta {quote!{ rmcp::model::Meta(rmcp::object!(#meta))}}else{quote!{None}};

and use with item definition only with json, for instance

#[prompt( name = "example_prompt", meta = {"meta_key":"meta_value"})]asyncfn example_prompt(

How Has This Been Tested?

  • Code was tested via modelcontextprotocol/inspector.

Breaking Changes

No

Closes#557

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

CopilotAI review requested due to automatic review settings November 24, 2025 16:45
@github-actionsgithub-actionsBot added T-test Testing related changes T-config Configuration file changes T-core Core library changes T-examples Example code changes T-handler Handler implementation changes T-macros Macro changes T-model Model/data structure changes labels Nov 24, 2025
pub struct CounterAnalysisArgs {
/// The target value you're trying to reach
pub goal: i32,
pub goal: String,

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed type to String, because in standard arguments are strings https://modelcontextprotocol.io/specification/2025-06-18/schema#prompts/get

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string? I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string?

I suppose, now there is error if using mcpinspector when calling counter_analysis tool, e.g. using examples/counter_streamhttp server. Screenshot attached

Image

I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Using macro would be good solution, at least for primitive types, now it's possible to use any type with jsonschema.
Frankly speeking, I changed type to string because I was testing with inspector, but now I thinks it would be better to revert change type and changes in different PR.

@pbezglasnypbezglasnyDec 4, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted field type change. In other sdks(typescript, python) is allowed to define not string arguments of prompt the same way as rust sdk, despite string type requirements. There was issue in inspector modelcontextprotocol/inspector#869 that stands that client should send string arguments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds _meta field support to Prompts, Resources, and paginated list results to align with the MCP specification. The changes enable servers to attach arbitrary metadata to these entities, which was previously only available for Tools.

Key changes:

  • Added meta: Option<Meta> field to Prompt, Resource, and all paginated result types (ListPromptsResult, ListResourcesResult, ListResourceTemplatesResult, ListToolsResult)
  • Extended #[prompt], #[tool_handler], and #[prompt_handler] macros to accept meta parameter
  • Updated the Counter example to demonstrate meta usage in prompts and handlers

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
crates/rmcp/src/model/resource.rsAdded meta field to RawResource struct with proper serde annotations
crates/rmcp/src/model/prompt.rsAdded meta field to Prompt struct and imported Meta type
crates/rmcp/src/model/content.rsUpdated test to initialize meta: None for resource content
crates/rmcp/src/model.rsUpdated paginated_result! macro to include meta field in generated structs
crates/rmcp/src/handler/server/router.rsReplaced explicit struct initialization with ..Default::default() for cleaner code
crates/rmcp-macros/src/tool_handler.rsAdded meta parameter support to #[tool_handler] macro
crates/rmcp-macros/src/prompt_handler.rsAdded meta parameter support to #[prompt_handler] macro
crates/rmcp-macros/src/prompt.rsAdded meta parameter support to #[prompt] macro
examples/servers/src/common/counter.rsDemonstrated meta usage in prompts and handlers; changed goal type from i32 to String with validation
crates/rmcp/tests/test_message_schema/*.jsonUpdated JSON schemas to reflect new _meta fields in all affected types

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadcrates/rmcp-macros/src/prompt_handler.rs Outdated
Comment on lines +797 to +798
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
pub meta: Option<Meta>,

CopilotAINov 24, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Field ordering inconsistency: The meta field is placed first in paginated result structs, but in entity structs like Tool, Resource, and Prompt, the meta field is placed last (after icons). For consistency, consider placing meta last in this macro as well, after next_cursor and the items field. This would match the convention used in other structs throughout the codebase.

Copilot uses AI. Check for mistakes.
Comment threadexamples/servers/src/common/counter.rs Outdated
@athola

Copy link
Copy Markdown

LGTM. if there is a requirement to update associated tests or documentation I would encourage doing so but this appears to address my ticket here: #557

@jokemanfire
jokemanfire merged commit 81411fc into modelcontextprotocol:mainDec 4, 2025
10 of 11 checks passed
This was referenced Dec 2, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-configConfiguration file changesT-coreCore library changesT-examplesExample code changesT-handlerHandler implementation changesT-macrosMacro changesT-modelModel/data structure changesT-testTesting related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing resource-level metadata to listResources (lacks parity with readResource contents meta)

4 participants

@pbezglasny@athola@jokemanfire
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Added _meta field to prompts, resources and paginated results by pbezglasny · Pull Request #558 · modelcontextprotocol/rust-sdk · GitHub
Skip to content

Added _meta field to prompts, resources and paginated results - #558

Merged
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field
Dec 4, 2025
Merged

Added _meta field to prompts, resources and paginated results#558
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field

Conversation

@pbezglasny

@pbezglasnypbezglasny commented Nov 24, 2025

Copy link
Copy Markdown
Contributor

Motivation and Context

MCP specifies _meta field for requested entities. Currently _meta field implemeted for tool, but missing for others.

This PR:

  • adds _meta field for Prompt, Resource
  • adds _meta field for PaginatedResult: ListToolsResult, ListPromptsResult, ListResourceTemplatesResult, ListPromptsResult.
  • adds the meta attribute to tool_handler and prompt_handler macros
  • updates Counter example to include example of usage new attributes(there is an issues with RustRover to parse attributes, but examples are working)

Format of meta attribute is the same as existed for tool.

let meta = ifletSome(meta) = meta {
quote!{Some(#meta)}
}else{
quote!{None}
};

In this case you need to provide Meta object, but we can update to something like

let meta = ifletSome(meta) = meta {quote!{ rmcp::model::Meta(rmcp::object!(#meta))}}else{quote!{None}};

and use with item definition only with json, for instance

#[prompt( name = "example_prompt", meta = {"meta_key":"meta_value"})]asyncfn example_prompt(

How Has This Been Tested?

  • Code was tested via modelcontextprotocol/inspector.

Breaking Changes

No

Closes#557

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

CopilotAI review requested due to automatic review settings November 24, 2025 16:45
@github-actionsgithub-actionsBot added T-test Testing related changes T-config Configuration file changes T-core Core library changes T-examples Example code changes T-handler Handler implementation changes T-macros Macro changes T-model Model/data structure changes labels Nov 24, 2025
pub struct CounterAnalysisArgs {
/// The target value you're trying to reach
pub goal: i32,
pub goal: String,

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed type to String, because in standard arguments are strings https://modelcontextprotocol.io/specification/2025-06-18/schema#prompts/get

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string? I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string?

I suppose, now there is error if using mcpinspector when calling counter_analysis tool, e.g. using examples/counter_streamhttp server. Screenshot attached

Image

I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Using macro would be good solution, at least for primitive types, now it's possible to use any type with jsonschema.
Frankly speeking, I changed type to string because I was testing with inspector, but now I thinks it would be better to revert change type and changes in different PR.

@pbezglasnypbezglasnyDec 4, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted field type change. In other sdks(typescript, python) is allowed to define not string arguments of prompt the same way as rust sdk, despite string type requirements. There was issue in inspector modelcontextprotocol/inspector#869 that stands that client should send string arguments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds _meta field support to Prompts, Resources, and paginated list results to align with the MCP specification. The changes enable servers to attach arbitrary metadata to these entities, which was previously only available for Tools.

Key changes:

  • Added meta: Option<Meta> field to Prompt, Resource, and all paginated result types (ListPromptsResult, ListResourcesResult, ListResourceTemplatesResult, ListToolsResult)
  • Extended #[prompt], #[tool_handler], and #[prompt_handler] macros to accept meta parameter
  • Updated the Counter example to demonstrate meta usage in prompts and handlers

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
crates/rmcp/src/model/resource.rsAdded meta field to RawResource struct with proper serde annotations
crates/rmcp/src/model/prompt.rsAdded meta field to Prompt struct and imported Meta type
crates/rmcp/src/model/content.rsUpdated test to initialize meta: None for resource content
crates/rmcp/src/model.rsUpdated paginated_result! macro to include meta field in generated structs
crates/rmcp/src/handler/server/router.rsReplaced explicit struct initialization with ..Default::default() for cleaner code
crates/rmcp-macros/src/tool_handler.rsAdded meta parameter support to #[tool_handler] macro
crates/rmcp-macros/src/prompt_handler.rsAdded meta parameter support to #[prompt_handler] macro
crates/rmcp-macros/src/prompt.rsAdded meta parameter support to #[prompt] macro
examples/servers/src/common/counter.rsDemonstrated meta usage in prompts and handlers; changed goal type from i32 to String with validation
crates/rmcp/tests/test_message_schema/*.jsonUpdated JSON schemas to reflect new _meta fields in all affected types

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadcrates/rmcp-macros/src/prompt_handler.rs Outdated
Comment on lines +797 to +798
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
pub meta: Option<Meta>,

CopilotAINov 24, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Field ordering inconsistency: The meta field is placed first in paginated result structs, but in entity structs like Tool, Resource, and Prompt, the meta field is placed last (after icons). For consistency, consider placing meta last in this macro as well, after next_cursor and the items field. This would match the convention used in other structs throughout the codebase.

Copilot uses AI. Check for mistakes.
Comment threadexamples/servers/src/common/counter.rs Outdated
@athola

Copy link
Copy Markdown

LGTM. if there is a requirement to update associated tests or documentation I would encourage doing so but this appears to address my ticket here: #557

@jokemanfire
jokemanfire merged commit 81411fc into modelcontextprotocol:mainDec 4, 2025
10 of 11 checks passed
This was referenced Dec 2, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-configConfiguration file changesT-coreCore library changesT-examplesExample code changesT-handlerHandler implementation changesT-macrosMacro changesT-modelModel/data structure changesT-testTesting related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing resource-level metadata to listResources (lacks parity with readResource contents meta)

4 participants

@pbezglasny@athola@jokemanfire
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Added _meta field to prompts, resources and paginated results by pbezglasny · Pull Request #558 · modelcontextprotocol/rust-sdk · GitHub
Skip to content

Added _meta field to prompts, resources and paginated results - #558

Merged
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field
Dec 4, 2025
Merged

Added _meta field to prompts, resources and paginated results#558
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field

Conversation

@pbezglasny

@pbezglasnypbezglasny commented Nov 24, 2025

Copy link
Copy Markdown
Contributor

Motivation and Context

MCP specifies _meta field for requested entities. Currently _meta field implemeted for tool, but missing for others.

This PR:

  • adds _meta field for Prompt, Resource
  • adds _meta field for PaginatedResult: ListToolsResult, ListPromptsResult, ListResourceTemplatesResult, ListPromptsResult.
  • adds the meta attribute to tool_handler and prompt_handler macros
  • updates Counter example to include example of usage new attributes(there is an issues with RustRover to parse attributes, but examples are working)

Format of meta attribute is the same as existed for tool.

let meta = ifletSome(meta) = meta {
quote!{Some(#meta)}
}else{
quote!{None}
};

In this case you need to provide Meta object, but we can update to something like

let meta = ifletSome(meta) = meta {quote!{ rmcp::model::Meta(rmcp::object!(#meta))}}else{quote!{None}};

and use with item definition only with json, for instance

#[prompt( name = "example_prompt", meta = {"meta_key":"meta_value"})]asyncfn example_prompt(

How Has This Been Tested?

  • Code was tested via modelcontextprotocol/inspector.

Breaking Changes

No

Closes#557

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

CopilotAI review requested due to automatic review settings November 24, 2025 16:45
@github-actionsgithub-actionsBot added T-test Testing related changes T-config Configuration file changes T-core Core library changes T-examples Example code changes T-handler Handler implementation changes T-macros Macro changes T-model Model/data structure changes labels Nov 24, 2025
pub struct CounterAnalysisArgs {
/// The target value you're trying to reach
pub goal: i32,
pub goal: String,

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed type to String, because in standard arguments are strings https://modelcontextprotocol.io/specification/2025-06-18/schema#prompts/get

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string? I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string?

I suppose, now there is error if using mcpinspector when calling counter_analysis tool, e.g. using examples/counter_streamhttp server. Screenshot attached

Image

I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Using macro would be good solution, at least for primitive types, now it's possible to use any type with jsonschema.
Frankly speeking, I changed type to string because I was testing with inspector, but now I thinks it would be better to revert change type and changes in different PR.

@pbezglasnypbezglasnyDec 4, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted field type change. In other sdks(typescript, python) is allowed to define not string arguments of prompt the same way as rust sdk, despite string type requirements. There was issue in inspector modelcontextprotocol/inspector#869 that stands that client should send string arguments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds _meta field support to Prompts, Resources, and paginated list results to align with the MCP specification. The changes enable servers to attach arbitrary metadata to these entities, which was previously only available for Tools.

Key changes:

  • Added meta: Option<Meta> field to Prompt, Resource, and all paginated result types (ListPromptsResult, ListResourcesResult, ListResourceTemplatesResult, ListToolsResult)
  • Extended #[prompt], #[tool_handler], and #[prompt_handler] macros to accept meta parameter
  • Updated the Counter example to demonstrate meta usage in prompts and handlers

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
crates/rmcp/src/model/resource.rsAdded meta field to RawResource struct with proper serde annotations
crates/rmcp/src/model/prompt.rsAdded meta field to Prompt struct and imported Meta type
crates/rmcp/src/model/content.rsUpdated test to initialize meta: None for resource content
crates/rmcp/src/model.rsUpdated paginated_result! macro to include meta field in generated structs
crates/rmcp/src/handler/server/router.rsReplaced explicit struct initialization with ..Default::default() for cleaner code
crates/rmcp-macros/src/tool_handler.rsAdded meta parameter support to #[tool_handler] macro
crates/rmcp-macros/src/prompt_handler.rsAdded meta parameter support to #[prompt_handler] macro
crates/rmcp-macros/src/prompt.rsAdded meta parameter support to #[prompt] macro
examples/servers/src/common/counter.rsDemonstrated meta usage in prompts and handlers; changed goal type from i32 to String with validation
crates/rmcp/tests/test_message_schema/*.jsonUpdated JSON schemas to reflect new _meta fields in all affected types

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadcrates/rmcp-macros/src/prompt_handler.rs Outdated
Comment on lines +797 to +798
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
pub meta: Option<Meta>,

CopilotAINov 24, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Field ordering inconsistency: The meta field is placed first in paginated result structs, but in entity structs like Tool, Resource, and Prompt, the meta field is placed last (after icons). For consistency, consider placing meta last in this macro as well, after next_cursor and the items field. This would match the convention used in other structs throughout the codebase.

Copilot uses AI. Check for mistakes.
Comment threadexamples/servers/src/common/counter.rs Outdated
@athola

Copy link
Copy Markdown

LGTM. if there is a requirement to update associated tests or documentation I would encourage doing so but this appears to address my ticket here: #557

@jokemanfire
jokemanfire merged commit 81411fc into modelcontextprotocol:mainDec 4, 2025
10 of 11 checks passed
This was referenced Dec 2, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-configConfiguration file changesT-coreCore library changesT-examplesExample code changesT-handlerHandler implementation changesT-macrosMacro changesT-modelModel/data structure changesT-testTesting related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing resource-level metadata to listResources (lacks parity with readResource contents meta)

4 participants

@pbezglasny@athola@jokemanfire
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Added _meta field to prompts, resources and paginated results by pbezglasny · Pull Request #558 · modelcontextprotocol/rust-sdk · GitHub
Skip to content

Added _meta field to prompts, resources and paginated results - #558

Merged
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field
Dec 4, 2025
Merged

Added _meta field to prompts, resources and paginated results#558
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field

Conversation

@pbezglasny

@pbezglasnypbezglasny commented Nov 24, 2025

Copy link
Copy Markdown
Contributor

Motivation and Context

MCP specifies _meta field for requested entities. Currently _meta field implemeted for tool, but missing for others.

This PR:

  • adds _meta field for Prompt, Resource
  • adds _meta field for PaginatedResult: ListToolsResult, ListPromptsResult, ListResourceTemplatesResult, ListPromptsResult.
  • adds the meta attribute to tool_handler and prompt_handler macros
  • updates Counter example to include example of usage new attributes(there is an issues with RustRover to parse attributes, but examples are working)

Format of meta attribute is the same as existed for tool.

let meta = ifletSome(meta) = meta {
quote!{Some(#meta)}
}else{
quote!{None}
};

In this case you need to provide Meta object, but we can update to something like

let meta = ifletSome(meta) = meta {quote!{ rmcp::model::Meta(rmcp::object!(#meta))}}else{quote!{None}};

and use with item definition only with json, for instance

#[prompt( name = "example_prompt", meta = {"meta_key":"meta_value"})]asyncfn example_prompt(

How Has This Been Tested?

  • Code was tested via modelcontextprotocol/inspector.

Breaking Changes

No

Closes#557

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

CopilotAI review requested due to automatic review settings November 24, 2025 16:45
@github-actionsgithub-actionsBot added T-test Testing related changes T-config Configuration file changes T-core Core library changes T-examples Example code changes T-handler Handler implementation changes T-macros Macro changes T-model Model/data structure changes labels Nov 24, 2025
pub struct CounterAnalysisArgs {
/// The target value you're trying to reach
pub goal: i32,
pub goal: String,

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed type to String, because in standard arguments are strings https://modelcontextprotocol.io/specification/2025-06-18/schema#prompts/get

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string? I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string?

I suppose, now there is error if using mcpinspector when calling counter_analysis tool, e.g. using examples/counter_streamhttp server. Screenshot attached

Image

I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Using macro would be good solution, at least for primitive types, now it's possible to use any type with jsonschema.
Frankly speeking, I changed type to string because I was testing with inspector, but now I thinks it would be better to revert change type and changes in different PR.

@pbezglasnypbezglasnyDec 4, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted field type change. In other sdks(typescript, python) is allowed to define not string arguments of prompt the same way as rust sdk, despite string type requirements. There was issue in inspector modelcontextprotocol/inspector#869 that stands that client should send string arguments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds _meta field support to Prompts, Resources, and paginated list results to align with the MCP specification. The changes enable servers to attach arbitrary metadata to these entities, which was previously only available for Tools.

Key changes:

  • Added meta: Option<Meta> field to Prompt, Resource, and all paginated result types (ListPromptsResult, ListResourcesResult, ListResourceTemplatesResult, ListToolsResult)
  • Extended #[prompt], #[tool_handler], and #[prompt_handler] macros to accept meta parameter
  • Updated the Counter example to demonstrate meta usage in prompts and handlers

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
crates/rmcp/src/model/resource.rsAdded meta field to RawResource struct with proper serde annotations
crates/rmcp/src/model/prompt.rsAdded meta field to Prompt struct and imported Meta type
crates/rmcp/src/model/content.rsUpdated test to initialize meta: None for resource content
crates/rmcp/src/model.rsUpdated paginated_result! macro to include meta field in generated structs
crates/rmcp/src/handler/server/router.rsReplaced explicit struct initialization with ..Default::default() for cleaner code
crates/rmcp-macros/src/tool_handler.rsAdded meta parameter support to #[tool_handler] macro
crates/rmcp-macros/src/prompt_handler.rsAdded meta parameter support to #[prompt_handler] macro
crates/rmcp-macros/src/prompt.rsAdded meta parameter support to #[prompt] macro
examples/servers/src/common/counter.rsDemonstrated meta usage in prompts and handlers; changed goal type from i32 to String with validation
crates/rmcp/tests/test_message_schema/*.jsonUpdated JSON schemas to reflect new _meta fields in all affected types

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadcrates/rmcp-macros/src/prompt_handler.rs Outdated
Comment on lines +797 to +798
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
pub meta: Option<Meta>,

CopilotAINov 24, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Field ordering inconsistency: The meta field is placed first in paginated result structs, but in entity structs like Tool, Resource, and Prompt, the meta field is placed last (after icons). For consistency, consider placing meta last in this macro as well, after next_cursor and the items field. This would match the convention used in other structs throughout the codebase.

Copilot uses AI. Check for mistakes.
Comment threadexamples/servers/src/common/counter.rs Outdated
@athola

Copy link
Copy Markdown

LGTM. if there is a requirement to update associated tests or documentation I would encourage doing so but this appears to address my ticket here: #557

@jokemanfire
jokemanfire merged commit 81411fc into modelcontextprotocol:mainDec 4, 2025
10 of 11 checks passed
This was referenced Dec 2, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-configConfiguration file changesT-coreCore library changesT-examplesExample code changesT-handlerHandler implementation changesT-macrosMacro changesT-modelModel/data structure changesT-testTesting related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing resource-level metadata to listResources (lacks parity with readResource contents meta)

4 participants

@pbezglasny@athola@jokemanfire
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Added _meta field to prompts, resources and paginated results by pbezglasny · Pull Request #558 · modelcontextprotocol/rust-sdk · GitHub
Skip to content

Added _meta field to prompts, resources and paginated results - #558

Merged
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field
Dec 4, 2025
Merged

Added _meta field to prompts, resources and paginated results#558
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field

Conversation

@pbezglasny

@pbezglasnypbezglasny commented Nov 24, 2025

Copy link
Copy Markdown
Contributor

Motivation and Context

MCP specifies _meta field for requested entities. Currently _meta field implemeted for tool, but missing for others.

This PR:

  • adds _meta field for Prompt, Resource
  • adds _meta field for PaginatedResult: ListToolsResult, ListPromptsResult, ListResourceTemplatesResult, ListPromptsResult.
  • adds the meta attribute to tool_handler and prompt_handler macros
  • updates Counter example to include example of usage new attributes(there is an issues with RustRover to parse attributes, but examples are working)

Format of meta attribute is the same as existed for tool.

let meta = ifletSome(meta) = meta {
quote!{Some(#meta)}
}else{
quote!{None}
};

In this case you need to provide Meta object, but we can update to something like

let meta = ifletSome(meta) = meta {quote!{ rmcp::model::Meta(rmcp::object!(#meta))}}else{quote!{None}};

and use with item definition only with json, for instance

#[prompt( name = "example_prompt", meta = {"meta_key":"meta_value"})]asyncfn example_prompt(

How Has This Been Tested?

  • Code was tested via modelcontextprotocol/inspector.

Breaking Changes

No

Closes#557

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

CopilotAI review requested due to automatic review settings November 24, 2025 16:45
@github-actionsgithub-actionsBot added T-test Testing related changes T-config Configuration file changes T-core Core library changes T-examples Example code changes T-handler Handler implementation changes T-macros Macro changes T-model Model/data structure changes labels Nov 24, 2025
pub struct CounterAnalysisArgs {
/// The target value you're trying to reach
pub goal: i32,
pub goal: String,

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed type to String, because in standard arguments are strings https://modelcontextprotocol.io/specification/2025-06-18/schema#prompts/get

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string? I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string?

I suppose, now there is error if using mcpinspector when calling counter_analysis tool, e.g. using examples/counter_streamhttp server. Screenshot attached

Image

I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Using macro would be good solution, at least for primitive types, now it's possible to use any type with jsonschema.
Frankly speeking, I changed type to string because I was testing with inspector, but now I thinks it would be better to revert change type and changes in different PR.

@pbezglasnypbezglasnyDec 4, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted field type change. In other sdks(typescript, python) is allowed to define not string arguments of prompt the same way as rust sdk, despite string type requirements. There was issue in inspector modelcontextprotocol/inspector#869 that stands that client should send string arguments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds _meta field support to Prompts, Resources, and paginated list results to align with the MCP specification. The changes enable servers to attach arbitrary metadata to these entities, which was previously only available for Tools.

Key changes:

  • Added meta: Option<Meta> field to Prompt, Resource, and all paginated result types (ListPromptsResult, ListResourcesResult, ListResourceTemplatesResult, ListToolsResult)
  • Extended #[prompt], #[tool_handler], and #[prompt_handler] macros to accept meta parameter
  • Updated the Counter example to demonstrate meta usage in prompts and handlers

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
crates/rmcp/src/model/resource.rsAdded meta field to RawResource struct with proper serde annotations
crates/rmcp/src/model/prompt.rsAdded meta field to Prompt struct and imported Meta type
crates/rmcp/src/model/content.rsUpdated test to initialize meta: None for resource content
crates/rmcp/src/model.rsUpdated paginated_result! macro to include meta field in generated structs
crates/rmcp/src/handler/server/router.rsReplaced explicit struct initialization with ..Default::default() for cleaner code
crates/rmcp-macros/src/tool_handler.rsAdded meta parameter support to #[tool_handler] macro
crates/rmcp-macros/src/prompt_handler.rsAdded meta parameter support to #[prompt_handler] macro
crates/rmcp-macros/src/prompt.rsAdded meta parameter support to #[prompt] macro
examples/servers/src/common/counter.rsDemonstrated meta usage in prompts and handlers; changed goal type from i32 to String with validation
crates/rmcp/tests/test_message_schema/*.jsonUpdated JSON schemas to reflect new _meta fields in all affected types

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadcrates/rmcp-macros/src/prompt_handler.rs Outdated
Comment on lines +797 to +798
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
pub meta: Option<Meta>,

CopilotAINov 24, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Field ordering inconsistency: The meta field is placed first in paginated result structs, but in entity structs like Tool, Resource, and Prompt, the meta field is placed last (after icons). For consistency, consider placing meta last in this macro as well, after next_cursor and the items field. This would match the convention used in other structs throughout the codebase.

Copilot uses AI. Check for mistakes.
Comment threadexamples/servers/src/common/counter.rs Outdated
@athola

Copy link
Copy Markdown

LGTM. if there is a requirement to update associated tests or documentation I would encourage doing so but this appears to address my ticket here: #557

@jokemanfire
jokemanfire merged commit 81411fc into modelcontextprotocol:mainDec 4, 2025
10 of 11 checks passed
This was referenced Dec 2, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-configConfiguration file changesT-coreCore library changesT-examplesExample code changesT-handlerHandler implementation changesT-macrosMacro changesT-modelModel/data structure changesT-testTesting related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing resource-level metadata to listResources (lacks parity with readResource contents meta)

4 participants

@pbezglasny@athola@jokemanfire
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Added _meta field to prompts, resources and paginated results by pbezglasny · Pull Request #558 · modelcontextprotocol/rust-sdk · GitHub
Skip to content

Added _meta field to prompts, resources and paginated results - #558

Merged
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field
Dec 4, 2025
Merged

Added _meta field to prompts, resources and paginated results#558
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field

Conversation

@pbezglasny

@pbezglasnypbezglasny commented Nov 24, 2025

Copy link
Copy Markdown
Contributor

Motivation and Context

MCP specifies _meta field for requested entities. Currently _meta field implemeted for tool, but missing for others.

This PR:

  • adds _meta field for Prompt, Resource
  • adds _meta field for PaginatedResult: ListToolsResult, ListPromptsResult, ListResourceTemplatesResult, ListPromptsResult.
  • adds the meta attribute to tool_handler and prompt_handler macros
  • updates Counter example to include example of usage new attributes(there is an issues with RustRover to parse attributes, but examples are working)

Format of meta attribute is the same as existed for tool.

let meta = ifletSome(meta) = meta {
quote!{Some(#meta)}
}else{
quote!{None}
};

In this case you need to provide Meta object, but we can update to something like

let meta = ifletSome(meta) = meta {quote!{ rmcp::model::Meta(rmcp::object!(#meta))}}else{quote!{None}};

and use with item definition only with json, for instance

#[prompt( name = "example_prompt", meta = {"meta_key":"meta_value"})]asyncfn example_prompt(

How Has This Been Tested?

  • Code was tested via modelcontextprotocol/inspector.

Breaking Changes

No

Closes#557

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

CopilotAI review requested due to automatic review settings November 24, 2025 16:45
@github-actionsgithub-actionsBot added T-test Testing related changes T-config Configuration file changes T-core Core library changes T-examples Example code changes T-handler Handler implementation changes T-macros Macro changes T-model Model/data structure changes labels Nov 24, 2025
pub struct CounterAnalysisArgs {
/// The target value you're trying to reach
pub goal: i32,
pub goal: String,

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed type to String, because in standard arguments are strings https://modelcontextprotocol.io/specification/2025-06-18/schema#prompts/get

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string? I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string?

I suppose, now there is error if using mcpinspector when calling counter_analysis tool, e.g. using examples/counter_streamhttp server. Screenshot attached

Image

I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Using macro would be good solution, at least for primitive types, now it's possible to use any type with jsonschema.
Frankly speeking, I changed type to string because I was testing with inspector, but now I thinks it would be better to revert change type and changes in different PR.

@pbezglasnypbezglasnyDec 4, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted field type change. In other sdks(typescript, python) is allowed to define not string arguments of prompt the same way as rust sdk, despite string type requirements. There was issue in inspector modelcontextprotocol/inspector#869 that stands that client should send string arguments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds _meta field support to Prompts, Resources, and paginated list results to align with the MCP specification. The changes enable servers to attach arbitrary metadata to these entities, which was previously only available for Tools.

Key changes:

  • Added meta: Option<Meta> field to Prompt, Resource, and all paginated result types (ListPromptsResult, ListResourcesResult, ListResourceTemplatesResult, ListToolsResult)
  • Extended #[prompt], #[tool_handler], and #[prompt_handler] macros to accept meta parameter
  • Updated the Counter example to demonstrate meta usage in prompts and handlers

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
crates/rmcp/src/model/resource.rsAdded meta field to RawResource struct with proper serde annotations
crates/rmcp/src/model/prompt.rsAdded meta field to Prompt struct and imported Meta type
crates/rmcp/src/model/content.rsUpdated test to initialize meta: None for resource content
crates/rmcp/src/model.rsUpdated paginated_result! macro to include meta field in generated structs
crates/rmcp/src/handler/server/router.rsReplaced explicit struct initialization with ..Default::default() for cleaner code
crates/rmcp-macros/src/tool_handler.rsAdded meta parameter support to #[tool_handler] macro
crates/rmcp-macros/src/prompt_handler.rsAdded meta parameter support to #[prompt_handler] macro
crates/rmcp-macros/src/prompt.rsAdded meta parameter support to #[prompt] macro
examples/servers/src/common/counter.rsDemonstrated meta usage in prompts and handlers; changed goal type from i32 to String with validation
crates/rmcp/tests/test_message_schema/*.jsonUpdated JSON schemas to reflect new _meta fields in all affected types

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadcrates/rmcp-macros/src/prompt_handler.rs Outdated
Comment on lines +797 to +798
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
pub meta: Option<Meta>,

CopilotAINov 24, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Field ordering inconsistency: The meta field is placed first in paginated result structs, but in entity structs like Tool, Resource, and Prompt, the meta field is placed last (after icons). For consistency, consider placing meta last in this macro as well, after next_cursor and the items field. This would match the convention used in other structs throughout the codebase.

Copilot uses AI. Check for mistakes.
Comment threadexamples/servers/src/common/counter.rs Outdated
@athola

Copy link
Copy Markdown

LGTM. if there is a requirement to update associated tests or documentation I would encourage doing so but this appears to address my ticket here: #557

@jokemanfire
jokemanfire merged commit 81411fc into modelcontextprotocol:mainDec 4, 2025
10 of 11 checks passed
This was referenced Dec 2, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-configConfiguration file changesT-coreCore library changesT-examplesExample code changesT-handlerHandler implementation changesT-macrosMacro changesT-modelModel/data structure changesT-testTesting related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing resource-level metadata to listResources (lacks parity with readResource contents meta)

4 participants

@pbezglasny@athola@jokemanfire
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Added _meta field to prompts, resources and paginated results by pbezglasny · Pull Request #558 · modelcontextprotocol/rust-sdk · GitHub
Skip to content

Added _meta field to prompts, resources and paginated results - #558

Merged
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field
Dec 4, 2025
Merged

Added _meta field to prompts, resources and paginated results#558
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field

Conversation

@pbezglasny

@pbezglasnypbezglasny commented Nov 24, 2025

Copy link
Copy Markdown
Contributor

Motivation and Context

MCP specifies _meta field for requested entities. Currently _meta field implemeted for tool, but missing for others.

This PR:

  • adds _meta field for Prompt, Resource
  • adds _meta field for PaginatedResult: ListToolsResult, ListPromptsResult, ListResourceTemplatesResult, ListPromptsResult.
  • adds the meta attribute to tool_handler and prompt_handler macros
  • updates Counter example to include example of usage new attributes(there is an issues with RustRover to parse attributes, but examples are working)

Format of meta attribute is the same as existed for tool.

let meta = ifletSome(meta) = meta {
quote!{Some(#meta)}
}else{
quote!{None}
};

In this case you need to provide Meta object, but we can update to something like

let meta = ifletSome(meta) = meta {quote!{ rmcp::model::Meta(rmcp::object!(#meta))}}else{quote!{None}};

and use with item definition only with json, for instance

#[prompt( name = "example_prompt", meta = {"meta_key":"meta_value"})]asyncfn example_prompt(

How Has This Been Tested?

  • Code was tested via modelcontextprotocol/inspector.

Breaking Changes

No

Closes#557

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

CopilotAI review requested due to automatic review settings November 24, 2025 16:45
@github-actionsgithub-actionsBot added T-test Testing related changes T-config Configuration file changes T-core Core library changes T-examples Example code changes T-handler Handler implementation changes T-macros Macro changes T-model Model/data structure changes labels Nov 24, 2025
pub struct CounterAnalysisArgs {
/// The target value you're trying to reach
pub goal: i32,
pub goal: String,

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed type to String, because in standard arguments are strings https://modelcontextprotocol.io/specification/2025-06-18/schema#prompts/get

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string? I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string?

I suppose, now there is error if using mcpinspector when calling counter_analysis tool, e.g. using examples/counter_streamhttp server. Screenshot attached

Image

I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Using macro would be good solution, at least for primitive types, now it's possible to use any type with jsonschema.
Frankly speeking, I changed type to string because I was testing with inspector, but now I thinks it would be better to revert change type and changes in different PR.

@pbezglasnypbezglasnyDec 4, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted field type change. In other sdks(typescript, python) is allowed to define not string arguments of prompt the same way as rust sdk, despite string type requirements. There was issue in inspector modelcontextprotocol/inspector#869 that stands that client should send string arguments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds _meta field support to Prompts, Resources, and paginated list results to align with the MCP specification. The changes enable servers to attach arbitrary metadata to these entities, which was previously only available for Tools.

Key changes:

  • Added meta: Option<Meta> field to Prompt, Resource, and all paginated result types (ListPromptsResult, ListResourcesResult, ListResourceTemplatesResult, ListToolsResult)
  • Extended #[prompt], #[tool_handler], and #[prompt_handler] macros to accept meta parameter
  • Updated the Counter example to demonstrate meta usage in prompts and handlers

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
crates/rmcp/src/model/resource.rsAdded meta field to RawResource struct with proper serde annotations
crates/rmcp/src/model/prompt.rsAdded meta field to Prompt struct and imported Meta type
crates/rmcp/src/model/content.rsUpdated test to initialize meta: None for resource content
crates/rmcp/src/model.rsUpdated paginated_result! macro to include meta field in generated structs
crates/rmcp/src/handler/server/router.rsReplaced explicit struct initialization with ..Default::default() for cleaner code
crates/rmcp-macros/src/tool_handler.rsAdded meta parameter support to #[tool_handler] macro
crates/rmcp-macros/src/prompt_handler.rsAdded meta parameter support to #[prompt_handler] macro
crates/rmcp-macros/src/prompt.rsAdded meta parameter support to #[prompt] macro
examples/servers/src/common/counter.rsDemonstrated meta usage in prompts and handlers; changed goal type from i32 to String with validation
crates/rmcp/tests/test_message_schema/*.jsonUpdated JSON schemas to reflect new _meta fields in all affected types

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadcrates/rmcp-macros/src/prompt_handler.rs Outdated
Comment on lines +797 to +798
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
pub meta: Option<Meta>,

CopilotAINov 24, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Field ordering inconsistency: The meta field is placed first in paginated result structs, but in entity structs like Tool, Resource, and Prompt, the meta field is placed last (after icons). For consistency, consider placing meta last in this macro as well, after next_cursor and the items field. This would match the convention used in other structs throughout the codebase.

Copilot uses AI. Check for mistakes.
Comment threadexamples/servers/src/common/counter.rs Outdated
@athola

Copy link
Copy Markdown

LGTM. if there is a requirement to update associated tests or documentation I would encourage doing so but this appears to address my ticket here: #557

@jokemanfire
jokemanfire merged commit 81411fc into modelcontextprotocol:mainDec 4, 2025
10 of 11 checks passed
This was referenced Dec 2, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-configConfiguration file changesT-coreCore library changesT-examplesExample code changesT-handlerHandler implementation changesT-macrosMacro changesT-modelModel/data structure changesT-testTesting related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing resource-level metadata to listResources (lacks parity with readResource contents meta)

4 participants

@pbezglasny@athola@jokemanfire
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Added _meta field to prompts, resources and paginated results by pbezglasny · Pull Request #558 · modelcontextprotocol/rust-sdk · GitHub
Skip to content

Added _meta field to prompts, resources and paginated results - #558

Merged
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field
Dec 4, 2025
Merged

Added _meta field to prompts, resources and paginated results#558
jokemanfire merged 1 commit into
modelcontextprotocol:mainfrom
pbezglasny:meta_field

Conversation

@pbezglasny

@pbezglasnypbezglasny commented Nov 24, 2025

Copy link
Copy Markdown
Contributor

Motivation and Context

MCP specifies _meta field for requested entities. Currently _meta field implemeted for tool, but missing for others.

This PR:

  • adds _meta field for Prompt, Resource
  • adds _meta field for PaginatedResult: ListToolsResult, ListPromptsResult, ListResourceTemplatesResult, ListPromptsResult.
  • adds the meta attribute to tool_handler and prompt_handler macros
  • updates Counter example to include example of usage new attributes(there is an issues with RustRover to parse attributes, but examples are working)

Format of meta attribute is the same as existed for tool.

let meta = ifletSome(meta) = meta {
quote!{Some(#meta)}
}else{
quote!{None}
};

In this case you need to provide Meta object, but we can update to something like

let meta = ifletSome(meta) = meta {quote!{ rmcp::model::Meta(rmcp::object!(#meta))}}else{quote!{None}};

and use with item definition only with json, for instance

#[prompt( name = "example_prompt", meta = {"meta_key":"meta_value"})]asyncfn example_prompt(

How Has This Been Tested?

  • Code was tested via modelcontextprotocol/inspector.

Breaking Changes

No

Closes#557

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

CopilotAI review requested due to automatic review settings November 24, 2025 16:45
@github-actionsgithub-actionsBot added T-test Testing related changes T-config Configuration file changes T-core Core library changes T-examples Example code changes T-handler Handler implementation changes T-macros Macro changes T-model Model/data structure changes labels Nov 24, 2025
pub struct CounterAnalysisArgs {
/// The target value you're trying to reach
pub goal: i32,
pub goal: String,

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed type to String, because in standard arguments are strings https://modelcontextprotocol.io/specification/2025-06-18/schema#prompts/get

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string? I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the args support prompt must be string?

I suppose, now there is error if using mcpinspector when calling counter_analysis tool, e.g. using examples/counter_streamhttp server. Screenshot attached

Image

I think there must be some problem, or we should convert very type to String in prompt macro, but not enforcing the args's type should be String?

Using macro would be good solution, at least for primitive types, now it's possible to use any type with jsonschema.
Frankly speeking, I changed type to string because I was testing with inspector, but now I thinks it would be better to revert change type and changes in different PR.

@pbezglasnypbezglasnyDec 4, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted field type change. In other sdks(typescript, python) is allowed to define not string arguments of prompt the same way as rust sdk, despite string type requirements. There was issue in inspector modelcontextprotocol/inspector#869 that stands that client should send string arguments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds _meta field support to Prompts, Resources, and paginated list results to align with the MCP specification. The changes enable servers to attach arbitrary metadata to these entities, which was previously only available for Tools.

Key changes:

  • Added meta: Option<Meta> field to Prompt, Resource, and all paginated result types (ListPromptsResult, ListResourcesResult, ListResourceTemplatesResult, ListToolsResult)
  • Extended #[prompt], #[tool_handler], and #[prompt_handler] macros to accept meta parameter
  • Updated the Counter example to demonstrate meta usage in prompts and handlers

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
crates/rmcp/src/model/resource.rsAdded meta field to RawResource struct with proper serde annotations
crates/rmcp/src/model/prompt.rsAdded meta field to Prompt struct and imported Meta type
crates/rmcp/src/model/content.rsUpdated test to initialize meta: None for resource content
crates/rmcp/src/model.rsUpdated paginated_result! macro to include meta field in generated structs
crates/rmcp/src/handler/server/router.rsReplaced explicit struct initialization with ..Default::default() for cleaner code
crates/rmcp-macros/src/tool_handler.rsAdded meta parameter support to #[tool_handler] macro
crates/rmcp-macros/src/prompt_handler.rsAdded meta parameter support to #[prompt_handler] macro
crates/rmcp-macros/src/prompt.rsAdded meta parameter support to #[prompt] macro
examples/servers/src/common/counter.rsDemonstrated meta usage in prompts and handlers; changed goal type from i32 to String with validation
crates/rmcp/tests/test_message_schema/*.jsonUpdated JSON schemas to reflect new _meta fields in all affected types

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadcrates/rmcp-macros/src/prompt_handler.rs Outdated
Comment on lines +797 to +798
#[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
pub meta: Option<Meta>,

CopilotAINov 24, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Field ordering inconsistency: The meta field is placed first in paginated result structs, but in entity structs like Tool, Resource, and Prompt, the meta field is placed last (after icons). For consistency, consider placing meta last in this macro as well, after next_cursor and the items field. This would match the convention used in other structs throughout the codebase.

Copilot uses AI. Check for mistakes.
Comment threadexamples/servers/src/common/counter.rs Outdated
@athola

Copy link
Copy Markdown

LGTM. if there is a requirement to update associated tests or documentation I would encourage doing so but this appears to address my ticket here: #557

@jokemanfire
jokemanfire merged commit 81411fc into modelcontextprotocol:mainDec 4, 2025
10 of 11 checks passed
This was referenced Dec 2, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-configConfiguration file changesT-coreCore library changesT-examplesExample code changesT-handlerHandler implementation changesT-macrosMacro changesT-modelModel/data structure changesT-testTesting related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing resource-level metadata to listResources (lacks parity with readResource contents meta)

4 participants

@pbezglasny@athola@jokemanfire