wpxmcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| WPX_SITES | No | JSON array/object of WordPress sites managed by the server when deployed to Cloudflare | |
| WORDPRESS_URL | No | The URL of the WordPress site, e.g. https://example.com | |
| WPX_AUTH_TOKEN | No | Bearer token used to authenticate MCP clients with the Cloudflare Worker deployment | |
| WORDPRESS_USERNAME | No | WordPress username with Application Password access | |
| WORDPRESS_APP_PASSWORD | No | WordPress Application Password (spaces and dashes are usually included) |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_sitesA | 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. |
| get_siteA | 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. |
| test_siteA | 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. |
| get_audit_logA | 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?". |
| discover_content_typesA | 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. |
| list_contentA | 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. |
| get_contentA | 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. |
| get_content_summaryA | 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. |
| get_content_by_slugA | 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. |
| find_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 |
| create_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 |
| update_contentA | Update any content type by ID. Supply |
| delete_contentA | 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. |
| discover_taxonomiesA | 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. |
| list_termsA | List terms in any taxonomy with search, ordering, hierarchy filtering and pagination. Works for categories, tags and custom taxonomies alike. |
| get_termA | Fetch one taxonomy term by ID, including its description, parent, item count and any registered term meta. |
| create_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. |
| update_termA | Update a term's name, slug, description, parent or meta in any taxonomy. Changing a slug changes the term archive URL. |
| delete_termA | 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). |
| assign_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. |
| get_content_termsA | Get every taxonomy term assigned to one content item, grouped by taxonomy and resolved to full term objects rather than bare IDs. |
| list_mediaA | List items in the media library with search, type filtering, date filtering and pagination. |
| get_mediaA | Fetch one media item by ID, including its source URL, dimensions, generated sizes, alt text and where it is attached. |
| create_mediaA | Upload a file into the media library from any of three sources: |
| update_mediaB | Update a media item's title, alt text, caption, description or attachment — without re-uploading the file. |
| edit_mediaA | Legacy alias for update_media, kept for backward compatibility. Prefer update_media. |
| delete_mediaA | 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. |
| search_stock_photosA | Search Unsplash or Pexels for royalty-free photos and get back candidate image URLs with their required attribution. Pass a chosen result's |
| list_usersA | 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. |
| get_userA | Fetch one user by ID, or the authenticated user with id: "me". Includes roles and a summary of notable capabilities when permitted. |
| create_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. |
| update_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. |
| delete_userA | 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. |
| list_rolesA | 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. |
| list_commentsA | 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. |
| get_commentA | Fetch one comment by ID with its full text, author details and moderation status. |
| create_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. |
| update_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. |
| delete_commentA | Delete a comment. It goes to the trash by default and is recoverable; force: true removes it permanently and requires confirm: true. |
| 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. |
| list_pluginsA | 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. |
| get_pluginA | Get full details about one installed plugin by its plugin file path, e.g. "woocommerce/woocommerce" or "hello-dolly/hello". |
| activate_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. |
| deactivate_pluginA | Deactivate an active plugin. Its features stop working immediately; settings and data are normally retained. |
| install_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. |
| create_pluginA | 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. |
| delete_pluginA | 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. |
| search_pluginsA | 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. |
| get_plugin_infoA | 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. |
| list_themesA | List every theme installed on the site, showing which is active, which are block (full-site-editing) themes, and their versions and parents. |
| get_themeA | 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). |
| activate_themeA | 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. |
| install_themeA | Install a theme from the WordPress.org repository by slug. Does not activate it — use activate_theme, or the draft workflow, afterwards. |
| search_themesA | 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. |
| create_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 |
| create_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. |
| list_theme_filesA | List the files in a theme (or theme draft) with sizes, so you can see the template structure before reading or editing anything. |
| read_theme_fileA | 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. |
| write_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. |
| edit_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. |
| delete_theme_fileA | 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. |
| get_preview_urlA | 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. |
| publish_draft_themeA | 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. |
| delete_draft_themeA | Discard a draft theme and its files. The live site is unaffected — this only removes the sandbox copy. |
| list_draft_themesA | List the theme drafts that exist on the site, with what each was cloned from and when it was last touched. |
| list_menusA | 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. |
| get_menuB | Get one navigation menu together with all of its items, rendered as an indented tree so the hierarchy is obvious. |
| create_menuA | Create an empty navigation menu, optionally assigning it to one or more theme locations. Add entries afterwards with add_menu_item. |
| update_menuA | Rename a menu or change which theme locations it fills. |
| delete_menuA | 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. |
| add_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 |
| update_menu_itemA | Change a menu item's label, target, nesting or position. |
| delete_menu_itemA | Remove one item from a navigation menu. Its children are re-parented to the top level rather than deleted. |
| reorder_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. |
| list_sidebarsA | 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. |
| list_widgetsA | List widgets, optionally within one sidebar, including their settings and rendered output. |
| create_widgetA | Add a widget to a sidebar. |
| update_widgetA | Change a widget's settings or move it to a different sidebar or position. |
| delete_widgetA | Remove a widget. By default it is moved to the inactive widgets area so its settings survive; force: true deletes it outright. |
| list_templatesA | 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. |
| get_templateA | Get one block template or template part, including its block markup, so you can inspect or edit the layout of an entire page type. |
| update_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. |
| get_global_stylesA | 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. |
| update_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 |
| list_block_typesA | 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. |
| list_reusable_blocksB | List the site's reusable blocks / synced patterns — the fragments editors reuse across pages. Editing one changes every place it appears. |
| get_theme_modsA | 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. |
| set_theme_modA | 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. |
| get_site_settingsA | 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. |
| update_site_settingsA | Update the site's core settings. These are global and take effect immediately for every visitor — changing |
| site_infoA | 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. |
| get_page_htmlA | 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. |
| search_siteA | 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. |
| list_revisionsA | 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. |
| restore_revisionA | Restore a piece of content to an earlier revision. The current version is itself saved as a revision first, so this is reversible. |
| get_content_metaA | 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 |
| set_content_metaA | 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. |
| rest_apiA | 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. |
| discover_rest_routesA | 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. |
| list_cli_commandsA | 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. |
| run_wp_cliA | 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 |
| execute_sql_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. |
| discover_abilitiesA | 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. |
| get_ability_infoA | 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". |
| run_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. |
| code_snippetA | 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. |
| register_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. |
| list_field_groupsA | 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. |
| delete_field_groupA | 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. |
| get_optionsA | 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. |
| set_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. |
| bulk_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. |
| audit_contentA | 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. |
| audit_mediaA | 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. |
| load_skillA | 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. |
| list_skillsA | List every available playbook — the bundled ones and any you have saved. Saved skills shadow bundled ones with the same name. |
| save_skillA | 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. |
| delete_skillB | Delete one of your saved playbooks. Bundled playbooks cannot be deleted, but a saved skill of the same name will override one. |
| tail_error_logA | 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. |
| purge_cacheA | 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. |
| security_auditA | 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. |
| backup_statusA | 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. |
| inspect_registryA | 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. |
| inspect_optionsA | 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. |
| cleanup_optionsA | 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. |
| inspect_databaseA | 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. |
| profile_urlA | 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. |
| get_template_for_urlA | 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. |
| diff_global_stylesA | 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. |
| reset_template_customizationA | 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. |
| list_style_variationsA | 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. |
| apply_style_variationA | 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. |
| list_block_patternsA | 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. |
| validate_theme_jsonA | 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. |
| check_accessibilityA | 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. |
| get_seo_metaA | 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). |
| set_seo_metaA | 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. |
| seo_site_checkA | 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. |
| check_linksA | Find broken links and images in rendered content: 4xx/5xx and network failures, redirect chains, http:// links on an https site (mixed content), and internal links to draft, trashed or missing content. Scans given ids, a content type, or one front-end URL. Internal links only by default; external checks are opt-in and never reach private or loopback addresses. Checks run with bounded concurrency and are capped per call — follow next_cursor for the rest (each checked link costs 1–2 outbound requests, which matters on Cloudflare Workers). |
| internal_link_reportA | Build the internal link graph across published content and report orphans (nothing links to them), dead ends (they link to nothing), links pointing at drafts/private/trashed items, and link suggestions: related pairs (shared categories/tags and title keywords) with no link between them. Read-only — suggestions only; add links with update_content. Based on content bodies, so menu, widget and archive links are not counted. |
| content_inventoryA | 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. |
| content_calendarA | 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. |
| fleet_reportA | 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. |
| inspect_pluginA | 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 |
| list_admin_pagesA | 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 |
| admin_pageA | 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. |
| get_plugin_settingsA | 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 |
| update_plugin_settingsA | 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 |
| restore_plugin_settingsA | 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. |
| submit_admin_formA | 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 |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 150 tools
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.
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.
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.
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.