Model Context Protocol
WordPress MCP server (for AI agents)
OAuth sign-in, no API key. One URL, click Authorize, done. Your agent publishes markdown as real Gutenberg posts — images re-hosted, categories and tags by name, SEO fields where your site supports them — and you approve what goes live.
MCP server URL
https://mcp.pressbotics.com/mcpAdd as a custom MCP server. Static pb_live_ keys remain available for custom or self-hosted agents.
Connect your agent
No MCP client offers a one-click install for a third-party server. The real flow is the same everywhere: copy the URL, add it as a custom connector, authorize once.
Pressbotics MCP server URL
https://mcp.pressbotics.com/mcpEvery client works the same way: copy this, then add it as a custom MCP server. There is no installer to click.
Connect Claude
Walked end to end- 1Copy the Pressbotics MCP server URL above.
- 2In Claude, open Settings → Connectors and choose Add custom connector.
- 3Name it Pressbotics, paste the URL, and click Add.
- 4Click Connect — Claude opens Pressbotics in your browser. Sign in and click Authorize.
- 5Back in Claude, start a new chat and ask it to list your sites.
The 20 tools
This is the whole surface. Nothing else is exposed.
| Tool | What it does |
|---|---|
| create_connect_link | Creates a one-time link the site owner opens to connect a WordPress site. |
| get_connect_status | Reports whether a connect link has been completed and which site it produced. |
| list_sites | Lists the connected sites the caller is allowed to publish to. |
| get_site_context | Returns a site's handle, capabilities, categories, tags, brand voice notes and approval policy. |
| site_health | Re-probes a site and reports WordPress version, plugin detection and SEO capability. |
| list_content | Lists and filters existing posts on a site so an agent can find something to update. |
| list_media | Lists attachments already in the site's media library, so an existing image can be reused. |
| create_media_upload | Creates an upload link the person opens to hand over a file the agent cannot forward itself. |
| get_media_upload | Polls an upload until it is ready and returns the media_ref to pass to a publish call. |
| publish_post | Creates a post from markdown and publishes it (or queues it for approval). |
| schedule_post | Same as publish_post, plus a future publish_at timestamp. |
| update_post | Updates an existing post by id with new content, taxonomy, media or SEO fields. |
| get_post_status | Returns the current state of a submitted action, including per-component outcomes. |
| list_scheduled | Lists scheduled posts across the caller's sites with their times and current state. |
| reschedule_post | Moves a scheduled post to a new time, on WordPress as well as in Pressbotics. |
| cancel_scheduled | Cancels a scheduled post before it runs, reverting it to a draft on WordPress. |
| schedule_batch | Schedules several posts in one call — a week of content at a time. |
| create_recurrence | Creates a standing cadence that generates empty scheduled slots. It does not write content. |
| list_recurrences | Lists the cadences on a site, with their pattern, timezone and next slots. |
| cancel_recurrence | Stops a cadence generating further slots. Slots already created remain. |
Publish parameters
Shared by publish_post, schedule_post and update_post. publish_at applies to schedule_post only; post_id to update_post only.
| Parameter | Type | Notes |
|---|---|---|
| site | string | Site handle or URL. Required. |
| title | string | Post title — the on-page headline. Required. |
| markdown | string | Post body in markdown. Converted to Gutenberg blocks. Required. |
| excerpt | string | WordPress excerpt. Does NOT set the meta description. |
| categories | string[] | Category names (not ids). Matched by name or created. |
| tags | string[] | Tag names (not ids). Matched by name or created. |
| featured_image_url | string (URL) | Public URL. Downloaded and sideloaded as the featured image. |
| featured_image_id | number | An attachment id already in the media library. Find one with list_media. |
| featured_media_ref | string | A file the person uploaded through the media handoff. From get_media_upload. |
| seo_title | string | The title tag. Max 70 characters. Needs the companion plugin + an SEO plugin (Yoast verified; Rank Math supported, untested). |
| meta_description | string | The search-result description. Max 200 characters. Same plugin requirement. |
| focus_keyword | string | Max 120 characters. Same plugin requirement. |
| canonical_url | string (URL) | Canonical link for the post. |
| request_review | boolean | Force the post into the approval queue regardless of site policy. |
| idempotency_key | string | Required. Repeat calls with the same key return the original action instead of duplicating. |
| publish_at | ISO 8601 | schedule_post only. Future publish time. |
| post_id | number | update_post only. The WordPress post to update. Required there. |
Three featured-image inputs, mutually exclusive
Supplying more than one is rejected — never silently resolved.
| Parameter | Source | Behaviour |
|---|---|---|
| featured_image_url | A publicly reachable URL | Pressbotics downloads it and sideloads it into the media library, then sets it as the featured image. |
| featured_image_id | An attachment already on the site | Reuse something in the media library. Find the id with list_media. |
| featured_media_ref | A file the person just uploaded | Produced by the media upload handoff: create_media_upload, the person uploads, get_media_upload returns the ref. |
list_content filters
Every post comes back with date and modified, so an agent can find the post you published last Tuesday.
| Filter | Type | Meaning |
|---|---|---|
| search | string | Free-text search across post titles and content. |
| category | string | Category name. |
| tag | string | Tag name. |
| status | string | Accepted, but list_content only returns published posts today. Drafts and scheduled posts are not listed. |
| published_after | ISO 8601 or YYYY-MM-DD | Only posts published on or after this moment. |
| published_before | ISO 8601 or YYYY-MM-DD | Only posts published before this moment. |
| order_by | date | title | modified | Sort field. |
| order | asc | desc | Sort direction. |
| page | number | 1-based page number. |
| limit | number | Results per page. |
Markdown becomes Gutenberg blocks
- Paragraphs
- Headings H1–H6
- Bold, italic and links
- Bulleted lists
- Numbered lists
- Blockquotes
- Pullquotes (:::pullquote)
- Fenced code blocks
- Tables
- Horizontal rules / separators
- Images, with an optional caption
- Galleries (:::gallery)
- Cover blocks (:::cover)
- Columns (:::columns)
- Groups (:::group)
- Embeds from supported providers
- Self-hosted video files
- Self-hosted audio files
Composite blocks with ::: directives
Some Gutenberg blocks have no markdown equivalent. Write them as fence directives inside the markdown parameter — :::name on its own line, closed by ::: on its own line.
| Directive | Block | What it does |
|---|---|---|
| :::cover <image-url> | wp:cover | Full-bleed hero with the enclosed content overlaid. The hero image is uploaded to the media library like any other image. |
| :::pullquote | wp:pullquote | A large decorative quote, distinct from a normal > blockquote. A second paragraph inside becomes the citation. |
| :::gallery | wp:gallery | One image per line — markdown image syntax or a bare URL. Produces a gallery with nested images, all uploaded. |
| :::columns | wp:columns | Columns separated by a line containing only ---. Markdown inside each column is compiled normally. |
| :::group | wp:group | A grouped section. |
:::cover https://cdn.example.com/hero.jpg
# Inside the launch of Orbit 2.0
A year of work, in one release.
:::
Orbit 2.0 is the biggest release we have shipped.
:::pullquote
We stopped optimising the old thing and rebuilt the loop.
Ana Reyes, Head of Product
:::

