Skip to main content
Glama

wpxmcp

The open-source MCP server that runs your WordPress sites like a senior admin would — content, design, plugins, SEO, performance, security and the whole fleet, from Claude, ChatGPT, Cursor or any MCP client.

Deploy to Cloudflare CI License: MIT MCP 2026-07-28 WordPress 6.0–7.1

150 tools · 20 playbooks · stdio + remote · many sites, one server · MIT · no subscription, no usage cap


Why I built this

I run several WordPress sites, and I wanted an AI agent to do the real work on them — not just draft a post, but find out why a page is slow, fix a meta description in Rank Math, check whether a plugin update broke the checkout, tidy a bloated options table.

The official route stopped short. The WordPress MCP Adapter is the right long-term idea, but it can only expose what something has registered as an ability — and out of the box core registers three, all read-only. It is one endpoint per site, it has to be installed on every site, and nothing in it tells you why a page is slow or whether your site is exposed.

The commercial route came with a meter. The hosted and plugin-based MCPs that can do more charge per site or per seat, cap how many requests or actions you get, and hold your credentials on their servers. For a handful of sites managed every day, the limits arrived before the work was done — and I could not read, fix or extend the thing I was paying for.

So I built the server I needed, used it on my own sites until it was dependable, and released it. It is free, MIT-licensed, self-hosted, and has no usage limit other than your own WordPress.


Related MCP server: wordpress-mcp

What it looks like

"The pricing page still shows the old price, and it feels slow. Sort it out."

An illustrative session, abridged.

find_content_by_url  https://example.com/pricing/          → page 812
update_content       edits: [{ find: "$39", replace: "$49" }]  → 1 replacement
get_page_html        /pricing/                              → still shows $39
purge_cache          scope: url                             → WP Rocket purged
get_page_html        /pricing/                              → $49 ✓
profile_url          /pricing/
  → 184 queries (61 duplicates from wp-content/plugins/pricing-table)
  → external HTTP call to api.currency.example 1.4s on every request

It read the rendered page instead of trusting a 200, found the stale cache, and then found the real reason the page was slow — with the file and plugin responsible.


Why wpxmcp

It is not reinventing the wheel

wpxmcp is built on what WordPress already ships: the REST API, Application Passwords and the Abilities API (it is a client of wp-abilities/v1, so plugin-registered abilities just work). When a plugin offers its own REST route or ability, wpxmcp uses it — so the plugin's validation, hooks and cache invalidation run. It falls back in order: ability → REST → the plugin's own settings save → WP-CLI → guarded SQL. The optional companion plugin only adds what core has no API for at all: logs, profiling, theme files, WP-CLI, SQL, admin screens.

Compared with the official MCP Adapter

WordPress MCP Adapter

wpxmcp

What the agent can do

Whatever plugins registered as abilities

150 tools on day one, plus every registered ability

Sites per connection

One

Many — one server, one connection

Install on each site

Required

Optional (113 tools need nothing on the site)

Diagnostics, profiling, security, SEO, fleet

—

✅

Guardrails (dry-run, drafts, confirm tokens)

Up to each ability

✅ built in

They are complementary: install the adapter if you like, and wpxmcp will call the same abilities.

Compared with commercial plugin-based MCPs

Typical commercial MCP

wpxmcp

Price

Per site / per seat, monthly

Free

Usage

Request or action quotas

No cap

Where credentials live

Vendor's servers, or inside the site

Your Cloudflare account or your machine

Can you read and change it

No

Yes — MIT

Lock-in

Their plugin, their dashboard

Standard MCP, standard WordPress APIs

The power of open source, in practice

  • Auditable guardrails. Every safety claim in SECURITY.md is code you can read and a test you can run — and each was verified to refuse, not just to exist.

  • Extensible by you. Add a tool with one defineTool({...}); save your team's conventions as a playbook with save_skill.

  • Yours to deploy. Cloudflare Workers free tier, or node dist/index.js on a laptop. No telemetry; the only outside services it calls are the ones a tool names (WordPress.org, the WPVulnerability database, stock-photo APIs you configure).


What it does, by who you are

Site owners and webmasters

  • Plain-language edits that read the page back before and after, draft before publish, and say plainly when something cannot be undone

  • security_audit — exposed files, user enumeration, XML-RPC, weak config, admin accounts, and known-vulnerable plugins from the WPVulnerability database, scored and sorted

  • purge_cache for WP Rocket, LiteSpeed, W3TC, WP Super Cache, SiteGround, Kinsta, WP Engine and more — then proves the page changed

  • backup_status before anything risky; tail_error_log when the site shows a critical error

Plugin power users — operate any installed plugin as an admin

  • inspect_plugin maps what a plugin exposes: REST routes, abilities, settings, admin screens

  • get_plugin_settings / update_plugin_settings write through WordPress's own settings save, so the plugin's sanitisation runs — with a preview, a confirm step and one-call undo

  • admin_page / submit_admin_form read and submit any wp-admin screen as the administrator — Yoast, Rank Math, WooCommerce, forms, caching — even where no API exists

WordPress developers

  • profile_url — Query Monitor over MCP: every query with caller and plugin, duplicates, external HTTP calls, PHP warnings, assets, memory, and the template that rendered the page

  • inspect_registry — post types, meta, blocks, REST routes, shortcodes, cron, and hooks with file:line of every callback

  • inspect_options, cleanup_options, inspect_database — autoload bloat, orphaned data and tables, attributed to the plugin that left them

  • WP-CLI (emulated — no SSH), guarded SQL, the Abilities API, rest_api for anything else

Theme developers

  • Sandboxed theme drafts with private preview links; never edit a live theme

  • diff_global_styles — what the Site Editor changed versus theme.json; reset_template_customization to revert

  • validate_theme_json — schema, duplicate slugs, missing font files, WCAG contrast across every style variation

  • check_accessibility on any page or draft preview; apply_style_variation, list_block_patterns, classic PHP + Tailwind scaffolding

SEO and content teams

  • get_seo_meta / set_seo_meta across Yoast, Rank Math, AIOSEO, SEOPress and The SEO Framework — and a check that what is stored is what actually renders

  • seo_site_check, check_links, internal_link_report (orphans and link suggestions), content_inventory (CSV), content_calendar

  • Page-builder aware: Elementor, Divi, Beaver Builder, Bricks and Breakdance content is detected and never corrupted by an HTML edit

Agencies

  • fleet_report — every client site in one call: reachability, versions, pending updates, Site Health, noindex left on, HTTPS — worst first

  • One deployment, one bearer token per team, credentials in Worker Secrets instead of on every laptop

Every tool →


Guardrails that hold

  • New content is a draft; deletes go to the trash.

  • Bulk edits, SQL, search-replace, settings changes and form submissions preview first and return a single-use confirm_token bound to those exact arguments.

  • Theme work happens in a sandboxed copy; publishing backs up the previous theme.

  • Protected options, path traversal, stacked SQL, off-site fetches and private-network requests are refused — at the server and in the plugin.

  • Every sensitive action is written to an append-only audit log, locally and on the site.


Deploy to Cloudflare

Or three commands:

npm install
openssl rand -hex 32 | npx wrangler secret put WPX_AUTH_TOKEN
npx wrangler secret put WPX_SITES     # your sites JSON, then Ctrl-D
npm run deploy

Connect any client:

{
  "mcpServers": {
    "wpxmcp": {
      "type": "http",
      "url": "https://wpxmcp.<your-subdomain>.workers.dev/mcp",
      "headers": { "Authorization": "Bearer <your WPX_AUTH_TOKEN>" }
    }
  }
}

