Skip to content

Provide resource URI in both meta.uri and meta.mcp.uri (adapter version collision) - #30

Merged
oxyc merged 1 commit into
masterfrom
fix/resource-uri-compat
Jun 24, 2026
Merged

oxyc merged 1 commit into
masterfrom
fix/resource-uri-compat

Conversation

@oxyc

@oxyc oxyc commented Jun 24, 2026

Copy link
Copy Markdown
Member

Symptom

Production (medihealth) logs Resource URI not found in ability meta for 'gds/block-types-list' (and gds/site-map, gds/design-theme-json, gds/acf-fields) continuously — every MCP resource registration fails. This persisted after #29 shipped and deployed.

Root cause: two copies of wordpress/mcp-adapter, older one wins the autoload

There are two mcp-adapter installs on disk, both registering the WP\MCP\ namespace:

Path Version Reads URI from
web/app/plugins/mcp-adapter/ v0.5.0 meta.mcp.uri (with top-level fallback)
web/app/plugins/woocommerce/vendor/wordpress/mcp-adapter/ v0.4.1 (bundled in WooCommerce) top-level meta.uri only

WooCommerce bundles its own older copy, and its v0.4.1 autoloader wins, so v0.4.1 is the code actually executing. #29 moved uri/mimeType out of top-level meta and into meta.mcp — correct for v0.5.0, but it removed the URI from exactly where the running v0.4.1 reads it → "Resource URI not found".

Verified on the prod server

  • adapter files on disk emit the v0.5.0 message (...at 'mcp.uri'), gds-mcp = f1ae4aa9 (Fix: register MCP resource URI under meta.mcp.uri #29 deployed), BlockCatalogResource has 'uri' => 'blocks://catalog' under meta.mcp — all correct.
  • yet the logs show the v0.4.1 wording (...in ability meta data) firing right up to "now".
  • grep -rln "in ability meta data" ~/public/current/.../plugins/woocommerce/vendor/wordpress/mcp-adapter/.../RegisterAbilityAsMcpResource.php (the v0.4.1 copy).

So this is not OPcache and not a stale deploy — a PHP restart/redeploy does nothing. It's a duplicate-package namespace collision.

Fix (this PR)

Declare uri/mimeType in both top-level meta and meta.mcp for all 4 resource abilities (BlockCatalogResource, SiteMapResource, ThemeJsonResource, AcfFieldsResource). This resolves regardless of which adapter wins:

  • v0.4.1 reads top-level meta.uri
  • v0.5.0 reads meta.mcp.uri first (so no _doing_it_wrong deprecation notice) ✓

HelpAbility already reads meta.mcp.uri ?? meta.uri. php -l clean; composer lint (pint) + composer stan (phpstan) pass; meta-shape tests unaffected (uri still present at mcp.uri).

Follow-up (separate, not this PR)

The cleaner long-term fix is to eliminate the duplicate adapter so only one version loads — i.e. stop WooCommerce's bundled v0.4.1 from registering (composer-level dedupe, or a small mu-plugin forcing the v0.5.0 autoload first). Carrying two versions of the same library risks other conflicts. This PR makes gds-mcp robust either way in the meantime.

🤖 Generated with Claude Code

PR #29 moved the resource `uri`/`mimeType` for the four MCP resource
abilities (gds/block-types-list, gds/site-map, gds/design-theme-json,
gds/acf-fields) out of top-level `meta` and into `meta.mcp`, on the
assumption that medihealth runs WordPress/mcp-adapter >= 0.5.0 (which
reads `meta.mcp.uri`).

The `resource_uri_not_found` error is still firing in production on
medihealth (~83x/day, latest 2026-06-24 08:02) despite #29 being
deployed (gds-mcp dev-master f1ae4aa, deployed 2026-06-23 16:57).

Root cause: the error text in production is
"...URI must be provided in ability meta data." — this is the PRE-0.5.0
adapter message. v0.5.0's message is "...URI must be provided at
'mcp.uri'." The pre-0.5.0 RegisterAbilityAsMcpResource::get_uri() reads
ONLY top-level `meta.uri` and has no knowledge of `meta.mcp.uri`. So
medihealth's actually-running adapter is < 0.5.0 even though its
composer.lock pins v0.5.0 (ref 7bfc49f4) — the deployed vendor/ is stale
relative to the lockfile. By moving `uri` exclusively into `meta.mcp`,
#29 removed the only location the deployed adapter reads, so the URI
became unresolvable and the error persists.

Fix: declare `uri`/`mimeType` in BOTH top-level `meta` AND `meta.mcp`
for all four resource abilities. This is adapter-version agnostic:
- adapter < 0.5.0 finds top-level `meta.uri`;
- adapter >= 0.5.0 finds `meta.mcp.uri` first (so no deprecation
  `_doing_it_wrong` notice is triggered).

HelpAbility already reads `meta.mcp.uri ?? meta.uri`, and the meta-shape
tests (HelpAbilityTest::test_resources_include_uri, SchemaValidationTest)
remain satisfied.

Note: the real underlying issue is the adapter-version skew on
medihealth (deployed vendor < lockfile). This change makes gds-mcp
robust across adapter versions regardless, but medihealth should also be
redeployed so vendor/wordpress/mcp-adapter actually matches v0.5.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@oxyc oxyc changed the title fix(resources): provide resource URI in both top-level meta and meta.mcp (adapter-version compat) Provide resource URI in both meta.uri and meta.mcp.uri (adapter version collision) Jun 24, 2026
@oxyc
oxyc merged commit b7ce030 into master Jun 24, 2026
2 checks passed
oxyc added a commit that referenced this pull request Jul 31, 2026
…recation (#31)

mcp-adapter 0.5.0 resolves resource meta through get_mcp_meta(), which
prefers meta.mcp.{key} and logs a deprecation notice when it falls back to
the top-level key. #29/#30 moved uri/mimeType into meta.mcp but left
annotations at the top level, so every WP-CLI run logged four notices:

  Ability meta key "annotations" is deprecated. Use "mcp.annotations"
  instead. | Context: {"ability":"gds/block-types-list", ...}

Mirror annotations into meta.mcp for the four resource abilities. The
top-level copy stays: RegisterAbilityAsMcpTool still reads only
$ability_meta['annotations'] in 0.5.0, and adapters < 0.5.0 read top-level
for resources too.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant