WP Manifestindependent plugin directory
manifest / ai / sayed-wp-conductor-for-claude

Sayed WP Conductor for Claude

Secure Model Context Protocol (MCP) server for WordPress — bearer-token + OAuth 2.1 with PKCE, scope + capability dual-gate, audit log, brute-force lockout, 25 built-in tools.

by Taher Sayed · github.com/tahersayed/sayed-wp-conductor-for-claude · website

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/tahersayed/sayed-wp-conductor-for-claude/archive/refs/heads/main.zip

Powered by Taher Sayed · Taher Sayed

A WordPress plugin that turns your site into a secure Model Context Protocol (MCP) server so Claude (and any MCP-compatible client) can read, write, moderate and administrate it — with every call scoped, capability-checked, rate-limited and audit-logged.

Implements MCP 2025-06-18 over Streamable HTTP / JSON-RPC 2.0.

Sayed WP Conductor banner


Why Sayed WP Conductor?

Most WordPress AI plugins either expose an admin session to a third party or skip auth entirely. Sayed WP Conductor is built around hard interlocks:

  • No anonymous access. Every request needs a bearer token.
  • Tokens hashed at rest (SHA-256). The plaintext is shown to the admin once, never recoverable.
  • Triple gate per call. MCP scope (read / write / admin) + WordPress capability (current_user_can) + optional "danger mode" interlock for destructive ops.
  • Audit log for every successful and failed call (token id, IP, method, tool, status, note).
  • Transport hardening. HTTPS enforced, Origin checked, request size capped, rate-limited, constant-time token comparison.
  • SSRF guard on media.upload (rejects private / loopback / reserved IPs).
  • Self-protection. The plugin will refuse to deactivate itself via plugins.toggle.

Install / upgrade

From WordPress.org (recommended once approved): Search for "Sayed WP Conductor for Claude" under Plugins → Add New, install, activate.

From this repo (development install):

cd wp-content/plugins/
git clone https://github.com/TaherSayed/sayed-wp-conductor-for-claude.git sayed-wp-conductor-for-claude

Then activate Sayed WP Conductor for Claude under Plugins. The 30-second setup wizard runs on first activation. (The local folder must be named sayed-wp-conductor-for-claude so it matches the text-domain slug.)

From a release zip: Download the latest sayed-wp-conductor-for-claude-x.y.z.zip from Releases and upload via Plugins → Add New → Upload Plugin.

After install:

  1. Go to Sayed WP Conductor → Tokens and issue a token (bind it to a least-privileged WP user).
  2. Tune Sayed WP Conductor → Settings — allowed origins, rate limit, destructive ops, trust-proxy, OAuth options, enabled tools.

Requires: PHP 8.0+ and WordPress 6.2+.


Endpoints

Purpose URL
MCP (RPC) https://your-site/wp-json/claude-mcp/v1/rpc
Discovery https://your-site/wp-json/claude-mcp/v1/discovery

Auth: Authorization: Bearer cmcp_xxxxx…


Tools — what Claude can do

Read (read scope)

Tool What
site.info Site name, URL, language, timezone
site.health WP/PHP/MySQL versions, debug flags, available updates, plugins/themes count, disk free
posts.list List posts / pages / CPTs
posts.get Fetch single post (full content + meta)
posts.search Full-text search
media.list List attachments
comments.list List comments by status
terms.list List terms in any taxonomy
settings.get Read whitelisted site options

Write (write scope)

Tool What
posts.create Create post / page / CPT, with categories, tags, meta
posts.update Edit any of the above
posts.delete Trash — permanent only with danger mode
media.upload Sideload image/file from a public URL (SSRF-guarded)
media.delete Delete attachment
comments.moderate Approve / hold / spam / trash / untrash
terms.create Add a category, tag, or custom term

Admin (admin scope)

Tool What
users.list / users.create / users.update User management (passwords NOT settable via MCP)
plugins.list / plugins.toggle List, activate, deactivate plugins (cannot deactivate Sayed WP Conductor itself)
themes.list / themes.activate List and switch themes
settings.update Update whitelisted options (sensitive keys require danger mode)

Quick test (curl)

TOKEN="cmcp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
HOST="https://your-site.tld"

# initialize
curl -sS -X POST "$HOST/wp-json/claude-mcp/v1/rpc" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -H "Accept: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","clientInfo":{"name":"curl","version":"1"},"capabilities":{}}}' | jq

# list tools
curl -sS -X POST "$HOST/wp-json/claude-mcp/v1/rpc" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -H "Accept: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | jq

# create a draft post
curl -sS -X POST "$HOST/wp-json/claude-mcp/v1/rpc" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -H "Accept: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"posts.create","arguments":{"title":"Hello from Claude","content":"<p>It works.</p>","status":"draft"}}}' | jq

For each WordPress site managed by Taher Sayed, create at least:

Purpose Scopes Bound user Notes
Daily reading / monitoring read low-privilege subscriber Use for dashboards and reports
Content workflows read, write editor Post creation, media uploads, comment moderation
Maintenance & admin read, write, admin administrator Plugin/theme/user management. Set short expiry.

Add IP allowlist on each token if you call from a fixed location.


Security checklist

  • [ ] HTTPS on, Require HTTPS enabled
  • [ ] Tokens bound to least-privileged WP users
  • [ ] Rate limit configured
  • [ ] Allowed origins set to your actual clients
  • [ ] Audit log enabled — checked regularly
  • [ ] Danger mode OFF unless you explicitly need permanent deletes / siteurl edits
  • [ ] WP core, PHP, this plugin kept up to date

Threats handled

  • DNS rebinding (Origin allowlist)
  • Token theft / replay (hash at rest, expiry, revocation, IP allowlist)
  • Timing attacks (constant-time compare, dummy compare on miss)
  • Abuse / runaway loops (per-token rate limit, body size cap)
  • Privilege escalation (WP capability final check)
  • SSRF on media URL fetches (no private / loopback / reserved IPs)
  • Self-lockout (refuses to deactivate Sayed WP Conductor itself)
  • Log poisoning (control-char strip, length cap, no token plaintext)

Threats NOT handled

  • Compromised WP admin credentials
  • A malicious tool added via the cmcp_register_tools filter — only install code you trust
  • Host-level attacks

Adding custom tools

add_filter( 'cmcp_register_tools', function( array $tools ) {
    $tools[] = new class extends \CMCP\Tools\AbstractTool {
        public function name(): string        { return 'orders.recent'; }
        public function description(): string { return 'Recent WooCommerce orders.'; }
        public function input_schema(): array {
            return [
                'type' => 'object',
                'properties' => [ 'limit' => [ 'type' => 'integer', 'minimum' => 1, 'maximum' => 50 ] ],
                'additionalProperties' => false,
            ];
        }
        public function required_scope(): string      { return \CMCP\Auth::SCOPE_READ; }
        public function required_capability(): string { return 'manage_woocommerce'; }
        public function execute( array $args ): array {
            // your query …
            return $this->json( [ 'todo' => true ] );
        }
    };
    return $tools;
} );

Enable the new tool name in Sayed WP Conductor → Settings → Enabled tools.


WP-CLI

wp cmcp token issue --label="ci" --scopes=read,write --user-id=2 --expires-days=90
wp cmcp token list
wp cmcp token revoke 5

License

GPL-2.0-or-later · © Taher Sayed