Skip to main content
Glama

ItchWPMCP

Local MCP server for Codex/Claude to query and edit WordPress content through the WordPress REST API.

It can be used with any WordPress site that has the REST API enabled and supports Application Password authentication.

Setup

  1. Create a WordPress application password: WordPress Admin -> Users -> Profile -> Application Passwords

  2. Copy .env.example to .env and fill in:

    WP_BASE_URL=https://your-wordpress-site.example
    WP_USERNAME=your-wordpress-username
    WP_APP_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxx
    WP_ALLOW_PRODUCTION_WRITES=false
  3. Install dependencies:

    npm install
  4. Run the server:

    npm start

    If Node cannot verify your site's certificate chain, set NODE_OPTIONS=--use-system-ca in your MCP client environment.

Related MCP server: mcp-wordpress

Tools

Pages

  • wordpress_list_pages: list WordPress pages.

  • wordpress_get_page: get a page by ID.

  • wordpress_create_page: create a page, defaulting to draft status.

  • wordpress_clone_page: clone an existing page into a new draft page.

  • wordpress_update_page: update title, content, excerpt, slug, status, parent, or menu order.

  • wordpress_update_page_status: update only a page status.

  • wordpress_delete_page: trash or delete a page with confirmation.

Posts

  • wordpress_list_posts: list WordPress posts.

  • wordpress_get_post: get a post by ID.

  • wordpress_create_post: create a post, defaulting to draft status.

  • wordpress_update_post: update a post.

  • wordpress_delete_post: trash or delete a post with confirmation.

Media

  • wordpress_list_media: list media library items.

  • wordpress_upload_media: upload a local file to the media library.

Taxonomies

  • wordpress_list_categories: list post categories.

  • wordpress_create_category: create a post category.

  • wordpress_list_tags: list post tags.

  • wordpress_create_tag: create a post tag.

Site & Users

  • wordpress_get_settings: read general site settings.

  • wordpress_update_settings: update selected general site settings.

  • wordpress_list_users: list users if the authenticated user has permission.

  • wordpress_list_plugins: list plugins if the authenticated user has permission.

  • wordpress_update_plugin_status: activate or deactivate an installed plugin.

Classic Navigation & Menus

  • wordpress_list_menus: list classic WordPress menus.

  • wordpress_list_menu_items: list menu items for a classic menu.

Sidebars & Widgets

  • wordpress_list_sidebars: list all registered widget areas (header, footer, sidebar, etc.).

  • wordpress_get_sidebar: get a specific widget area and its widget IDs.

  • wordpress_list_widgets: list widget instances with rendered HTML previews.

  • wordpress_create_widget: create a widget instance in a sidebar.

  • wordpress_update_widget: update widget instance settings.

  • wordpress_delete_widget: delete a widget instance with confirmation.

Post & Page Meta

  • wordpress_get_post_meta: read registered REST meta fields for a page or post.

  • wordpress_update_post_meta: update registered REST meta fields for a page or post.

Elementor Page Builder

  • elementor_get_page_structure: read a page's Elementor layout as a readable tree (sections → columns → widgets).

  • elementor_create_page: create a page pre-configured for Elementor editing.

  • elementor_append_sections: append one or more Elementor sections to the end of a page.

  • elementor_replace_section: replace an Elementor section at a specific index.

  • elementor_delete_section: remove an Elementor section at a specific index with confirmation.

  • elementor_update_widget_settings: find a widget by ID and merge new settings into it.

  • elementor_list_templates: list templates saved in the Elementor template library.

  • elementor_get_template: get an Elementor template's content and structure.

  • elementor_apply_template: apply a template to a page, replacing its current content.

  • elementor_save_as_template: save a page's Elementor data as a new reusable template.

  • elementor_widget_reference: return schema and example JSON for any Elementor widget type.

Elementor Meta

  • wordpress_get_elementor_meta: read Elementor-related meta and template fields for a page or post.

  • wordpress_update_elementor_meta: update _elementor_data, _elementor_edit_mode, _elementor_template_type, _elementor_version, _elementor_page_settings, and _wp_page_template.

  • wordpress_update_elementor_data: update only _elementor_data for a page or post.

  • wordpress_list_elementor_routes: list Elementor REST API routes on the configured site.

  • wordpress_elementor_rest_request: advanced REST API escape hatch limited to Elementor namespaces.

FSE Templates (WordPress 7.0)

