{"id":294616,"date":"2026-04-24T17:15:08","date_gmt":"2026-04-24T17:15:08","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/iato-mcp\/"},"modified":"2026-05-06T01:14:50","modified_gmt":"2026-05-06T01:14:50","slug":"iato-mcp","status":"publish","type":"plugin","link":"https:\/\/pan.wordpress.org\/plugins\/iato-mcp\/","author":23472460,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","version":"1.4.10","stable_tag":"1.4.10","tested":"6.9.4","requires":"6.2","requires_php":"8.0","requires_plugins":null,"header_name":"IATO MCP","header_author":"IATO","header_description":"Exposes an MCP server from any self-hosted WordPress install, enabling IATO analyze-and-fix workflows via Claude Desktop and other AI clients.","assets_banners_color":"809d9a","last_updated":"2026-05-06 01:14:50","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/iato.ai\/wordpress-mcp","header_author_uri":"https:\/\/iato.ai","rating":0,"author_block_rating":0,"active_installs":0,"downloads":487,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.1.10":{"tag":"1.1.10","author":"iatoai","date":"2026-04-24 17:15:11"},"1.1.11":{"tag":"1.1.11","author":"iatoai","date":"2026-04-24 18:15:19"},"1.1.12":{"tag":"1.1.12","author":"iatoai","date":"2026-04-24 18:28:25"},"1.2.0":{"tag":"1.2.0","author":"iatoai","date":"2026-04-28 01:12:00"},"1.2.1":{"tag":"1.2.1","author":"iatoai","date":"2026-04-28 01:32:21"},"1.2.2":{"tag":"1.2.2","author":"iatoai","date":"2026-04-28 12:25:07"},"1.2.3":{"tag":"1.2.3","author":"iatoai","date":"2026-04-28 12:50:20"},"1.2.4":{"tag":"1.2.4","author":"iatoai","date":"2026-04-28 14:04:56"},"1.3.0":{"tag":"1.3.0","author":"iatoai","date":"2026-04-28 17:29:19"},"1.3.1":{"tag":"1.3.1","author":"iatoai","date":"2026-04-28 18:00:40"},"1.3.2":{"tag":"1.3.2","author":"iatoai","date":"2026-04-28 18:15:13"},"1.3.3":{"tag":"1.3.3","author":"iatoai","date":"2026-04-28 18:32:19"},"1.3.4":{"tag":"1.3.4","author":"iatoai","date":"2026-04-28 18:50:53"},"1.3.5":{"tag":"1.3.5","author":"iatoai","date":"2026-04-28 19:11:26"},"1.4.0":{"tag":"1.4.0","author":"iatoai","date":"2026-05-01 14:03:55"},"1.4.1":{"tag":"1.4.1","author":"iatoai","date":"2026-05-01 17:32:13"},"1.4.10":{"tag":"1.4.10","author":"iatoai","date":"2026-05-06 01:14:50"},"1.4.2":{"tag":"1.4.2","author":"iatoai","date":"2026-05-01 18:02:17"},"1.4.3":{"tag":"1.4.3","author":"iatoai","date":"2026-05-01 18:22:52"},"1.4.4":{"tag":"1.4.4","author":"iatoai","date":"2026-05-02 16:21:10"},"1.4.5":{"tag":"1.4.5","author":"iatoai","date":"2026-05-04 14:15:14"},"1.4.6":{"tag":"1.4.6","author":"iatoai","date":"2026-05-04 14:30:17"},"1.4.7":{"tag":"1.4.7","author":"iatoai","date":"2026-05-04 14:50:48"},"1.4.8":{"tag":"1.4.8","author":"iatoai","date":"2026-05-05 17:42:52"},"1.4.9":{"tag":"1.4.9","author":"iatoai","date":"2026-05-05 18:22:14"}},"upgrade_notice":{"1.4.10":"<p>The JSON config snippets the plugin emits now use a unique-per-site inner <code>mcpServers<\/code> key derived from the site&#039;s hostname (e.g. <code>iato-garennebigby-dev<\/code>) instead of the hardcoded <code>iato-wordpress<\/code>. Lets agencies paste config snippets from many WordPress installs into a single Claude Desktop config without silent overwrites. Existing connections keep working unchanged.<\/p>","1.4.9":"<p>Docs-only release: adds the plugin demo video to the WordPress.org plugin page Description. No code changes. Safe to skip if you&#039;ve already updated to 1.4.8.<\/p>","1.4.8":"<p>Adds page-builder-aware safety rails to the MCP <code>initialize<\/code> response: a dynamic instructions string telling the AI agent which write tools to use for which builder, with a mandatory check-first rule before any content edit. Closes a silent-failure class where <code>update_post<\/code> on Elementor-built posts succeeded in the database but never reached the frontend. Also adds Beaver Builder per-post detection.<\/p>","1.4.7":"<p>Fixes a misleading UX in Settings where IATO Platform and Crawl Management tool toggles appeared enabled even when no IATO API key was configured \u2014 making the checkboxes placebo. Toggles are now visually disabled with an inline hint until an API key is set. No backend or auth changes.<\/p>","1.4.6":"<p>Completes the rollback Settings UI fix from 1.4.5 by adding rollback to the second gating constant (<code>TOOL_CATEGORIES<\/code>) the rendering loop actually iterates \u2014 so the checkbox now actually appears under a new &quot;Safety&quot; category. Also unifies the inner server key in the Settings page config snippet from <code>wordpress<\/code> to <code>iato-wordpress<\/code> to match the dismissible notice.<\/p>","1.4.5":"<p>Fixes the rollback MCP tool being invisible on the Settings page and silently stripped from <code>iato_mcp_tools<\/code> on every Settings save (a bug present since v1.4.0 introduced rollback). One-shot migration auto-restores rollback for affected installs on upgrade. Also makes the <code>initialize<\/code> capability advertisement honest about whether rollback is actually registered.<\/p>","1.4.4":"<p>Fixes the OAuth flow: clicking Approve on the consent screen now correctly redirects back to the OAuth client (Claude, Cursor, etc.) with an authorization code instead of dumping users on \/wp-admin. The connector framework on the client side then transitions to &quot;Connected&quot; as expected. Required for anyone trying to connect via Claude.ai&#039;s Add Connector or Claude Desktop&#039;s Connectors UI.<\/p>","1.4.3":"<p>Restructures the dismissible &quot;Ready to Connect&quot; admin notice so its two connection methods (Connectors UI \/ Claude Desktop config file) are presented as mutually-exclusive options instead of a confusing three-step sequence. No code-path or auth-handler changes \u2014 purely a clarity fix in the onboarding notice.<\/p>","1.4.2":"<p>Makes the Application Password auth path documented in the v1.4.1 setup wizard actually work (the auth handler was hard-rejecting non-Bearer requests, so wizard Methods 2 and 3 were returning 401). Also fixes the dismissible setup notice to emit a Claude-Desktop-compatible stdio-bridge config, and relabels the Settings page hero-card so its audience (HTTP MCP clients) is unambiguous. Recommended upgrade for anyone on 1.4.1.<\/p>","1.4.1":"<p>Setup wizard restructured around the three real connection paths (Connectors UI \/ Direct HTTP \/ stdio bridge), and the stdio JSON snippet now references the actual <code>mcp-remote<\/code> npm package with an env-var credential pattern. Recommended for any new install; existing connections are unaffected.<\/p>","1.4.0":"<p>Adds a <code>rollback<\/code> MCP tool and change-receipt coverage for <code>update_post<\/code> \/ <code>create_post<\/code>, closing the gap that previously left the two highest-volume write tools without an audit trail. Claude can now undo any tracked change in a single tool call.<\/p>","1.3.5":"<p>Docs-only release: corrects a stale FAQ tool count and adds widget-flavored example prompts. No code changes; safe to skip if you&#039;ve already updated to 1.3.4.<\/p>","1.3.4":"<p>Drops <code>change_receipt<\/code> from <code>update_elementor_widgets_bulk<\/code> per-result rows (still persisted to the audit table; bulk callers query by post_id). Lands the 4-page H1-flip benchmark under the spec&#039;s<\/p>","1.3.3":"<p>Slims v2 write responses by ~93 bytes per result by eliding the previous_revision echo when the caller didn&#039;t pass if_revision. Lands the canonical 4-page bulk benchmark under the spec&#039;s<\/p>","1.3.2":"<p>Slims v2 write-tool responses by ~600 bytes per update by removing redundant change_receipt fields. Brings 4-page bulk sweeps under the 2 KB spec target. No API breakage \u2014 the slim receipt still carries the change_id for downstream lookup.<\/p>","1.3.1":"<p>Fixes the Elementor v2 bulk + find tools rejecting every request with auth_denied (capability-check mismatch with the bearer auth model). Adds an idempotent migration so existing installs see the new v2 tools enabled automatically on upgrade. Required for anyone on 1.3.0.<\/p>","1.3.0":"<p>Adds widget-grained Elementor tools (v2 surface) \u2014 patch a single widget without re-uploading the whole document, with optimistic concurrency and idempotency. Existing v1 tools are unchanged. Recommended upgrade for anyone editing Elementor pages from Claude.<\/p>","1.2.4":"<p>Fixes <code>list_iato_crawls<\/code> returning the wrong identifier (numeric DB id instead of the UUID), which broke the chain into the other bridge tools. Adds dual-key envelope resilience for the same endpoint. Recommended upgrade for anyone on 1.2.0\u20131.2.3.<\/p>","1.2.3":"<p>Sends workspace_id as a JSON integer so the platform&#039;s Pydantic binding accepts it. Required to make the crawl-control tools fully functional; recommended upgrade for anyone on 1.2.0\u20131.2.2.<\/p>","1.2.2":"<p>Completes the workspace_id scoping fix from 1.2.1. After upgrading, click Test connection in Settings &gt; IATO MCP once to populate the workspace_id, then crawl management will work end-to-end.<\/p>","1.2.1":"<p>Fixes workspace_id scoping for the new crawl-management tools and a PHP 8.2-only return type that broke installs on PHP 8.0\/8.1. Recommended upgrade for anyone on 1.2.0.<\/p>","1.2.0":"<p>Adds three crawl-control MCP tools so Claude can start, check, and list IATO crawls without leaving the conversation. Admin only for <code>start_iato_crawl<\/code>.<\/p>","1.1.12":"<p>Adds Plugin URI and contextual links to iato.ai throughout the listing. No code changes.<\/p>","1.1.11":"<p>Readme accuracy pass. No code changes.<\/p>","1.1.10":"<p>First stable release to the WordPress.org directory.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3514829,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3514829,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3514829,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":400},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3514829,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.1.10","1.1.11","1.1.12","1.2.0","1.2.1","1.2.2","1.2.3","1.2.4","1.3.0","1.3.1","1.3.2","1.3.3","1.3.4","1.3.5","1.4.0","1.4.1","1.4.10","1.4.2","1.4.3","1.4.4","1.4.5","1.4.6","1.4.7","1.4.8","1.4.9"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3514833,"resolution":"1","location":"assets","locale":"","width":1544,"height":898},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3514833,"resolution":"2","location":"assets","locale":"","width":1544,"height":382},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3514833,"resolution":"3","location":"assets","locale":"","width":1544,"height":1357},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3514833,"resolution":"4","location":"assets","locale":"","width":1544,"height":1109}},"screenshots":{"1":"Settings page \u2014 MCP connection info with endpoint URL and API key","2":"Settings page \u2014 IATO Platform configuration and tool toggles","3":"Setup wizard \u2014 auto-generated Claude Desktop configuration","4":"OAuth authorization screen \u2014 approve AI client connections"},"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[2353,229563,242115,186,1557],"plugin_category":[55],"plugin_contributors":[261008],"plugin_business_model":[],"class_list":["post-294616","plugin","type-plugin","status-publish","hentry","plugin_tags-ai","plugin_tags-claude","plugin_tags-mcp","plugin_tags-seo","plugin_tags-sitemap","plugin_category-seo-and-marketing","plugin_contributors-iatoai","plugin_committers-iatoai"],"banners":{"banner":"https:\/\/ps.w.org\/iato-mcp\/assets\/banner-772x250.png?rev=3514829","banner_2x":"https:\/\/ps.w.org\/iato-mcp\/assets\/banner-1544x500.png?rev=3514829","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/iato-mcp\/assets\/icon-128x128.png?rev=3514829","icon_2x":"https:\/\/ps.w.org\/iato-mcp\/assets\/icon-256x256.png?rev=3514829","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/iato-mcp\/assets\/screenshot-1.png?rev=3514833","caption":"Settings page \u2014 MCP connection info with endpoint URL and API key"},{"src":"https:\/\/ps.w.org\/iato-mcp\/assets\/screenshot-2.png?rev=3514833","caption":"Settings page \u2014 IATO Platform configuration and tool toggles"},{"src":"https:\/\/ps.w.org\/iato-mcp\/assets\/screenshot-3.png?rev=3514833","caption":"Setup wizard \u2014 auto-generated Claude Desktop configuration"},{"src":"https:\/\/ps.w.org\/iato-mcp\/assets\/screenshot-4.png?rev=3514833","caption":"OAuth authorization screen \u2014 approve AI client connections"}],"raw_content":"<!--section=description-->\n<p>WordPress.com has a built-in MCP server. Now self-hosted WordPress does too.<\/p>\n\n<p><a href=\"https:\/\/iato.ai\/wordpress-mcp\">IATO MCP<\/a> connects your WordPress site to Claude Desktop and other MCP-enabled AI clients. Once connected, you can ask Claude to audit your site and fix SEO issues, identify orphan pages, clean up broken links, and more \u2014 all in a single conversation.<\/p>\n\n<p>https:\/\/www.youtube.com\/watch?v=gSX6Vc9Yask<\/p>\n\n<h4>How it works<\/h4>\n\n<ol>\n<li>Install and activate the plugin<\/li>\n<li>Follow the setup wizard \u2014 copy the config into Claude Desktop, or use \"Add Custom Connector\" with your site URL<\/li>\n<li>Connect your <a href=\"https:\/\/iato.ai\">IATO account<\/a> for AI-powered analysis (<a href=\"https:\/\/iato.ai\">free trial<\/a> up to 500 pages)<\/li>\n<\/ol>\n\n<h4>What Claude can do<\/h4>\n\n<p><strong>Without an IATO account (40 WordPress tools):<\/strong><\/p>\n\n<ul>\n<li>Read and edit posts, pages, and media<\/li>\n<li>Create new posts and pages with excerpt support<\/li>\n<li>Update SEO titles and meta descriptions (Yoast SEO, RankMath, SEOPress)<\/li>\n<li>Update canonical URLs<\/li>\n<li>Update image alt text<\/li>\n<li>Read and edit navigation menus<\/li>\n<li>Manage categories, tags, and taxonomy terms<\/li>\n<li>Manage JSON-LD structured data<\/li>\n<li>Manage redirect rules<\/li>\n<li>Read and write Elementor page builder data<\/li>\n<li>Widget-grained Elementor edits with optimistic concurrency, idempotency, and bulk operations<\/li>\n<li>Resolve URLs to their rendering post (Theme Builder shadowing detection)<\/li>\n<li>Search content across the site<\/li>\n<li>Read site info and settings<\/li>\n<li>Read and filter comments<\/li>\n<li>One-call rollback for any tracked write \u2014 every change emits a receipt with a stable <code>change_id<\/code>; pass it back to the <code>rollback<\/code> tool and the original value is restored<\/li>\n<\/ul>\n\n<p><strong>With an <a href=\"https:\/\/iato.ai\">IATO account<\/a> (12 bridge tools \u2014 full analyze-and-fix pipeline):<\/strong><\/p>\n\n<ul>\n<li>Start a new crawl of your site directly from Claude (admin only)<\/li>\n<li>Check crawl status and list recent crawl jobs<\/li>\n<li>Run a full SEO audit and fix title, meta description, and alt text issues automatically<\/li>\n<li>Identify orphan pages not linked from any navigation menu<\/li>\n<li>Audit navigation menus for gaps and missing sections<\/li>\n<li>Surface thin content with specific improvement recommendations<\/li>\n<li>Map broken links to source posts for direct editing<\/li>\n<li>Analyze site taxonomy and suggest consolidations<\/li>\n<li>Get AI-prioritized suggestions across all areas<\/li>\n<li>Flag slow pages with contributing performance factors<\/li>\n<\/ul>\n\n<h4>Supported SEO plugins<\/h4>\n\n<ul>\n<li>Yoast SEO<\/li>\n<li>RankMath<\/li>\n<li>SEOPress<\/li>\n<li>Falls back to native WordPress title if none detected<\/li>\n<\/ul>\n\n<h4>Example prompts<\/h4>\n\n<blockquote>\n  <p>\"Crawl my site and fix all missing meta descriptions\"<\/p>\n  \n  <p>\"Show me pages that aren't in any navigation menu and add them to the right place\"<\/p>\n  \n  <p>\"What are the most impactful improvements I can make to my site right now?\"<\/p>\n  \n  <p>\"Find all broken links and tell me which posts contain them\"<\/p>\n  \n  <p>\"Audit my categories and tags and suggest consolidations\"<\/p>\n  \n  <p>\"Set every H2 heading in these Elementor posts to H1\"<\/p>\n  \n  <p>\"Find all button widgets on the site and change their color to #ff0000\"<\/p>\n<\/blockquote>\n\n<h4>External Services<\/h4>\n\n<p>This plugin connects to the following external service when configured:<\/p>\n\n<p><strong>IATO API<\/strong> (<a href=\"https:\/\/iato.ai\">https:\/\/iato.ai<\/a>) \u2014 When you enter an IATO API key in the plugin settings, the plugin sends requests to <code>https:\/\/iato.ai\/api<\/code> to retrieve crawl data, SEO audit results, sitemap information, and AI-generated improvement suggestions. No data is sent to IATO until you configure an API key. Your public page URLs (as crawled by IATO) and crawl analysis results are transmitted.<\/p>\n\n<ul>\n<li><a href=\"https:\/\/iato.ai\/terms\">IATO Terms of Service<\/a><\/li>\n<li><a href=\"https:\/\/iato.ai\/privacy\">IATO Privacy Policy<\/a><\/li>\n<\/ul>\n\n<p>The plugin also implements an OAuth 2.0 authorization server on your WordPress site so that MCP clients like Claude Desktop can authenticate via the standard \"Add Custom Connector\" flow. This communication stays between the MCP client and your WordPress site \u2014 no data is sent to third parties during authentication.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin files to <code>\/wp-content\/plugins\/iato-mcp\/<\/code> or install via the WordPress plugin directory<\/li>\n<li>Activate the plugin via the Plugins menu in WordPress<\/li>\n<li>Follow the setup wizard that appears \u2014 it provides the JSON config for Claude Desktop<\/li>\n<li>In Claude Desktop, either paste the JSON config or use \"Add Custom Connector\" and enter your site URL<\/li>\n<li>Optionally, go to Settings &gt; IATO MCP to enter your IATO API key for the full analysis pipeline<\/li>\n<\/ol>\n\n<p>For detailed setup instructions, see the <a href=\"https:\/\/iato.ai\/wordpress-mcp-docs\">IATO MCP documentation<\/a>.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20i%20need%20an%20iato%20account%3F\"><h3>Do I need an IATO account?<\/h3><\/dt>\n<dd><p>No. The plugin works standalone for reading and editing WordPress content with 40 built-in tools. An <a href=\"https:\/\/iato.ai\">IATO account<\/a> (<a href=\"https:\/\/iato.ai\">free trial<\/a> up to 500 pages) unlocks 12 additional bridge tools: start\/list\/status crawl management, SEO audit, broken links, content gaps, orphan pages, navigation audit, taxonomy analysis, AI suggestions, and performance reports.<\/p><\/dd>\n<dt id=\"which%20wordpress%20version%20is%20required%3F\"><h3>Which WordPress version is required?<\/h3><\/dt>\n<dd><p>WordPress 6.2 or higher with PHP 8.0+. The plugin uses the WordPress REST API and implements OAuth 2.0 for secure authentication with AI clients.<\/p><\/dd>\n<dt id=\"does%20this%20work%20on%20shared%20hosting%3F\"><h3>Does this work on shared hosting?<\/h3><\/dt>\n<dd><p>Yes. The plugin uses standard HTTP requests (one per MCP call) rather than long-lived connections, so it works on all hosting environments including shared hosting.<\/p><\/dd>\n<dt id=\"which%20ai%20clients%20are%20supported%3F\"><h3>Which AI clients are supported?<\/h3><\/dt>\n<dd><p>Any MCP-enabled client: Claude Desktop, Cursor, VS Code with GitHub Copilot, and any client that supports the Streamable HTTP MCP transport.<\/p><\/dd>\n<dt id=\"how%20does%20authentication%20work%3F\"><h3>How does authentication work?<\/h3><\/dt>\n<dd><p>The plugin generates a secure API key on activation. You can authenticate in two ways: paste the provided Bearer token config into your AI client, or use Claude Desktop's \"Add Custom Connector\" flow which handles OAuth 2.0 with PKCE automatically.<\/p><\/dd>\n<dt id=\"why%20does%20the%20plugin%20support%20two%20auth%20methods%3F\"><h3>Why does the plugin support two auth methods?<\/h3><\/dt>\n<dd><p>AI clients like Claude Desktop authenticate via a WordPress Application Password (or the OAuth 2.0 \/ PKCE flow), which is the WordPress-native pattern most users will use. The plugin also accepts the plugin-generated Bearer token at the same MCP endpoint \u2014 that path is used by the IATO platform's own integrations (for example, the dashboard's \"Sync pages, posts, menus, and taxonomy from WordPress\" feature, which composes the plugin's read tools to pull content into IATO). Both methods land at <code>\/wp-json\/iato-mcp\/v1\/message<\/code> and are validated by <code>class-auth.php<\/code>. You don't have to choose \u2014 paste your Bearer token into the IATO platform connection, generate an Application Password for Claude Desktop, and the same plugin handles both.<\/p><\/dd>\n<dt id=\"is%20my%20content%20sent%20to%20iato%20or%20anthropic%3F\"><h3>Is my content sent to IATO or Anthropic?<\/h3><\/dt>\n<dd><p>WordPress content (post titles, meta descriptions, etc.) is never sent to IATO. IATO crawls your public URLs the same way a search engine would. Claude processes content within your AI client session only. The IATO API is only called when you use bridge tools, and only crawl analysis data (not your content) is transmitted.<\/p><\/dd>\n<dt id=\"can%20i%20control%20which%20tools%20are%20available%3F\"><h3>Can I control which tools are available?<\/h3><\/dt>\n<dd><p>Yes. Go to Settings &gt; IATO MCP to enable or disable individual tools. You can turn off any tool you don't want AI clients to access.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.4.10<\/h4>\n\n<ul>\n<li>Fix: the JSON config snippets emitted by the plugin (setup wizard Method 3, dismissible \"Ready to Connect\" notice, Settings hero card) now use a unique-per-site inner <code>mcpServers<\/code> key derived from the WordPress site's hostname (e.g. <code>iato-garennebigby-dev<\/code>, <code>iato-dynomapper-com<\/code>) instead of the hardcoded <code>iato-wordpress<\/code>. Agencies managing multiple WordPress installs from a single AI client (Claude Desktop, Claude Code, etc.) can now paste config snippets from many IATO MCP installs into the same client config file without one silently overwriting another (JSON object keys are unique, so two snippets sharing a key was a silent collision). Existing connections that were set up with the old <code>iato-wordpress<\/code> key continue to work \u2014 the inner key is a display name only, not part of any HTTP request \u2014 so no migration is needed.<\/li>\n<\/ul>\n\n<h4>1.4.9<\/h4>\n\n<ul>\n<li>Docs: added the plugin demo video to the top of the Description section on the WordPress.org plugin page (auto-embedded by WordPress.org's readme renderer when a YouTube URL is on its own line). No code changes; safe to skip if you've already updated to 1.4.8.<\/li>\n<\/ul>\n\n<h4>1.4.8<\/h4>\n\n<ul>\n<li>New: dynamic page-builder-aware server instructions injected into the MCP <code>initialize<\/code> response. The plugin now detects which page-builder plugins are active on the WordPress site (Elementor, Divi, WPBakery, Beaver Builder, Gutenberg) and emits a context-specific instruction string telling the AI agent which write tools are correct for which builder, with a mandatory <code>get_page_builder<\/code> check-first rule before any content edit. Closes a class of silent-failure bug where <code>update_post<\/code> on an Elementor-built post would succeed at the database level but never reach the frontend (because Elementor stores content in <code>_elementor_data<\/code>, not <code>post_content<\/code>). Detected-but-unsupported builders (Divi, WPBakery, Beaver Builder for writes) are explicitly flagged so the agent tells the user to edit in the WP admin instead of attempting a write that won't take effect. Uses the standard MCP <code>instructions<\/code> field added in spec rev 2025-03-26; older clients on 2024-11-05 cleanly ignore the unknown field.<\/li>\n<li>New: <code>get_page_builder<\/code> now detects Beaver Builder posts (via <code>_fl_builder_enabled<\/code> post meta) and returns <code>beaver-builder<\/code>. Previously these posts fell through to the <code>gutenberg<\/code> or <code>classic<\/code> branch, misleading the agent about how to handle them.<\/li>\n<\/ul>\n\n<h4>1.4.7<\/h4>\n\n<ul>\n<li>Fix: Settings \u2192 IATO MCP no longer presents the IATO Platform and Crawl Management tool toggles as functional when no IATO API key is configured. Previously the checkboxes appeared enabled and saveable, but bridge tool registration is gated by a separate condition at <code>iato-mcp.php:85<\/code> (the bridge tool files only <code>require_once<\/code> when the API key is non-empty), so the toggles were placebo \u2014 a user could check every box, save, and still get <code>Unknown tool: get_iato_sitemap<\/code> on every call with no UI signal explaining why. The toggle inputs in those two categories are now <code>disabled<\/code> when the API key is empty, the category card grays out (55% opacity), and an inline banner under the heading explains: \"These tools require an IATO API key. Add it under 'IATO Platform' above to enable them \u2014 until then, these toggles have no effect.\" When the user pastes an API key and saves, the categories become interactive again.<\/li>\n<\/ul>\n\n<h4>1.4.6<\/h4>\n\n<ul>\n<li>Fix: <code>rollback<\/code> now appears as a checkbox on the Settings \u2192 IATO MCP page (under a new \"Safety\" category). v1.4.5 added rollback to the <code>TOOL_NAMES<\/code> constant \u2014 which fixed the sanitize-strip behavior \u2014 but the Settings UI rendering loop iterates a separate constant, <code>TOOL_CATEGORIES<\/code>, which also needed rollback added. Without the category entry, the checkbox was never rendered. Adding <code>'Safety' =&gt; ['rollback']<\/code> closes the gap.<\/li>\n<li>Polish: unified the inner <code>mcpServers<\/code> server key shown in the Settings page hero card config snippet from <code>wordpress<\/code> to <code>iato-wordpress<\/code>, matching the dismissible setup notice. Cosmetic only \u2014 the inner key is a user-facing display name they can rename \u2014 but eliminates an unnecessary inconsistency between the two snippets.<\/li>\n<\/ul>\n\n<h4>1.4.5<\/h4>\n\n<ul>\n<li>Fix: <code>rollback<\/code> tool now appears in the Settings \u2192 IATO MCP per-tool toggle list, and the Settings save no longer silently strips it from <code>iato_mcp_tools<\/code>. When v1.4.0 added the rollback MCP tool, the developer forgot to add it to the <code>TOOL_NAMES<\/code> constant in <code>class-settings.php<\/code>. Consequence: no UI checkbox for it, and <code>sanitize_tools()<\/code> (which <code>array_intersect<\/code>s saved values against TOOL_NAMES) was stripping it from existing installs every time a user clicked Save Settings. Once stripped, <code>is_tool_enabled('rollback')<\/code> returned false and the tool stopped registering. Adding rollback to TOOL_NAMES fixes both the UI and the strip behavior.<\/li>\n<li>Fix: idempotent migration restores <code>rollback<\/code> to <code>iato_mcp_tools<\/code> for any install where it had been stripped by the previous bug. Runs once on plugin upgrade, no-op for installs that didn't lose it.<\/li>\n<li>Fix: <code>capabilities.rollback<\/code> in the <code>initialize<\/code> response now reflects actual tool registration instead of being hardcoded <code>true<\/code>. Previously, an install with rollback disabled (manually or via the strip bug above) would advertise <code>rollback: true<\/code> in capabilities, causing clients that feature-detect to attempt rollback calls that returned <code>tool_not_found<\/code>.<\/li>\n<\/ul>\n\n<h4>1.4.4<\/h4>\n\n<ul>\n<li>Fix: clicking Approve on the OAuth consent screen no longer redirects users to \/wp-admin instead of back to the OAuth client. The handler at <code>class-oauth.php:181<\/code> was using <code>wp_safe_redirect()<\/code> for the post-approval callback, but <code>wp_safe_redirect<\/code> silently rewrites any URL whose host isn't on WordPress's <code>allowed_redirect_hosts<\/code> allowlist to <code>admin_url()<\/code> \u2014 which means every external OAuth callback (claude.ai, cursor.sh, etc.) was being silently rewritten to \/wp-admin\/, leaving the connector stuck on \"Connect\" because the client never received an authorization code. Switched to <code>wp_redirect()<\/code>, which is the correct primitive for OAuth callbacks (the protocol requires an external redirect by design).<\/li>\n<li>Fix: the not-logged-in branch of the authorize handler at <code>class-oauth.php:132<\/code> was passing <code>$_SERVER['REQUEST_URI']<\/code> through <code>sanitize_text_field()<\/code> before building the post-login redirect URL. <code>sanitize_text_field<\/code> strips <code>%XX<\/code> percent-encoded sequences as an HTML-entity defense, which mangled the inner <code>redirect_uri<\/code> parameter (every <code>:<\/code> and <code>\/<\/code> removed) and broke the post-login bounce back to \/oauth\/authorize. Now uses <code>wp_unslash<\/code> only, which is correct for a server-set value used as a redirect target.<\/li>\n<li>Hardening: <code>\/oauth\/authorize<\/code> now refuses requests whose <code>client_id<\/code> isn't registered via the dynamic client registration endpoint at <code>\/oauth\/register<\/code>. Previously the redirect_uri allowlist was opt-in (validated only when the client_id existed in the registered set) \u2014 after the wp_redirect change above lets external redirects through, that opt-in shape was an open-redirect surface. Spec-compliant clients (Claude, Cursor, etc.) already register before authorize, so this is a no-op for them.<\/li>\n<li>Fix: <code>initialize<\/code> now echoes the client's requested <code>protocolVersion<\/code> when it's one we recognize (<code>2024-11-05<\/code>, <code>2025-03-26<\/code>, <code>2025-06-18<\/code>) instead of always returning <code>2024-11-05<\/code>. Falls back to <code>2025-06-18<\/code> for unknown requests. Forward-compat for clients on newer MCP revs.<\/li>\n<\/ul>\n\n<h4>1.4.3<\/h4>\n\n<ul>\n<li>Fix: dismissible \"MCP \u2014 Ready to Connect\" admin notice restructured. The previous \"1. Copy \/ 2. Open Claude Desktop \/ 3. (Optional) IATO key\" framing implied a sequential three-step flow, but Step 1's snippet and Step 2's \"Or use Add Custom Connector\" sub-line were actually two mutually-exclusive connection methods, and Step 3 was unrelated optional setup. Notice now leads with the endpoint URL (with its own Copy button), then presents Option A (Connectors UI \/ OAuth, recommended) and Option B (Claude Desktop config file with the mcp-remote stdio snippet) as clearly-labeled alternatives separated by an \"\u2014 or \u2014\" divider, with the IATO API key and \"see the setup wizard for other clients\" line moved to a non-numbered footer. Same content, structure no longer suggests dependence between the two paths.<\/li>\n<\/ul>\n\n<h4>1.4.2<\/h4>\n\n<ul>\n<li>Fix: <code>Authorization: Basic &lt;Application Password&gt;<\/code> is now an accepted auth path on the MCP endpoint, alongside the existing plugin Bearer token. v1.4.1 documented Application Password support in the setup wizard but <code>class-auth.php<\/code> was hard-rejecting any non-Bearer header \u2014 users following wizard Methods 2 or 3 were getting 401s. This release makes the wizard's promise actually work. Trust grant in this version is identical to the Bearer path (full admin once authenticated); per-user capability enforcement under Application Password is tracked separately as a v1.6 hardening item.<\/li>\n<li>Fix: dismissible setup notice now emits a Claude-Desktop-compatible stdio-bridge config (<code>mcp-remote<\/code> via <code>npx<\/code>, Bearer + <code>iato_mcp_key<\/code> in an <code>env<\/code> entry) instead of the direct-HTTP <code>{url, headers}<\/code> format that Claude Desktop's config file can't consume. Same bug class as the v1.4.1 wizard fix; this catches the second occurrence in the admin notice.<\/li>\n<li>Fix: relabeled the Settings page hero-card config block from \"Claude Desktop Configuration\" to \"HTTP MCP clients (MCP Inspector, IDEs, scripts)\" \u2014 the snippet is still the right config for those clients, just no longer mislabels its audience. Adds a one-line pointer to the setup wizard for stdio-only clients.<\/li>\n<\/ul>\n\n<h4>1.4.1<\/h4>\n\n<ul>\n<li>Fix: setup wizard restructured around the three actual connection methods. The previous \"1. URL \u2192 2. Application Password \u2192 3. Claude Desktop config\" framing presented OAuth-via-Connectors users with a credential step they didn't need, and the JSON snippet referenced <code>@modelcontextprotocol\/server-http<\/code> \u2014 a package that doesn't exist on npm. The wizard now leads with the endpoint URL, then presents three mutually exclusive method cards: Connectors UI (OAuth, recommended), Direct HTTP (Basic Auth for MCP Inspector \/ IDEs \/ scripts), and Manual config (stdio bridge for Claude Desktop config file, Cursor, Cline, Zed).<\/li>\n<li>Fix: stdio-bridge JSON snippet now uses <code>mcp-remote<\/code> (the real npm package) and passes the credential via an <code>env<\/code> entry referenced as <code>${IATO_AUTH}<\/code> in <code>args<\/code>, working around Claude Desktop's args parser breaking on spaces inside inline header strings.<\/li>\n<\/ul>\n\n<h4>1.4.0<\/h4>\n\n<ul>\n<li>New: <code>rollback<\/code> MCP tool. Reverses any prior write by <code>change_id<\/code>. Wraps the existing <code>wp-json\/iato-mcp\/v1\/rollback<\/code> REST endpoint so Claude can undo a change in one MCP call instead of the user constructing a manual HTTP request. Validates the stored <code>before_value<\/code> to prevent tampering, dispatches by <code>target_type<\/code>, and marks the receipt rolled-back so it cannot be re-applied. Requires <code>edit_posts<\/code> (with elevated <code>manage_options<\/code> for <code>menu_item<\/code> and <code>redirect<\/code> receipts to mirror the original write capability).<\/li>\n<li>New: change receipts on <code>update_post<\/code> and <code>create_post<\/code>. Previously these two write tools returned no audit trail, so even though every other write tool emitted a receipt, the most common edits \u2014 title, content, excerpt, status, and net-new posts \u2014 couldn't be rolled back. <code>update_post<\/code> now records one receipt per actually-changed field (skipping no-op resends); <code>create_post<\/code> records <code>target_type=post, field=create<\/code>, and <code>rollback<\/code> reverses it via <code>wp_trash_post<\/code> (recoverable from the WP trash).<\/li>\n<li>New: <code>capabilities.rollback: true<\/code> in the <code>initialize<\/code> response so MCP clients can feature-detect rollback support without a <code>tools\/list<\/code> round-trip \u2014 same pattern as the existing <code>capabilities.elementor.v2<\/code>.<\/li>\n<li>Migration: appends <code>rollback<\/code> to the saved <code>iato_mcp_tools<\/code> per-tool toggle option on first request after upgrade so existing installs see the new tool enabled by default. Same idempotent migration pattern used for the v2 Elementor tools in 1.3.5.<\/li>\n<\/ul>\n\n<h4>1.3.5<\/h4>\n\n<ul>\n<li>Docs: corrected the FAQ entry that still claimed \"30 built-in tools\" \u2014 now reflects the v1.3.0 widget-grained Elementor surface (39 WordPress native + 12 IATO bridge = 51 total).<\/li>\n<li>Docs: added two example prompts demonstrating widget-grained edits (\"Set every H2 heading in these Elementor posts to H1\" and \"Find all button widgets on the site and change their color to #ff0000\") so the v2 capability is concrete for end users who don't know Elementor jargon.<\/li>\n<li>No code changes.<\/li>\n<\/ul>\n\n<h4>1.3.4<\/h4>\n\n<ul>\n<li>Optimization: <code>update_elementor_widgets_bulk<\/code> no longer echoes <code>change_receipt<\/code> on per-result rows. Receipts are still persisted to the <code>iato_change_receipts<\/code> audit table; bulk callers who need them can query by post_id + applied_at. Saves ~120 bytes per result. Brings the canonical 4-page H1-flip benchmark response under the v2 spec's &lt;2 KB hard target. Singleton <code>update_elementor_widget<\/code> and <code>update_elementor_patch<\/code> responses keep the slim receipt for backward-compat and convenience.<\/li>\n<\/ul>\n\n<p><h4>1.3.3<\/h4><\/p>\n\n<ul>\n<li>Optimization: v2 write tools (<code>update_elementor_widget<\/code>, <code>update_elementor_patch<\/code>, <code>update_elementor_widgets_bulk<\/code>) now elide <code>previous_revision<\/code> from per-result responses unless the caller passed <code>if_revision<\/code>. Rationale: a client that passed <code>if_revision<\/code> already knows the prior hash (echoing back confirms what the server saw on conflict), and a client that didn't pass it doesn't need it on the wire \u2014 they get <code>current_revision<\/code> to chain the next write. Saves ~93 bytes per result; brings the canonical 4-page H1-flip benchmark response under the v2 spec's &lt;2 KB hard target on the <code>op: replace<\/code> path.<\/li>\n<\/ul>\n\n<p><h4>1.3.2<\/h4><\/p>\n\n<ul>\n<li>Fix: v2 write tools (<code>update_elementor_widget<\/code>, <code>update_elementor_patch<\/code>, <code>update_elementor_widgets_bulk<\/code>) used to echo a verbose <code>change_receipt<\/code> containing the entire <code>applied_patch<\/code> JSON-stringified into <code>before_value<\/code>. That duplicated the top-level <code>applied_patch<\/code> field on every response and pushed bulk-update payloads over the spec's &lt;2 KB target on a 4-page sweep. The receipt's <code>before_value<\/code> was also semantically wrong (it should be the value being replaced, not the patch). Fixed both: storage rows now record the canonical <code>previous_revision<\/code> \u2192 <code>current_revision<\/code> pair, and the API response carries only the receipt id + metadata (<code>{change_id, target_type, field, applied_at}<\/code>). Full audit data still queryable from the <code>iato_change_receipts<\/code> table for rollback. Per-update savings ~0.6\u20130.8 KB; on a 4-page bulk sweep that's ~3 KB shaved off the wire.<\/li>\n<\/ul>\n\n<p><h4>1.3.1<\/h4><\/p>\n\n<ul>\n<li>Fix: <code>update_elementor_widgets_bulk<\/code> and <code>find_elementor_widgets<\/code> no longer reject every request with <code>auth_denied<\/code>. The handlers were calling <code>current_user_can( 'edit_post', $post_id )<\/code> \/ <code>current_user_can( 'read_post', $pid )<\/code> per-target, but bearer-authenticated MCP requests don't establish a logged-in WP user \u2014 <code>wp_get_current_user()<\/code> returns 0, and meta-cap checks against post objects always fail. v1 tools sidestep this via <code>IATO_MCP_Auth::require_cap()<\/code>, which is a flag check that returns true for any bearer-authenticated request (per the documented \"the plugin key grants full administrative access\" auth model). The v2 handlers now match v1 semantics.<\/li>\n<li>Fix: idempotent one-shot migration on plugin update. Existing installs upgrading from 1.2.x to 1.3.x previously saw the nine new Elementor v2 tools auto-disabled because saved <code>iato_mcp_tools<\/code> per-tool toggle arrays didn't include the new names. The migration appends new tool names to the saved option on first request after upgrade. New installs unaffected.<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>New: widget-grained Elementor surface (v2). Nine new MCP tools \u2014 <code>list_elementor_widgets<\/code>, <code>get_elementor_widget<\/code>, <code>update_elementor_widget<\/code>, <code>update_elementor_patch<\/code>, <code>update_elementor_widgets_bulk<\/code>, <code>find_elementor_widgets<\/code>, <code>set_heading_level<\/code>, <code>set_widget_setting<\/code>, <code>resolve_url<\/code>. Replaces the all-or-nothing <code>update_elementor_data<\/code> for surgical edits while preserving the v1 tool unchanged.<\/li>\n<li>New: optimistic concurrency on every v2 write via <code>if_revision<\/code> (sha256 of stored Elementor data). Mismatch returns <code>revision_conflict<\/code> with the current revision so clients can re-sync without an extra read.<\/li>\n<li>New: idempotency keys on every v2 write via <code>idempotency_key<\/code>. Same key + same payload within 60s returns the cached response with <code>idempotency_replay: true<\/code>; same key + different payload returns 409. Scoped per-(user, tool).<\/li>\n<li>New: structured <code>applied_patch<\/code> diff response on every v2 write \u2014 RFC 6902 ops with <code>previous_value<\/code> extension. Identical shape in <code>dry_run<\/code> mode so clients can preview before committing.<\/li>\n<li>New: <code>update_elementor_patch<\/code> accepts an RFC 6902 JSON Patch over the entire document for surgical array-entry edits (repeater rows, indexed inserts) where v2 widget patch's replace-only array semantics are too coarse.<\/li>\n<li>New: <code>find_elementor_widgets<\/code> searches every Elementor post in the workspace (capped at 500 in 1.3.0) for widgets matching a filter spec \u2014 operators <code>eq<\/code>, <code>ne<\/code>, <code>in<\/code>, <code>nin<\/code>, <code>exists<\/code>.<\/li>\n<li>New: <code>resolve_url<\/code> walks the WordPress rewrite cascade and reports the rendering post + Theme Builder template shadowing (Elementor Pro). Best-effort across Elementor versions; returns <code>limited_resolution: true<\/code> when the platform's APIs aren't available.<\/li>\n<li>New: <code>is_shadowed_by<\/code> field on <code>get_post<\/code> (opt-in via <code>include_shadowing: true<\/code>) \u2014 surfaces Theme Builder template overrides without requiring a separate <code>resolve_url<\/code> call.<\/li>\n<li>New: <code>format<\/code> parameter on <code>get_elementor_data<\/code> \u2014 <code>raw<\/code> (existing), <code>compact<\/code> (defaults stripped, top-20 widget types), <code>summary<\/code> (skeleton tree of <code>{widget_id, type, peek_fields}<\/code>). All formats include the canonical <code>revision<\/code> hash for use with v2 if_revision guards.<\/li>\n<li>New: <code>initialize<\/code> response advertises <code>capabilities.elementor.v2: true<\/code> when Elementor is active so clients can feature-detect without a <code>tools\/list<\/code> round-trip.<\/li>\n<li>Existing v1 tools (<code>get_elementor_data<\/code>, <code>update_elementor_data<\/code>) remain functional with unchanged signatures \u2014 no breaking changes.<\/li>\n<\/ul>\n\n<h4>1.2.4<\/h4>\n\n<ul>\n<li>Fix: <code>list_iato_crawls<\/code> now returns the UUID <code>job_id<\/code> as <code>crawl_id<\/code> instead of the numeric DB primary key. The numeric <code>id<\/code> had no FK relationship to the other bridge tools (which all key off the UUID via <code>\/crawl\/jobs\/{uuid}\/...<\/code>), so handing it back to Claude broke the analyze-and-fix chain at the first hop.<\/li>\n<li>Fix: <code>list_iato_crawls<\/code> envelope read now falls back from canonical <code>data.jobs<\/code> to bare <code>jobs<\/code> if the platform regresses or a new un-wrapped endpoint slips through. Same dual-key resilience pattern used for <code>\/workspaces<\/code> during the v1.1 transition.<\/li>\n<\/ul>\n\n<h4>1.2.3<\/h4>\n\n<ul>\n<li>Fix: <code>start_iato_crawl<\/code> now sends <code>workspace_id<\/code> as a JSON integer, not a JSON string. The platform's POST \/crawl\/start handler binds the field as <code>Optional[int]<\/code> via Pydantic; depending on strict-mode it can reject <code>\"44\"<\/code> while accepting <code>44<\/code>. Resolves orphan-crawl creation that persisted from 1.2.0\u20131.2.2.<\/li>\n<\/ul>\n\n<h4>1.2.2<\/h4>\n\n<ul>\n<li>Fix: Test connection now persists the workspace_id when validation succeeds, so the crawl-control tools can scope requests correctly. Previously the option remained empty even after a successful validation, which made <code>start_iato_crawl<\/code> create orphan jobs and <code>list_iato_crawls<\/code> return an empty list.<\/li>\n<li>Fix: <code>start_iato_crawl<\/code> and <code>list_iato_crawls<\/code> now use <code>resolve_workspace_id()<\/code> (with built-in lazy-load fallback) instead of reading the option directly. Self-heals existing installs that validated their key before 1.2.2.<\/li>\n<\/ul>\n\n<h4>1.2.1<\/h4>\n\n<ul>\n<li>Fix: <code>start_iato_crawl<\/code> now tags new crawls with the user's workspace_id so they are properly scoped to the connected IATO account<\/li>\n<li>Fix: <code>list_iato_crawls<\/code> now filters by workspace_id to return crawls owned by the connected account (previously returned an empty list even when crawls existed)<\/li>\n<li>Fix: replace PHP 8.2-only <code>: true|WP_Error<\/code> literal type with <code>: bool|WP_Error<\/code> across class-auth, class-seo-adapter, class-rollback, and tool-redirects so the plugin parses cleanly on PHP 8.0\/8.1 as the header advertises<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>New: <code>start_iato_crawl<\/code> MCP tool \u2014 Claude can kick off an IATO crawl of the current site directly from a conversation (admin only; consumes IATO platform quota)<\/li>\n<li>New: <code>get_iato_crawl_status<\/code> MCP tool \u2014 poll a specific crawl job until it completes<\/li>\n<li>New: <code>list_iato_crawls<\/code> MCP tool \u2014 list recent crawl jobs to find the most recent completed crawl_id<\/li>\n<li>New \"Crawl Management\" category in Settings &gt; IATO MCP &gt; Tools<\/li>\n<li>Bridge tool count: 9 \u2192 12; total registered tools: 39 \u2192 42<\/li>\n<li>New FAQ entry on the dual auth methods (Application Password \/ OAuth for AI clients vs. Bearer token for the IATO platform's WordPress Sync UI)<\/li>\n<\/ul>\n\n<h4>1.1.12<\/h4>\n\n<ul>\n<li>Added Plugin URI to plugin header<\/li>\n<li>Added contextual links to iato.ai throughout the plugin description, installation, and FAQ sections<\/li>\n<li>Added link to documentation page<\/li>\n<\/ul>\n\n<h4>1.1.11<\/h4>\n\n<ul>\n<li>Readme accuracy corrections: updated tool count from 17 to 30, expanded feature list with Elementor, canonical URLs, structured data, redirects, and excerpt support, corrected minimum WordPress version to 6.2<\/li>\n<\/ul>\n\n<h4>1.1.10<\/h4>\n\n<ul>\n<li>30 WordPress native tools including Elementor read\/write and the new <code>excerpt<\/code> parameter on <code>update_post<\/code><\/li>\n<li>9 IATO bridge tools: sitemap, SEO fixes, broken links, content gaps, orphan pages, navigation audit, AI suggestions, performance reports, taxonomy analysis<\/li>\n<li>OAuth 2.0 authorization server with PKCE for Claude Desktop connector flow<\/li>\n<li>Dynamic client registration (RFC 7591)<\/li>\n<li>SEO adapter supporting Yoast SEO, RankMath, and SEOPress<\/li>\n<li>Single Settings page with General and Diagnostics tabs; 39 per-tool toggles<\/li>\n<li>AJAX-based Save Settings to sidestep host-level options.php timeouts<\/li>\n<li>\"Test connection\" button for explicit IATO API key validation<\/li>\n<li>Change receipts audit trail for every write operation, with Claude-callable rollback endpoint<\/li>\n<li>MCP <code>notifications\/*<\/code> methods silently accepted per JSON-RPC spec<\/li>\n<li>Plugin-generated API key with Bearer token authentication<\/li>\n<\/ul>","raw_excerpt":"Exposes an MCP server from any self-hosted WordPress site, enabling AI agents like Claude to audit and fix your site in a single workflow.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/pan.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/294616","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pan.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/pan.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/pan.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=294616"}],"author":[{"embeddable":true,"href":"https:\/\/pan.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/iatoai"}],"wp:attachment":[{"href":"https:\/\/pan.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=294616"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/pan.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=294616"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/pan.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=294616"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/pan.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=294616"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/pan.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=294616"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/pan.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=294616"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}