Skip to content

MCP client: bridge external MCP servers as built-in tools (closes #38) - #51

Merged
lezama merged 1 commit into
mainfrom
ship/issue-38-mcp-client-bridge
May 18, 2026
Merged

MCP client: bridge external MCP servers as built-in tools (closes #38)#51
lezama merged 1 commit into
mainfrom
ship/issue-38-mcp-client-bridge

Conversation

@lezama

@lezama lezama commented May 17, 2026

Copy link
Copy Markdown
Owner

Closes #38

Summary

Adds a wp-admin → openclaWP → MCP Clients page that lets admins register external MCP servers and have their advertised tools surface in the local ability registry under mcp/<server>/<tool>, so agents can call them just like any other ability.

What ships

  • OpenclaWP_Mcp_Client_Store — CPT-backed store for server configs (transport, command/args/env or url/headers, per-tool allowlist + disabled list, cached tool metadata, last-error).
  • OpenclaWP_Mcp_Client_Transport — thin MCP 2025-06-18 JSON-RPC client. Implements initialize + tools/list + tools/call over stdio (proc_open) and over Streamable HTTP (wp_remote_post).
  • OpenclaWP_Mcp_Client_Bridge — registers each enabled server's non-disabled, allowlisted tools as WP abilities under mcp/<slug>/… and proxies execution back through the transport. Errors surface as WP_Errors so the loop's tool-call mediator can degrade gracefully ("the X tool is unavailable…").
  • OpenclaWP_Mcp_Clients_Admin — list / add / edit / re-test / per-tool enable-disable / delete. Three one-click recipes:
    • Fetchnpx -y @modelcontextprotocol/server-fetch, works out of the box.
    • Context7npx -y @upstash/context7-mcp, needs CONTEXT7_API_KEY.
    • GitHub MCPnpx -y @modelcontextprotocol/server-github, needs GITHUB_PERSONAL_ACCESS_TOKEN.

No new PHP or JS dependencies. The transport uses PHP's built-in proc_open and WordPress's wp_remote_post.

Test plan

  • vendor/bin/phpunit --testsuite unit — 41 tests, 88 assertions, all green (9 new tests under tests/unit/McpClientBridgeTest.php).
  • php tests/smoke.php — exits 0 (full smoke needs a real WP via studio wp eval-file).
  • npm run lint — clean.
  • npm run build — webpack compiled successfully.
  • Manual on a Studio site: install the Fetch recipe, click Re-test, see fetch tool advertised, attach mcp/fetch/fetch to an agent's default_config['tools'], ask the agent "fetch https://example.com" — agent receives the markdown.
  • Graceful degradation: disable Fetch (e.g. wrong command), confirm the agent reports the tool is unavailable instead of hanging.
  • Per-tool disable: from the edit page, disable an individual tool, confirm it disappears from the agent's tool surface on next request.

What's deferred

  • HTTP transport is wired but unproven against a real Streamable HTTP MCP server.
  • Catalog-mode integration with Multi-turn agentic loop with tool calling #1 (tool-discovery meta-tools) — bridged abilities all live under the openclawp-mcp-clients category so a future catalog layer can filter them as a group.
  • OAuth flow for MCP servers that require it. The HTTP path supports static bearer headers via the config UI today.

Hard rules

  • No edits to vendor/automattic/agents-api/.
  • No .mcp.json at the repo root — the admin page is the canonical surface.
  • composer.json unchanged. package.json unchanged (lockfile has only peer-flag reclassifications from npm install).

Adds a wp-admin → openclaWP → MCP Clients page that lets admins register
external MCP servers and have their advertised tools surface in the local
ability registry under the `mcp/<server>/<tool>` prefix, so agents can
call them just like any other ability.

v1 ships:

* `OpenclaWP_Mcp_Client_Store` — CPT-backed store for server configs
  (transport, command/args/env or url/headers, per-tool allowlist +
  disabled list, cached tool metadata, last-error).
* `OpenclaWP_Mcp_Client_Transport` — thin MCP 2025-06-18 JSON-RPC client.
  Implements initialize + tools/list + tools/call over stdio
  (`proc_open`) and over Streamable HTTP (`wp_remote_post`).
* `OpenclaWP_Mcp_Client_Bridge` — registers each enabled server's
  non-disabled, allowlisted tools as WP abilities under `mcp/<slug>/…`
  and proxies execution back through the transport. Errors surface as
  WP_Errors so the loop's tool mediator can degrade gracefully.
* `OpenclaWP_Mcp_Clients_Admin` — list / add / edit / re-test / per-tool
  enable-disable / delete. Three one-click recipes: Fetch (works out of
  the box), Context7 (needs CONTEXT7_API_KEY), GitHub MCP (needs
  GITHUB_PERSONAL_ACCESS_TOKEN).
* Unit tests assert that bridged tools show up under the `mcp/` prefix,
  that disabled/allowlist filtering works, and that unsafe tool names
  are sanitised in the ability path while preserving the original
  server-native name for tools/call round-trip.

Deferred to follow-ups:

* HTTP transport is wired but unproven against a real server.
* Catalog-mode integration with #1 (tool-discovery meta-tools).
* OAuth flow for MCP servers that require it (current http path
  supports static bearer headers via the config UI).

Closes #38
@lezama
lezama force-pushed the ship/issue-38-mcp-client-bridge branch from f77aad2 to 358d764 Compare May 18, 2026 10:48
@lezama
lezama merged commit 6506140 into main May 18, 2026
6 checks passed
@lezama
lezama deleted the ship/issue-38-mcp-client-bridge branch May 18, 2026 10:52
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.

Bridge external MCP servers as built-in tools (Context7, Fetch, GitHub)

1 participant