# wordpress-mcp [Health: Active]

**Category:** 💰 Finance & Fintech  
**Repository:** https://github.com/cvrt-jh/wordpress-mcp  
**GitHub Stars:** 3  
**npm Downloads (last month):** 3476  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/wordpress-mcp

## Description
Lightweight WordPress MCP server - 42 tools, token-optimized (95% smaller responses)

## Tools
Capabilities this server exposes over MCP:

- **list_sites** — List the WordPress sites this server can manage. Every other tool requires a `site` argument set to one of these ids.
- **wp_site_info** — Get WordPress site information (name, description, URL, timezone)
- **wp_get_settings** — Get the WordPress settings exposed by wp/v2/settings (title, tagline, url, email, timezone, date/time format, language, reading and discussion settings, site logo/icon, plus plugin-registered ones)
- **wp_update_settings** — Update WordPress site settings (only the given fields change); returns all settings afterwards
- **wp_get_namespaces** — List available REST API namespaces (plugins may add custom endpoints)
- **wp_list_posts** — List WordPress posts with optional filters
- **wp_get_post** — Get a single post by ID (content, when requested, is the raw stored markup)
- **wp_create_post** — Create a new WordPress post
- **wp_update_post** — Update an existing post (only the given fields change)
- **wp_delete_post** — Delete a post (moves to trash, or permanently if force=true)
- **wp_search_posts** — Search posts by keyword (shortcut; wp_list_posts has every filter)
- **wp_list_pages** — List WordPress pages
- **wp_get_page** — Get a single page by ID (content, when requested, is the raw stored markup)
- **wp_create_page** — Create a new WordPress page
- **wp_update_page** — Update an existing page (only the given fields change)
- **wp_delete_page** — Delete a page (moves to trash, or permanently if force=true)
- **wp_list_users** — List WordPress users
- **wp_me** — Get the currently authenticated user
- **wp_get_user** — Get a user by ID
- **wp_create_user** — Create a new WordPress user
- **wp_update_user** — Update an existing user (only the given fields change)
- **wp_delete_user** — Delete a user permanently, reassigning their content to another user
- **wp_list_plugins** — List all installed plugins
- **wp_get_plugin** — Get plugin details by slug
- **wp_activate_plugin** — Activate an installed plugin (via cvrt-mcp-endpoints, avoids the often-blocked core route)
- **wp_deactivate_plugin** — Deactivate an installed plugin (via cvrt-mcp-endpoints)
- **wp_delete_plugin** — Delete an installed plugin (via cvrt-mcp-endpoints; deactivates first)
- **wp_list_themes** — List all installed themes
- **wp_get_active_theme** — Get the currently active theme
- **wp_get_theme** — Get theme details by stylesheet name
- **wp_activate_theme** — Activate a theme (switch themes)
- **wp_list_media** — List media library items
- **wp_get_media** — Get a media item by ID
- **wp_update_media** — Update media item metadata (title, alt text, caption, description, attachment, ...); only the given fields change
- **wp_delete_media** — Delete a media item and its files
- **wp_list_categories** — List categories
- **wp_create_category** — Create a new category
- **wp_update_category** — Update a category (only the given fields change)
- **wp_delete_category** — Delete a category permanently (its posts fall back to the default category)
- **wp_list_tags** — List tags
- **wp_create_tag** — Create a new tag
- **wp_update_tag** — Update a tag (only the given fields change)
- **wp_delete_tag** — Delete a tag permanently
- **wp_list_comments** — List comments
- **wp_get_comment** — Get a comment by ID
- **wp_create_comment** — Create a comment on a post (or a block note with type=note)
- **wp_update_comment** — Update a comment (approve, edit content, move, ...); only the given fields change
- **wp_delete_comment** — Delete a comment (moves to trash, or permanently if force=true)
- **wp_moderate_comments** — Batch moderate comments by status
- **mcp_search_plugins** — Search the WordPress.org plugin repository. Returns { total, plugins: [{ name, slug, version, author, rating, active_installs, description }] }.
- **mcp_install_plugin** — Install a plugin from WordPress.org by slug. If activation fails the plugin stays installed and activation_error says why.
- **mcp_update_plugin** — Update a single plugin to the latest version. refresh:true first runs a fresh update check for it (wp.org and Plugin Update Checker / GitHub releases), so a just-released update is seen without waiting 12 h. A plugin that was active before is reactivated after the file swap (reactivated / reactivate_error report it). updated:false means already up to date; a failed download or unpack is an error (502, cvrt-mcp-endpoints 1.16.0+). cvrt-mcp-endpoints itself is refused (409): update it via mcp_install_plugin_zip or wp-admin.
- **mcp_check_plugin_updates** — Check for plugin updates now: runs every Plugin Update Checker instance (GitHub-released plugins such as the cvrt-* and wp-woo-pdf-builder; their own check otherwise runs every 12 h) and a fresh wp.org check. plugin limits the PUC run to one plugin. Returns puc_checked (slugs) and updates [{plugin, name, current, new_version, source: puc|wporg}]. Audit-logged. cvrt-mcp-endpoints 1.16.0+.
- **mcp_update_all_plugins** — Update all plugins with available updates. cvrt-mcp-endpoints itself is never bulk-updated and is listed under skipped.
- **mcp_install_plugin_zip** — Install a plugin from a ZIP URL (GitHub releases, custom sources). The URL must end in .zip or be a github.com / api.github.com release asset URL (private repo assets supported with a token).
- **mcp_search_themes** — Search the WordPress.org theme repository. Returns { total, themes: [{ name, slug, version, author, rating, description }] }.
- **mcp_install_theme** — Install a theme from WordPress.org by slug
- **mcp_update_theme** — Update a single theme to latest version
- **mcp_update_all_themes** — Update all themes with available updates
- **mcp_delete_theme** — Delete an inactive theme (the active theme is refused)
- **mcp_install_theme_zip** — Install a theme from a public ZIP URL (must end in .zip). Unlike mcp_install_plugin_zip there is no GitHub token support: private release assets cannot be installed this way.
- **mcp_get_version** — Get WordPress version and update status
- **mcp_get_system_info** — Get comprehensive system information
- **mcp_check_updates** — Force a check for WordPress core, plugin, and theme updates. Returns { core: new core version or null, plugins: count, themes: count }.
- **mcp_update_core** — Update WordPress to the latest version. Returns { updated: false, message } when already up to date.
- **mcp_flush_rewrite** — Flush permalink rewrite rules
- **mcp_flush_cache** — Flush the WordPress object cache and delete all transients and site transients. Does NOT purge a page cache in front of WordPress (Bearfort forts: the nginx page cache is purged by bearfort-cache.php on content changes; a manual purge goes through the Bearfort API, not this tool).
- **mcp_get_tables** — List the site's database tables (current table prefix only) with data/index size in MB and approximate row count, largest first
- **mcp_search_replace** — Search and replace a string in every text column of the site's tables (current table prefix only). Plain SQL REPLACE: it is NOT serialization-safe, so a replacement of different length corrupts serialized PHP values (options, postmeta, widgets). Both strings pass through sanitize_text_field on the server (tags and line breaks are stripped). total_changes and tables count matching rows per column, not occurrences.
- **mcp_optimize_tables** — Run OPTIMIZE TABLE on every table with the site's table prefix
- **mcp_clean_revisions** — Delete old post revisions, keeping the newest `keep` per post
- **mcp_clean_comments** — Permanently delete all spam and trashed comments
- **mcp_list_options** — List WordPress options (name ascending) with an optional name prefix filter. Secret-looking values are returned as "[masked]". Note: autoload is only true for legacy 'yes' rows (WP 6.6+ stores 'on'/'auto', reported as false).
- **mcp_get_option** — Get a single option value. Secret-looking values are returned as "[masked]". masked: true says the value (or part of it) was hidden.
- **mcp_set_option** — Create or update an option (any option, no allow-list: be careful with siteurl, home, active_plugins etc.). A value containing "[masked]" is refused, since writing back a masked read would destroy the stored secret. The echoed value is masked like reads. Note: created is always false (cvrt-mcp-endpoints 1.14.2 checks it after writing).
- **mcp_delete_option** — Delete an option (404 if it does not exist)
- **mcp_bulk_get_options** — Get multiple options at once. A missing option comes back as false. Secret-looking values are returned as "[masked]".
- **mcp_list_menus** — List all navigation menus (id, name, slug, item count, assigned locations)
- **mcp_get_menu_locations** — Get registered menu locations and the menu assigned to each
- **mcp_get_menu** — Get a menu with all its items. Each item has id, title, url, type, object, object_id, parent, position, target, classes, xfn, attr_title, description, status.
- **mcp_create_menu** — Create a new navigation menu
- **mcp_delete_menu** — Delete a navigation menu
- **mcp_add_menu_item** — Add an item to a menu. A custom link needs url; a page/post or term item needs object_type post_type/taxonomy plus object and object_id of an existing object. Only the given fields are sent; the plugin defaults the rest (object_type custom, parent 0, appended at the end). target, classes, xfn, attr_title, description and status are set afterwards with mcp_update_menu_item.
- **mcp_delete_menu_item** — Delete a menu item. Its children move up to its own parent; the response lists them as reparented.
- **mcp_update_menu** — Rename a navigation menu (the menu's description and parent are kept)
- **mcp_update_menu_item** — Partially update a menu item: only the given fields are sent and changed, every other stored field (type, linked object, url, ...) is kept (cvrt-mcp-endpoints 1.14.2+). The linked object (type/object/object_id) cannot be changed here: delete the item and add a new one. The response lists the changed fields.
- **mcp_assign_menu_location** — Assign a menu to a registered theme location (see mcp_get_menu_locations); menu_id 0 unassigns
- **mcp_list_sidebars** — List all registered sidebars
- **mcp_get_sidebar_widgets** — Get all widgets in a sidebar
- **mcp_list_widget_types** — List all available widget types
- **mcp_get_widget** — Get a widget's details
- **mcp_add_widget** — Add a widget to a sidebar
- **mcp_update_widget** — Update a widget's settings. The given keys are merged into the stored settings; keys not given are kept.
- **mcp_delete_widget** — Remove a widget from its sidebar
- **mcp_reorder_widgets** — Set the widget order of a sidebar. Pass the COMPLETE list: widgets of the sidebar left out are removed from it (their settings stay, but they end up in no sidebar, not even Inactive Widgets).
- **mcp_move_widget** — Move a widget to a different sidebar
- **mcp_get_health** — Get a quick site health status and score (100 minus 20 per issue: WP_DEBUG on, no HTTPS, pending updates)
- **mcp_get_debug_info** — Get debug information: WordPress settings, server, database (name, prefix, charset), paths and debug constants
- **mcp_get_php_info** — Get PHP configuration details
- **mcp_get_plugins_health** — Get plugin health status and available updates
- **mcp_get_cron_status** — Get WordPress cron status: schedules and the next 50 events (total_events counts all)
- **mcp_run_cron** — Run the earliest scheduled event of a cron hook now, like `wp cron event run`: a recurring event moves to its next slot, a single event is unscheduled, then the hook fires (404 if not scheduled). Returns next_run_timestamp (null for a single event). Audit-logged. cvrt-mcp-endpoints 1.16.0+; older versions leave the event due.
- **mcp_get_action_scheduler** — Action Scheduler queue (WooCommerce emails, webhooks, PDF jobs): counts per status, past_due pending actions and the 10 most recent failures with their last log message (secret-masked). available:false when Action Scheduler is not loaded. cvrt-mcp-endpoints 1.16.0+.
- **mcp_run_action_scheduler** — Run due (past-due pending) Action Scheduler actions now through Action Scheduler's own runner, oldest first. Optional hook/group filters. Returns processed, failed, remaining. 501 when Action Scheduler is not active. Audit-logged. cvrt-mcp-endpoints 1.16.0+.
- **mcp_scan_uploads** — Scan the uploads directory for executable files (.php, .phtml, .phar, .pht, .phps, .shtml, .cgi, also double extensions like x.php.jpg). Read-only; symlinks are not followed. Each finding has path, size, modified, sha256, benign and reason (a code-free 'Silence is golden' index.php, or a known plugin file such as a Borlabs Cookie compatibility patch, checked by active plugin + path + the file's own guard; cvrt-mcp-endpoints 1.16.1+). Caps: 500 findings, 200000 files (truncated says so). cvrt-mcp-endpoints 1.16.0+.
- **mcp_get_audit_log** — Audit trail of state-changing MCP calls on this site (cron runs, Action Scheduler runs, update checks), newest first: time, action, user, context (secret-masked). The site keeps the newest 200. cvrt-mcp-endpoints 1.16.0+.
- **mcp_list_post_types** — List all public post types (name, labels, hierarchical, has_archive, rest_base, supports, taxonomies, published count)
- **mcp_get_post_type** — Get detailed schema for a post type (supports, taxonomies, counts per status, labels)
- **mcp_list_cpt_posts** — List posts of any post type (id, title, slug, status, date, modified, author, excerpt, parent) with paging totals
- **mcp_create_cpt_post** — Create a post of any post type. Meta keys are run through sanitize_key (lowercase a-z0-9_-).
- **mcp_update_cpt_post** — Update a post of any post type. Only the given fields change; meta keys are merged (update_post_meta per key).
- **mcp_delete_cpt_post** — Delete a post of any post type (moves to trash unless force is true)
- **mcp_list_taxonomies** — List all public taxonomies (name, labels, hierarchical, post_types, rest_base, term count)
- **mcp_get_taxonomy** — Get taxonomy details (labels, description, hierarchical, post_types, term count)
- **mcp_list_terms** — List terms for any taxonomy (categories, tags, custom taxonomies): id, name, slug, description, parent, count
- **mcp_create_term** — Create a term in any taxonomy
- **mcp_update_term** — Update a term in any taxonomy. Only the given fields change.
- **mcp_delete_term** — Delete a term from any taxonomy (permanent; terms have no trash)
- **mcp_assign_terms** — Assign taxonomy terms to a post. Terms can be IDs, slugs or names; slugs/names that match no term are skipped silently.
- **mcp_list_users** — List WordPress users (id, username, email, display_name, first_name, last_name, roles, registered) with role/search filters. Returns { users, total, page }.
- **mcp_get_user** — Get user details by ID (profile fields, roles, capabilities, registered, posts_count)
- **mcp_create_user** — Create a new WordPress user. Returns { id, username, created }; the password is never echoed.
- **mcp_update_user** — Update an existing user. Only the given fields change. Use mcp_change_user_role for the role.
- **mcp_delete_user** — Delete a user. WITHOUT reassign, all of the user's posts and links are deleted too. The current API user cannot delete itself.
- **mcp_list_roles** — List all available WordPress user roles (slug, name, capabilities, user count)
- **mcp_change_user_role** — Change a user's role (replaces all current roles)
- **mcp_get_user_meta** — Get all meta data for a user (keys starting with _ are hidden; single values are flattened)
- **mcp_update_user_meta** — Set meta data for a user (merged per key; keys are run through sanitize_key, so lowercase a-z0-9_-)
- **mcp_list_media** — List media library items (id, title, url, mime_type, date; images also alt, width, height) with paging totals
- **mcp_get_media** — Get detailed media item info (caption, description, filename, filesize, image sizes, attached_to)
- **mcp_sideload_media** — Upload media to WordPress from a public external URL (private/internal hosts are refused)
- **mcp_update_media** — Update media item metadata (title, alt text, caption, description). Only the given fields change.
- **mcp_delete_media** — Delete a media item and its files
- **mcp_bulk_delete_media** — Delete multiple media items at once. Returns the deleted and failed IDs.
- **mcp_regenerate_thumbnails** — Regenerate image thumbnails for a media item (images only)
- **mcp_get_media_stats** — Get media library statistics (counts by MIME type, total size, upload path/url, max upload size)
- **mcp_get_elementor_build** — Get full Elementor page build (containers, widgets, settings tree) with element and widget counts
- **mcp_get_elementor_flat** — Get flat list of all Elementor elements on a page (id, elType, widgetType, parent_id, depth, settings); easier to search/filter than the tree
- **mcp_get_elementor_element** — Get a single Elementor element with full settings, its parent id and child ids
- **mcp_update_elementor_element** — Update settings on a single Elementor element (merge by default). With widget_type, replaces the widget in place (same id, position and parent), e.g. turn a V4 placeholder into a V3 html widget; the type must be registered with Elementor. Give settings, widget_type, or both.
- **mcp_get_elementor_page_settings** — Get Elementor page-level settings (hide title, custom CSS, etc.). Fails if the post is not built with Elementor.
- **mcp_update_elementor_page_settings** — Update Elementor page-level settings. Top-level keys are merged into the stored settings (a nested value replaces the old one whole); returns the merged settings.
- **mcp_list_elementor_templates** — List Elementor library templates (headers, footers, singles, loop items, popups) with theme builder conditions; at most 100, ordered by title
- **mcp_get_elementor_conditions** — Get theme builder display conditions for an Elementor template (Elementor Pro)
- **mcp_get_elementor_kit** — Get Elementor global kit settings (colors, fonts, typography, spacing, button defaults)
- **mcp_update_elementor_kit** — Update Elementor global kit settings (colors, fonts, typography). Top-level keys are merged; a nested value such as system_colors replaces the old one whole, so send the complete list. Returns the merged settings.
- **mcp_search_elementor** — Search published Elementor-built posts for widgets, settings, or text in string setting values (case-insensitive)
- **acf_list_field_groups** — List all ACF field groups with their fields (key, name, label, type)
- **acf_get_field_group** — Get ACF field group with full field configuration
- **acf_create_field_group** — Create an ACF field group with fields (active, shown in REST, labels on top)
- **acf_update_field_group** — Update an existing ACF field group. Only the given group settings change. The endpoint re-imports the whole group through acf_import_field_group, which deletes stored fields whose key is not in the imported list, so pass the COMPLETE fields list (fields without a key get field_ + md5(group key + name), matching ones made by acf_create_field_group).
- **acf_delete_field_group** — Delete an ACF field group and its fields (stored post values are kept)
- **acf_export_field_group** — Export a field group in ACF JSON format (for import/backup)
- **acf_import_field_groups** — Import ACF field groups from JSON export format (each needs key, title and fields). The endpoint does not look up an existing group by key, so importing a key that already exists can create a duplicate; use acf_update_field_group for existing groups.
- **acf_get_post_fields** — Get all ACF field values for a post (name => { value, type, label })
- **acf_update_post_fields** — Update multiple ACF field values for a post (field names are run through sanitize_key, so use lowercase names or field keys)
- **acf_get_post_field** — Get a single ACF field value for a post
- **acf_update_post_field** — Update a single ACF field value for a post (updated is false when the value did not change)
- **woo_list_products** — List WooCommerce products (slim: id, name, slug, type, status, sku, prices, stock, category ids)
- **woo_get_product** — Get WooCommerce product details (descriptions, stock, tags, images, attributes, dates)
- **woo_create_product** — Create a WooCommerce product
- **woo_update_product** — Update a WooCommerce product; only the given fields change (type, images and attributes cannot be changed here)
- **woo_delete_product** — Delete a WooCommerce product (to trash unless force)
- **woo_list_variations** — List the available (purchasable, visible) variations of a variable product
- **woo_create_variation** — Create a variation of a variable product. Note: wp-pilot-pro 1.1.0 declares `attributes` as a list and rejects this map with 400 until the plugin declares it as an object
- **woo_update_variation** — Update a product variation; only the given fields change
- **woo_delete_variation** — Delete a product variation permanently
- **woo_list_attributes** — List global product attributes
- **woo_list_attribute_terms** — List terms of a global attribute (including empty ones)
- **woo_create_attribute** — Create a global product attribute (taxonomy pa_{slug})
- **woo_create_attribute_term** — Create a term for a global attribute
- **woo_list_categories** — List product categories
- **woo_create_category** — Create a product category
- **woo_update_category** — Update a product category; only the given fields change
- **woo_delete_category** — Delete a product category
- **woo_list_tags** — List product tags (including empty ones)
- **woo_list_orders** — List WooCommerce orders (slim)
- **woo_get_order** — Get WooCommerce order details (payment, billing, shipping, line items, totals)
- **woo_update_order_status** — Update order status (triggers the usual WooCommerce status emails)
- **woo_add_order_note** — Add a note to an order
- **woo_get_order_notes** — Get order notes
- **woo_list_customers** — List WooCommerce customers (users with the given role)
- **woo_get_customer** — Get customer details (incl. billing and shipping address)
- **woo_create_customer** — Create a customer
- **woo_update_customer** — Update a customer; only the given fields (and address keys) change
- **woo_get_customer_orders** — Get a customer's latest 20 orders plus total spent and order count
- **woo_list_coupons** — List published WooCommerce coupons
- **woo_get_coupon** — Get coupon details
- **woo_create_coupon** — Create a coupon
- **woo_update_coupon** — Update a coupon; only the given fields change
- **woo_delete_coupon** — Delete a coupon permanently
- **woo_sales_report** — Get sales report (completed + processing orders)
- **woo_top_sellers** — Get top selling products by quantity (completed + processing orders)
- **woo_stock_report** — Get stock status report (stock-managed products, lowest stock first)
- **woo_get_product_meta** — Get all product meta data plus _regular_price, _sale_price, _price, _stock, _stock_status, _sku
- **woo_update_product_meta** — Update product meta data (merged; _regular_price, _sale_price, _stock, _stock_status, _sku go through the product setters)
- **woo_bulk_update_stock** — Bulk update product stock; per product only the given fields change
- **fulfillment_get_settings** — Get the cvrt-order-fulfillment plugin settings. Secret values are returned as { set: boolean }, never raw.
- **fulfillment_update_settings** — Update cvrt-order-fulfillment settings. Only provide the keys you want to change; omitted keys keep their stored value. Secrets are write-only: a blank/omitted secret keeps the stored value (never wipes it), the literal "__clear" deletes it. Returns the settings as fulfillment_get_settings does (secrets as { set }).
- **fulfillment_status** — Pipeline health: which credentials are set, ClickUp list/assignee, when the print agent last polled, and print-queue counts.
- **fulfillment_queue** — Print-queue state: status counts (pending/printing/printed/failed) and the 20 most recent jobs (id, order_id, type, status, attempts, error, created_at, printed_at).
- **fulfillment_reprint_job** — Reset a print job to pending so the agent prints it again. Returns { ok: true }; 404 { ok: false, error } for an unknown job.
- **fulfillment_fulfill_order** — Manually (force) run fulfillment for an order: renders the packing slip, creates the ClickUp task, notifies Slack. Bypasses the idempotency guard, so it can create a duplicate ClickUp task. Audit-logged.
- **fulfillment_update_check** — Force an immediate plugin-update check (bypassing PUC's throttle) and report { available, current, remote, error } (plus throttled: true when answered from the cached check, about once per 30s). Read-only: it installs nothing. Apply an update from wp-admin or with mcp_update_plugin (cvrt-mcp-endpoints); the plugin deliberately has no self-update route.
- **legal_status** — Legal document status for a site: which documents are required, filled and published, plus a single compliant flag. Impressum and Datenschutz are always required; AGB and Widerruf become required when WooCommerce is active.
- **legal_list_documents** — List all legal document types with their required/filled state and linked page.
- **legal_get_document** — Get one legal document including its ordered sections.
- **legal_put_document** — Replace a whole legal document (every section not listed is gone). Sections are ordered; omit slug to derive it from the heading. The linked page's post_content is rewritten at once. The plugin ships no legal prose - it stores and renders what it is given. Returns { saved: true }.
- **legal_render_document** — Render a document to normalized HTML without saving. Useful to preview the heading hierarchy and slug ids before writing.
- **legal_get_page** — Get which page a legal document is linked to: linked, page_id, the page's post status, and ok (linked AND published). A required document only counts as reachable, and legal_status only turns compliant, when ok is true. Requires cvrt-legal 0.4.2+.
- **legal_link_page** — Link a legal document to its WordPress page (post type page only; posts and products are refused). The rendered document is written into the page's post_content at once (mirrored: true, false while the document is empty) and on every later save, so a deactivated plugin still leaves the text on the page. Linking impressum/datenschutz also fills the consent banner's imprint/privacy link if that is still unset (banner_linked). page_id 0 unlinks. Requires cvrt-legal 0.4.2+.
- **legal_add_section** — Append a section to a legal document (creates the document if it is still empty). On a generated document the section is kept across regenerations. Returns { slug }, the resolved slug, which is what shortcodes address.
- **legal_update_section** — Update a section. The slug is never rewritten, so shortcodes already placed on a page keep working when a heading is renamed.
- **legal_delete_section** — Delete a section from a legal document.
- **legal_get_consent** — Get the cookie consent banner configuration: enabled, gtm_id, loader_url, ga4_id, ahrefs_key, ads_id, gtm_services { analytics, marketing }, privacy_page, imprint_page, log_enabled, backdrop. Change it with legal_put_consent.
- **legal_put_consent** — Configure the consent banner and every tracking credential the site uses. Merges: only the keys given change, an omitted key keeps its stored value, an empty string clears an id. Nothing is handed to the browser until the visitor accepts - this plugin owns GTM, GA4, Google Ads and Ahrefs Web Analytics precisely because it owns the gate. Search-engine verification meta tags are NOT here; those belong to cvrt-seo-manager because they fire no request. Returns { saved: true }; read the result back with legal_get_consent.
- **legal_get_theme** — Get the banner theme: preset name, CSS custom property overrides and the rendered CSS.
- **legal_put_theme** — Set the banner theme preset and/or individual CSS custom properties. All or nothing: one invalid name or value rejects the whole request (400, names in data.invalid). Returns { saved: true }.
- **legal_get_settings** — Get cvrt-legal settings. Secret values are returned as { set: boolean }, never raw.
- **legal_consent_log_get** — Get every logged consent decision for one consent_id (the banner's own record of what it asked and what the visitor chose). Requires manage_options. Logging itself stays off until legal_put_consent's log_enabled is set, which should only happen after the Datenschutz document has an 'einwilligungsnachweis' section describing it. Requires cvrt-legal 0.5.0+.
- **legal_consent_log_stats** — Aggregate consent decision counts by action and banner_version over a day range [from, to) (both optional, default the last 30 days including today; at most 366 days). Returns { from, to, rows: [{ action, banner_version, count }] }. Requires manage_options. Logging itself stays off until legal_put_consent's log_enabled is set, which should only happen after the Datenschutz document has an 'einwilligungsnachweis' section describing it. Requires cvrt-legal 0.5.0+.
- **legal_consent_log_export** — Export the raw consent decision log as CSV for a day range (same optional from/to rules as legal_consent_log_stats). Returns { filename, csv }; the csv is the full file text, ready to write out as-is. Requires manage_options. Logging itself stays off until legal_put_consent's log_enabled is set, which should only happen after the Datenschutz document has an 'einwilligungsnachweis' section describing it. Requires cvrt-legal 0.5.0+.
- **legal_update_settings** — Update cvrt-legal settings. github_token (PUC auto-updates on a private repo) is write-only: a blank value keeps the stored one. required_override forces a document required or not ({agb: false}). Returns the settings as legal_get_settings does (secrets as { set }).
- **legal_get_facts** — Get the Impressum fields (company, address, register, VAT id, ...) the generator fills into both Impressum and Datenschutz, plus which required ones are missing. Requires cvrt-legal 0.7.0+.
- **legal_put_facts** — Set Impressum fields. Merges: only the keys given change; an empty string clears a field. An unknown key, a value outside a select field's options or an invalid email is refused (400); a checkbox field stores "ja" or empty. Needs an imported Impressum library (409 otherwise). Regenerates every generated document and returns the new state as legal_get_facts does. Requires cvrt-legal 0.7.0+.
- **legal_get_generator** — Get a generated document's state: active, library loaded, the selection (ticked modules, options, kept custom sections) and the sections it writes. Requires cvrt-legal 0.7.0+.
- **legal_put_generator** — Tick or untick modules and options, then regenerate the document (the Datenschutz tab over the API). Merges into the stored selection; unknown module or option keys are refused (400). Needs the library imported (409), and for datenschutz the required Impressum facts filled (409). Returns the new state as legal_get_generator does. Sections tied to a switch (Einwilligungsnachweis, Barrierefreiheits-Werkzeug) follow that switch and are not ticked here. Requires cvrt-legal 0.7.0+.
- **legal_get_generator_library** — Get the imported text library of a generated document (the texts come from websites/bin/legal-v4/privacy, the plugin ships none). Requires cvrt-legal 0.7.0+.
- **legal_put_generator_library** — Import the text library of a generated document and regenerate it if active. Give the library inline or as library_file, a local .json path (e.g. websites/bin/legal-v4/privacy/library-datenschutz.json). A library using the 'accessibility' flag needs cvrt-legal 0.8.0+ on the site first.
- **legal_restore_generator** — Restore a generated document to how it was before the generator first wrote it, and stop generating it. Requires cvrt-legal 0.7.0+.
- **legal_get_social** — Get the social-media section configurator: networks on offer, which are switched on with their profile URLs, and the rendered preview. Requires cvrt-legal 0.6.0+.
- **legal_put_social** — Switch social networks and set their profile URLs (plain https only), then rewrite the Datenschutz social-media section; with nothing on, the section is removed. NOT a merge: every network missing from networks is switched off, so always send the full set you want on. Needs the modules imported and a Datenschutz document (409 otherwise). Returns the new state as legal_get_social does. Requires cvrt-legal 0.6.0+.
- **legal_get_social_modules** — Get the imported social-media text modules. Requires cvrt-legal 0.6.0+.
- **legal_put_social_modules** — Import the social-media text modules, inline or as modules_file (websites/bin/legal-v4/social-media/library.json). Careful: importing while nothing is ticked removes an existing section; call legal_put_social with the current networks right after. Requires cvrt-legal 0.6.0+.
- **legal_get_accessibility** — Get the self-hosted accessibility tool's settings (enabled, position, colour, tools, statement link) and the tools on offer. Requires cvrt-legal 0.8.0+.
- **legal_put_accessibility** — Configure the self-hosted accessibility tool (replaces the Ally widget; no third-party request, needs no consent). Merges: omitted keys keep their value. Switching enabled rewrites a generated Datenschutz (section Barrierefreiheits-Werkzeug). Returns the stored settings. Requires cvrt-legal 0.8.0+.
- **legal_get_accessibility_report** — Get the markup repair report: totals per rule (fixed / open) and per page what was repaired and what is still open, i.e. what the site's own markup must fix. Each page is recorded at most once a day, newest 100 pages. Requires cvrt-legal 0.9.0+.
- **legal_reset_accessibility_report** — Clear the markup repair report, e.g. after fixing the source, so new page views record afresh. Requires cvrt-legal 0.9.0+.
- **legal_get_shop_withdrawal** — Withdrawal function settings (Widerrufsbutton, § 356a BGB / § 13a FAGG) of cvrt-legal 0.12.1+ on a WooCommerce shop: whether WooCommerce's own withdrawal feature is on, the prescribed labels, single email, item picker, footer link, My Account menu, order actions, which emails carry the link, withdrawal period. 404 when WooCommerce is not active.
- **legal_put_shop_withdrawal** — Change the withdrawal function settings; only the keys given change, an invalid value is a 400 and nothing is written. core_feature switches WooCommerce's own withdrawal feature (409 below WooCommerce 11.1). The two labels are legally prescribed: change them only to the wording the law requires.
- **legal_list_withdrawal_requests** — Withdrawal requests customers submitted through the shop's withdrawal function, newest first.
- **fields_status** — cvrt-fields status: plugin version, definition counts per kind, whether ACF / Elementor / Elementor Pro are active, JSON sync state and JSON read error.
- **fields_get_settings** — Get cvrt-fields settings. The GitHub update token is returned as { set: boolean }, never raw; also the JSON sync path and whether it is writable.
- **fields_update_settings** — Update cvrt-fields settings. github_token is write-only and stored encrypted; a blank or omitted token keeps the stored one. clear_github_token: true deletes it. Returns the settings as fields_get_settings does (token as { set }).
- **fields_list_types** — List the available field types (text, date_picker, image, relationship, ...) with their settings.
- **fields_get_location_values** — Values usable in field-group location rules: post types, page templates, taxonomies, options pages, user forms.
- **fields_get_schema** — Editor form schema of one definition kind (fields and their options). Read it before fields_create_definition / fields_update_definition.
- **fields_list_definitions** — List all definitions of one kind from every source (database, JSON, PHP) with their _source.
- **fields_get_definition** — Get one definition by kind and key.
- **fields_create_definition** — Create a definition (field group, post type, taxonomy or options page). The body is the definition itself; omitted keys take the kind's defaults, and a missing key is generated (group_..., post_type_..., taxonomy_..., ui_options_page_...). Fails with 409 when the key exists, 400 when it does not validate. Returns the stored definition (201).
- **fields_update_definition** — Replace a definition as a whole: omitted keys fall back to the kind's defaults (it is not a merge, so send the full definition from fields_get_definition with your changes). The key always comes from the path; a key in the body is ignored. 404 when it does not exist, 409 cvrt_fields_defined_in_code for a PHP definition, 409 cvrt_fields_json_shadowed when a read-only JSON file still overrides the database copy. Returns the stored definition.
- **fields_delete_definition** — Delete a database definition. Stored field values stay in post/term/user meta and options.
- **fields_sync_definition** — Copy a JSON-sourced definition into the database. Only JSON definitions can be synced.
- **seo_status** — Get cvrt-seo-manager status: { version, configured, dependencies: { php, wordpress } }.
- **seo_get_settings** — Get cvrt-seo-manager settings grouped by section (titles, robots, social, knowledge_graph, schema, verification, indexnow, search_console, advanced, sitemap, breadcrumbs, images, links, local_seo, monitor_404, woocommerce). Secret values are returned as { set: boolean }, never raw.
- **seo_update_settings** — Update cvrt-seo-manager settings (partial: only the keys you send change; unknown keys are ignored). Send keys flat ({ title_separator: '|' }) or grouped ({ titles: { title_separator: '|' } }); keys are the option names without the csm_ prefix. Returns the full settings (GET shape, secrets masked). Groups and keys: titles: title_separator, title_home, desc_home, title_post, desc_post, title_page, desc_page, title_product, desc_product, title_category, title_tag, title_author, title_search, title_404 (templates, tokens like %title% %sep% %sitename%). robots: default_robots (text); booleans noindex_archives, noindex_tags, noindex_author, noindex_search, noindex_paginated, noindex_password_protected, noindex_empty_archives, robots_max_directives. social: default_og_image (attachment ID), default_twitter_card (summary | summary_large_image), social_profiles (object network => URL, e.g. { facebook: 'https://...', twitter: '@handle' }), social_extra_profiles (1.12.0+: extra schema sameAs profile URLs as an array, a JSON array string or one URL per line; only absolute http(s) URLs are kept, duplicates removed), og_home_title, og_home_description, og_home_image (attachment ID). knowledge_graph: kg_type, kg_name, kg_description (multi-line), kg_logo (attachment ID), kg_url. schema: schema_defaults (object post_type => BlogPosting | Article | NewsArticle | WebPage | Product), schema_article_type, software_app (site-wide SoftwareApplication object, same shape as the per-post field). verification: verify_google, verify_bing, verify_pinterest, verify_yandex (public meta tokens). indexnow: indexnow_enabled (bool), indexnow_key (SECRET, write-only; blank keeps the stored key). search_console: gsc_service_account (SECRET, write-only: the service-account JSON key as a string; validated before anything is written; blank keeps it, null clears it), gsc_property, gsc_auto_submit (bool). advanced: robots_txt_extra (multi-line), llms_txt. sitemap: sitemap_post_types, sitemap_taxonomies, html_sitemap_post_types (arrays of slugs), sitemap_exclude_noindex, sitemap_images, sitemap_authors (bools), sitemap_max_per_page (int). breadcrumbs: breadcrumbs_enabled, breadcrumbs_show_home, breadcrumbs_show_post_title (bools), breadcrumbs_separator, breadcrumbs_home_label. images: image_seo_enabled (bool), image_alt_template, image_title_template. links: nofollow_external, external_new_tab, strip_category_base (bools). local_seo: local_business_type, local_address (object), local_phone, local_email, local_hours (array), local_geo ({ latitude, longitude }), local_price_range. monitor_404: 404_monitor_enabled (bool), 404_retention_days, 404_max_rows (ints), 404_exclude_patterns (array of patterns). woocommerce: woo_remove_base_slug, woo_remove_category_base, woo_remove_generator (bools), woo_brand_taxonomy.
- **seo_get_post_seo** — Get the SEO meta for a post (every field, null when unset; plus language and translations when Polylang is active).
- **seo_update_post_seo** — Update the SEO meta for a post (partial: only the fields you give change; null deletes a field). Purges the post's page cache. Returns the post's full SEO meta.
- **seo_delete_post_seo** — Delete (reset) every SEO meta field of a post. Returns { deleted: true }.
- **seo_get_post_analysis** — Run the SEO content analysis for a post: { score, checks }.
- **seo_list_posts_seo** — List SEO meta of published posts, newest ID first: [{ id, title, url, seo, language?, translations? }].
- **seo_bulk_update_posts_seo** — Bulk update SEO meta of up to 100 posts. Each item is { id, ...fields } with the same fields as seo_update_post_seo (null deletes a field, omitted fields are kept). Returns { updated, errors: [{ index, id?, message }] }.
- **seo_get_term_seo** — Get the SEO meta for a taxonomy term: { title, description, robots, og_image, schema } (null when unset).
- **seo_update_term_seo** — Update the SEO meta for a taxonomy term (partial; null deletes a field). Returns the term's full SEO meta.
- **seo_delete_term_seo** — Delete (reset) every SEO meta field of a taxonomy term. Returns { deleted: true }.
- **seo_keyword_check** — Check whether a focus keyword is already used by another post (case-insensitive). Returns { unique, posts: [{ id, title }] }.
- **seo_list_redirects** — List redirects, newest first: { items: [{ id, from_url, to_url, type, is_regex, hits, enabled, created_at, updated_at }], total, pages }.
- **seo_create_redirect** — Create a redirect. Rejects invalid regex, unknown status codes and redirect loops/chains deeper than 5. Returns the redirect.
- **seo_get_redirect** — Get a redirect by id.
- **seo_update_redirect** — Update a redirect (partial: omitted fields keep their stored value). Returns the redirect.
- **seo_delete_redirect** — Delete a redirect by id. Returns { deleted: true }.
- **seo_list_monitor_log** — List the 404 monitor log: { items: [{ id, url, hits, first_seen, last_seen, ... }], total, pages }.
- **seo_clear_monitor_log** — Delete 404 monitor log entries: one entry by id, or every entry last seen within from..to (inclusive dates, either bound optional). With no argument the WHOLE log is cleared. Returns { deleted, success }.
- **seo_create_redirect_from_log** — Create a 301 redirect from a 404 monitor log entry's URL to to_url. Fails with 409 when a redirect from that URL already exists.
- **seo_sitemap_status** — Get sitemap status: { sitemap_url, post_types, taxonomies, total_urls, search_console? }.
- **seo_sitemap_ping** — Submit the sitemap to Google Search Console (needs the search_console settings) and return the status Search Console reports. The old Google/Bing ping URLs are switched off.
- **seo_indexnow_ping** — Submit URLs to IndexNow (one request per URL). Returns [{ url, ok, error? }]; ok means the site dispatched the ping (non-blocking), a failing URL does not stop the others.
- **seo_export_settings** — Export every csm_* option as a flat { csm_name: value } map. Secrets are masked as { set: boolean }.
- **seo_import_settings** — Import settings from a flat { csm_name: value } map (the seo_export_settings shape). Only csm_* keys are written; secrets (csm_indexnow_key, csm_gsc_service_account, csm_github_token) are never imported. Returns the number of options written.
- **seo_export_csv** — Export post SEO meta as a CSV string (post_id, post_title, url, seo_title, seo_description, focus_keywords, seo_score).
- **seo_import_csv** — Import post SEO meta from CSV in the seo_export_csv format (header row, then one row per post with at least 7 columns; export first and edit that). Give the CSV inline (csv) or as a local .csv path (csv_file). It is sent as the raw text/csv request body. Returns { success, errors } row counts.
- **seo_export_redirects** — Export every redirect as a CSV string (source, target, type, is_regex, enabled).
- **seo_import_redirects** — Import redirects from CSV in the seo_export_redirects format (header row source,target,type[,is_regex],enabled; the is_regex column is detected from the header). Give the CSV inline (csv) or as a local .csv path (csv_file). It is sent as the raw text/csv request body.
- **seo_import_migrate** — Migrate from RankMath or Yoast. Default: per-post/term meta and redirects are migrated (WRITES immediately, dry_run is not honoured here) and { posts_migrated, terms_migrated, redirects_migrated, errors } is returned. With settings=true (RankMath only) ONLY the global titles/meta/sitemap/robots settings are ported instead, and dry_run=true reports { written, skipped, dry_run } without writing.
- **fort_backup_create** — Start a backup of the site's whole fort (files + database) on Bearfort now, e.g. before risky changes. Returns { jobId, status }; follow it with fort_job_get. Audit-logged by Bearfort. Needs BEARFORT_API_KEY.
- **fort_backup_list** — List the fort's backup generations on Bearfort (newest first, as the worker reports them). Restore is not available here: use the Bearfort dashboard. Needs BEARFORT_API_KEY.
- **fort_job_get** — Status of a Bearfort job on this fort (backup, restore, migration, ...). with_log:true adds the job's log text. Needs BEARFORT_API_KEY.
- **fort_cache_purge** — Purge the fort's nginx page cache (through Bearfort's cache-purge service, the same request WordPress itself makes on content changes), flush the fort's own object-cache keys and reset OPcache. details says 'Page cache: purged', or 'requested' if the purger had not run yet (it runs every 2 s). Needs BEARFORT_API_KEY and Bearfort fleet 2026-10-08.3+ (before that the page cache was not actually purged).
- **fort_logs_read** — Read the fort's server logs: access (nginx), error (nginx), php (PHP errors) or wp-cron (its systemd journal). Filters run on the worker: lines = last N matching lines (1-2000, default 200), grep = keep lines containing this text (case-insensitive literal, no regex), since = drop lines older than this ISO time with zone (stack-trace lines stay with their entry). A missing log is an error, not an empty answer. Secret URL parameters (token=, key=, pass=, ...) and credential shapes are masked. Needs BEARFORT_API_KEY (Bearfort fleet 2026-10-08.3+ for the filters).
- **woo_helper_status** — cvrt-woo-helper status: plugin version, WooCommerce and Stripe Gateway active/version, whether the CVRT hub is on, GitHub token { set }.
- **woo_helper_get_settings** — cvrt-woo-helper settings (secrets as { set }, never raw).
- **woo_helper_update_settings** — Update cvrt-woo-helper settings. github_token is write-only (blank or omitted keeps the stored one); clear_github_token:true deletes it.
- **woo_helper_get_stripe** — The Stripe express-checkout settings cvrt-woo-helper manages: express checkout on/off, button locations per type and what they mean per page, and whether Stripe.js loads only on the checkout (scripts_checkout_only, so it does not load before consent on product pages).
- **woo_helper_update_stripe** — Change Stripe express checkout through cvrt-woo-helper. Only the keys given change. locations maps a button type (apple_google_pay, link, amazon_pay) to the pages it shows on (product, cart, checkout). 409 when the Stripe Gateway plugin is inactive.
- **woo_helper_stripe_status** — Read-only WooCommerce Stripe Gateway status from cvrt-woo-helper (recursively masked): mode, enabled methods, express checkout and Stripe.js loading per page.
- **woo_helper_get_emails** — WooCommerce email look managed by cvrt-woo-helper 0.2.0+: logo (id, url, warning for unsafe formats), logo width, colours, footer text, product images, certificate link once, plus the environment (WooCommerce version, email template improved/classic/block_editor, PDF builder).
- **woo_helper_update_emails** — Change the WooCommerce email look through cvrt-woo-helper 0.2.0+. Only the keys given change; an invalid value is a 400 naming the field and nothing is written. Returns the settings as woo_helper_get_emails does.
- **woo_helper_send_test_email** — SENDS A REAL EMAIL: a WooCommerce order-email preview to `to`. settings (same keys as woo_helper_update_emails) are applied to this one email only and NOT saved, to try a look before saving it. Rate limited (30 s per user, 10 per hour per site; 429). Needs WooCommerce 9.6+ (409) and cvrt-woo-helper 0.2.0+.
- **woo_helper_get_invoices** — Invoice settings of cvrt-woo-helper 0.4.0+ (sevDesk / Lexware Office): settings, API keys per provider as { set, constant } (never the key), the cached provider lists (contact persons, templates, layouts, ...), whether invoicing is active, and order counts per invoice status.
- **woo_helper_put_invoices** — Change cvrt-woo-helper invoice settings; only the keys given change, an invalid value is a 400 and nothing is written. api_keys is WRITE-ONLY (a blank key keeps the stored one) and is never returned; clear_api_keys deletes keys. dry_run stays on until explicitly switched off: with it off, paid orders create REAL invoices in the live ledger.
- **woo_helper_invoices_test_connection** — Test the invoice provider connection (read-only GETs: company, tax type, small-business status).
- **woo_helper_invoices_refresh** — Reload the provider's lists (contact persons, templates, letter papers, payment methods, units, print layouts, payment conditions) into the settings cache. Read-only at the provider.
- **woo_helper_list_invoice_orders** — Orders by invoice status: done, dry_run, queued, retry or failed.
- **woo_helper_get_invoice_order** — Invoice state of one order: status, invoice number, error, attempts, has_pdf, the dry-run request preview, and credit notes.
- **woo_helper_create_invoice** — DESTRUCTIVE, IRREVERSIBLE: creates a REAL invoice for this order in the live sevDesk/Lexware ledger. An invoice there cannot be deleted, only cancelled with a cancellation invoice. Refused with 409 while dry-run is on. Check woo_helper_get_invoice_order (preview) first. Requires confirm:true.
- **stripe_get_settings** — WooCommerce Stripe Gateway settings, secrets masked, plus the active mode (live/test).
- **stripe_get_account** — The Stripe account behind the gateway: country, default currency, charges/payouts enabled, details submitted, requirements (currently_due, past_due, disabled_reason).
- **stripe_list_webhooks** — Webhook endpoints of the Stripe account: id, url, status, api_version, number of events; configured:true marks the endpoint that delivers to this site's gateway URL.
- **stripe_recreate_webhook** — Recreate this site's Stripe webhook with the gateway's own routine: a new endpoint is created first, then older endpoints for this site's URL are deleted, and the new signing secret is stored on the site (never returned). Use when stripe_list_webhooks shows no enabled configured endpoint. Needs confirm:true; audit-logged.
- **stripe_list_payment_method_configs** — Stripe payment method configurations: per configuration every payment method with available, preference (what was chosen) and value (what is in effect).
- **stripe_set_payment_method** — Turn one payment method of a Stripe payment method configuration on or off (display preference). The method must exist in that configuration (see stripe_list_payment_method_configs). Needs confirm:true; audit-logged.
- **stripe_list_charges** — Recent Stripe charges: id, amount, currency, status, created, paid/refunded, payment method type, outcome, failure code/message, WooCommerce order_id. No customer personal data or card details.
- **stripe_list_refunds** — Recent Stripe refunds: id, amount, currency, status, created, charge, reason, WooCommerce order_id. Read-only; refunds are not created here.
- **woo_gateway_status** — WooCommerce payment gateways for a customer country: id, title, enabled, available (offered at checkout, WooCommerce's own check for an empty cart, so minimum-total gateways show unavailable), plus cvrt-woo-helper's Stripe status (express checkout, where Stripe.js loads) when that plugin is active. cvrt-mcp-endpoints 1.17.0+.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "wordpress-mcp": {
    "command": "npx",
    "args": ["-y","@cavort-it-systems/wordpress-mcp"],
    "env": {
      "WORDPRESS_SITES": ""
    }
  }
}
```

**Requires environment variables:** `WORDPRESS_SITES` — the values above are empty placeholders; fill in real credentials before running (see the repository for what each one is for).

## Documentation

## What wordpress-mcp MCP server does

The wordpress-mcp MCP server exposes WordPress management operations to MCP-compatible AI clients. It can inspect site information and settings, list REST API namespaces, and create, read, update, search, or delete posts and pages. User administration is also covered through tools for listing users, checking the authenticated user, and managing user records.

The server includes plugin and theme inspection. Agents can list plugins, retrieve plugin details, and activate, deactivate, or delete plugins using the plugin file path expected by the server, such as `akismet/akismet.php`. Theme tools list themes, identify the active theme, and retrieve details for a selected theme.

Responses are automatically reduced to essential fields instead of returning the full, verbose WordPress REST payload. The README gives examples of large reductions for post and plugin responses, but the exact response fields depend on the tool.

## How it works

A single process can serve multiple WordPress installations. Each configured site has an ID, URL, username, and password. Call `list_sites` first to discover the available IDs; it returns site IDs and URLs without exposing passwords. Other tools receive the selected site ID as their `site` argument.

Authentication uses WordPress Application Passwords, available in WordPress 5.6 and later. The MCP process sends authenticated requests to the configured WordPress site and returns trimmed results to the client. Plugin activation, deactivation, and deletion use the `mcp/v1` routes provided for those operations.

## Setup and configuration

Install the package globally or run it with `npx`:

```bash
npm install -g @cavort-it-systems/wordpress-mcp
npx @cavort-it-systems/wordpress-mcp
```

Set `WORDPRESS_SITES` to a JSON array containing objects with `id`, `url`, `username`, and `password` properties. The older single-site variables `WORDPRESS_SITE_URL`, `WORDPRESS_USERNAME`, and `WORDPRESS_PASSWORD` are no longer read.

For each WordPress account, create an Application Password under Users → Profile → Application Passwords. The README instructs users to preserve the spaces in the generated password. Claude Desktop can launch the server with an MCP configuration using `npx`; Claude Code can add it with `claude mcp add` and the same environment variable.

## Tools and capabilities

The documented standard tools cover:

- Site information, settings retrieval and updates, and REST namespace discovery
- Post listing, filtering, searching, creation, editing, retrieval, and deletion
- Page listing, creation, editing, retrieval, and deletion
- User listing, current-user lookup, individual lookup, creation, editing, and deletion
- Plugin listing, detail lookup, activation, deactivation, and deletion
- Theme listing, active-theme lookup, and theme detail lookup

The wordpress-mcp MCP server also identifies configured sites without returning stored credentials, which is useful when an agent needs to choose a target before making a request.

## Limitations and notes

Every tool other than `list_sites` requires a configured site ID. Credentials are stored in the `WORDPRESS_SITES` configuration, so access to the MCP process configuration should be restricted appropriately.

Plugin state changes require the relevant `mcp/v1` routes and use a plugin file path rather than a plugin slug. The server is intended for WordPress sites that accept the configured Application Password credentials.

_Full upstream README: https://allmcps.com/mcp/wordpress-mcp/readme_