It speaks MCP 2026-07-28 (stateless, no handshake) and still serves clients on 2025-era revisions from the same endpoint. The free tier covers 100,000 requests a day. Full walkthrough →

Or run it locally

git clone https://github.com/alokemajumder/wpxmcp.git
cd wpxmcp && npm install && npm run build
npm run doctor          # checks reachability, auth, capabilities, plugin
claude mcp add wpxmcp -- node /absolute/path/to/wpxmcp/dist/index.js \
  -e WORDPRESS_URL=https://example.com \
  -e WORDPRESS_USERNAME=admin \
  -e "WORDPRESS_APP_PASSWORD=abcd EFGH ijkl MNOP qrst UVWX"

Create the Application Password under Users → Profile → Application Passwords. WordPress only offers them over HTTPS, and some hosts strip the Authorization header — test_site detects both. Auth guide →


Do you need the companion plugin?

Not for most work. 113 of the 150 tools run against a stock WordPress with nothing installed.

The other 37 do things core WordPress has no API for: reading the error log, profiling a request, operating admin screens, WP-CLI, SQL, theme files, cache purges and code snippets. Each of those tools names the plugin when it is missing, and tells you how to install it. What it adds and how it is secured → · Comparison and evidence →


Documentation

Tool reference

Every tool, generated from the code

Deploy to Cloudflare

Secrets, custom domains, rotation, troubleshooting

WordPress auth

Application Passwords, roles, HTTPS, header passthrough

Configuration

Every option and precedence rule

Companion plugin

What it adds, how it is secured

Comparison

Versus other WordPress MCP servers

Security

Threat model and guardrails

Contributing

Setup, conventions, adding a tool or playbook


Status

v2.0.0. CI on Node 20, 22 and 24, PHP 7.4 and 8.3, with the Worker build verified on every push.

Every release is verified against a live WordPress 7.1, not only unit-tested: the full tool surface exercised over stdio and over HTTP, on both the 2026-07-28 and 2025-era protocols, with every guardrail confirmed to refuse. The suites are in audit/ and re-runnable against any throwaway WordPress.

Issues and pull requests are read. Especially welcome: playbooks for plugins you know well, and adapters for more cache, backup and SEO plugins. If wpxmcp saves you time, a star helps other people find it.

Development

npm install && npm run build
npm test            # unit tests, no network needed
npm run cf:dev      # the Worker locally at :8787/mcp

Adding a tool is one defineTool({...}) — it appears on both transports and in the generated tool reference automatically.

License

MIT — see LICENSE. Not affiliated with the WordPress Foundation, Automattic, or Cloudflare.

Available Tools

150 tools
activate_pluginActivate a pluginA

Activate an installed plugin. Activation runs the plugin's code immediately — a plugin incompatible with this WordPress or PHP version can fatal the site, so prefer testing on staging first.

Inputs: plugin (required), site_id, network_wide.

activate_themeActivate a themeA
Destructive

Switch the site's active theme. This changes the entire front-end appearance immediately, and widget/menu assignments do not always carry across. Requires confirm: true. If you are iterating on a theme you are building, use the draft workflow and publish_draft_theme instead.

Inputs: stylesheet (required), confirm, site_id.

add_menu_itemAdd a menu itemA

Add an entry to a navigation menu. It can point at a post, page or custom post type (object_id + object), a taxonomy term, or an arbitrary URL. Use parent to nest it under another item and menu_order to position it.

Inputs: title (required), menu_id (required), url, xfn, +10 more.

admin_pageView a wp-admin screen as adminA
Read-only

View any wp-admin screen as the authenticated administrator and get back its structure rather than raw HTML: the page title, its notices (errors, warnings, "Settings saved" messages), the wp-admin links on it, and every form with its fields (name, type, label, current value, options for selects/radios, whether required, and the help text), plus a capped text summary. This is how you read a plugin's settings screen that has no REST route — for example "admin.php?page=wpseo_titles" (Yoast) or "admin.php?page=rank-math-options-titles". The server authenticates the request with a single-use token; no cookie ever reaches the client.

Inputs: url_or_page (required), site_id.

apply_style_variationApply a style variationA
Destructive

Apply one of the active theme's style variations to the site's global styles — what choosing it in Site Editor → Styles does. Without confirm_token it is a dry run showing the JSON-path diff between the current user styles and the result. A full variation replaces the user's global-styles customisations; a colour or typography partial is merged into them. The previous state is kept as a global-styles revision (GET /wp/v2/global-styles/{id}/revisions), which is how to undo.

Inputs: kind, mode, index, title, +2 more.

assign_terms_to_contentAssign terms to contentA

Assign taxonomy terms to any content item. Terms may be given as IDs or as names — names that do not exist are created for you. By default this replaces the item's terms in that taxonomy; pass mode: "add" to keep the existing ones, or "remove" to detach.

Inputs: terms (required), taxonomy (required), content_id (required), mode, +3 more.

audit_contentAudit content qualityA
Read-only

Sweep a content type and report the problems worth fixing: missing SEO titles and descriptions, missing or duplicate H1s, thin content, missing featured images, missing excerpts, uncategorised posts, and images without alt text. Read-only — it names the issues and the IDs so you can fix them with bulk_update_content or update_content.

Inputs: type, limit, status, site_id, +1 more.

audit_mediaAudit the media libraryA
Read-only

Audit the media library for images missing alt text and for attachments not referenced by any content. Alt text is the highest-value accessibility fix on most sites, and unused media is where disk usage quietly accumulates.

Inputs: limit, site_id, check_unused.

backup_statusCheck backup statusA
Read-only

Report which backup plugin the site uses (UpdraftPlus, BackWPup, Duplicator, All-in-One WP Migration, Jetpack VaultPress Backup, BlogVault, WPvivid, BackupBuddy) and when the last completed backup was taken, with a warning when there is none or it is stale. Run this before any risky change — updates, theme publishes, search-replace, bulk deletes. Host-level backups are invisible to WordPress and are flagged as unknown. Needs the companion plugin.

Inputs: site_id.

bulk_update_contentBulk update contentA

Apply the same change to many items at once — set a status, reassign an author, add a category, or run a find/replace across bodies. Always previews first: the initial call reports exactly which items would change and how, and returns a confirm_token you must echo back to apply it. Nothing is written without that token.

Inputs: type, limit, filter, changes, +3 more.

check_accessibilityCheck a page's accessibilityA
Read-only

Fetch a page on the configured site and run deterministic accessibility checks on its server-rendered HTML: html lang, page title, a single h1 and no skipped heading levels, images without alt (alt="" is treated as decorative), links and buttons with no accessible name, generic link text ("read more", "click here"), form controls without labels, duplicate ids, iframes without title, autoplaying media, a viewport that disables zoom, and WCAG contrast of block colour classes (has-{slug}-color / has-{slug}-background-color and inline colours) resolved against the theme palette. Each issue has a WCAG reference, severity, snippet and fix. Works on draft-theme preview URLs from get_preview_url. It does not run JavaScript or compute CSS, so it complements rather than replaces a browser audit.

Inputs: url, rules, site_id, max_issues, +1 more.

cleanup_optionsClean up options and transientsA
Destructive

