WordPress MCP Server

WordPress MCP Server

MCP server that gives AI assistants direct execution access to WordPress for publishing, scheduling, updating posts, featured images, and RankMath SEO meta across multiple client sites.

Category
访问服务器

README

WordPress MCP Server

A Model Context Protocol (MCP) server that gives ClickUp Brain direct execution access to WordPress — publishing, scheduling, and updating posts, setting featured images, and writing RankMath SEO meta — across every Contractor Scale client site, without relaying through Donna.

Runs on Cloudflare Workers, following the same architecture as the sibling MCPs in this fleet (google-ads-mcp-cs, meta-ads-mcp-cs, gsc-mcp-cs): a single-file Worker, dual SSE/streamable-HTTP transport, static API-key auth, in-memory session map.

Why this exists

Brain had the WordPress Connector skill (knowledge of how to structure WP REST calls) but no execution path of its own — every publish/update request had to be delegated to Donna via the Donna MCP, which introduced stale credential-path bugs and premature "blocked on credentials" messages before Donna even attempted execution. This Worker gives Brain the same publish/edit/schedule capability Donna has, in one loop. See OPERATIONS-11119.

Features

  • 8 WordPress tools covering publish/schedule, update, list/query, featured images, RankMath SEO meta, and a raw-request escape hatch (see Available Tools)
  • Supabase-backed multi-tenant credentials — reads wp_credentials per client_slug (54+ client sites), the same table and application-password auth model as contractor-scale/skills/wordpress
  • Dual Transport: SSE (/sse) and Streamable HTTP (/mcp) — ClickUp Brain connects via /mcp
  • Cloudflare Workers: Serverless, global edge network
  • Fail-closed credential resolution: a client with no stored application password errors clearly instead of hanging or silently succeeding

Available Tools

Tool Purpose
wp_list_clients List every client site configured in Supabase wp_credentials (no secrets returned)
wp_list_posts Query posts on a client site by status, search term, or slug
wp_get_post Get a single post by ID (e.g. to confirm a publish/update landed)
wp_publish_post Create a post — status: "draft" | "publish" | "future" (+ date) for scheduling
wp_update_post Update an existing post's content, status, slug, or scheduled date
wp_set_featured_image Fetch an image from a URL, upload it to the site's media library, and assign it as a post's featured image
wp_set_seo_meta Set RankMath SEO title/description/focus keyword on a post. Rejects non-RankMath sites server-side (checks wp_credentials.seo_plugin) before making any WP call; also requires RankMath's show_in_rest enabled for those meta keys on the target site
wp_raw_request Escape hatch for anything not covered above (e.g. DELETE /wp-json/elementor/v1/cache) — logs a warning so recurring use can graduate to a dedicated tool

Every tool except wp_list_clients takes a client argument (the wp_credentials.client_slug).

Getting Started

1. Prerequisites

  • Node.js 18+ and npm
  • A Cloudflare account with Workers enabled
  • Access to the cs-shared Doppler project (for SUPABASE_URL / SUPABASE_SERVICE_ROLE_KEY)

2. Clone and install

git clone https://github.com/isaganiesteron/wordpress-mcp-cs.git
cd wordpress-mcp-cs
npm install

3. Configure local secrets

cp wrangler.jsonc.example wrangler.jsonc
cp .dev.vars.example .dev.vars

