Releases: wisnuub/claude-connector
Release list
v1.6.0 — Divi 5 hardening: fix kses data loss, add verification tooling
Fixes a silent data-loss bug affecting all builder content, and adds the tooling needed to verify a write actually did what you asked.
Found while building a 44-page Divi 5 site end to end through the connector.
Fixed
Builder content is no longer destroyed on write. None of the three transports called wp_set_current_user(), so every request ran as user 0. WordPress attaches the kses filters whenever the current user lacks unfiltered_html, so wp_insert_post() / wp_update_post() HTML-escaped block delimiters — <!-- wp:divi/section --> became <!-- wp:divi/section --> — which made the layout unparseable while still returning HTTP 200. No warning, and the damage only visible on the rendered page.
The connector now assumes a real user at claude_auth(), the single choke point all three transports relay through. Configurable under Settings → Claude Connector → Act as user, which warns if the chosen account lacks the capability. On multisite the kses filters are dropped explicitly, since ordinary administrators there do not hold unfiltered_html. This also fixes post_author defaulting to 0 on created posts.
Every content write is now re-read afterwards and fails loudly if the delimiters were escaped, so this cannot regress silently again.
POST /divi/data/{id} applies the full Divi 5 postmeta set. It set only _et_pb_use_builder, which is enough for Divi 4 but leaves a Divi 5 page rendering on the theme's default template with a widget sidebar and a duplicated title. posts_create / posts_update now infer the same on detecting <!-- wp:divi/ in the content.
GET / POST /options accept dotted paths such as et_divi.divi_integration_head, so one value inside a serialised theme options array can be read or patched without pulling and rewriting the whole blob. The protected-options blocklist is enforced on the root key.
One-click setup was broken. The Mac and Windows scripts fetched index.js but not knowledge.js, which it imports, so a fresh install crashed on startup. They also skipped the download when node_modules already existed, so existing installs never picked up newer tools. Both now refresh on every run.
Added
POST /content/replace— find and replace using plain HTML, without needing to know how the builder escaped it. Block attributes are JSON inside an HTML comment, and the escaping differs by author: the Divi 5 visual builder writes\u003ch1\u003ewhile hand-written block JSON leaves the brackets literal. Both forms coexist on one site, so a plain-HTMLREPLACE()matches neither — and since MySQL reports changed rather than matched rows, a SQL replace that found nothing looks identical to one that worked. This tries every known encoding, reports which matched, writes using it, revalidates the blocks and flushes Divi's CSS cache.GET /render— fetch a page server-side as an anonymous visitor and return a structural health summary: title, meta description, h1 count, heading outline, section count, images missing alt, empty paragraphs, escaped-delimiter detection, sidebar presence. Optionalexpectassertions make verification a single call.GET /blocks/validate/{id}— detects escaped delimiters, unbalanced block comments and invalid attribute JSON. Divi 5 stores module attributes as JSON in HTML comments, so one unbalanced brace corrupts a page with no parse error.GET /divi/audit— finds builder pages missing critical postmeta, and pages where Divi's generated per-module CSS indices are disjoint from the rendered markup. That second one is the signature of a bug where installing any plugin invalidates Divi's caches and the regeneration offsets every index, silently killing all attribute styling sitewide with nothing wrong in the database.POST /divi/resave— the remedy for the above, and the required follow-up after editingpost_contentwith raw SQL.POST /divi/meta/{id}— repair builder postmeta without touching content.POST /files/fetch— download a URL straight intowp-contentserver-side, so generated content no longer has to be transmitted through the model's context. Returns asha256so the transfer can be verified without a read-back.POST /db/queryimprovements —paramsfor$wpdb->prepare()bound placeholders;matched_rowsalongsidechanged_rows, because MySQL reports changed not matched and aREPLACE()that found nothing was indistinguishable from success;dry_runto rehearse inside a transaction and roll back; and an explicit warning when rows matched but none changed.POST /cache/purgeis builder-aware —builder: truealso clears Divi'set-cachedirectory and_divi_dynamic_assets_cached_*postmeta plus Elementor's generated CSS, none of which a raw SQL write invalidates.resave_builder_posts: trueforces clean regeneration.GET /statusreportsacting_as(user, login, whether it holdsunfiltered_html) and abuilderblock, so misconfiguration is visible before it corrupts anything.- MCP server version handshake against the plugin, warning on mismatch at startup and in
wp_status. - Tool descriptions now document
argsovercommandforwp_wpcliand list the blocked subcommands. - New docs:
DIVI5.mdbuild workflow, and a filled-in Divi section inKNOWLEDGE.md.
Verified
Against WordPress 7.1 / PHP 8.3 / Divi 5.12.1 on a live site: block delimiters survive a REST write, post_author is correct, the validator catches malformed JSON and unclosed blocks with no false positives on valid content, /divi/audit reports healthy across 45 builder pages, /files/fetch returns a sha256 matching an independent hash of the source, and /content/replace matched visual-builder content and hand-written content in their respective encodings.
Upgrading
Auto-update from WP Admin → Plugins, or download claude-connector.zip below. Also re-run the one-click setup script (Settings → Claude Connector) to refresh the MCP server — the plugin and the MCP server ship together, and a stale index.js will not expose the new tools.
v1.5.0 — Security hardening, ACF field CRUD, encrypted WAF bypass, PHP lint
What's new in v1.5.0
🔐 Encrypted transport mode (biggest WAF bypass yet)
New WP_MODE=enc uses AES-256-GCM to encrypt every command before sending it. The firewall only sees opaque base64 — no PHP code, no SQL, no JSON structure to trigger ModSecurity or Imunify360 body-inspection rules. No Cloudflare account or external server needed.
To use it, set WP_MODE=enc in your .mcp.json env block. The key is derived automatically from your existing API key.
🛡️ PHP lint before file write
Writing a .php file with a syntax error now returns a 422 with the exact error and line number before touching the file. No more accidental white screens on child theme edits.
💾 Auto-backup before overwrite
Every file write now saves a timestamped .bak copy (e.g. functions.php.20260809143022.bak) before overwriting. The response includes the backup path.
🔒 Security hardening
- Rate limiting on auth failures: 10 attempts per IP per 5 minutes →
429 Too Many Requests - DB query guard: pass
"readonly": trueto block non-SELECT queries; destructive queries (DROP/TRUNCATE/DELETEwithoutWHERE) require"confirm_destructive": true - WP-CLI expanded blocklist:
eval,eval-file,package,db import,core download/updateare now blocked
🆕 ACF/SCF field value CRUD
Works with ACF Free, ACF Pro, and Secure Custom Fields (SCF):
| Endpoint | Description |
|---|---|
GET /acf/groups/{key}/export |
Export a field group + all fields as JSON |
GET /acf/fields/{post_id} |
Read all field values for a post |
POST /acf/fields/{post_id} |
Write field values for a post (supports repeaters, flex content) |
GET /acf/options |
Read ACF options-page field values |
POST /acf/options |
Write ACF options-page field values |
New MCP tools: wp_acf_group_export, wp_acf_fields_get, wp_acf_fields_set, wp_acf_options_get, wp_acf_options_set
Other
str_ends_with()polyfill added for PHP 7.4 compatibility- MCP server version bumped to 1.5.0
v1.4.2
What's new
- Fixed plugin update folder naming so updates work correctly regardless of how the zip was downloaded -- browser duplicates like
claude-connector (1).zipor GitHub's-mainsuffix no longer cause a second copy of the plugin to appear instead of replacing the existing one - Mac setup script now uses
.terminalformat -- no more permissions error on double-click - Security hardening from v1.4.1
How to update
Download claude-connector.zip below and install via WP Admin > Plugins > Add New > Upload Plugin.
Sites already running v1.4.1 will see this update appear automatically in WP Admin > Dashboard > Updates.
v1.4.1
What's new
- Mac setup script now downloads as a
.terminalfile instead of.command-- fixes the "you do not have appropriate access privileges" error on macOS when double-clicking the downloaded file - Security hardening: API key accepted via header only, protected options blocked from reads
How to update
Download claude-connector.zip and install via WP Admin > Plugins > Add New > Upload Plugin.
v1.4.0
What's new
- GitHub-based auto-updates - no wordpress.org listing needed. WP Admin -> Plugins now checks GitHub Releases directly and supports one-click Update Now.
- Admin-AJAX connection mode - bypasses Cloudflare/WAF blocking of direct REST API calls by routing through wp-admin/admin-ajax.php.
- WP-CLI support and MCP server - local Node.js bridge exposes the plugin's endpoints as MCP tools for Claude Code, with per-site workspace folders.
- One-click setup scripts - Settings page offers a Mac (.command) and Windows (.ps1) download that installs the MCP bridge, writes .mcp.json + CLAUDE.md, and opens the workspace in VSCode automatically. The download button shown is detected from the visitor's browser.
- Windows script fixes: emits a UTF-8 BOM (without it, Windows PowerShell 5.1 fails to parse the script and the window silently closes), retries GitHub downloads on rate-limiting, checks for a complete install instead of just index.js, and self-elevates to Administrator via UAC.
- Removed the Cloudflare Worker relay system in favor of the simpler admin-ajax bridge.
v1.1.0
What's new
WAF-bypass file writes
Sites behind Cloudflare (or similar WAFs) often block POST requests containing raw PHP code. v1.1.0 adds two ways around this without needing SFTP or cPanel:
Base64 content:
```json
POST /files
{ "path": "themes/my-theme/file.php", "content_b64": "" }
```
Chunked staging (for large files or strict WAFs):
```json
POST /files/stage { "path": "...", "content_b64": "...", "chunk_index": 0, "chunk_total": 1 }
POST /files/commit { "path": "...", "chunk_total": 1 }
```
Access log
- Every API request recorded: IP, method, endpoint, status, timestamp
GET /logsandPOST /logs/clearendpoints- Settings page shows Last Access row (always visible, like cPanel's last login)
- Logging toggle in WP Admin → Settings → Claude Connector