Support / Royal MCP Pro / SEO Agency Suite

SEO Agency Suite

Complete reference for the 11 SEO Agency Suite tools in Royal MCP Pro. Portfolio-scale SEO audit + bulk meta writers for all five supported SEO plugins (Yoast, Rank Math, SEOPress, AIOSEO, SEObolt) + widget bulk ops + Redirection plugin bulk import/export/rule-set apply. All bulk writers use the safer 2-step commit envelope with drift detection and a longer 168-hour undo TTL.

The two-step commit envelope

Every bulk write in this suite uses a two-step commit pattern — different from the direct-write pattern the Divi / Elementor / WC bulk tools use. This is a deliberate safety layer: SEO meta and widget content live in surfaces users often edit outside your MCP session, so racing an editor is a real risk. The two-step envelope catches drift between preview and commit.

Step 1 — Preview (no commit_token)

Call the tool with your update payload but no commit_token. The response is a dry-run preview: what would change per row, plus a fresh commit_token string. Nothing is written.

Step 2 — Commit (echo the commit_token back)

Call the tool a second time with the same update payload PLUS the commit_token from step 1. The token has a 5-minute TTL and is one-shot — consumed on successful commit, or on any conflict / drift. Successful commit issues a 168-hour undo token.

Drift detection

Between step 1 and step 2, the tool re-reads the target rows. If any target's state changed — someone edited Yoast meta in wp-admin, a scheduled cron rewrote a widget, another MCP session touched the row — step 2 rejects with a conflict error + drifted_post_ids array naming the rows that moved. Nothing is written. You call step 1 again with a fresh preview and try again.

Why 168 hours (7 days) instead of 72?

SEO meta changes often surface in Search Console rankings on a 3–7 day lag. If a bulk meta rewrite tanks rankings, you may not know until day 5 or 6. The 168-hour window gives you time to notice and roll back before the tokens age out.

SEO tools (1 audit + 5 bulk writers)

wp_audit_seo_bulk ⭐

Bulk SEO audit across a post type. Returns per-page findings (title/description length + issue, noindex, H1 count, word count, image count, images missing alt, featured image, issues list) plus an optional aggregated rollup (issues by type, worst offenders). Auto-detects Yoast SEO, Rank Math, SEOPress, AIOSEO, or SEObolt; falls back to WordPress-native fields (post_title, post_excerpt) when none is active. Read-only.

Arguments

NameTypeDescription
post_typestringPost type to audit (must be a registered CPT slug). Default: post.
paginateobject{page, per_page}. Defaults: page 1, per_page 100 (max 500).
rollupbooleanInclude the aggregated rollup summary alongside per-page results. Default true.
snapshotbooleanWhen true and SiteVault is installed, kick off a pre-audit backup. Default false. Snapshot failure never aborts the audit.

Example

Run wp_audit_seo_bulk on my page post type with rollup=true. Then tell me the top 3 issues by count and the 5 worst-offender post IDs.

No undo (read-only). Requires manage_options.

Shared arguments across the 5 SEO plugin bulk writers

All five bulk-meta writers (yoast_bulk_update_meta, rankmath_bulk_update_meta, seopress_bulk_update_meta, aioseo_bulk_update_meta, seobolt_bulk_update_meta) accept the same input shape:

NameTypeDescription
updates requiredarrayUp to 100 per-post update rows. Each row must include post_id and at least one field.
dry_runbooleanForce a step-1 preview even if you already have a commit_token. Default false.
commit_tokenstringRequired for the actual write (step 2). Get it from the step-1 dry-run response. TTL: 5 minutes. One-shot.

Per-update-row 3-state field model — OMIT the key to leave the field UNCHANGED; pass "" or null to CLEAR (delete meta / revert to plugin default); pass a value to SET.

FieldTypeDescription
post_id requiredintegerTarget post ID.
titlestringSEO title (browser tab / SERP display).
descriptionstringMeta description (SERP snippet).
focus_keywordstringPrimary focus keyword for SEO scoring.
noindexbooleantrue = force noindex. false = force explicit index (overrides site default) — EXCEPT SEOPress, see per-tool notes. null = revert to site default on all plugins.
canonicalstringCanonical URL (or clear).