:::gallery

https://cdn.example.com/g2.jpg

:::
:::columns
### Faster
Builds are 3x quicker.
---
### Simpler
One screen instead of four.
:::
https://www.youtube.com/watch?v=dQw4w9WgXcQ
https://cdn.example.com/walkthrough.mp4Image captions
Markdown's title argument becomes a real WordPress figcaption. Without a title argument no caption is rendered — this is the only way to caption an image.
Video, audio and embeds
A bare link on its own line to a media file becomes a real player, not a link or an embed card.
| Kind | Extensions | Block |
|---|---|---|
| Video | .mp4 .webm .ogv .mov .m4v | wp:video |
| Audio | .mp3 .wav .m4a .ogg .oga .flac | wp:audio |
A bare link to a supported provider becomes wp:embed: YouTube, Vimeo, TikTok, Spotify, SoundCloud, Wistia. Any other URL stays an ordinary paragraph or link — embedding is not universal.
Partial success is reported, not hidden
A post can publish while one component fails — an unreachable image, a term that couldn't be created. Every publish response carries per-component outcomes, so your agent knows exactly what landed. Read them before reporting success to your user: a post can go live without its featured image, and the response will say so.
| Field | Values | Meaning |
|---|---|---|
| state | queued | published | scheduled | failed | rejected | reverted | What happened to the post itself. Everything below describes its components. |
| partial | boolean | True when the post landed but at least one component did not. |
| image_status | none | ok | failed | Featured image outcome. |
| image_error | string | Why the featured image failed, when it did. |
| taxonomy_status | none | ok | partial | failed | Categories and tags outcome. |
| taxonomy_error | string | Which terms could not be applied. |
| seo_status | none | ok | unsupported | Whether SEO meta was actually written. |
| seo_error | string | Which piece is missing when seo_status is "unsupported". |
| embed_status | none | ok | partial | failed | Whether provider embeds resolved. A provider that will not embed stays a plain link and the post still publishes. |
| embeds | array | The embed URLs found and what each became. |
| inline_images | { total, failed, errors } | Inline image re-hosting. An image that cannot be fetched is REMOVED from the post body and listed in errors; the post still publishes. |
| post_url | string (URL) | The live post URL, once it exists. |
| render_check | pass | fail | not_yet | pass: the live post was fetched and rendered correctly. fail: it did not, and the post was reverted to draft. not_yet: a scheduled post that is not public yet — the scheduler verifies it when it goes live and writes pass or fail then. |
The SEO status contract
Every publish, schedule and update response returns seo_status.
| seo_status | Meaning | Detail |
|---|---|---|
| none | No SEO fields were requested on the call. | Nothing to write. |
| unsupported | SEO fields were requested but the site cannot write them. | seo_error names the missing piece: the Pressbotics companion plugin, or a supported SEO plugin. |
| ok | The site is capable and the SEO meta was actually written. | Requires the companion plugin AND an SEO plugin. Yoast is verified end to end on a live site; Rank Math is supported but has not been tested. Only the active plugin's meta keys are written. |
"ok" requires both the free Pressbotics companion plugin and an SEO plugin. Yoast is verified end to end on a live site; Rank Math is supported but has not been tested. Only the active plugin's meta keys are written. Other SEO plugins are not supported and return "unsupported". Note the distinctions: the post title is the headline, seo_title is the title tag (max 70), the excerpt is the on-site summary, and meta_description is the search-result description (max 200). The excerpt does not set the meta description.
What it can and cannot do
It can
- Create, schedule and update posts from markdown
- Set a featured image and re-host inline images
- Assign categories and tags by name
- Set SEO title, meta description, focus keyword and canonical URL (plugin + Yoast; Rank Math supported, untested)
- Read a site's context, content list and health
- Hold every post for your approval
It cannot
- Managing WordPress users
- Changing site settings
- Installing, activating or configuring plugins
- Changing or editing themes
- Running WordPress core updates
By design. A compromised agent can post something you can revert — one click in Activity unpublishes it and keeps the content as a draft, or puts an earlier version back. It cannot take over the site.