Fill in .dev.vars with real values (never commit this file — it's gitignored):

API_KEY=<any local test value>
SUPABASE_URL=<from Doppler cs-shared/dev>
SUPABASE_SECRET_KEY=<Doppler's SUPABASE_SERVICE_ROLE_KEY value>

Pull real values without ever printing them, if Doppler CLI is set up:

doppler run --project cs-shared --config dev -- <write env vars to .dev.vars>

4. Test locally

npm run dev
curl http://localhost:8787/

5. Deploy to Cloudflare Workers

npm run deploy

SUPABASE_URL / SUPABASE_SECRET_KEY are synced automatically to the deployed Worker by the centralized pipeline in the contractor-scale repo (tools/scripts/maintenance/sync-doppler-to-cloudflare-worker.js, TARGETS.wordpress-mcp) on a daily cron + Doppler webhook. API_KEY is never auto-synced (by design, per that script's NEVER_AUTO set — it's a unique per-worker secret) and must be set once manually:

wrangler secret put API_KEY

If you set API_KEY and then the sync script runs wrangler@3 secret bulk for the Supabase keys, re-verify API_KEY still authenticates afterward — during this Worker's initial deploy, that sequence caused API_KEY to briefly stop resolving until it was re-set with wrangler@4. Only seen once; flagged here in case it recurs.

Using with ClickUp Brain

  1. Deploy this Worker (above)
  2. In ClickUp, go to App Center → MCP Servers → Connect an MCP Server
  3. Fill in:
    • Name: WordPress MCP
    • URL: https://wordpress-mcp.isagani.workers.dev/mcp — use /mcp, not /sse. Brain's setup flow does a GET that expects a response to fully complete; /sse holds the connection open indefinitely (that's correct SSE behavior, but it reads as a stuck/hung setup in the UI).
    • Authentication Method: if there's no direct "API Key" option, use Custom Headers with header name X-API-Key and the deployed API_KEY value
  4. Run the smoke test in TEST_PROMPT.md

Project Structure

.
├── src/
│   └── index.ts          # Entire MCP server: config, Supabase/WP helpers, tools, framework code
├── test/
│   └── index.spec.ts     # Vitest (currently the stock starter test — needs real coverage)
├── postman/               # Postman collection (currently the starter's example-tool requests)
├── TEST_PROMPT.md         # WordPress MCP smoke test prompts (for ClickUp Brain or manual curl)
├── wrangler.jsonc.example # Copy to wrangler.jsonc (gitignored)
├── .dev.vars.example      # Copy to .dev.vars (gitignored) — API_KEY, SUPABASE_URL, SUPABASE_SECRET_KEY
├── package.json
├── tsconfig.json
└── README.md

API Endpoints

Health check

  • GET / — server info + available transport endpoints (no API key required)

Streamable HTTP transport (/mcp) — what ClickUp Brain uses

  • POST /mcp — JSON-RPC message. On initialize, the server mints a session ID and returns it in the Mcp-Session-Id response header; subsequent requests must include that header.
  • DELETE /mcp — terminate a session (header shape-validated only, not persisted server-side)

SSE transport (/sse)

  • GET /sse — opens an SSE stream, emits an endpoint event with the session-specific message URL, then keeps the connection open with a 30s keepalive ping
  • POST /sse — direct HTTP fallback (no open stream)
  • POST /sse/message?sessionId={id} — send a JSON-RPC message on an active SSE session

Credential Resolution

Every tool (except wp_list_clients) calls resolveClient(client, env), which:

  1. Queries Supabase wp_credentials for the given client_slug via PostgREST (env.SUPABASE_URL / env.SUPABASE_SECRET_KEY)
  2. Fails closed with a clear error if no row exists, auth_type isn't application_password, or no token is stored
  3. Builds a Basic auth header (btoa(username:token), spaces stripped from the displayed application password) for the site's own /wp-json/... REST API

This mirrors contractor-scale/skills/wordpress/scripts/_wp.js — same table, same auth model, same fail-closed error messages — just reading from Worker secrets instead of process.env, with no local-file fallback (Workers have no filesystem).

Known Risks / Things to Verify Per-Site

  • RankMath meta over REST depends on show_in_rest being registered for rank_math_title/rank_math_description/rank_math_focus_keyword on that specific site. Confirmed working on at least one site in production; not guaranteed across all 54+. (wp_set_seo_meta does enforce seo_plugin === 'rankmath' server-side, but can't verify show_in_rest without attempting the write.)
  • Redirects are out of scope — RankMath/Yoast expose no REST redirect route; that's handled separately by contractor-scale/skills/wordpress/scripts/wp-redirect.js via the Redirection plugin.
  • First request to a given client's live site through a cold Worker isolate can take 10-25s (TLS/DNS through the Workers runtime) — a retry succeeds quickly. Not a bug, just latency to expect on the first call after a deploy.

Troubleshooting

"client 'X' has no token stored" / "auth_type='X'; only supports 'application_password'"

The wp_credentials row for that slug either doesn't have an application password provisioned, or uses a different auth method. Provision one in WordPress: Users → Profile → Application Passwords.

ClickUp Brain's "Connect an MCP Server" spinner never finishes

You're pointed at /sse instead of /mcp. See Using with ClickUp Brain above.

wp_set_seo_meta succeeds (HTTP 200) but the meta doesn't show up in RankMath

That site likely doesn't have show_in_rest enabled for the RankMath meta keys. This is a per-site WordPress/plugin configuration issue, not a bug in this Worker.

Deployment fails

  • wrangler login / confirm the right Cloudflare account (isagani, account ID e9251afb5c2abd46a9504aa5d714aceb) via CLOUDFLARE_ACCOUNT_ID
  • Confirm the worker name in wrangler.jsonc is wordpress-mcp

Resources

License

MIT (scaffolded from isaganiesteron/typingmind-mcp-cloudflare-starter)

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选