yoast_bulk_update_meta

Bulk-update Yoast SEO meta across up to 100 posts. Routes to Yoast's meta keys. Two-step commit + drift detection + 168h undo.

Requires Yoast SEO to be the active SEO plugin. Rank Math / SEOPress / AIOSEO / SEObolt have separate bulk-write tools. See shared arguments above.

Undo: 168h token — restores each affected post's Yoast meta exactly.

rankmath_bulk_update_meta

Bulk-update Rank Math SEO meta across up to 100 posts. Routes to Rank Math's meta keys (rank_math_title, rank_math_description, rank_math_focus_keyword, rank_math_robots array, rank_math_canonical_url).

Noindex handling: noindex toggles preserve other robots tokens (nofollow, noimageindex) already on the post. Two-step commit + drift detection + 168h undo. Requires Rank Math active.

Undo: 168h token — restores each affected post's Rank Math meta exactly.

seopress_bulk_update_meta

Bulk-update SEOPress meta across up to 100 posts. Routes to SEOPress's meta keys (_seopress_titles_title, _seopress_titles_desc, _seopress_analysis_target_kw, _seopress_robots_index, _seopress_robots_canonical).

SEOPress noindex quirk

SEOPress has no explicit-index concept — noindex: false and noindex: null both delete the meta row (revert to site default). If you want to force "always index" on Yoast/RankMath/AIOSEO you'd use noindex: false; on SEOPress there's no equivalent action.

Two-step commit + drift detection + 168h undo. Requires SEOPress active.

Undo: 168h token — restores each affected post's SEOPress meta exactly.

aioseo_bulk_update_meta

Bulk-update AIOSEO (All in One SEO) meta across up to 100 posts. Dual-writes to legacy post_meta AND to the wp_aioseo_posts custom table on modern versions so both surfaces stay coherent.

Never-touched posts show as warnings

Posts that AIOSEO has never touched (no wp_aioseo_posts row) surface in the response's warnings array. Open the post once in the AIOSEO editor to seed a row, then re-run the bulk update.

Two-step commit + drift detection + 168h undo. Requires AIOSEO active.

Undo: 168h token — restores each affected post's AIOSEO meta exactly.

seobolt_bulk_update_meta

Bulk-update SEObolt meta across up to 100 posts. Routes to SEObolt's _seobolt_meta_* post-meta keys. Two-step commit + drift detection + 168h undo. Requires SEObolt active.

SEObolt is Royal Plugins' own SEO plugin — treated exactly the same way as Yoast, Rank Math, SEOPress, and AIOSEO by the auto-detect layer. If SEObolt is the active SEO plugin on the site, this writer is what runs when you call bulk-meta updates.

Undo: 168h token — restores each affected post's SEObolt meta exactly.

Widget bulk tools (2)

Both widget tools require edit_theme_options capability plus the Royal MCP settings toggle "Allow AI to modify theme appearance" — a deliberate second gate because widget changes affect site-wide chrome and can't be undone visually as easily as post content.

wp_bulk_update_widgets

Bulk-update widget instance settings across up to 100 widgets. Settings are partial-merged: keys you pass overwrite, keys you omit stay unchanged.

Arguments

NameTypeDescription
updates requiredarrayUp to 100 {widget_id, settings} rows. widget_id examples: "text-2", "custom_html-5", "block-15".
dry_runbooleanForce step-1 preview even with a commit_token present.
commit_tokenstringRequired for the actual write (step 2). TTL 5 min. One-shot.

Widgets not found are surfaced in the response's skipped array, not raised as errors.

Undo: 168h token — restores prior widget instances exactly.

wp_bulk_replace_widget_content

Literal find/replace across every stored instance of a widget type (e.g. update the copyright year on every text widget site-wide, or fix a URL across every custom_html widget). Walks all STRING values in each instance's settings — non-string values (numeric IDs, booleans) are left untouched.

Regex NOT supported

