Skip to content

feat: pass _meta through resources/read path#211

Merged
seuros merged 2 commits intoseuros:masterfrom
crisnahine:mcp-meta-passthrough
Apr 15, 2026
Merged

feat: pass _meta through resources/read path#211
seuros merged 2 commits intoseuros:masterfrom
crisnahine:mcp-meta-passthrough

Conversation

@crisnahine
Copy link
Copy Markdown
Contributor

@crisnahine crisnahine commented Apr 15, 2026

Fixes a pre-existing spec gap. ext-apps/src/generated/schema.json defines _meta on Resource, TextResourceContents, and BlobResourceContents, but action_mcp was dropping it on the resources/read path.

changes

  • Resource accepts _meta: kwarg, emits it on to_h, includes it in == and hash
  • Content::Resource accepts _meta: kwarg, emits it on the inner resource: hash (matches TextResourceContents / BlobResourceContents shape, not the outer {type, resource} envelope)
  • normalize_read_content in server/resources.rb passes _meta through on the inner contents
  • ResourceTemplate#build_resource accepts and forwards _meta:
  • both Resource and Content::Resource raise ArgumentError on non-Hash _meta

tests

  • _meta assertions folded into existing tests in resource_test.rb, content_test.rb, and resource_template_test.rb
  • MetaEchoTemplate added to the dummy app; server/resources_test.rb uses it to drive a real send_resource_read call and assert the wire shape

scope

spec-gap fix only. no MCP Apps vocabulary. the MCP Apps support (#202) builds on top in a follow-up PR.

Resource, Content::Resource, resource_template#build_resource and the
server resources handler now preserve _meta from template resolve
through to the wire response. closes a pre-existing spec gap: the
ext-apps schema.json defines _meta on Resource, TextResourceContents
and BlobResourceContents, but the gem was dropping it.

Inner _meta is emitted on the inner resource hash, not the outer
content envelope, matching apps.mdx:233-259 (TextResourceContents /
BlobResourceContents definitions).

Validation: ArgumentError if _meta is passed as a non-Hash. Empty hash
is treated the same as nil (not emitted).
@crisnahine crisnahine force-pushed the mcp-meta-passthrough branch from b0a3ab5 to b759280 Compare April 15, 2026 10:34
@crisnahine crisnahine marked this pull request as ready for review April 15, 2026 10:37
Comment thread lib/action_mcp/content/resource.rb Outdated
Comment thread lib/action_mcp/resource.rb Outdated
the Ruby kwarg and attr_reader are `meta` now, wire output is still `_meta`.
`_` prefix in Ruby means unused, which was misleading.

also duck-type the input: respond_to?(:to_hash) first, then :to_h, otherwise
ArgumentError. scoped to Resource, Content::Resource, and
ResourceTemplate#build_resource so this PR stays narrow.
@seuros seuros merged commit e495469 into seuros:master Apr 15, 2026
9 checks passed
@crisnahine crisnahine deleted the mcp-meta-passthrough branch April 16, 2026 05:11
crisnahine added a commit to crisnahine/action_mcp that referenced this pull request Apr 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants