Skip to content

Releases: tropk-ai/mcp-for-wordpress

v0.5.5 — fix invalid JSON schemas (Claude API 400)

Choose a tag to compare

@Webinhood Webinhood released this 22 Jul 23:45

Fixes the tools.N.custom.input_schema: JSON schema is invalid 400 error that crashed Claude/Cowork sessions when loading the plugin's MCP tools.

Root cause: 6 abilities declared an any-type property as an empty PHP array ('value' => []), which json_encode serializes as [] — invalid under JSON Schema draft 2020-12 (a schema must be an object or boolean).

Fixed input schemas: options-update, meta-update-post-meta, elementor-update-widget-setting, theme-set-customizer, bulk-set-meta, tropk-theme-set-mod. The same pattern was also fixed in 3 output schemas (options-get, system-get-transient, meta-get-post-meta).

All 508 tool schemas now validate clean against the draft 2020-12 meta-schema.

v0.5.4 — first tagged public release

Choose a tag to compare

@Webinhood Webinhood released this 27 Jun 04:12

This release consolidates three latent registration-order fixes that surfaced during a deep OAuth debugging session on a live VPS. Note up front: none of these patches was the root cause of the "could not register at login service" / "Não foi possível registrar no serviço de login" error that prompted the investigation — that error turned out to be operational (an nginx location ~ /.well-known { try_files $uri =404; } block that swallowed path-aware AS metadata requests before they reached WordPress, plus Elementor Maintenance Mode returning 503 on the anonymous /tropk-mcp/oauth/authorize consent page and /wp-json/tropk-mcp/v1/mcp session endpoint). Hosts hitting that symptom should re-check nginx routing and any maintenance-mode plugin before assuming the plugin itself is at fault. See the "Host configuration requirements" section below.

The three plugin-side fixes shipped here are real latent bugs surfaced by that session:

  1. Rewrite-flush priority race (was: MetadataEndpoints::register_rewrites()): the version-bump flush_rewrite_rules() ran inline at init:10 immediately after registering the .well-known/* rules, but BEFORE AuthorizationEndpoint::register_rewrite() (also init:10, registered later in Bootstrap) had a chance to add its ^tropk-mcp/oauth/authorize/?$ rule. On hosts where the persisted rewrite_rules option had not been re-flushed since the rule was introduced, /tropk-mcp/oauth/authorize would 404 until the admin manually visited Settings → Permalinks. The flush is now a dedicated maybe_flush_rewrites() callback at init:999, so every component that adds a rewrite rule at the default init:10 priority has registered by the time it fires.

  2. Abilities API hook-name bridge (was: McpServerBootstrap::register()): the vendored wordpress/mcp-adapter v0.5.x package registers its three core abilities (mcp-adapter/discover-abilities, mcp-adapter/get-ability-info, mcp-adapter/execute-ability) via add_action('wp_abilities_api_init', …) deferred inside maybe_create_default_server(), which is only reached during rest_api_init:15. On hosts where (a) WordPress core ships the Abilities API natively (WP 6.9+/7.0, fires wp_abilities_api_init during init), or (b) another plugin lazy-instantiates WP_Abilities_Registry during plugins_loaded, the action can fire BEFORE mcp-adapter's add_action() lands — leaving the three core abilities unregistered. McpComponentRegistry then logs WordPress ability '…' does not exist for each at server-creation time. The fix bridges BOTH name variants (wp_abilities_api_init for WP core, abilities_api_init for the vendor fallback) onto McpAdapter's public registration methods from plugins_loaded:20, plus a belt-and-braces synchronous fallback at init:5 for the race where either action already fired by then. Respects the upstream mcp_adapter_create_default_server filter. Mirrors the double-hook pattern already used by AbilityRegistrar for our own abilities.

  3. Repo / release hygiene: the public tropk-ai/mcp-for-wordpress repo was out of sync with the internal development mirror (last public push was 0.5.14, no tags, no GitHub releases). This release tags the public main and ships an installable zip via GitHub Releases so external evaluators can pull a known-good build without scraping the source tree. From this release onward, every version bump on the internal mirror is mirrored to the public repo with a matching tag and release artifact on the same day.

Host configuration requirements (read this before reporting an OAuth bug)

The OAuth fall-through that motivated this release was misdiagnosed at length as a plugin bug when both root causes were in the host. Sites running the plugin behind common stacks should confirm:

  • Path-aware AS metadata discovery — modern MCP brokers (Claude.ai, ChatGPT, Cursor) probe /.well-known/oauth-authorization-server<resource-path> per RFC 8414, not only the bare /.well-known/oauth-authorization-server. If your webserver short-circuits /.well-known/<anything-else> to a 404 (typical nginx try_files $uri $uri/ =404 block, common LiteSpeed .well-known ACME-only block), the broker discovery 404s before the request reaches WordPress and the connector aborts with a generic "could not register" message. nginx fix: replace location ~ /.well-known { try_files $uri $uri/ =404; } with location ~ ^/\\.well-known/oauth- { try_files $uri $uri/ /index.php?$args; } or remove the catch-all entirely so WordPress's own rewrite rules (which the plugin registers) can match.

  • Anonymous-request gates — the OAuth consent screen at /tropk-mcp/oauth/authorize AND the MCP transport endpoint at /wp-json/tropk-mcp/v1/mcp MUST be reachable without an authenticated session. Anything that intercepts unauthenticated frontend traffic — Elementor Maintenance Mode, "Coming Soon" / Under Construction plugins, basic-auth at the webserver layer, aggressive bot/UA firewalls, REST API hardeners that reject anonymous calls — will return a non-2xx (Elementor returns 503) for these endpoints and the broker aborts. Maintenance-mode plugins typically have a path-exclusion option; whitelist /tropk-mcp/* and /.well-known/oauth-* and /wp-json/tropk-mcp/* there.

  • Rewrite rule presence — after upgrading the plugin to 0.5.4 or first installing, the version-bump flush should regenerate rewrite_rules automatically. If the broker reports a 404 at the authorize hop, confirm with wp rewrite list | grep tropk-mcp/oauth that ^tropk-mcp/oauth/authorize/?$ is listed; if not, run wp rewrite flush --hard once.