Reduce options-table weight in one of three ways: delete_expired_transients (expired transients and site transients, plus timeout rows whose value is gone), set_autoload_off (stop loading named options on every request — they remain readable on demand), or delete_options (remove named options). Always two steps: the first call is a dry run that returns exactly what would change, the bytes saved, what was refused and a confirm_token; repeat the identical call with that token to apply it. Core WordPress options, wpxmcp's own state and lock-out options (siteurl, active_plugins, user roles, salts…) are refused. Deleting an option a plugin still uses resets that plugin's setting, so check owners in inspect_options first. Needs the companion plugin.

Inputs: action (required), names, site_id, confirm_token.

code_snippetManage code snippetsA

Add PHP, CSS or JavaScript to the site as a managed snippet rather than by editing theme files — so it survives theme updates and can be switched off without touching code. New snippets are always created DISABLED: you activate them in wp-admin after reading the code. PHP snippets are syntax-checked before they are saved, so a parse error is reported rather than fataling the site.

Inputs: action (required), id, code, title, +5 more.

content_calendarContent calendarA
Read-only

Editorial calendar view: scheduled (future) content grouped by ISO week, publishing cadence per week over the last N weeks, stale drafts not touched in N days, and gaps against a target posts-per-week. Useful for content teams planning what to publish next.

Inputs: types, site_id, weeks_back, weeks_ahead, +2 more.

content_inventoryContent inventoryA
Read-only

Export a content inventory — one row per item with id, type, status, URL, title, word count, published and modified dates, author name, term names, whether it has a featured image, and the SEO title/description when Yoast exposes them. JSON or CSV, with field selection and cursor pagination, for content audits, migrations and spreadsheets.

Inputs: types, cursor, fields, format, +3 more.

create_classic_themeScaffold a classic themeA

Scaffold a complete classic PHP theme styled with Tailwind, as a draft. Classic templates with utility classes are far more reliable to generate and to review than nested block markup — the output is readable, diffable and predictable. The scaffold includes style.css, functions.php, header/footer, index, single, page, archive, 404, search, comments, a theme.css holding the design tokens (colors, fonts, radii) that every template reuses, and a Tailwind CDN setup wired to those tokens.

Inputs: name (required), slug, author, tokens, +3 more.

create_commentCreate a commentA

Post a comment on a content item, optionally as a threaded reply. Set status to "approve" to publish it immediately (requires moderation capability); otherwise it enters the normal moderation queue.

Inputs: post (required), content (required), date, author, +6 more.

create_contentCreate contentA

Create a post, page, or any custom post type. Content is created as a DRAFT unless you explicitly pass status: "publish" — this server never publishes to a live site implicitly. Schedule by passing status: "future" with a future date. Taxonomy terms can be given by name and are created if missing.

Inputs: date, meta, slug, type, +16 more.

create_draft_themeCreate a draft themeA

Clone an installed theme into an isolated draft copy that you can edit freely without touching the live site. Every theme edit should go through a draft: write files, preview them on a private tokenised URL, then publish_draft_theme when you are happy (which backs up the previous theme first). Omit from_theme to clone the currently active theme.

Inputs: site_id, draft_name, from_theme.

create_mediaUpload mediaA

Upload a file into the media library from any of three sources: file_path (a path on the machine running this MCP server — this is how you upload a local screenshot), url (downloaded here, then uploaded), or base64_data. WordPress runs its normal image pipeline, generating the registered thumbnail sizes. Always set alt_text for images — it is required for accessibility and read by search engines.

Inputs: url, post, title, caption, +9 more.

create_menuCreate a navigation menuA

Create an empty navigation menu, optionally assigning it to one or more theme locations. Add entries afterwards with add_menu_item.

Inputs: name (required), site_id, auto_add, locations, +1 more.

create_pluginCreate a plugin (alias of install)A

Install a plugin from the WordPress.org repository. This is the REST API's own naming for the install operation — install_plugin is the clearer name for the same thing.

Inputs: slug (required), status, site_id.

create_termCreate a termA

Create a term in any taxonomy. If a term with the same name already exists, WordPress rejects it — search with list_terms first when you might be duplicating.

Inputs: name (required), meta, slug, parent, +3 more.

create_userCreate a userA

Create a WordPress user. Requires an Administrator account. Choose the role deliberately — "administrator" grants full control of the site including plugin and theme installation.

Inputs: email (required), password (required), username (required), url, +7 more.

create_widgetAdd a widgetA

Add a widget to a sidebar. id_base names the widget type (block, text, nav_menu, search, categories, recent-posts…). For the modern "block" widget, put block markup in instance.content — that is how the block-based widget editor stores everything.

Inputs: id_base (required), sidebar (required), site_id, instance, +1 more.

deactivate_pluginDeactivate a pluginA

Deactivate an active plugin. Its features stop working immediately; settings and data are normally retained.

Inputs: plugin (required), site_id.

delete_commentDelete a commentA
Destructive

Delete a comment. It goes to the trash by default and is recoverable; force: true removes it permanently and requires confirm: true.

Inputs: id (required), force, confirm, site_id.

delete_contentDelete contentA
Destructive

Delete content of any type. By default it goes to the trash and stays recoverable from wp-admin. Permanent deletion requires force: true AND confirm: true, and cannot be undone — the row is removed from the database along with its meta.

Inputs: id (required), type, force, confirm, +1 more.

delete_draft_themeDelete a draft themeA
Destructive

Discard a draft theme and its files. The live site is unaffected — this only removes the sandbox copy.

Inputs: theme (required), confirm, site_id.

delete_field_groupDelete a field groupA
Destructive

Remove a registered field group. The stored values are left in place, so the data is not lost and the group can be re-registered to expose it again.

Inputs: group_key (required), confirm, site_id.

delete_mediaDelete a media itemA
Destructive

Delete a media item. Attachments bypass the trash by default in WordPress, so deletion removes the file from disk permanently and requires confirm: true. Any content still referencing the file will show a broken image.

Inputs: id (required), confirm, site_id.

delete_menuDelete a navigation menuA
Destructive

Delete a navigation menu and all of its items. Any theme location it filled falls back to the theme's default output. Requires confirm: true.

Inputs: id (required), confirm, site_id.

delete_menu_itemDelete a menu itemA
Destructive

Remove one item from a navigation menu. Its children are re-parented to the top level rather than deleted.

Inputs: id (required), site_id.

delete_pluginDelete a pluginA
Destructive

Delete an installed plugin from the server. The plugin must be inactive first. Files are removed permanently; many plugins also drop their database tables on uninstall. Requires confirm: true.

Inputs: plugin (required), confirm, site_id.

delete_skillDelete a saved playbookB

Delete one of your saved playbooks. Bundled playbooks cannot be deleted, but a saved skill of the same name will override one.

Inputs: name (required).

delete_termDelete a termA
Destructive

Delete a term from any taxonomy. Terms have no trash — deletion is immediate and permanent, so this reports what will be affected and requires confirm: true. Content assigned to the term is not deleted; it simply loses the assignment (posts losing their only category fall back to the default category).

Inputs: id (required), confirm, site_id, taxonomy.

delete_theme_fileDelete a theme fileA
Destructive

Delete a file from a theme draft. Refuses to touch a live active theme unless explicitly allowed. Deleting a required template (index.php, style.css) breaks the theme.

Inputs: path (required), theme, confirm, site_id, +1 more.

delete_userDelete a userA
Destructive

Delete a user. WordPress has no trash for users, so this is permanent and requires confirm: true. You must say what happens to their content: reassign it to another user (strongly preferred) or let it be deleted with them.

Inputs: id (required), confirm, site_id, reassign_to.

delete_widgetDelete a widgetA
Destructive

