=== Zen MCP Bridge ===
Contributors: guramzhgamadze
Tags: ai, claude, anthropic, mcp, connector
Requires at least: 6.9
Tested up to: 7.0
Requires PHP: 8.0
Stable tag: 3.2.3
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Connect your WordPress site to Claude.ai via the Model Context Protocol (MCP), giving Claude read-only access to your site's internals.

== Description ==

Zen MCP Bridge turns your WordPress site into an MCP server that Claude.ai can connect to. Once connected, Claude can inspect your site's architecture in real time — plugins, database schema, source code, ACF fields, REST routes, cron jobs and more — so it can write plugins, debug issues and answer questions tailored to your exact setup.

**Read-only by default. Claude cannot write, delete or modify anything unless you explicitly enable the opt-in write mode — and even then it can only work with drafts, allowlisted options, plugin toggles, caches and terms, with every action audited.**

= Features =

* Full OAuth 2.1 authorization server with PKCE (S256), dynamic client registration (RFC 7591) and auto-discovery (RFC 8414 + RFC 9728).
* Bearer Token auth as a simpler alternative to OAuth — never expires.
* Configurable OAuth token lifetime — 1 hour, 24 hours, 7 days or 30 days, plus an emergency "Revoke all tokens" button.
* 25 read-only MCP tools covering site info, plugins, themes, post types, taxonomies, options, posts, database schema, structured table reads, files, code search, logs, hooks, ACF fields, users, menus, cron, transients, widgets, REST routes, Action Scheduler, WooCommerce and Elementor.
* MCP resources (site snapshots at wordpress:// URIs) and canned prompts for site analysis, debugging and plugin writing.
* Opt-in **write mode** (off by default): six scoped write tools — create/update DRAFT posts, update allowlisted options, toggle plugins, clear caches, create terms. OAuth sessions additionally need a write grant ticked on the consent screen; everything is audited. Deleting, publishing, user management and write SQL are never possible.
* WordPress Abilities API integration (WP 6.9+): tools are discoverable by the WordPress AI ecosystem, admin-only. Stands down automatically when the official AI Provider for Anthropic plugin is active.
* MCP specification 2025-11-25 compliant.
* Rate limiting, path-traversal guards, credential redaction and clickjacking protection.
* Apache + FastCGI compatible (Authorization header normalization built in).
* Zero dependencies — pure WordPress, no Composer required.

= Available tools =

Read: `wp_get_site_info`, `wp_get_plugins`, `wp_get_themes`, `wp_get_post_types`, `wp_get_taxonomies`, `wp_get_options`, `wp_query_posts`, `wp_get_post`, `wp_get_db_schema`, `wp_db_query`, `wp_list_files`, `wp_read_file`, `wp_search_code`, `wp_get_logs`, `wp_get_hooks`, `wp_get_acf_fields`, `wp_get_users`, `wp_get_menus`, `wp_get_cron_jobs`, `wp_get_transients`, `wp_get_scheduled_actions`, `wp_get_active_widgets`, `wp_get_rest_routes`, `wp_get_woocommerce`, `wp_get_elementor`.

Write (only with write mode enabled): `wp_create_draft_post`, `wp_update_draft_post`, `wp_update_option`, `wp_toggle_plugin`, `wp_clear_cache`, `wp_create_term`.

== Installation ==

1. Upload the plugin to `wp-content/plugins/zen-mcp-bridge`, or install it from your WordPress admin.
2. Activate the plugin through the **Plugins** screen.
3. Go to **Settings → MCP Bridge** to find your endpoint URL and Bearer token.
4. Flush rewrite rules once: **Settings → Permalinks → Save Changes**.

== Frequently Asked Questions ==

= How do I connect with a Bearer token (simplest)? =

1. In Claude.ai: **Profile → Settings → Connectors → Add custom connector**.
2. Paste your MCP endpoint URL (shown on **Settings → MCP Bridge**), for example `https://your-site.com/wp-json/zen-mcp/v1/bridge`.
3. Set the auth type to **Bearer Token** (or **API Key**) and paste the token from the settings page.
4. Save. Bearer tokens never expire.

= How does the OAuth 2.1 login flow work? =

Claude.ai auto-discovers the OAuth server from the `/.well-known/` URLs and opens a login page on your site, where an administrator clicks **Allow Access**. If Claude.ai asks for details manually, use the Authorization URL and Token URL shown in the **OAuth (advanced)** section of the settings page, any Client ID except the literal text "Bearer Token", and the scope `claudeai`.

= I get a 404 / rest_no_route error =

Go to **Settings → Permalinks** and click **Save Changes** to flush rewrite rules, and confirm the plugin is active.

= The Authorization header is always empty (Apache + FastCGI) =

This is handled automatically. If it persists, add this line to your `.htaccess`:
`RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]`

= How do I enable debug logging? =

Define `WP_DEBUG`, `WP_DEBUG_LOG` (true) and `WP_DEBUG_DISPLAY` (false) in `wp-config.php`, then read `wp-content/debug.log` or use the `wp_get_logs` tool.

= Is it safe? =

By default, yes — everything is read-only: credentials are redacted, database reads are structured (no raw SQL — table and column names are whitelisted against the live schema and every value is parameterized), file access is contained within `wp-content`, and OAuth uses mandatory PKCE with single-use, expiring authorization codes. Write access exists only when an administrator switches on write mode, is limited to drafts, allowlisted options, plugin toggles, caches and terms, and every write is recorded in the audit log. Deleting content, publishing, managing users and write SQL are impossible regardless of settings.

= How does write mode work? =

Enable it under **Settings → MCP Bridge → Write mode** (off by default). The static Bearer token then gains write access; OAuth sessions must additionally tick "Allow write access" on the consent screen (the `claudeai:write` scope). Six scoped tools become available; drafts can never be published, options must be on an allowlist you control (site identity, code-execution and secret options are refused even if listed), and the plugin can never toggle itself off. Each write tool can be disabled individually and every call is audited.

= How does this relate to the "AI Provider for Anthropic" plugin? =

They point in opposite directions and can coexist: that plugin lets WordPress call Claude's API; Zen MCP Bridge lets Claude.ai read this site. When AI Provider for Anthropic is active, Zen MCP Bridge automatically stops registering its tools as WordPress Abilities so the site's AI surface has a single owner — Claude.ai access via the MCP endpoint is unaffected. The `zenmcp_enable_abilities` filter overrides this.

== Screenshots ==

1. Connection settings — the MCP endpoint URL and Bearer token to paste into a Claude.ai custom connector, plus the OAuth token lifetime and the per-IP rate limit.
2. Per-tool switches and write mode — every tool can be turned off individually (write tools are badged); write mode is off by default and has its own option allowlist.
3. OAuth 2.1 (advanced) — authorization, token and discovery URLs, extra redirect URIs, and the WordPress Abilities API status card.
4. Active OAuth tokens — issued tokens with client, user, issue/expiry and last-used times, each revocable on the spot, plus the built-in health check.
5. Health check, audit log and emergency revocation — every tool call is recorded with credential, tool, arguments, IP and outcome; all OAuth tokens can be invalidated instantly.

== External services ==

This plugin is a bridge to **Claude.ai**, the AI assistant operated by **Anthropic**. That is the entire purpose of the plugin: it turns your site into an MCP (Model Context Protocol) server that Claude.ai connects to so it can read your WordPress data and help you build and debug your site.

**What the service is and what it is used for:** Claude.ai (Anthropic) is a third‑party AI assistant. You connect it to this plugin's MCP endpoint from the Claude.ai app. Claude then reads your site through the plugin's tools to answer questions, write code and debug issues tailored to your setup.

**What data is sent, and when:** No data is sent anywhere until *you*, as an administrator, connect Claude.ai to this site and authenticate (with the Bearer token or by completing the OAuth login). After that, data is transmitted to Claude.ai only in direct response to a request Claude makes, and only the data returned by the specific read tool it calls — for example site/plugin/theme information, post content, database query results (with credentials redacted), or source files under `wp-content` (with sensitive files such as `.env`, `wp-config` copies, keys and database dumps blocked). Options and query results have secret‑shaped values redacted, user passwords are never returned, and — unless you explicitly turn on the optional write mode — nothing on your site is ever modified. During the OAuth login flow the browser is also redirected to Claude.ai callback URLs (`https://claude.ai/api/mcp/auth_callback` and the `app.`/`www.` variants) carrying a short‑lived authorization code. The plugin does not send any usage analytics or telemetry, and it does not contact Anthropic on its own — Claude.ai always initiates the connection.

**Service terms and privacy policy:** Anthropic Consumer Terms of Service — https://www.anthropic.com/legal/consumer-terms ; Anthropic Privacy Policy — https://www.anthropic.com/legal/privacy ; Anthropic Usage Policy — https://www.anthropic.com/legal/aup

== Changelog ==

= 3.2.3 =
* **Fixed a database error written to the log on every site with fewer than 5,000 audit entries.** Audit-log retention pruning computed its cutoff as `MAX(id) - 5000` inside the query; because `id` is `BIGINT UNSIGNED`, that underflowed and raised "BIGINT UNSIGNED value is out of range". The cutoff is now calculated in PHP and the delete is skipped entirely until the table actually exceeds the retention limit. No audit data was ever lost — the failing statement deleted nothing.
* The Abilities API status card now reports the tools it actually registers. It previously counted the full 31-tool registry and described them all as read-only, ignoring per-tool switches and counting the six write tools even when write mode was off.

= 3.2.2 =
* **`wp_db_query` no longer accepts raw SQL.** It is now a structured, injection-proof table reader: you name a table, columns, WHERE conditions, ordering and a limit, and the plugin builds the query — table/column names are validated against the live schema and every value is bound through `$wpdb->prepare()`. Credential columns stay blocked and secret values redacted. Joins and aggregate expressions are no longer supported (use `wp_query_posts` or the dedicated inspector tools).

= 3.2.1 =
* Dynamic client registration now derives `client_id` from a dedicated plugin secret instead of the WordPress `AUTH_KEY`, keeping core authentication secrets scoped to authentication.
* The OAuth consent page loads its styles from an external stylesheet (no inline `<style>`).
* Documented the Claude.ai / Anthropic external service in the readme.
* Added `X-Content-Type-Options: nosniff` to all plugin responses (MCP endpoint, OAuth token/discovery endpoints, consent page) — hardening surfaced by an OWASP ZAP scan.

= 3.2.0 =
* **Opt-in write mode (off by default)** with six scoped write tools: `wp_create_draft_post` / `wp_update_draft_post` (status locked to draft/pending — publishing always needs a human), `wp_update_option` (admin-managed allowlist with hard denies for site identity, code-execution and secret options), `wp_toggle_plugin` (cannot touch Zen MCP Bridge itself), `wp_clear_cache` and `wp_create_term`.
* **Consent-screen write grant**: OAuth sessions receive write access only when "Allow write access" is explicitly ticked during authorization (`claudeai:write` scope); the static Bearer token has write access only while write mode is on.
* **MCP tool annotations**: all tools now declare `readOnlyHint` (and write tools `destructiveHint: false`) per the 2025-11-25 specification.
* Write tools are hidden from `tools/list` for credentials without write access, individually toggleable, registered as Abilities only in write mode, and fully audited.

= 3.1.0 =
* **Cache-safe token revocation**: "Revoke all" now bumps a token-generation counter instead of deleting options-table rows, so it works instantly under Redis/Memcached object caches too. **Existing OAuth sessions must re-authenticate once after this update.**
* **Token manager**: active OAuth tokens are listed in the admin (client, user, issued, expires, last used) with per-token revocation.
* **Secret-exfiltration hardening**: `wp_db_query` now rejects queries referencing the plugin's own credentials and redacts secret-bearing values (API keys, session tokens, consumer secrets) from results; `wp_get_options` applies the same secret-name heuristic; sensitive files (.env, wp-config copies, SQL dumps, keys/certificates) cannot be read or searched, and credential-like lines are masked in code-search results.
* **Audit log**: every tool call is recorded (credential, tool, arguments, IP, outcome) with an admin viewer, filtering and automatic retention.
* **Per-tool switches**: any of the 25 tools can be disabled entirely from the settings page — hidden from tools/list, rejected by tools/call, and excluded from Abilities.
* **Configurable rate limit** (10–1000 tool calls per minute per IP) and an in-admin **health check** that runs the same initialize/tools/discovery checks a Claude.ai connection performs.
* Developer: PHPUnit test suite with GitHub Actions CI, phpcs.xml ruleset.

= 3.0.0 =
* Renamed from "WordPress MCP Bridge" to **Zen MCP Bridge** (new slug, `zenmcp_` code prefix, text domain and REST namespace `zen-mcp/v1`). Existing installs keep their Bearer token, redirect URIs and token lifetime via a one-time migration on activation. **The MCP endpoint URL changed — reconnect Claude.ai to `…/wp-json/zen-mcp/v1/bridge`.**
* Rebuilt the admin settings page to the Zen family theme: card layout, external stylesheet/script (no inline styles or handlers), and setup/troubleshooting docs moved into a Help tab. Settings consolidated into a single option.
* Six new read-only tools: `wp_search_code`, `wp_get_post`, `wp_get_transients` (auth/secret values redacted), `wp_get_scheduled_actions`, `wp_get_woocommerce` (no customer data or credentials) and `wp_get_elementor` — 25 tools total.
* MCP `resources` (site snapshots at `wordpress://` URIs) and `prompts` (site analysis, error debugging, plugin writing) capabilities.
* WordPress Abilities API bridge (WP 6.9+): tools registered as admin-only abilities; stands down automatically when AI Provider for Anthropic is active.
* Added `uninstall.php` (removes options and transients on delete) and internationalization.

= 2.8.0 =
* Configurable OAuth token lifetime (1 hour / 24 hours / 7 days / 30 days) and an emergency "Revoke all tokens" button.
* MCP specification 2025-11-25 support: latest protocol version, `client_id_metadata_document_supported`, `scope` in `WWW-Authenticate`, and `description` in `serverInfo`.
* Hardened a SQL-injection vector in the DB-schema tool and corrected the OAuth consent nonce sanitizer (2.7.0).

= 2.6.0 =
* Fixed an OAuth consent 403 (two-nonce form) and blocked the plugin's own Bearer token from the options tool. Crash-hardened the cron tool and added transient cleanup on deactivation.

= 2.5.0 =
* Added dynamic client registration (RFC 7591), corrected the required PHP version, and closed path-containment and OAuth parameter-handling gaps.

= 2.2.0 – 2.4.0 =
* Implemented the full OAuth 2.1 PKCE authorization server with discovery endpoints, plus CORS, clickjacking, path-traversal and Apache/FastCGI fixes.

= 2.1.0 =
* Initial hardened release: GET/OPTIONS handling, CORS headers and the read-only tool suite.

== Upgrade Notice ==

= 3.2.3 =
Bugfix release: stops the audit-log pruner writing a "BIGINT UNSIGNED value is out of range" database error to the log, and corrects the tool count shown on the Abilities API card. Recommended for all users; no action needed.

= 3.2.2 =
The wp_db_query tool changed from raw SQL to a structured, injection-proof table reader (name a table + columns + filters instead of writing SQL). Joins/aggregations are no longer available; everything else is unchanged.

= 3.2.1 =
Review-compliance release: client_id derivation no longer uses a core auth key, the consent page uses an external stylesheet, and the Claude.ai/Anthropic external service is now documented. No action needed.

= 3.2.0 =
Adds opt-in write mode (off by default — nothing changes unless you enable it): draft-only post tools, allowlisted option updates, plugin toggling, cache clearing and term creation, gated behind a consent-screen write grant and fully audited.

= 3.1.0 =
Security hardening: cache-safe revocation, token manager, audit log, per-tool switches, secret redaction. Existing OAuth sessions must re-authenticate once after updating; Bearer Token connections are unaffected.

= 3.0.0 =
Renamed to Zen MCP Bridge. The MCP endpoint URL changed to `…/wp-json/zen-mcp/v1/bridge` — update your Claude.ai connector and re-authenticate after upgrading. Your Bearer token and settings are migrated automatically.
