From b58ad702b4b71d83985ce16cc2faa645b144cb46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Sch=C3=B6ldstr=C3=B6m?= Date: Wed, 24 Jun 2026 05:18:07 -0300 Subject: [PATCH] fix(resources): provide resource URI in both top-level meta and meta.mcp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- src/Abilities/AcfFieldsResource.php | 7 +++++++ src/Abilities/BlockCatalogResource.php | 7 +++++++ src/Abilities/SiteMapResource.php | 7 +++++++ src/Abilities/ThemeJsonResource.php | 7 +++++++ 4 files changed, 28 insertions(+) diff --git a/src/Abilities/AcfFieldsResource.php b/src/Abilities/AcfFieldsResource.php index c6f596a..5b318b7 100644 --- a/src/Abilities/AcfFieldsResource.php +++ b/src/Abilities/AcfFieldsResource.php @@ -30,6 +30,13 @@ public static function register(): void 'permission_callback' => '__return_true', 'execute_callback' => [new self, 'execute'], 'meta' => [ + // Provide the resource URI/mimeType in BOTH locations for adapter + // cross-compatibility: WordPress/mcp-adapter >= 0.5.0 reads meta.mcp.uri + // (canonical), while < 0.5.0 reads only top-level meta.uri. Keeping both + // works on every adapter version without triggering 0.5.0 deprecation + // notices (the mcp.* copy is matched first). + 'uri' => 'acf://fields', + 'mimeType' => 'application/json', 'mcp' => [ 'type' => 'resource', 'public' => true, diff --git a/src/Abilities/BlockCatalogResource.php b/src/Abilities/BlockCatalogResource.php index b0b5589..3185b00 100644 --- a/src/Abilities/BlockCatalogResource.php +++ b/src/Abilities/BlockCatalogResource.php @@ -25,6 +25,13 @@ public static function register(): void 'permission_callback' => '__return_true', 'execute_callback' => [new self, 'execute'], 'meta' => [ + // Provide the resource URI/mimeType in BOTH locations for adapter + // cross-compatibility: WordPress/mcp-adapter >= 0.5.0 reads meta.mcp.uri + // (canonical), while < 0.5.0 reads only top-level meta.uri. Keeping both + // works on every adapter version without triggering 0.5.0 deprecation + // notices (the mcp.* copy is matched first). + 'uri' => 'blocks://catalog', + 'mimeType' => 'application/json', 'mcp' => [ 'type' => 'resource', 'public' => true, diff --git a/src/Abilities/SiteMapResource.php b/src/Abilities/SiteMapResource.php index 66a5a6c..7cf80d4 100644 --- a/src/Abilities/SiteMapResource.php +++ b/src/Abilities/SiteMapResource.php @@ -30,6 +30,13 @@ public static function register(): void 'permission_callback' => '__return_true', 'execute_callback' => [new self, 'execute'], 'meta' => [ + // Provide the resource URI/mimeType in BOTH locations for adapter + // cross-compatibility: WordPress/mcp-adapter >= 0.5.0 reads meta.mcp.uri + // (canonical), while < 0.5.0 reads only top-level meta.uri. Keeping both + // works on every adapter version without triggering 0.5.0 deprecation + // notices (the mcp.* copy is matched first). + 'uri' => 'site://pages', + 'mimeType' => 'application/json', 'mcp' => [ 'type' => 'resource', 'public' => true, diff --git a/src/Abilities/ThemeJsonResource.php b/src/Abilities/ThemeJsonResource.php index 3f9fee0..4d3a743 100644 --- a/src/Abilities/ThemeJsonResource.php +++ b/src/Abilities/ThemeJsonResource.php @@ -24,6 +24,13 @@ public static function register(): void 'permission_callback' => '__return_true', 'execute_callback' => [new self, 'execute'], 'meta' => [ + // Provide the resource URI/mimeType in BOTH locations for adapter + // cross-compatibility: WordPress/mcp-adapter >= 0.5.0 reads meta.mcp.uri + // (canonical), while < 0.5.0 reads only top-level meta.uri. Keeping both + // works on every adapter version without triggering 0.5.0 deprecation + // notices (the mcp.* copy is matched first). + 'uri' => 'theme://json', + 'mimeType' => 'application/json', 'mcp' => [ 'type' => 'resource', 'public' => true,