Remove a widget. By default it is moved to the inactive widgets area so its settings survive; force: true deletes it outright.

Inputs: id (required), force, site_id.

diff_global_stylesDiff global styles against theme.jsonA
Read-only

Show exactly what the Site Editor has overridden in a block theme: a JSON-path diff of the user's global-styles customisations against the theme's own theme.json values (palette entries are matched by slug), plus every template and template part whose source is "custom" — edited in the Site Editor and therefore no longer following the theme's files. Use it before editing theme.json (a user override silently wins over file changes) or before shipping a theme update.

Inputs: site_id, max_entries, include_unchanged.

discover_abilitiesDiscover plugin abilitiesA
Read-only

List the abilities registered on the site through the WordPress Abilities API — capabilities that plugins such as WPForms, AIOSEO or SeedProd expose for programmatic use. Running a plugin's own ability is always safer than writing to its tables directly, because the plugin's validation, hooks and cache invalidation still run.

Inputs: search, site_id.

discover_content_typesDiscover content typesA
Read-only

List every content type registered on the site — post, page, and any custom post type — with its REST base, whether it is hierarchical, which taxonomies apply, and which fields it supports. Call this before working with an unfamiliar site: a type absent here is registered with show_in_rest => false and cannot be reached over REST at all.

Inputs: site_id, include_counts.

discover_rest_routesDiscover REST routesA
Read-only

List the REST namespaces and routes the site actually registers, including those added by plugins. Use this before rest_api so you call routes that exist — WordPress route shapes vary between plugin versions and guessing wastes calls.

Inputs: search, site_id, namespace.

discover_taxonomiesDiscover taxonomiesA
Read-only

List every taxonomy on the site — categories, tags, and any custom taxonomy — with its REST base, which post types it applies to, and whether it is hierarchical. A taxonomy missing here is registered with show_in_rest => false and is unreachable over REST.

Inputs: site_id, for_type.

edit_mediaEdit a media item (alias)A

Legacy alias for update_media, kept for backward compatibility. Prefer update_media.

Inputs: id (required), post, title, caption, +3 more.

edit_theme_fileEdit a theme fileA

Make targeted find/replace edits inside a theme file, leaving the rest untouched. Safer than write_theme_file for changing one function or block of markup. An edit that matches nothing fails loudly rather than silently writing nothing.

Inputs: path (required), edits (required), theme, site_id, +1 more.

execute_sql_queryRun a database queryA

Run a SQL query against the WordPress database through the companion plugin. SELECT/SHOW/DESCRIBE/EXPLAIN run immediately with an enforced row limit. Anything that mutates data is blocked unless you pass allow_mutation: true, and even then it first returns a preview and a confirm_token that you must echo back — stacked statements are always refused. Reach for this only when the REST API and WP-CLI cannot get at the data: raw SQL bypasses WordPress hooks, so caches are not invalidated and plugin logic does not run.

Inputs: query (required), site_id, max_rows, confirm_token, +1 more.

find_content_by_urlFind (and optionally update) content by URLA

Resolve any WordPress front-end URL to the content behind it, detecting the post type from the URL shape (so /documentation/getting-started/ finds the documentation custom post type), then optionally update it in the same call. This is the tool to reach for when a human hands you a link. Detection tries, in order: an explicit ?p= id, the site's own search index, the registered rewrite base, then a slug sweep across every type.

Inputs: url (required), date, meta, slug, +19 more.

fleet_reportFleet health reportA
Read-only

One report across every configured WordPress site (or a chosen subset), checked in parallel: reachability and response time, WordPress version, pending core/plugin/theme updates, active plugin count, companion plugin presence, HTTPS, search-engine blocking (blog_public / homepage noindex) and Site Health critical issues. Each site is isolated, so one failure never breaks the report. Sites are sorted worst first with headline issues — the starting point for agency maintenance rounds.

Inputs: site_ids, timeout_ms, concurrency, check_homepage, +1 more.

get_ability_infoGet ability detailsA
Read-only

Get the full definition of one ability, including its input and output schemas and whether it is destructive, so you can call it correctly the first time. Ability names are namespaced, e.g. "my-plugin/get-site-info".

Inputs: name (required), site_id.

get_audit_logRead the audit logA
Read-only

Read the append-only local audit log of every sensitive action this server has taken — writes, deletes, SQL, WP-CLI, theme publishes — with timestamp, site, tool, target and outcome. Useful for answering "what did the AI actually change?".

Inputs: limit, site_id, all_sites.

get_commentGet a commentA
Read-only

Fetch one comment by ID with its full text, author details and moderation status.

Inputs: id (required), site_id.

get_contentGet content by IDA
Read-only

Fetch one item of any content type by ID, including the raw content body exactly as stored — which is what you must read before making targeted edits, since the block editor stores markup with HTML comment delimiters.

Inputs: id (required), raw, type, site_id, +2 more.

get_content_by_slugFind content by slugA
Read-only

Look up content by slug across every content type at once, or within specific types. Use when you know the URL tail but not which post type owns it.

Inputs: slug (required), types, site_id, include_content.

get_content_metaRead custom fieldsA
Read-only

Read the custom fields (post meta) on a content item, including keys that are not registered with show_in_rest and therefore invisible to get_content. Needs the companion plugin to see unregistered keys. Values over 20,000 characters are truncated unless the key is requested by name in keys.

Inputs: id (required), keys, site_id, include_protected.

get_content_summaryGet a content summaryA
Read-only

Return a minimal summary of one item — id, title, slug, status, excerpt, taxonomies, word count and SEO fields (Yoast, Rank Math, AIOSEO or SEOPress) — without the body. Built for audits and lookups over many items. Accepts either an id (with type) or a full URL.

Inputs: id, url, type, site_id.

get_content_termsGet terms on contentA
Read-only

Get every taxonomy term assigned to one content item, grouped by taxonomy and resolved to full term objects rather than bare IDs.

Inputs: content_id (required), type, site_id.

get_global_stylesGet global stylesA
Read-only

Read a block theme's global styles — the palette, typography, spacing and per-block styling that theme.json defines and the Site Editor overrides. This is where a block theme's design tokens live.

Inputs: site_id, include_theme_defaults.

get_mediaGet a media itemA
Read-only

Fetch one media item by ID, including its source URL, dimensions, generated sizes, alt text and where it is attached.

Inputs: id (required), site_id.

get_menuGet a menu with its itemsB
Read-only

Get one navigation menu together with all of its items, rendered as an indented tree so the hierarchy is obvious.

Inputs: id (required), site_id.

get_optionsRead site optionsA
Read-only

Read values from the WordPress options table by name — where plugins and themes keep their configuration. Autoloaded options are also where a bloated database often hides.

Inputs: limit, names, search, site_id.

get_page_htmlGet rendered page HTMLA
Read-only

Fetch the fully rendered HTML that a visitor receives for any URL on the configured site (other hosts, and redirects to them, are refused), so you can verify that a change actually appears on the front end rather than trusting the API's word for it. Returns the server-rendered HTML — content injected later by JavaScript will not appear. Optionally extracts just the SEO-relevant head tags or the visible text.

Inputs: url, mode, site_id, max_chars, +1 more.

get_pluginGet a pluginA
Read-only

Get full details about one installed plugin by its plugin file path, e.g. "woocommerce/woocommerce" or "hello-dolly/hello".

Inputs: plugin (required), site_id.

get_plugin_infoGet repository plugin infoA
Read-only

