WP-MCP

by rnaga

Not rated
GitHub

About

Manage and publish WordPress content directly from your AI assistant — no PHP required. Supports both STDIO and Streamable HTTP for broad client compatibility.

Details

Author
rnaga
Categories
Productivity, Other, Automation

Usage reference for environment variables

The HTTP server loads its configuration from environment variables—typically via a local.envfile, inherited process environment, or settings provided by your hosting platform.

If a variable is omitted, the server falls back to safe defaults (for example CORS defaults to, DNS rebinding protection is disabled, and OAuth metadata is skipped). Set only the values your provider requires.

The Model Context Protocol defines three first-class primitives:tools(callable actions),resources(readable assets exposed by URI), andprompts(templated message sequences).defaultMcpPrimitivesin this package currently ships tool implementations, but the same decorator + registration pattern lets you expose resources and prompts as well. The workflow below covers scaffolding, authoring a class, and wiring it into each transport.

Use the CLI to initialize the TypeScript scaffolding and install dependencies.

The command implemented insrc/cli/local.cli.tsinstalls@rnaga/wp-nodeand@rnaga/wp-mcp, places a startersrc/index.ts, copiestsconfig.json, creates a.gitignore, and addsdev,build, andstartscripts topackage.json.

├── package.json ├── src │ └── index.ts ├── tsconfig.json └── package-lock.json

This subcommand (seesrc/cli/http.cli.ts) runs the WordPress prompts, installs the same dependencies, copies the HTTPsrc/index.tstemplate, and appends the MCP-specific settings to.envor.env.<environment>. After the scaffold finishes you can runnpm run devto boot the Express transport.

Create a file such assrc/mcp/example-suite.mcp.tsand add a class decorated with@mcpand@mcpBind. Each@mcpBindmethod receives the MCP server instance plus runtime metadata so you can register tools, resources, or prompts in one place.

