Skip to main content
Glama
README.md
<p align="center">
  <img src="assets/banner.png" alt="claude-wp-mcp — MCP server for WordPress" width="100%">
</p>

# claude-wp-mcp

**MCP server for WordPress** — lets Claude (or any [Model Context Protocol](https://modelcontextprotocol.io) client) read and manage a WordPress site over the built-in WP REST API. No plugin required on the WordPress side.

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Node](https://img.shields.io/badge/node-%3E%3D18-green.svg)](package.json)

Works with **Claude Code**, **Claude Desktop**, and any other MCP-compatible client (Cursor, Cline, Windsurf, etc.).

## Features

- **Posts** — list, get, create, update, delete
- **Pages** — list, get, create, update, delete
- **Taxonomies** — list categories, list tags
- **Media** — list media library items, upload images/files (from a URL or a local path, one or many in a batch)
- **Users** — list users
- **`wp_request` escape hatch** — call any other `/wp-json/...` route (any REST namespace, any method) for things not covered by a dedicated tool
- **`fetch_url`** — fetch any web page (not limited to the configured WordPress site), get back Markdown plus title/description, e.g. to turn another page's content into a WordPress post/page. Respects `robots.txt` and paginates long pages. Sites behind a Cloudflare bot challenge can't be solved by a plain HTTP fetch — `fetch_url` detects that case and errors with guidance to fetch the page via a real browser (e.g. Claude in Chrome) instead
- Works read-only out of the box against any public WordPress site; write operations use a WordPress Application Password (no custom plugin needed)

## Requirements

- Node.js 18+
- A reachable WordPress site with the REST API enabled (default on any WordPress install)
- For write operations: a WordPress user with an [Application Password](https://make.wordpress.org/core/2020/11/05/application-passwords-integration-guide/)

## Installation

```bash
git clone https://github.com/gs4lthung/claude-wp-mcp.git
cd claude-wp-mcp
npm install
```

## Configuration

The server is configured entirely through environment variables:

| Variable | Required | Description |
|---|---|---|
| `WP_BASE_URL` | Yes | Base URL of the WordPress site, e.g. `http://localhost:10004` |
| `WP_USERNAME` | For writes | WordPress username |
| `WP_APP_PASSWORD` | For writes | WordPress [Application Password](https://make.wordpress.org/core/2020/11/05/application-passwords-integration-guide/) (not your login password) |

Generate an application password in **wp-admin → Users → Profile → Application Passwords**.

## Usage

### Claude Code

```bash
claude mcp add claude-wp-mcp -s user \
  -e WP_BASE_URL=http://localhost:10004 \
  -e WP_USERNAME=<user> \
  -e WP_APP_PASSWORD=<app-password> \
  -- node /path/to/claude-wp-mcp/src/index.js
```

Omit `WP_USERNAME` / `WP_APP_PASSWORD` to run read-only. Verify it's connected with `claude mcp list`.

### Claude Desktop

Add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "claude-wp-mcp": {
      "command": "node",
      "args": ["/path/to/claude-wp-mcp/src/index.js"],
      "env": {
        "WP_BASE_URL": "http://localhost:10004",
        "WP_USERNAME": "<user>",
        "WP_APP_PASSWORD": "<app-password>"
      }
    }
  }
}
```

### Any other MCP client

Point it at `node src/index.js` (stdio transport) with the environment variables above.

## Tools reference

| Tool | Auth required | Description |
|---|---|---|
| `wp_site_info` | No | Site name, URL, active REST namespaces — good connection sanity check |
| `wp_list_posts` | No | List posts (search, status, pagination) |
| `wp_get_post` | No | Get a single post by ID |
| `wp_create_post` | Yes | Create a post |
| `wp_update_post` | Yes | Update a post |
| `wp_delete_post` | Yes | Delete a post |
| `wp_list_pages` | No | List pages (search, pagination) |
| `wp_get_page` | No | Get a single page by ID |
| `wp_create_page` | Yes | Create a page |
| `wp_update_page` | Yes | Update a page |
| `wp_delete_page` | Yes | Delete a page |
| `wp_list_categories` | No | List categories |
| `wp_list_tags` | No | List tags |
| `wp_list_media` | No | List media library items |
| `wp_upload_media` | Yes | Upload one or more files (images etc.) from a URL or local path to the media library |
| `wp_list_users` | No (limited fields without auth) | List users |
| `wp_request` | Depends on route | Call any other WP REST API route directly |
| `fetch_url` | No | Fetch any web page and return its title, description, and content as Markdown (respects robots.txt, paginated; errors with guidance instead of a raw 403 if the page is behind a Cloudflare bot challenge) |

## Security notes

- Use an **Application Password**, never your real WordPress login password.
- Application Passwords can be scoped to a single site and revoked independently from **wp-admin → Users → Profile**.
- This server talks directly to the REST API you configure — don't point it at a production site with a write-capable password unless you mean to.

## License

[MIT](LICENSE)

TDQS

B3.4/5.0

Scored across 17 tools

Disambiguation5/5

Each tool maps clearly to a distinct WordPress resource and action: full CRUD for posts and pages, read-only lists for categories/tags/media/users, plus site info, URL fetching, and an explicit REST escape hatch. The list/get/create/update/delete variants are not ambiguous because the target resource is always named.

Naming Consistency4/5

The wp_ prefix and list/get/create/update/delete verb_noun pattern are highly consistent for the main post and page tools. Minor deviations like wp_site_info, fetch_url, and wp_request break the pattern slightly, but they are still readable and predictable overall.

Tool Count4/5

At 17 tools, the server is slightly above the ideal 3-15 range, but the count is justified by parallel CRUD surfaces for posts and pages plus supporting resource lookups. No tool feels redundant, though the set is a bit heavy for casual use.

Completeness4/5

Posts and pages have complete CRUD/lifecycle coverage, and categories/tags/media/users provide the read-side needed for content authoring. There are minor gaps around dedicated create/update/delete tools for taxonomies, media, and users, plus comments/settings, but the wp_request escape hatch covers any remaining WP REST API route.

Maintenance

ActivityMaintained
ResponsivenessNo issues