Literal match only. This is deliberate for safety — regex on user-typed widget content is a foot-gun class of bug that has no good fit inside an AI-driven workflow. If you need regex, do the find/replace client-side and use wp_bulk_update_widgets to write the transformed settings back.

Arguments

NameTypeDescription
widget_type requiredstringWidget id_base (the piece before the -N), e.g. text, custom_html, block, nav_menu.
find requiredstringLiteral string to find.
replace requiredstringReplacement (may be empty to remove all occurrences).
case_insensitivebooleanDefault false. When true, uses str_ireplace.
dry_runbooleanForce step-1 preview.
commit_tokenstringRequired for step 2. TTL 5 min.

Undo: 168h token — restores prior widget instances exactly.

Redirection plugin bulk tools (3)

All three tools require the Redirection plugin by John Godley active. They wrap the plugin's storage layer with two-step commit + drift detection.

redirection_bulk_import

Bulk-import up to 100 redirects from a CSV. Header row required with at least source and destination columns; optional group, type, match_type.

Arguments

NameTypeDescription
csv_content requiredstringCSV body. First line = header; header must include source + destination. Columns: source, destination, group, type, match_type.
overwritebooleanWhen true, existing redirects with the same source are updated in-place. Default false (existing sources skipped and surfaced in the skipped list).
dry_runbooleanForce step-1 preview.
commit_tokenstringRequired for step 2. TTL 5 min.

Undo: 168h token — deletes only the redirects this batch CREATED and restores the ones it UPDATED. Never touches pre-existing redirects that weren't part of the batch.

redirection_bulk_export

Export existing Redirection entries as CSV. Read-only.

Arguments

NameTypeDescription
group_idintegerFilter to redirects in this group only. Use the Free-tier redirection_list_groups to discover IDs.
limitintegerDefault 500, min 1, max 5000.

No undo (read-only, no-op token returned for API consistency).

redirection_apply_rule_set

Apply a JSON-defined rule set (up to 100 rules) — same shape + semantics as redirection_bulk_import but takes a rules array directly instead of CSV. Useful for saved templates like "301 old blog URLs to new structure."

Arguments

NameTypeDescription
rules requiredarrayUp to 100 rule objects. Each: {source, destination, group?, type?, match_type?}. type is HTTP status (301 / 302 / 307; default 301).
overwritebooleanWhen true, existing redirects with the same source are updated in-place.
dry_runbooleanForce step-1 preview.
commit_tokenstringRequired for step 2. TTL 5 min.

Undo: 168h token — same shape as redirection_bulk_import (deletes newly-created, restores updated, ignores pre-existing).

Still Stuck? Two-Step Support Path

If a SEO Suite tool isn't behaving the way you expected, work through these two steps in order.

Step 1: Start with the Royal MCP Troubleshooting Guide

Royal MCP Troubleshooting — Start Here covers MCP-layer issues.

For Pro-specific patterns:

Step 2: Email priority support

If you've worked through Start Here and the relevant Pro-specific doc and the issue still isn't resolved, email priority support from your purchase email address at support@royalplugins.com. Priority email support is included with your license — typical response within 24 hours. Never include your license key in email; we look it up from your purchase address.

What to include in your email
  • Your hosting provider (SiteGround, Cloudways, Hostinger, Kinsta, WP Engine, Liquid Web, self-hosted VPS, etc.)
  • Royal MCP Pro version from WP Admin → Plugins
  • Which SEO plugin is active and its version (Yoast SEO / Rank Math / SEOPress / AIOSEO / SEObolt / none) — if using a bulk SEO writer
  • Redirection plugin version if using a Redirection tool
  • Active caching plugins (LiteSpeed Cache, WP Rocket, W3 Total Cache, SpeedyCache, Hummingbird, none)
  • Which MCP client — claude.ai web custom connector, Claude Desktop with mcp-remote, ChatGPT MCP, Cursor, or another MCP-compatible client
  • The exact tool name and args you called (redact any customer PII from the updates array if present)
  • Which step failed — step 1 preview, or step 2 commit? If step 2 rejected with conflict, include the drifted_post_ids array
  • Screenshot of the most recent oauth: row in Activity Log AND the most recent Pro tool row in Audit Log with View Details expanded