Get detailed information about one plugin from the WordPress.org repository — full description, changelog, version history, ratings breakdown, and compatibility. Use before installing or updating to see what changed.

Inputs: slug (required), include_sections.

get_plugin_settingsRead a plugin's settings optionA
Read-only

Read an option a plugin owns, unserialised into JSON, with obvious secrets (keys matching pass/secret/token/api_key/license) redacted to "••••" plus the last four characters. Omit option to list the options the plugin appears to own so you can pick one. This reads the raw stored option — the same data the plugin's settings screen edits.

Inputs: plugin (required), option, reveal, site_id.

get_preview_urlGet a theme preview URLA
Read-only

Get a tokenised private URL that renders the site using a draft theme, without affecting what anyone else sees. Share it or open it to check your work before publishing. The token expires, so fetch a fresh URL if it stops working.

Inputs: path, theme, site_id.

get_seo_metaGet SEO metadataA
Read-only

Read the SEO metadata for one piece of content (by id or URL), normalized across Yoast, Rank Math, AIOSEO, SEOPress and The SEO Framework: title, description, focus keyword, canonical, robots, Open Graph and schema types. Detects the active plugin, shows the per-item overrides it stores, and compares them with what the rendered page actually emits — a mismatch usually means page caching or a theme override. Works without an SEO plugin too (reports what WordPress core renders).

Inputs: id, url, type, plugin, +2 more.

get_siteGet site configurationA
Read-only

Get the full configuration for one site (secrets redacted), plus what the WordPress install reports about itself: name, description, timezone, WordPress version, permalink shape, and which optional wpxmcp capabilities are available.

Inputs: site_id, include_remote.

get_site_settingsGet site settingsA
Read-only

Read the site's core settings — title, tagline, timezone, date formats, posts-per-page, front page configuration, default category, comment and registration policy. Requires an Administrator account.

Inputs: site_id.

get_templateGet a block templateA
Read-only

Get one block template or template part, including its block markup, so you can inspect or edit the layout of an entire page type.

Inputs: id (required), kind, site_id.

get_template_for_urlWhich template renders a URLA
Read-only

Answer "which template file (or block template and template parts) renders this URL, and why?" — the resolved file, the template hierarchy WordPress tried, whether a block template or part has been customised in the Site Editor, the queried object and the conditional tags that were true. A lightweight profile_url. Needs the companion plugin.

Inputs: url, site_id, as_logged_in.

get_termGet a termA
Read-only

Fetch one taxonomy term by ID, including its description, parent, item count and any registered term meta.

Inputs: id (required), site_id, taxonomy.

get_themeGet a themeA
Read-only

Get details about one installed theme, including what it declares support for and whether it is a block theme (which changes how you build pages and templates).

Inputs: stylesheet (required), site_id.

get_theme_modsGet Customizer settingsA
Read-only

Read the active theme's Customizer settings (theme mods) — logo, colors, layout options and anything else the theme registers there. Classic themes keep much of their configuration here rather than in options.

Inputs: site_id.

get_userGet a userA
Read-only

Fetch one user by ID, or the authenticated user with id: "me". Includes roles and a summary of notable capabilities when permitted.

Inputs: id (required), site_id.

inspect_databaseInspect the databaseA
Read-onlyIdempotent

A developer's view of the WordPress database: every table with engine, collation, approximate rows, data and index bytes and reclaimable overhead; which plugin each non-core table belongs to, with tables whose owner is inactive, not installed or unknown listed as possible orphans; orphaned rows (postmeta, commentmeta and usermeta without a parent, term relationships pointing nowhere); revisions per post type, auto-drafts, trashed posts and spam/trash comments; and tables not on utf8mb4. Counts are capped so a huge table cannot stall the query. Works on MySQL/MariaDB and on the SQLite integration (sizes are then unavailable and noted). Read-only. Needs the companion plugin.

Inputs: site_id.

inspect_optionsInspect options and transientsA
Read-onlyIdempotent

Report where the options table carries weight: total autoloaded bytes against Site Health's 800 KB warning, the largest autoloaded options with an owner guessed from installed plugin/theme slugs (flagging owners that are inactive or no longer installed), a per-owner rollup, and transient hygiene for both transients and site transients — count, bytes, expired rows, orphaned timeout rows and the largest entries. Honours WordPress 6.6 autoload values (on/auto-on/auto). Use it before cleanup_options to decide what to change. Needs the companion plugin.

Inputs: limit, site_id.

inspect_pluginInspect an installed pluginA
Read-only