Full Site Editing templates control the overall layout of page types (single post, archive, 404, etc.).

  • wordpress_list_templates: list FSE block templates on the site.

  • wordpress_get_template: get a template by composite ID (e.g. twentytwentyfour//single) including its block markup.

  • wordpress_create_template: create a new custom FSE block template.

  • wordpress_update_template: update a template's content or title.

  • wordpress_delete_template: delete a custom FSE template with confirmation.

FSE Template Parts (WordPress 7.0)

Template parts are reusable layout regions such as headers and footers.

  • wordpress_list_template_parts: list FSE template parts, optionally filtered by area (header, footer, sidebar).

  • wordpress_get_template_part: get a template part including its block markup.

  • wordpress_update_template_part: update a template part's content, title, or area.

Synced Patterns / Reusable Blocks (WordPress 7.0)

Synced patterns (formerly reusable blocks) are shared block markup used across multiple pages.

  • wordpress_list_reusable_blocks: list synced patterns on the site.

  • wordpress_get_reusable_block: get a synced pattern by ID including its block markup.

  • wordpress_create_reusable_block: create a new synced pattern.

  • wordpress_update_reusable_block: update a synced pattern's content or title.

  • wordpress_delete_reusable_block: delete a synced pattern with confirmation.

Block Pattern Directory (WordPress 7.0)

  • wordpress_list_block_patterns: list block patterns registered on the site, with optional category and search filtering.

  • wordpress_list_block_pattern_categories: list all registered block pattern categories.

Icons (WordPress 7.0)

WordPress 7.0 introduced a server-side SVG Icon Registry and a native Icon block.

  • wordpress_list_icons: list registered SVG icons, with optional search and category filtering.

Font Library (WordPress 7.0)

The Font Library was extended to all theme types in WordPress 7.0.

  • wordpress_list_font_families: list font families installed in the Font Library.

  • wordpress_list_font_faces: list font face variations (weight, style, src) for a specific font family.

Global Styles (WordPress 7.0)

Global styles are the theme.json overrides managed through the Site Editor.

  • wordpress_get_global_styles: get the active theme's global styles (colors, typography, spacing). Pass a stylesheet slug to target a specific theme.

  • wordpress_update_global_styles: update the active theme's global styles by ID.

Block Navigation Menus (WordPress 7.0)

Block navigation menus are FSE navigation posts, distinct from classic WordPress menus.

  • wordpress_list_navigation_menus: list block-based navigation menus.

  • wordpress_create_navigation: create a new block-based navigation menu.

WP AI Connectors & Abilities (WordPress 7.0)

WordPress 7.0 introduced a Connectors API for sharing external service credentials across plugins, and an Abilities API for registering AI tasks.

  • wordpress_list_connectors: list registered external service connectors (AI providers, etc.).

  • wordpress_list_ai_abilities: list registered AI abilities available on this site.

Advanced / Escape Hatches

  • wordpress_rest_request: raw WordPress REST API access for any /wp-json/ path.

  • external_api_fetch: server-side HTTPS proxy for external APIs (CoinGecko, Oracle, etc.).


Write tools are enabled on staging URLs. If WP_BASE_URL is changed to production, writes are blocked unless WP_ALLOW_PRODUCTION_WRITES=true is set in .env.

Elementor Meta Tools

Use wordpress_update_elementor_meta when you need to save Elementor layout data through WordPress REST. Pass elementorData as either a JSON string or a JSON object/array; the tool stores it as _elementor_data.

Example:

{
  "id": 123,
  "postType": "page",
  "elementorEditMode": "builder",
  "elementorTemplateType": "wp-page",
  "elementorVersion": "3.30.0",
  "wpPageTemplate": "elementor_canvas",
  "elementorData": []
}

The available Elementor REST endpoints depend on the target WordPress site and installed Elementor plugins. Use wordpress_list_elementor_routes to inspect what the configured site exposes, then use wordpress_elementor_rest_request for site-specific Elementor endpoints.

If a meta key does not update through wordpress_update_post_meta, the target WordPress site has not registered that key for REST writes. In that case, add a small WordPress helper plugin or mu-plugin to register the specific meta keys with show_in_rest.

Use Another WordPress Site

Create an Application Password in that WordPress site's admin, then update .env:

WP_BASE_URL=https://another-wordpress-site.example
WP_USERNAME=your-wordpress-username
WP_APP_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxx
WP_ALLOW_PRODUCTION_WRITES=false

Keep WP_ALLOW_PRODUCTION_WRITES=false until you intentionally want write tools enabled on a production URL.

Port It For Another Person

  1. Copy this ItchWPMCP folder to their machine or publish it as a private/public repo.

  2. Run npm install inside the folder.

  3. Create a .env file from .env.example.

  4. In their WordPress admin, create an Application Password: Users -> Profile -> Application Passwords

  5. Put their site URL, username, and app password in .env.

  6. Register the MCP server in their MCP client.

Do not commit .env files. Application Passwords should stay local to each user/site.

Codex Config

Add this to ~/.codex/config.toml:

[mcp_servers.itch_wp_mcp]
command = "node"
args = ["<absolute-path-to-ItchWPMCP>/src/server.js"]
enabled = true
startup_timeout_sec = 20
tool_timeout_sec = 60

[mcp_servers.itch_wp_mcp.env]
WP_BASE_URL = "https://your-wordpress-site.example"
WP_USERNAME = "your-wordpress-username"
WP_APP_PASSWORD = "xxxx xxxx xxxx xxxx xxxx xxxx"
WP_ALLOW_PRODUCTION_WRITES = "false"
NODE_OPTIONS = "--use-system-ca"

If your MCP client cannot find node, set command to the absolute path of your Node executable. For example:

command = "<absolute-path-to-node>"

Claude Desktop Config

Add this to Claude Desktop's claude_desktop_config.json under mcpServers:

{
  "mcpServers": {
    "itch_wp_mcp": {
      "command": "node",
      "args": [
        "<absolute-path-to-ItchWPMCP>/src/server.js"
      ],
      "env": {
        "WP_BASE_URL": "https://your-wordpress-site.example",
        "WP_USERNAME": "your-wordpress-username",
        "WP_APP_PASSWORD": "xxxx xxxx xxxx xxxx xxxx xxxx",
        "WP_ALLOW_PRODUCTION_WRITES": "false",
        "NODE_OPTIONS": "--use-system-ca"
      }
    }
  }
}

Restart Claude Desktop after changing the config.

Multi-Site Setup

You do not need a separate copy of ItchWPMCP for every WordPress website. Keep one codebase and register multiple MCP servers, each with different environment variables.

Codex Multi-Site Example

[mcp_servers.wp_site_staging]
command = "node"
args = ["<absolute-path-to-ItchWPMCP>/src/server.js"]
enabled = true
startup_timeout_sec = 20
tool_timeout_sec = 60

[mcp_servers.wp_site_staging.env]
WP_BASE_URL = "https://staging.example.com"
WP_USERNAME = "site-admin"
WP_APP_PASSWORD = "xxxx xxxx xxxx xxxx xxxx xxxx"
WP_ALLOW_PRODUCTION_WRITES = "false"
NODE_OPTIONS = "--use-system-ca"

[mcp_servers.wp_client_site]
command = "node"
args = ["<absolute-path-to-ItchWPMCP>/src/server.js"]
enabled = true
startup_timeout_sec = 20
tool_timeout_sec = 60

[mcp_servers.wp_client_site.env]
WP_BASE_URL = "https://client-site.example"
WP_USERNAME = "client-admin"
WP_APP_PASSWORD = "xxxx xxxx xxxx xxxx xxxx xxxx"
WP_ALLOW_PRODUCTION_WRITES = "false"
NODE_OPTIONS = "--use-system-ca"

Claude Multi-Site Example

{
  "mcpServers": {
    "wp_site_staging": {
      "command": "node",
      "args": ["<absolute-path-to-ItchWPMCP>/src/server.js"],
      "env": {
        "WP_BASE_URL": "https://staging.example.com",
        "WP_USERNAME": "site-admin",
        "WP_APP_PASSWORD": "xxxx xxxx xxxx xxxx xxxx xxxx",
        "WP_ALLOW_PRODUCTION_WRITES": "false",
        "NODE_OPTIONS": "--use-system-ca"
      }
    },
    "wp_client_site": {
      "command": "node",
      "args": ["<absolute-path-to-ItchWPMCP>/src/server.js"],
      "env": {
        "WP_BASE_URL": "https://client-site.example",
        "WP_USERNAME": "client-admin",
        "WP_APP_PASSWORD": "xxxx xxxx xxxx xxxx xxxx xxxx",
        "WP_ALLOW_PRODUCTION_WRITES": "false",
        "NODE_OPTIONS": "--use-system-ca"
      }
    }
  }
}

The .env file is now only a local fallback. Per-site MCP environment variables take precedence when provided by Codex or Claude.

Safety Model

  • New pages/posts default to draft.

  • Destructive tools require confirmDelete=true.

  • Non-staging writes are blocked unless WP_ALLOW_PRODUCTION_WRITES=true.

  • wordpress_rest_request only allows paths under /wp-json/.

Available Tools

26 tools
wordpress_clone_pageB

Clone an existing WordPress page into a new draft page.

Inputs: sourceId (required), title (required), slug.

wordpress_create_categoryC

Create a WordPress post category.

Inputs: name (required), slug, description, parent.

wordpress_create_pageA

Create a WordPress page. Defaults to draft status for safe review before publishing.

Inputs: title (required), content, excerpt, slug, +3 more.

wordpress_create_postB

Create a WordPress post. Defaults to draft status for safe review before publishing.

Inputs: title (required), content, excerpt, slug, +4 more.

wordpress_create_tagC

Create a WordPress post tag.

Inputs: name (required), slug, description.

wordpress_delete_pageC

Delete or trash a WordPress page. Requires confirmDelete=true.

Inputs: id (required), force, confirmDelete.

wordpress_delete_postC

Delete or trash a WordPress post. Requires confirmDelete=true.

Inputs: id (required), force, confirmDelete.

wordpress_get_pageC

Get a WordPress page by ID from the configured site.

Inputs: id (required), context.

wordpress_get_postC

Get a WordPress post by ID from the configured site.

Inputs: id (required), context.

wordpress_get_settingsB

Get general WordPress site settings if the authenticated user has permission.

Inputs: no named parameters.

wordpress_list_categoriesC

List WordPress post categories.

Inputs: search, perPage.

wordpress_list_mediaC

List media library items.

Inputs: search, perPage.

wordpress_list_menu_itemsB

List menu items if the WordPress menu-items REST endpoint is available.

Inputs: menus, perPage.

wordpress_list_menusB

List menus if the WordPress menus REST endpoint is available.

Inputs: no named parameters.

wordpress_list_pagesC

List WordPress pages from the configured site.

Inputs: status, perPage.

wordpress_list_pluginsB

List WordPress plugins if the configured user can access the plugins REST endpoint.

Inputs: no named parameters.

wordpress_list_postsC

List WordPress posts from the configured site.

Inputs: status, perPage.

wordpress_list_tagsC

List WordPress post tags.

Inputs: search, perPage.

wordpress_list_usersC

List WordPress users if the authenticated user has permission.

Inputs: search, perPage.

wordpress_rest_requestB

Advanced escape hatch for WordPress REST API calls. Non-GET requests obey write guards.

Inputs: path (required), method, body, confirmDelete.

wordpress_update_pageB

Update a WordPress page by ID. Only title, content, excerpt, slug, status, parent, and menu order are supported.

Inputs: id (required), title, content, excerpt, +4 more.

wordpress_update_page_statusB

Update only the status for a WordPress page by ID.

Inputs: id (required), status (required).

wordpress_update_plugin_statusA

Activate or deactivate an installed plugin if the authenticated user has permission.

Inputs: plugin (required), status (required).

wordpress_update_postC

Update a WordPress post by ID.

Inputs: id (required), title, content, excerpt, +5 more.

wordpress_update_settingsB

Update general WordPress site settings. Only provided fields are changed.

Inputs: title, description, timezone, dateFormat, +8 more.

wordpress_upload_mediaC

Upload a local file to the WordPress media library.

Inputs: filePath (required), title, altText, caption.

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    B3.1/5.0

    Scored across 26 tools

    Disambiguation5/5

    Each tool targets a distinct WordPress resource and action. There is minimal overlap; even the similar update_page and update_page_status are clearly differentiated by scope.

    Naming Consistency5/5

    All tools follow a consistent wordpress_verb_noun pattern (e.g., wordpress_create_page, wordpress_list_posts). No mixing of conventions or ambiguous verbs.

    Tool Count4/5

    26 tools cover a broad domain including posts, pages, media, menus, plugins, settings, and users. While slightly heavy, each tool serves a clear purpose and the count is justified for comprehensive WordPress management.

    Completeness3/5

    CRUD for posts and pages is well-covered, but categories and tags lack delete/update, menus only support listing, and there is no user management beyond listing. These are notable gaps for a complete site administration surface.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers