Skip to content

Releases: wisnuub/claude-connector

v1.6.0 — Divi 5 hardening: fix kses data loss, add verification tooling

Choose a tag to compare

@wisnuub wisnuub released this 15 Sep 00:47

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 &lt;!-- wp:divi/section --&gt; — 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\u003e while hand-written block JSON leaves the brackets literal. Both forms coexist on one site, so a plain-HTML REPLACE() 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. Optional expect assertions 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 editing post_content with raw SQL.
  • POST /divi/meta/{id} — repair builder postmeta without touching content.
  • POST /files/fetch — download a URL straight into wp-content server-side, so generated content no longer has to be transmitted through the model's context. Returns a sha256 so the transfer can be verified without a read-back.
  • POST /db/query improvementsparams for $wpdb->prepare() bound placeholders; matched_rows alongside changed_rows, because MySQL reports changed not matched and a REPLACE() that found nothing was indistinguishable from success; dry_run to rehearse inside a transaction and roll back; and an explicit warning when rows matched but none changed.
  • POST /cache/purge is builder-awarebuilder: true also clears Divi's et-cache directory and _divi_dynamic_assets_cached_* postmeta plus Elementor's generated CSS, none of which a raw SQL write invalidates. resave_builder_posts: true forces clean regeneration.
  • GET /status reports acting_as (user, login, whether it holds unfiltered_html) and a builder block, 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 args over command for wp_wpcli and list the blocked subcommands.
  • New docs: DIVI5.md build workflow, and a filled-in Divi section in KNOWLEDGE.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

Choose a tag to compare

@wisnuub wisnuub released this 10 Aug 15:34

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": true to block non-SELECT queries; destructive queries (DROP/TRUNCATE/DELETE without WHERE) require "confirm_destructive": true
  • WP-CLI expanded blocklist: eval, eval-file, package, db import, core download/update are 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

Choose a tag to compare

@wisnuub wisnuub released this 12 Jul 16:45

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).zip or GitHub's -main suffix no longer cause a second copy of the plugin to appear instead of replacing the existing one
  • Mac setup script now uses .terminal format -- 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

Choose a tag to compare

@wisnuub wisnuub released this 12 Jul 16:39

What's new

  • Mac setup script now downloads as a .terminal file 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

Choose a tag to compare

@wisnuub wisnuub released this 06 Jul 16:39

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

Choose a tag to compare

@wisnuub wisnuub released this 03 May 14:32

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 /logs and POST /logs/clear endpoints
  • Settings page shows Last Access row (always visible, like cPanel's last login)
  • Logging toggle in WP Admin → Settings → Claude Connector

v1.0.1

Choose a tag to compare

@wisnuub wisnuub released this 03 May 14:03

Install

WP Admin → Plugins → Add New → Upload Plugin → claude-connector.zip

Requirements

  • PHP 7.4+
  • WordPress 5.8+

See the README for full API reference and usage.