Discover everything an installed plugin exposes and, crucially, how to control it: header data, whether it is active, version and pending update; its own REST routes (found by reflecting the callbacks defined in the plugin's files) with methods; Abilities API abilities it registers; Settings API settings it owns; the options it stores (with sizes and autoload); the wp-admin menu pages it adds; its custom post types, taxonomies, blocks, shortcodes and cron events. Returns a control_surface recommending the best path for changing its configuration — a REST route or ability where one exists, otherwise update_plugin_settings for its options, otherwise admin_page + submit_admin_form for its wp-admin screens. Use this first for any plugin (SEO plugins like Yoast or Rank Math, WooCommerce, forms, caching) before trying to change its settings.

Inputs: plugin (required), site_id.

inspect_registryInspect WordPress registriesA
Read-onlyIdempotent

See what the running WordPress has registered and which plugin, theme or core file registered it — the questions a developer answers with var_dump. kind selects the registry: post_types and taxonomies (all of them, including ones hidden from REST, with rest_base, supports, rewrite and owner); meta (register_meta keys per object type plus the most frequent unregistered postmeta keys with an owner guess); blocks (block types with dynamic flag, attribute count, supports, block.json source, styles, variations, plus block patterns); shortcodes (callback file:line); rest_routes (methods, callback file:line, and routes whose permission_callback is __return_true flagged public); hooks (busiest hooks, or every callback on one hook with priority and file:line); cron (events with next run, schedule, overdue and orphan flags); image_sizes; menus_locations; sidebars; capabilities (each role's caps added/removed versus a fresh install); scripts_styles (handles registered during REST). Needs the companion plugin.

Inputs: kind (required), limit, filter, site_id.

install_pluginInstall a pluginA

Install a plugin from the WordPress.org repository by its slug, optionally activating it straight away. Search first with search_plugins to get the right slug. Installation writes files to the server and needs filesystem write access.

Inputs: slug (required), site_id, activate.

install_themeInstall a themeA

Install a theme from the WordPress.org repository by slug. Does not activate it — use activate_theme, or the draft workflow, afterwards.

Inputs: slug (required), site_id.

list_admin_pagesList wp-admin menu pagesA
Read-only

List the wp-admin menu and submenu pages registered on the site — title, slug, URL, parent, required capability and the plugin each belongs to — so you can find the screen for a task (e.g. Yoast's "Search Appearance", Rank Math's "Titles & Meta", WooCommerce's settings tabs). Pass plugin to list only that plugin's pages. Menus are built from a snapshot captured on a real admin request; this refreshes it if needed.

Inputs: plugin, site_id.

list_block_patternsList block patternsA
Read-only

List the block patterns registered on the site — from core, the active theme's patterns/ folder, plugins and the pattern directory — with their categories, filterable by category and search text. Use it to reuse an existing pattern's markup instead of hand-writing layout. Pattern content is omitted by default because it is large; set include_content for truncated markup.

Inputs: limit, search, source, site_id, +3 more.

list_block_typesList block typesA
Read-only

List the block types registered on the site, with their attributes. Check here before generating block markup for an unfamiliar plugin's blocks — it tells you the exact block name and which attributes are valid.

Inputs: search, site_id, namespace.

list_cli_commandsList allowed WP-CLI commandsA
Read-only

List every WP-CLI command run_wp_cli will accept. The allowlist is default-deny: anything not listed here is refused, no matter how it is phrased. Each entry says whether it writes.

Inputs: filter.

list_commentsList commentsA
Read-only

List comments with filtering by post, status, author and date. Moderating? Filter status: "hold" for the pending queue or "spam" for what the spam filter caught — both require authentication.

Inputs: page, post, type, after, +9 more.

list_contentList contentA
Read-only

List items of any content type — posts, pages, or a custom post type — with filtering, search, ordering and pagination. Returns compact summaries by default so a listing never floods the context; pass full_content: true only when you genuinely need bodies.

Inputs: page, slug, tags, type, +18 more.

list_draft_themesList draft themesA
Read-only

List the theme drafts that exist on the site, with what each was cloned from and when it was last touched.

Inputs: site_id.

list_field_groupsList registered field groupsA
Read-only

List the editable field groups registered on the site, with their fields and where each appears. Check here before registering a group so you extend an existing one rather than duplicating it.

Inputs: site_id.

list_mediaList mediaA
Read-only

List items in the media library with search, type filtering, date filtering and pagination.

Inputs: page, after, order, author, +9 more.

list_menusList navigation menusA
Read-only

List the site's navigation menus and which theme locations they are assigned to. Note that block (full-site-editing) themes may instead use navigation blocks — list_content with type "wp_navigation" covers those.

Inputs: site_id.

list_pluginsList pluginsA
Read-only

List every plugin installed on the site with its activation status and version. Requires an Administrator account — WordPress exposes no plugin data to lower roles.

Inputs: search, status, site_id.

list_reusable_blocksList reusable blocks (patterns)B
Read-only

List the site's reusable blocks / synced patterns — the fragments editors reuse across pages. Editing one changes every place it appears.

Inputs: site_id.

list_revisionsList content revisionsA
Read-only

List the stored revisions of a piece of content, so you can see what changed and when — and recover a previous version if an edit went wrong.

Inputs: id (required), type, site_id, per_page.

list_rolesList rolesA
Read-only

List the roles registered on the site with their capabilities, so you can pick the right role before creating or updating a user. Uses the companion plugin when available and falls back to the standard WordPress roles otherwise.

Inputs: site_id.

list_sidebarsList widget areasA
Read-only

List the theme's widget areas (sidebars) and the widgets currently placed in each. Block themes typically have no classic sidebars — that is expected, not an error.

Inputs: site_id.

list_sitesList WordPress sitesA
Read-only

List every WordPress site configured on this MCP server, with its id, URL, auth method and whether it is writable. Start here when you do not know which site_id to use. Credentials are never returned.

Inputs: no named parameters.

list_skillsList playbooksA
Read-only

List every available playbook — the bundled ones and any you have saved. Saved skills shadow bundled ones with the same name.

Inputs: no named parameters.

list_style_variationsList style variationsA
Read-only

List the active block theme's style variations (styles/*.json, plus the colour-only and typography-only partials themes ship since WordPress 6.6) with each one's palette, font families and font sizes, so you can pick one without reading the JSON. Titles can repeat across kinds (a full "Evening" and a colour-only "Evening"), so each entry carries its index and kind.

Inputs: kind, site_id.

list_templatesList block templatesA
Read-only

List the block theme's templates (front-page, single, archive…) or template parts (header, footer). Block themes only — a classic theme returns nothing here, and you should use the theme file tools instead.

Inputs: kind, site_id.

list_termsList taxonomy termsA
Read-only

List terms in any taxonomy with search, ordering, hierarchy filtering and pagination. Works for categories, tags and custom taxonomies alike.

Inputs: page, post, slug, order, +7 more.

list_theme_filesList theme filesA
Read-only

List the files in a theme (or theme draft) with sizes, so you can see the template structure before reading or editing anything.

Inputs: theme, subdir, site_id.

list_themesList themesA
Read-only

List every theme installed on the site, showing which is active, which are block (full-site-editing) themes, and their versions and parents.

Inputs: status, site_id.

list_usersList usersA
Read-only

List users with search, role filtering, ordering and pagination. Email addresses and roles are only returned when the authenticated user has list_users capability (Administrator); otherwise WordPress returns just the public author profile.

Inputs: page, order, roles, search, +4 more.

list_widgetsList widgetsA
Read-only

List widgets, optionally within one sidebar, including their settings and rendered output.

Inputs: sidebar, site_id.

load_skillLoad a playbookA
Read-only

Load the playbook for the task at hand — a focused guide covering how to do this particular kind of WordPress work correctly, including the traps that are not obvious from the API. Call this FIRST when starting any substantive task: describe what you are about to do and the matching skill is returned. Page builders in particular (Elementor, Divi, Beaver Builder, Bricks, Breakdance) store content in builder-specific structures, and editing their posts as ordinary HTML corrupts the layout — the playbook explains what to do instead.

Inputs: name, query.

moderate_commentsBulk moderate commentsA

Approve, hold, spam, trash — or unspam/untrash — several comments in one call; the practical way to clear a moderation queue. Reports per-comment outcomes rather than failing the whole batch on one error.

Inputs: ids (required), action (required), site_id.

profile_urlProfile a page (Query Monitor style)A
Read-only

Profile how WordPress builds one front-end URL, like Query Monitor but over MCP: which template renders it, every database query (count, total time, slowest with caller and plugin/theme attribution, duplicates), printed scripts/styles, outbound HTTP calls, PHP warnings/notices, conditional tags, memory and timing, plus headline findings. Uses a single-use token so only this one request is instrumented; ordinary visitors are unaffected. Profiles as an anonymous visitor by default. Needs the companion plugin.

Inputs: url, site_id, sections, as_logged_in, +1 more.

publish_draft_themePublish a draft themeA
Destructive

Promote a draft theme to the live site. The currently active theme is backed up first, so the change is reversible. This is the one step that changes what visitors see — everything before it is sandboxed. Requires confirm: true.

Inputs: theme, confirm, site_id.

purge_cachePurge site cachesA
Idempotent

Clear the site's caches through each installed cache layer's own API — WP Rocket, LiteSpeed, W3 Total Cache, WP Super Cache, WP Fastest Cache, SiteGround, Cache Enabler, Breeze, Hummingbird, Nginx Helper, Autoptimize, Varnish (Proxy Cache Purge), WP-Optimize, the Cloudflare plugin, and Kinsta / WP Engine / Pantheon / GoDaddy host caches — plus the object cache. Use it when a change does not appear on the front end. With scope "url" only that page is purged where the layer supports it. Afterwards the page is re-fetched as a visitor and its cache headers reported, so you can tell whether a CDN WordPress cannot reach still holds the old copy. Needs the companion plugin.

Inputs: url, scope, verify, site_id.

read_theme_fileRead a theme fileA
Read-only

Read the contents of one theme file. Always read before editing — write_theme_file replaces the whole file, and edit_theme_file needs exact text to match.

Inputs: path (required), theme, site_id, max_chars.

register_fieldsRegister editable fieldsA

Register custom fields that appear as native meta boxes in wp-admin (or as a settings page for site-wide options), and are automatically exposed to the REST API so they can be read and written afterwards. Use this when building a theme so the site stays editable by humans without touching code. Values are stored as ordinary post meta or options, so the data survives even if this tooling is removed. Fourteen field types are supported: text, textarea, wysiwyg, number, email, url, date, select, checkbox, radio, color, image, gallery, repeater.

Inputs: title (required), fields (required), group_key (required), context, +4 more.

reorder_menu_itemsReorder menu itemsA

Set the order and nesting of several menu items at once, which is far less error-prone than updating them one by one.

Inputs: items (required), site_id.

reset_template_customizationReset a customised templateA
Destructive

Revert a template or template part that was edited in the Site Editor back to the theme's file, by deleting the database copy (DELETE /wp/v2/templates/{id}?force=true). Only works on items whose source is "custom" — find them with diff_global_styles. Without confirm_token it is a dry run that shows what would be lost; if the item was created in the Site Editor and has no theme file, deleting removes it entirely, and the preview says so.

Inputs: id (required), kind, site_id, confirm_token.

rest_apiCall any REST endpointA

Call any WordPress REST endpoint directly — the escape hatch for anything the dedicated tools do not cover, including routes registered by plugins such as WooCommerce, Yoast or ACF. Use discover_rest_routes first to find valid routes rather than guessing: an invented route returns rest_no_route and tells you nothing.

Inputs: route (required), body, query, method, +2 more.

restore_plugin_settingsRestore a plugin option from backupA
Destructive

Restore an option to a value saved before an update_plugin_settings write. Every write keeps the last five previous values; by default this restores the most recent. The first call previews the current value next to the one that would be restored and returns a confirm_token; the second applies it. The current value is itself backed up first, so a restore is undoable. Use this to roll back a settings change that broke something.

Inputs: option (required), site_id, backup_index, confirm_token.

restore_revisionRestore a revisionA

Restore a piece of content to an earlier revision. The current version is itself saved as a revision first, so this is reversible.

Inputs: id (required), revision_id (required), type, site_id.

run_abilityRun a plugin abilityA

Execute an ability registered through the WordPress Abilities API. This is the preferred way to write data a plugin owns — the plugin's own validation, hooks and cache invalidation all run, which raw SQL would bypass. Check get_ability_info for the input schema first. The Abilities API maps intent onto HTTP methods: read-only abilities use GET, ordinary ones POST, and destructive ones DELETE; this is chosen automatically unless you override it.

Inputs: name (required), input, method, site_id.

run_wp_cliRun a WP-CLI commandA

Run a WP-CLI command against the site. Commands are emulated in PHP by the companion plugin — no WP-CLI binary or SSH access is needed on the host. Only allowlisted commands run (see list_cli_commands); everything else is refused. Writing commands need an Administrator account, and search-replace always previews as a dry run before it will touch anything.

Inputs: command (required), format, site_id, confirm_token.

save_skillSave a playbookA

Save a playbook so future sessions follow the same conventions — your site's structure, a client's tone of voice, a deployment routine, the fields a particular theme expects. Written to ~/.wpxmcp/skills and loaded by load_skill from then on. Saving a skill with a bundled skill's name overrides it.

Inputs: name (required), title (required), content (required), description (required), +1 more.

search_pluginsSearch the plugin repositoryA
Read-only

Search the public WordPress.org plugin repository. Returns slug, rating, install count, last-updated date and compatibility — enough to judge whether a plugin is maintained before installing it. This queries WordPress.org, not your site.

Inputs: search (required), page, per_page.

search_siteSearch across the siteA
Read-only

Search every searchable content type at once using WordPress's own search index, returning what type each hit belongs to. Broader than list_content's per-type search.

Inputs: query (required), page, type, site_id, +2 more.

search_stock_photosSearch stock photosA
Read-only

Search Unsplash or Pexels for royalty-free photos and get back candidate image URLs with their required attribution. Pass a chosen result's download_url to create_media (along with its attribution) to bring it into the library. Requires UNSPLASH_ACCESS_KEY or PEXELS_API_KEY to be set on this MCP server.

Inputs: query (required), per_page, provider, orientation.

search_themesSearch the theme repositoryA
Read-only

Search the public WordPress.org theme directory. Returns slug, version, rating, install count, last-updated date, compatibility and whether it is a block theme — enough to choose one before install_theme. This queries WordPress.org, not your site.

Inputs: search (required), page, per_page, block_themes_only.

security_auditAudit site securityA
Read-only

A read-only security review with a 0–100 score and prioritised findings, each with evidence and a concrete fix. Probes the site from outside as an anonymous visitor (user enumeration via REST and ?author=, XML-RPC, public debug.log, exposed wp-config backups / .git / .env, uploads directory listing, security headers, version leaks, http→https), inspects configuration from inside via the companion plugin (debug display, file editor, wp-config permissions, admin usernames, application passwords, salts, pending updates, PHP end-of-life, inactive plugins/themes, HTTPS), and checks core, plugin and theme versions against the free WPVulnerability database. Works partially without the companion plugin and says what it skipped. Never downloads more than a few KB of any exposed file.

Inputs: site_id, max_lookups, include_external, include_vulnerabilities.

seo_site_checkSite-level SEO checkA
Read-only

Check the site-wide SEO fundamentals in one call: "Discourage search engines" (blog_public), robots.txt content and whether it blocks everything, sitemap reachability (core wp-sitemap.xml or the SEO plugin's index), homepage title/description/canonical/Open Graph, plain vs pretty permalinks, HTTPS and the http→https redirect, and duplicate titles across recent published content. Each check reports pass/warn/fail with a concrete fix.

Inputs: site_id, sample_size.

set_content_metaWrite custom fieldsA

Write custom fields (post meta) on a content item, including keys not registered with show_in_rest — which core REST refuses to write. Needs the companion plugin. Values are stored as standard post meta, so they survive if this tooling is removed.

Inputs: id (required), meta (required), site_id.

set_optionWrite a site optionA

Write a value to the WordPress options table. Options drive plugin and theme behaviour, and a wrong value can break the site — read the current value first with get_options, and prefer a plugin's own settings screen or ability where one exists.

Inputs: name (required), value (required), site_id, autoload.

set_seo_metaSet SEO metadataA
Destructive

Set the SEO title, meta description, focus keyword, canonical URL and robots noindex/nofollow for one content item, written the way the active SEO plugin expects: its own REST route where one exists (Rank Math updateMeta, AIOSEO, SEOPress), otherwise its post meta keys via core REST (when registered) or the companion plugin's meta route. Always previews first: the initial call shows before → after and returns a confirm_token; re-run with the token to write. Refuses when no SEO plugin is active, because WordPress core would ignore the values.

Inputs: id (required), type, title, plugin, +7 more.

set_theme_modSet a Customizer settingA

Write one Customizer setting (theme mod) for the active theme. What is valid depends entirely on the theme — read get_theme_mods first to see the keys it uses.

Inputs: key (required), value (required), site_id.

site_infoGet site intelligenceA
Read-only

A full diagnostic picture of the site in one call: WordPress and PHP versions, active theme, active plugins, database size, health checks, available updates, and server configuration. Start here when auditing a site or diagnosing a problem. Falls back to core REST data when the companion plugin is absent, and says which parts it could not see.

Inputs: site_id, include_health, include_plugins.

submit_admin_formSubmit a wp-admin settings formA
Destructive

Fill in and submit a form on a wp-admin screen as the administrator — the way to change plugin settings that live only on a wp-admin page with no REST route. First call is a dry run: it fetches the page, locates the form (by index or id), applies your changes on top of the current field values (hidden fields, nonce and referer included automatically; unchecked checkboxes handled correctly), and returns the diff of changed fields plus a confirm_token. Second call re-fetches the page for a fresh nonce, verifies the other field values have not changed since the preview, submits the form same-site, follows the redirect, and reports the resulting notices (e.g. "Settings saved.") and the new values. Unknown field names are refused with suggestions. Forms with file inputs, and screens that manage plugins/themes/users/exports/core updates, are refused — dedicated tools with proper guardrails exist for those.

Inputs: page (required), changes (required), form_id, site_id, +4 more.

tail_error_logRead the PHP error logA
Read-only

Read the end of the site's PHP error log (wp-content/debug.log or php.ini error_log) without downloading it, with duplicate errors grouped and each one attributed to the plugin, theme or core file that raised it. Also reports whether WP_DEBUG / WP_DEBUG_LOG / WP_DEBUG_DISPLAY are on and the last fatal error the companion plugin recorded — which is captured even when logging is off. Start here for white screens, 500 errors and "there has been a critical error". Needs the companion plugin.

Inputs: grep, level, lines, since, +1 more.

test_siteTest site connectionA
Read-only

Test connectivity and authentication against a site, and report exactly what works: REST reachability, whether credentials authenticate, which user they map to, that user's roles and capabilities, and whether the optional companion plugin is installed. Run this first when anything is behaving strangely — it names the specific misconfiguration rather than a generic failure.

Inputs: site_id.

update_commentUpdate a commentA

Update a comment's text, author details or moderation status. Setting status to "approve" publishes a held comment; "spam" marks it as spam; "trash" hides it recoverably; "unspam" and "untrash" restore it to its previous status.

Inputs: id (required), date, parent, status, +5 more.

update_contentUpdate contentA

Update any content type by ID. Supply content to replace the body wholesale, or edits for targeted find/replace changes that leave the rest of the document untouched — the latter is safer on long pages and is what you should reach for when changing a heading, a price, or one paragraph. An edit that matches nothing fails loudly rather than silently writing nothing.

Inputs: id (required), date, meta, slug, +18 more.

update_global_stylesUpdate global stylesA

Update a block theme's global styles — palette, typography, spacing, per-block styling. Changes apply site-wide immediately. Read them first: by default this merges only at the top level, so a partial settings object replaces that whole branch — pass merge: true to deep-merge instead.

Inputs: merge, styles, site_id, settings.

update_mediaUpdate a media itemB

Update a media item's title, alt text, caption, description or attachment — without re-uploading the file.

Inputs: id (required), post, slug, title, +5 more.

update_menuUpdate a navigation menuA

Rename a menu or change which theme locations it fills.

Inputs: id (required), name, site_id, auto_add, +2 more.

update_menu_itemUpdate a menu itemA

Change a menu item's label, target, nesting or position.

Inputs: id (required), url, menus, title, +6 more.

update_plugin_settingsUpdate a plugin's settings optionA
Destructive

Write an option a plugin owns through WordPress's update_option(), so any sanitize callback attached to it runs. Caveat: plugins that register settings only inside wp-admin (Yoast does) have no sanitizer in this request — the preview warns, and for those the plugin's settings screen via submit_admin_form is the sanitized path. Pass changes to deep-merge fields into the existing option (the usual case for a settings array), or value to replace the whole option. The previous value is backed up (last five kept) and can be undone with restore_plugin_settings. The first call is a dry run: it returns the before→after diff (before sanitization — the plugin may adjust or drop values on save) and a confirm_token; re-run with that token to apply, and the result reports what the sanitizer changed. Options wpxmcp protects, and options not attributable to the plugin (unless force_option), are refused. Prefer a plugin's REST route or ability when inspect_plugin shows one.

Inputs: option (required), plugin (required), value, changes, +3 more.

update_site_settingsUpdate site settingsA

Update the site's core settings. These are global and take effect immediately for every visitor — changing show_on_front or page_on_front changes what the homepage is, and changing start_of_week or timezone shifts every displayed date. Requires an Administrator account.

Inputs: title, site_id, language, timezone, +14 more.

update_templateUpdate a block templateA

Update a block template or template part's markup. This changes the layout of every page that uses it, so it takes effect site-wide immediately. WordPress stores the customisation in the database, leaving the theme's own file untouched — you can always revert in the Site Editor.

Inputs: id (required), content (required), kind, title, +2 more.

update_termUpdate a termA

Update a term's name, slug, description, parent or meta in any taxonomy. Changing a slug changes the term archive URL.

Inputs: id (required), meta, name, slug, +4 more.

update_userUpdate a userA

Update a user's profile, email, password or roles. Changing roles changes what that person can do — promoting to administrator grants full site control.

Inputs: id (required), url, meta, name, +10 more.

update_widgetUpdate a widgetA

Change a widget's settings or move it to a different sidebar or position.

Inputs: id (required), sidebar, site_id, instance, +1 more.

validate_theme_jsonValidate theme.jsonA
Read-only

Lint a block theme's theme.json and its style variations: version, duplicate palette/font-size/spacing/shadow slugs, invalid colour values, font families whose fontFace has no src, customTemplates/templateParts naming templates that do not exist, deprecated v1 keys and blocks, and WCAG contrast of the text/background pairs the styles actually use (root, link, button, headings, blocks and block style variations — resolved through the palette). Returns {valid, errors[], warnings[]} with JSON paths. Checks the active theme by default; pass theme_json to lint a draft file's text before writing it. Reading the raw file (for version and deprecated keys) needs the companion plugin; without it the merged REST data is linted.

Inputs: theme, site_id, theme_json, include_variations, +1 more.

write_theme_fileWrite a theme fileA

Create or overwrite a theme file, replacing its entire contents. Refuses to write to a live active theme by default — work in a draft (create_draft_theme) so the site stays untouched until you publish. PHP is syntax-checked before it is saved, so a parse error is reported rather than fataling the site.

Inputs: path (required), content (required), theme, site_id, +1 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 150 tools

    Disambiguation2/5

    Several tools are explicit duplicates or near-duplicates: create_plugin/install_plugin, edit_media/update_media, get_template_for_url/profile_url, and get_content_by_slug/find_content_by_url. Even with strong descriptions, the large number of overlapping retrieval, diagnostic, and plugin-settings tools makes reliable tool selection difficult.

    Naming Consistency3/5

    Most tools follow a clean verb_noun pattern such as list_*, get_*, create_*, update_*, and delete_*, but there are clear exceptions like site_info, fleet_report, content_inventory, content_calendar, code_snippet, and rest_api. The mixed conventions are still readable, but the pattern is not uniform.

    Tool Count1/5

    With 150 tools, this server is far beyond what an agent can reliably navigate; 50+ is an extreme mismatch per the calibration. Many audit, report, registry, and SEO functions could be consolidated into fewer, grouped tools.

    Completeness4/5

    The tool surface is exceptionally broad: content, media, taxonomies, users, comments, plugins, themes, menus, widgets, settings, SEO, audits, and escape-hatch tools like REST, WP-CLI, and SQL are all covered. The most notable gap is the absence of dedicated update operations for plugins, themes, and core updates, which are only reachable indirectly.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      C
      quality
      B
      maintenance
      Enables AI-powered WordPress management via MCP, with 158 tools for posts, pages, media, plugins, themes, users, comments, and more, plus token-optimized responses.
      335
      482 npm
      4
      MIT
    • F
      license
      Not graded
      quality
      F
      maintenance
      Enables AI assistants to interact with a WordPress site, allowing content and taxonomy management (list, create, update, delete) through 17 MCP tools.
      2
      -