feat: mcp enable + site create --mcp — make a site MCP-ready in one command#11
feat: mcp enable + site create --mcp — make a site MCP-ready in one command#11vikasiwp wants to merge 1 commit into
mcp enable + site create --mcp — make a site MCP-ready in one command#11Conversation
… in one command Provisions InstaMCP on a site with no wp-admin clicks, so an agent can spin up a sandbox and immediately drive it over MCP. - `instawp mcp enable <site>`: install+activate the InstaMCP plugin (if absent), enable Execute PHP + Site Files (read-write), mint a Bearer token tied to an administrator (→ mcp:admin scope), and emit a machine-readable connection blob plus ready-to-paste .mcp.json / `claude mcp add` snippets. Idempotent — the token is cached locally (the plugin stores only its hash) so re-running re-prints the same token; --rotate forces a fresh one. - `instawp site create --mcp [--plugins a,b]`: create → wait → install plugins → same enable path → same blob. Uses InstaMCP's supported Bearer-token transport (/insta-mcp?t=<token>). OAuth 2.1 client provisioning is intentionally NOT done: the plugin ships with INSTA_MCP_OAUTH_FEATURE_ENABLED=false (no OAuth tables/routes to mint against). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
|
Next step (human): run Also note the deliberate scope decision in the description: OAuth 2.1 client minting is intentionally not implemented — the plugin ships E2E on live site 2568862 is being validated by the QA agent (author has no SSH to customer hosts). |
QA: PASS ✅Env: live throwaway sandbox Built the branch clean ( 1.
|
| check | result |
|---|---|
insta-mcp plugin active |
yes (exit 0) |
insta_mcp_execute_php_enabled |
0 → 1 |
insta_mcp_site_files_mode |
read_only → read_write |
| token row | inserted for user_id 1 (administrator), label InstaWP CLI |
| sha256 of printed token | matches the stored token_hash on the site ✓ |
4. Idempotency ✅
Re-running mcp enable 2568862 printed the same token (rotated:false) and added no new row — COUNT(*) WHERE label='InstaWP CLI' stayed 1.
Bonus — --rotate ✅
--rotate minted a fresh token (rotated:true), still a single labelled row (no pile-up). New token → 200; the previous token → 401 (hash genuinely replaced).
Repro-before-fix: n/a (new feature) — but I disabled the two flags first and showed enable flip them 0→1 / read_only→read_write, so the run exercised the real code path, not a pre-configured no-op.
Notes for the merger:
- The
mcp:adminscope in the JSON is CLI-asserted (from the admin-token → scope map), and I independently confirmed the token can list & would drive admin tools (execute_php,db_query) over MCP — so it's substantiated, not just a label. - One transport caveat, not a PR bug: the QA host's ssh_config forces
ControlMasterwith a socket under a read-only~/.ssh; the CLI'ssshArgsdoesn't setControlMaster=no/ControlPath=none, so on such a host every SSH call fails to bind the mux socket. It works fine on a normal box. Might be worth having the CLI pin-o ControlPath=nonedefensively — flagging forengineer, out of scope for this verdict. - Plugin install path was NOT exercised (InstaMCP was already active on 2568862, so it hit the "already active" branch). The enable/token/endpoint logic is fully covered; a from-scratch install on a bare site is the one untested sub-path.
site create --mcp(the other command in this PR) was not tested here — this task scoped onlymcp enable.
Site restored to its original state (token table back to just the pre-existing "Default Token", flags at their original 1/read_write).
— QA
What
Adds two commands that make a site MCP-ready in one shot, so an agent can spin up an InstaWP sandbox and immediately drive it over MCP (InstaMCP) with no wp-admin clicks:
instawp mcp enable <site>— for an existing site:--plugin-zip <url>/INSTAMCP_PLUGIN_ZIP),insta_mcp_execute_php_enabled=1) and Site Files read-write (insta_mcp_site_files_mode=read_write),mcp:admin, via the plugin's role→scope map),--json) plus ready-to-paste.mcp.jsonandclaude mcp add …snippets.instawp site create --mcp [--plugins elementor,bricks]— create → wait for ready → install any--plugins→ run the same enable path → same blob.Idempotent: re-running re-prints the same token instead of minting a new one. The plugin stores only the token's SHA256 hash, so the plaintext is cached locally (
~/.config/instawp, keyed by site id, alongside the existing SSH/site caches).--rotateforces a fresh token (upserts a single labelled row — never piles up).All plumbing reuses the existing SSH transport (
ensureSshAccess+execViaSsh, MOTD-stripped) and config store — no new deps.Connection shape
Uses InstaMCP's supported Bearer-token transport, exactly as documented in the plugin's
docs/CLIENTS.mdand matching the liveinstawp-marketingreference (InstaMCP 1.9.2):The task asked to "mint an OAuth client + token." That is not currently possible from the CLI: the plugin ships with
INSTA_MCP_OAUTH_FEATURE_ENABLED = false(insta-mcp.php), so the OAuth tables (*_oauth_clients/*_authorization_codes/*_access_tokens/*_refresh_tokens) and the/oauth/authorize|token+.well-known/*routes are never created. There is nothing to register a client against.This PR therefore provisions the working, supported Bearer path. Enabling true OAuth 2.1 / DCR is a plugin-side change (flip the feature flag, ship the OAuth tables + a client-registration path, generate signing keys) — see the linked issue/report. Called out here per the task's "stop and surface if it needs a plugin change" guidance.
Testing
npm run build✅ ·npm test✅ (486/486)instawp mcp enable --help,instawp create --helpshow the new options).inspired-bear-cc5731.instawp.site) before merge (QA is being asked to do this).--pluginsslug validation,--plugin-zipURL guard). Its token/SQL "injection" flags were verified not-real (token is generated[0-9a-f]hex; SQL uses$wpdb->prepare).Next step (human):
/code-review ultra <PR#>before merge.