See the](https://manage.auth0.com/)@modelcontextprotocol/typescript-sdkrepository for end-to-end SDK usage and primitive registration examples.

import { z } from "zod"; import { mcp, mcpBind } from "@rnaga/wp-mcp/decorators"; import { Mcps } from "@rnaga/wp-mcp/mcp"; import type  as types from "@rnaga/wp-mcp/types"; @mcp("example_suite", { description: "Example bundle showing tools, resources, and prompts.", }) export class ExampleSuiteMcp { @mcpBind("example_tool", { title: "List Options", description: "Return the WordPress options table as JSON.", capabilities: ["read"], }) example(...args: types.McpBindParameters) { const [server, username, meta] = args; server.registerTool( meta.name, { title: meta.title, description: meta.description, inputSchema: undefined, }, async () => { const wp = await Mcps.getWpContext(username); const options = await wp.utils.crud.options.getAll(); return { content: [ { type: "text", text: JSON.stringify(options, null, 2), }, ], }; } ); return server; } }

- server– theMcpServerinstance from@modelcontextprotocol/sdk/server/mcp.js, which exposesregisterTool,registerResource, andregisterPrompt.
- username– the WordPress identity attached to the session; pass it toMcps.getWpContextto enforce capability checks when you touch WordPress APIs.
- meta– the decorator metadata (name,title,description, capabilities, roles) that you can reuse when you register primitives.

Mcps.getWpContextyields the hydrated@rnaga/wp-nodecontext. Use it inside tools, resources, or prompts to call CRUD helpers, gather site metadata, or enforce additional logic before returning MCP responses.

@rnaga/wp-mcpis a Model Context Protocol (MCP) server for WordPress that turns your site into an AI-operable surface. By exposing WordPress CRUD primitives to clients like Claude Desktop, an assistant can draft a post on demand, refine it collaboratively, and publish it straight into your database—no trip through wp-admin required.

Here are a few common scenarios this unlocks:

- Draft, revise, and publish posts directly from MCP clients such as Claude Desktop.
- Inspect WordPress users, their roles, and capabilities to audit site permissions or generate access reports.

Built on top of@rnaga/wp-node, the server ships with a curated MCP toolset covering posts, users, comments, terms, revisions, metadata, options, and site settings. The MCP server can manage the following database tables/resources:

You can spin up aSTDIO serverfor direct database access or host aStreamable HTTP MCP serverfor remote access. For convenience, layer on theCLI proxywhenever your MCP client needs a local bridge to the HTTP server. The proxy behaves like a local MCP server while relaying requests to the HTTP endpoint—perfect for clients that lack OAuth or WordPress Application Password support—so you can fit MCP workflows into existing editorial pipelines without re-implementing WordPress business logic.

The project includes a CLI (wp-mcp) that helps you:

- configure and launch a local STDIO MCP server that connects straight to your WordPress database;
- scaffold and initialize an Express-based Streamable HTTP MCP server (with env/TS boilerplate);
- authenticate against a remote WordPress environment (OAuth or Application Password) and run a JSON-RPC proxy so MCP clients can reach it securely;
- inspect available MCP primitives and manage the credentials stored under~/.wp-mcp.

Run this command to list the available CLI commands:

Usage: <command> <subcommand> [options] Commands: local Local MCP (stdio) server commands utils Utility commands for configuration, debugging, and MCP inspection http Scaffold a TypeScript project for the MCP streamable HTTP server and related tooling. remote Remote MCP server commands

Together, the server, CLI utilities, and proxy tooling let you CRUD WordPress content, manage users, and sync settings through the MCP standard without re-implementing WordPress logic.

Run the STDIO server when you can reach the database directly. The CLI launches an MCP process that assumes a WordPress user locally and exposes your site's tools over STDIO to the MCP client.

flowchart LR client(["MCP Client<br/>(e.g. Claude Desktop)"]) stdio(["Local STDIO MCP Server<br/>(wp-mcp CLI)"]) db(["WordPress Database"]) client <--> stdio stdio <--> db

-

Run the CLI to set up the database connection:

The CLI prompts you forhost,port,database name,user, andpassword. If your database requires SSL, you can provide CA, cert, and key file paths to secure remote access. Runnpx @rnaga/wp-mcp local configanytime to review the saved values.

Configure your MCP client to launch the server. ForClaude Desktop, open Settings → Developer → Edit Config and add this to yourclaude_desktop_config.json:

{ "mcpServers": { "wp-mcp": { "command": "npx", "args": ["-y", "@rnaga/wp-mcp", "--", "local", "start"], "env": { "LOCAL_USERNAME": "wp-admin" } } } }

Activate the server:Save the config file, then quit and restart your MCP client (for example, Claude Desktop). The WordPress tools will now appear in the MCP indicator at the bottom right of the chat input.

This displays a table showing the primitive name, title, description, required capabilities, and allowed roles.

Optional:Provide a WordPress config manifest if your project defines one (e.g.,src/_wp/config/wp.json). SetLOCAL_CONFIGin theenvobject above to the absolute path of your config file. If you don't have a custom config, omit this environment variable entirely. For the configuration manifest schema, seehttps://rnaga.github.io/wp-node/docs/getting-started/configuration.

Use the MCP Inspector for interactive testing and debugging:

npx -y @modelcontextprotocol/inspector npx @rnaga/wp-mcp local start -u wp-admin

This opens a visual interface athttp://localhost:6274where you can explore available tools, test them with different arguments, and inspect server responses.

Note:Inspector persists its "Environment Variables" panel in browser storage across sessions. If you previously added aPATHentry there while troubleshooting, delete it manually in the UI — a stale value can shadow the environment the server actually needs and won't be overridden by CLI flags or script changes.

Usage reference for CLI flags and environment variables:

Use the HTTP server when you need to expose MCP over the Internet or let remote teammates connect. The CLI scaffolds an Express app (seesrc/http/express/index.ts) that exposes both the MCP streaming HTTP transport and the SSE fallback while reusing the same primitive registry.

The wizard prompts for database connection details, creates awp-nodeproject, and seeds Express boilerplate plus TypeScript configuration for the HTTP transport.

├── _wp │ ├── config │ │ ├── index.d.ts │ │ └── wp.json │ └── settings.ts ├── .env ├── .gitignore ├── index.ts ├── package-lock.json ├── package.json ├── src │ └── index.ts └── tsconfig.json

Populate.envwith the values requested by the scaffolder and any HTTP-specific environment variables listed later in this document.

This relies onts-nodeso you can iterate without precompiling.

The compiled output boots the same Express server thatcreateHttpServerwires together in the library.

Use the remote proxy when your MCP client only understands STDIO or lacks full OAuth support but the WordPress environment is available over HTTP. The proxy keeps credentials in~/.wp-mcpand relays MCP requests to the remote server with the right Authorization header.

flowchart LR client(["MCP Client<br/>(e.g. Claude Desktop)"]) proxy(["CLI Proxy<br/>(handles OAuth<br/>or WP Application Password)"]) server(["MCP HTTP Server<br/>(Express instance in this repo)"]) db(["WordPress Database"]) client <--> proxy proxy <--> server server <--> db

Begin by enrolling the proxy with either WordPress Application Password credentials or an OAuth device flow so it can sign requests on behalf of your MCP client.

npx @rnaga/wp-mcp -- remote login password

Provide the authorization URL for your server (for examplehttp://localhost:3000), then enter the WordPress username and application password. The credentials are stored securely so future proxy runs can supply HTTP Basic auth automatically (WordPress Application Passwords are transmitted via the Basic scheme.)

The CLI calls/auth/device/start, prints the user code, and opens the verification URL in your browser. After you complete the device flow, the access and refresh tokens are written to~/.wp-mcp. You can re-runremote configorremote revoke-tokenas needed.

Usenpx @rnaga/wp-mcp -- remote config-clearif you ever need to remove stored secrets.

Configure Claude Desktop (or another MCP client) the same way you do for the local STDIO server, but point the command to the proxy:

{ "mcpServers": { "wp-mcp": { "command": "npx", "args": ["-y", "@rnaga/wp-mcp", "--", "remote", "proxy"], "env": { "REMOTE_AUTH_TYPE": "oauth", "REMOTE_URL": "https://wp-mcp.example.com/mcp" } } } }

Adjust theREMOTE_AUTH_TYPE(oauthorpassword) andREMOTE_URLto match your remote endpoint. You can also pass these at runtime with--authTypeand--remoteUrl. The proxy validates your saved credentials, refreshes OAuth tokens when they are within five minutes of expiry, and then exposes a local STDIO MCP server that delegates every call to the remote HTTP transport.

Once running, your client speaks STDIO locally while the proxy relays traffic to the remote Express server.

The Streamable HTTP deployment bundles Express middleware that bootstraps a WordPress context on each request, registers both the streaming HTTP and SSE transports, and layers in caching plus OAuth metadata handlers. The remote server operates as an OAuth 2.0resource server— clients must supply either a bearer token or a WordPress Application Password, and the server never behaves as an OAuth client itself. Discovery metadata is served from/.well-known/oauth-protected-resource, keeping the implementation aligned with RFC 9728.

The CLI's device-code helper (npx @rnaga/wp-mcp -- remote login oauth) extends the MCP tooling with a terminal-friendly flow. It talks to the server's/auth/device/endpoints, stores the resulting tokens in the secret vault (~/.wp-mcp), and enables the proxy to refresh and attach bearer credentials automatically.

The HTTP layer applies authentication across/mcpand/sseso only authorized callers can negotiate sessions. It supports:

- OAuth Bearer tokens– validated through the configured provider, with access tokens mapped to WordPress users before the MCP session initializes.
- WordPress Application Passwords– accepted over HTTP Basic auth and verified before the WordPress user is assumed server-side.

Failed bearer requests receive RFC 6750-compliantWWW-Authenticateheaders that include the authorization URI and requested scopes so clients can recover gracefully.

The server ships with provider profiles for GitHub, Google, and Auth0. Each profile encapsulates device-code issuance, token polling, refresh, and revocation logic that can be wired in when you instantiate the HTTP server. To use a different identity system, supply your own provider implementation through the same hook and keep the rest of the deployment unchanged.

To enable OAuth authentication, you need to register an application with your chosen provider and configure the credentials in your environment variables.
- Create an OAuth App: Navigate toGitHub Developer Settings> OAuth Apps > "New OAuth App"
- Configure your application:

- Application Name: Your app's display name
- Homepage URL: Your application's homepage
- Authorization Callback URL: Your OAuth callback endpoint

OAUTH_CLIENT_ID=your_github_client_id OAUTH_CLIENT_SECRET=your_github_client_secret

- Access Google Cloud Console: Go toGoogle Cloud Console
- Create OAuth credentials: Navigate to Menu > APIs & Services > Credentials > Create Credentials > OAuth client ID
- Configure OAuth consent screen: Set up app name, user support email, and audience settings
- Select application type: Choose the appropriate type (Web application, Desktop app, etc.)
- Get credentials: Note yourClient IDandClient Secret
- Set environment variables:

OAUTH_CLIENT_ID=your_google_client_id OAUTH_CLIENT_SECRET=your_google_client_secret

- Create application: Register aNative Applicationin yourAuth0 Dashboard
- Configure grant types: In Application Settings > Advanced > Grant Types, enable:

- Device Code(required for device flow)
- Refresh Token(optional, for token refresh)

OAUTH_DOMAIN=your-tenant.us.auth0.com OAUTH_CLIENT_ID=your_auth0_client_id OAUTH_CLIENT_SECRET=your_auth0_client_secret

Usage reference for environment variables

The HTTP server loads its configuration from environment variables—typically via a local.envfile, inherited process environment, or settings provided by your hosting platform.

If a variable is omitted, the server falls back to safe defaults (for example CORS defaults to, DNS rebinding protection is disabled, and OAuth metadata is skipped). Set only the values your provider requires.

The Model Context Protocol defines three first-class primitives:tools(callable actions),resources(readable assets exposed by URI), andprompts(templated message sequences).defaultMcpPrimitivesin this package currently ships tool implementations, but the same decorator + registration pattern lets you expose resources and prompts as well. The workflow below covers scaffolding, authoring a class, and wiring it into each transport.

Use the CLI to initialize the TypeScript scaffolding and install dependencies.

The command implemented insrc/cli/local.cli.tsinstalls@rnaga/wp-nodeand@rnaga/wp-mcp, places a startersrc/index.ts, copiestsconfig.json, creates a.gitignore, and addsdev,build, andstartscripts topackage.json.

├── package.json ├── src │ └── index.ts ├── tsconfig.json └── package-lock.json

This subcommand (seesrc/cli/http.cli.ts) runs the WordPress prompts, installs the same dependencies, copies the HTTPsrc/index.tstemplate, and appends the MCP-specific settings to.envor.env.<environment>. After the scaffold finishes you can runnpm run devto boot the Express transport.

Create a file such assrc/mcp/example-suite.mcp.tsand add a class decorated with@mcpand@mcpBind. Each@mcpBindmethod receives the MCP server instance plus runtime metadata so you can register tools, resources, or prompts in one place.

See the@modelcontextprotocol/typescript-sdkrepository for end-to-end SDK usage and primitive registration examples.

import { z } from "zod"; import { mcp, mcpBind } from "@rnaga/wp-mcp/decorators"; import { Mcps } from "@rnaga/wp-mcp/mcp"; import type * as types from "@rnaga/wp-mcp/types"; @mcp("example_suite", { description: "Example bundle showing tools, resources, and prompts.", }) export class ExampleSuiteMcp { @mcpBind("example_tool", { title: "List Options", description: "Return the WordPress options table as JSON.", capabilities: ["read"], }) example(...args: types.McpBindParameters) { const [server, username, meta] = args; server.registerTool( meta.name, { title: meta.title, description: meta.description, inputSchema: undefined, }, async () => { const wp = await Mcps.getWpContext(username); const options = await wp.utils.crud.options.getAll(); return { content: [ { type: "text", text: JSON.stringify(options, null, 2), }, ], }; } ); return server; } }

- server– theMcpServerinstance from@modelcontextprotocol/sdk/server/mcp.js, which exposesregisterTool,registerResource, andregisterPrompt.
- username– the WordPress identity attached to the session; pass it toMcps.getWpContextto enforce capability checks when you touch WordPress APIs.
- meta– the decorator metadata (name,title,description, capabilities, roles) that you can reuse when you register primitives.

Mcps.getWpContextyields the hydrated@rnaga/wp-nodecontext. Use it inside tools, resources, or prompts to call CRUD helpers, gather site metadata, or enforce additional logic before returning MCP responses.

3. Register the class with the server entry point

Both transports expose anmcpsarray; append your class so the server wires it up when booting. All primitives registered inside the class methods (tools, resources, prompts) become available to connected MCP clients.

import { createLocalServer } from "@rnaga/wp-mcp/cli/local"; import { ExampleSuiteMcp } from "./example-suite.mcp"; (async () => { const mcpServer = await createLocalServer({ username: process.env.LOCAL_USERNAME, mcps: [ExampleSuiteMcp], }); // connect transport... })();
import { MemoryCache } from "@rnaga/wp-mcp/http/cache/memory-cache"; import { createHttpServer } from "@rnaga/wp-mcp/http/express"; import { ExampleSuiteMcp } from "./example-suite.mcp"; const app = createHttpServer({ cacheClass: MemoryCache, mcps: [ExampleSuiteMcp], });

Start the server (npm run devlocally ornpm startafter building) and the registered tools, resources, and prompts appear to any MCP client connected through the local proxy or HTTP transport.

This server is published to theModel Context Protocol Registry, making it easily discoverable and installable by MCP clients.

You can find the server at:https://registry.modelcontextprotocol.io/v0/servers?search=wp-mcp&version=latest

The registry entry includes configuration details, required environment variables, and installation instructions.

Connects Claude to WordPress sites to create posts and manage sites using the WordPress REST API.

A personality-based MCP server for WordPress, providing role-appropriate tools for content management.

A secure bridge between AI assistants and WordPress, enabling site management and content operations through natural language.

The most secure MCP Server for WordPress with built-in Undo

MCP server for WordPress: connect Claude, ChatGPT, Cursor, and other AI clients to manage content, edit themes, run WP-CLI, and automate self-hosted WordPress sites.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.