Fix: WP_CLI::line() in serve command corrupts JSON-RPC stdout stream#194
Fix: WP_CLI::line() in serve command corrupts JSON-RPC stdout stream#194graham73may wants to merge 1 commit into
Conversation
When no --server flag is passed, the serve command called WP_CLI::line() to report which server it selected. WP_CLI::line() writes to stdout, which corrupts the JSON-RPC stream and breaks any MCP client using STDIO transport (Claude Code, VS Code, Cursor, etc.). WP_CLI::debug() writes to stderr and is suppressed by default, so it has no impact on normal usage but remains visible with --debug.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Unlinked AccountsThe following contributors have not linked their GitHub and WordPress.org accounts: @gmay-sbx. Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases. If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
There was a problem hiding this comment.
Pull request overview
Fixes a protocol-breaking stdout write in the wp mcp-adapter serve command when no --server flag is provided, ensuring the JSON-RPC 2.0 STDIO stream remains clean for MCP clients.
Changes:
- Replace
WP_CLI::line()(stdout) withWP_CLI::debug()(stderr) when auto-selecting the first registered server.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## trunk #194 +/- ##
============================================
- Coverage 88.45% 87.85% -0.60%
Complexity 1243 1243
============================================
Files 53 53
Lines 4035 4035
============================================
- Hits 3569 3545 -24
- Misses 466 490 +24
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Thanks for this. Inhale (the wp.org settings page i shipped on top of the Abilities API + MCP Adapter) had users hitting the corrupted-stream bug on every fresh |
Snippet in the Connection section pointed at a non-existent subcommand:
`wp mcp stdio` is not a registered command on the upstream MCP Adapter.
The McpCommand class only registers `serve` and `list`. Anyone copying
the snippet into Claude Desktop hit "command not found" on first run.
This patch makes three changes to the STDIO snippet:
1. `mcp` + `stdio` → `mcp-adapter` + `serve` (canonical subcommand
per the upstream README + cli-usage.md guide).
2. Add `--user=admin` to the args. Without it the serve process runs
as the OS user (root/www-data) and can't see admin-scoped abilities.
3. New line above the snippet noting that STDIO transport requires
WordPress and the MCP client to run on the same machine. The HTTP
transport snippet below is the correct path for remote sites.
Surfaced while reviewing WordPress/mcp-adapter#194 (a separate fix for
stdout corruption in the `serve` fallback path). Inhale's snippet always
passes --server explicitly so it does not hit #194's buggy fallback; the
fixes in this release are independent.
No change to the abilities filter, the settings page UI, or any stored
option. Safe upgrade.
Problem
When
wp mcp-adapter serveis called without a--serverflag, it falls back to the first registered server and callsWP_CLI::line()to report the selection:WP_CLI::line()writes to stdout. Theservecommand communicates with MCP clients over STDIO using the JSON-RPC 2.0 protocol, so anything written to stdout before the first{is treated as part of the protocol stream. This causes the client's JSON parser to fail immediately.Real-world impact: Any MCP client using STDIO transport (Claude Code, VS Code Copilot, Cursor, etc.) that omits
--serverwill fail to connect. Workarounds require piping output throughgrep '^{'to strip the non-JSON line.Fix
Change
WP_CLI::line()toWP_CLI::debug(). Debug output goes to stderr and is suppressed by default, so:--debugChange
includes/Cli/McpCommand.phpline 78: