WordPress Publishing
MCP tools for publishing content to WordPress via the REST API.
Available Tools
| Tool | Description |
|---|---|
test_wp_connection |
Verify WordPress credentials and fetch site info |
publish_to_wordpress |
Publish a single article |
publish_batch |
Publish multiple articles with rate limiting |
list_wp_categories |
List all WordPress categories |
All tools pull WordPress credentials from your project settings automatically. You can override them inline for one-off publishes to a different site.
test_wp_connection
Verify your WordPress credentials are working and fetch site metadata, categories, and available users.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
project_id |
string | ❌ | Active project | Project to pull credentials from |
wp_url |
string | ❌ | From settings | Override: WordPress site URL |
wp_username |
string | ❌ | From settings | Override: WordPress username |
wp_app_password |
string | ❌ | From settings | Override: Application password |
Response
{
"status": "success",
"site_name": "My Blog",
"site_url": "https://myblog.com",
"categories": [
{ "id": 1, "name": "Uncategorized", "slug": "uncategorized", "count": 12 }
],
"users": [
{ "id": 1, "name": "Admin", "slug": "admin" }
]
}
Error Response
{
"status": "failed",
"error": "Invalid username or application password."
}
publish_to_wordpress
Publish a single article to WordPress. Accepts Markdown or HTML content. The MCP server converts basic Markdown to HTML automatically.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
title |
string | ✅ | — | Post title |
content |
string | ✅ | — | Post content (Markdown or HTML) |
status |
enum | ❌ | draft |
publish, draft, or pending |
slug |
string | ❌ | Auto-generated | Custom URL slug |
category_ids |
number[] | ❌ | — | WordPress category IDs |
tag_ids |
number[] | ❌ | — | WordPress tag IDs |
excerpt |
string | ❌ | — | Post excerpt / meta description |
author_id |
number | ❌ | — | WordPress author ID |
featured_media_id |
number | ❌ | — | Featured image media ID (already uploaded to WP) |
project_id |
string | ❌ | Active project | Project to pull credentials from |
wp_url |
string | ❌ | From settings | Override: WordPress site URL |
wp_username |
string | ❌ | From settings | Override: WordPress username |
wp_app_password |
string | ❌ | From settings | Override: Application password |
Response
{
"status": "success",
"post_id": 1247,
"post_url": "https://myblog.com/how-to-set-up-docker-compose/",
"post_status": "draft"
}
publish_batch
Publish multiple articles sequentially with built-in rate limiting. Each article requires a title and content. Returns per-article results.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
articles |
object[] | ✅ | — | Array of articles (see below) |
delay_seconds |
number | ❌ | 3 |
Seconds between publishes |
project_id |
string | ❌ | Active project | Project to pull credentials from |
wp_url |
string | ❌ | From settings | Override: WordPress site URL |
wp_username |
string | ❌ | From settings | Override: WordPress username |
wp_app_password |
string | ❌ | From settings | Override: Application password |
Article object fields:
| Field | Type | Required | Description |
|---|---|---|---|
title |
string | ✅ | Post title |
content |
string | ✅ | Post content (Markdown or HTML) |
status |
enum | ❌ | publish, draft, or pending |
slug |
string | ❌ | Custom URL slug |
category_ids |
number[] | ❌ | WordPress category IDs |
tag_ids |
number[] | ❌ | WordPress tag IDs |
excerpt |
string | ❌ | Post excerpt / meta description |
Response
{
"status": "success",
"total": 5,
"successful": 5,
"failed": 0,
"results": [
{
"title": "Docker Compose Tutorial",
"status": "success",
"post_id": 1247,
"post_url": "https://myblog.com/docker-compose-tutorial/",
"post_status": "draft"
},
{
"title": "Kubernetes for Beginners",
"status": "success",
"post_id": 1248,
"post_url": "https://myblog.com/kubernetes-guide/",
"post_status": "draft"
}
]
}
Batch status is "success" (all passed), "partial" (some failed), or "failed" (all failed).
list_wp_categories
Fetch all categories from a WordPress site.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
project_id |
string | ❌ | Active project | Project to pull credentials from |
wp_url |
string | ❌ | From settings | Override: WordPress site URL |
wp_username |
string | ❌ | From settings | Override: WordPress username |
wp_app_password |
string | ❌ | From settings | Override: Application password |
Response
{
"status": "success",
"count": 8,
"categories": [
{ "id": 1, "name": "Uncategorized", "slug": "uncategorized", "count": 12, "parent": null },
{ "id": 5, "name": "Tutorials", "slug": "tutorials", "count": 24, "parent": null },
{ "id": 8, "name": "Docker", "slug": "docker", "count": 7, "parent": 5 }
]
}
Architecture
The MCP server communicates with WordPress using direct REST API calls via fetch(). Since the MCP server runs server-side (Node.js), there are no CORS restrictions, so no proxy is needed.
MCP Client → MCP Server → WordPress REST API (/wp-json/wp/v2/*)
The web app uses a Netlify Edge Function proxy (/api/wordpress-proxy) because it runs in the browser. The MCP server skips that layer entirely.
Authentication
All requests use HTTP Basic Authentication with WordPress Application Passwords:
Authorization: Basic base64(username:application_password)
Application Passwords are generated in the WordPress admin panel: Users → Your Profile → Application Passwords
Credential Resolution
Credentials are resolved in this order:
- Inline overrides (
wp_url,wp_username,wp_app_password) — takes priority - Project settings — pulled from the BPAI web dashboard configuration
This means you can configure your WordPress site once in the dashboard and every MCP tool call uses those credentials automatically.