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/mcp

Add as a custom MCP server. Static pb_live_ keys remain available for custom or self-hosted agents.

Connect your agent

Works with any MCP agent, including Claude, ChatGPT, Cursor and n8n. Copy the URL, add it as a custom connector, authorize once.

Pressbotics

Pressbotics MCP server URL

https://mcp.pressbotics.com/mcp

One connection. Your favourite agent. Copy this URL into your agent’s custom MCP connections.

Connect Claude

Verified agent
  1. 1Copy the Pressbotics MCP server URL above.
  2. 2In Claude, open Settings → Connectors and choose Add custom connector.
  3. 3Name it Pressbotics, paste the URL, and click Add.
  4. 4Click Connect — Claude opens Pressbotics in your browser. Sign in and click Authorize.
  5. 5Back in Claude, start a new chat and ask it to list your sites.
Open a new Claude chat

The 27 tools

This is the whole surface. Nothing else is exposed.

ToolWhat it does
create_connect_linkCreates a one-time link the site owner opens to connect a WordPress site.
get_connect_statusReports whether a connect link has been completed and which site it produced.
list_sitesLists the connected sites the caller is allowed to publish to.
get_site_contextReturns a site's handle, capabilities, categories, tags, brand voice notes and approval policy.
site_healthRe-probes a site and reports WordPress version, plugin detection and SEO capability.
list_contentLists and filters existing posts on a site so an agent can find something to update.
list_mediaLists attachments already in the site's media library, so an existing image can be reused.
create_media_uploadCreates an upload link the person opens to hand over a file the agent cannot forward itself.
get_media_uploadPolls an upload until it is ready and returns the media_ref to pass to a publish call.
update_mediaUpdates an existing media library item's alt text, title, caption or description.
publish_postCreates a post from markdown and publishes it (or queues it for approval).
schedule_postSame as publish_post, plus a future publish_at timestamp.
update_postUpdates an existing post by id with new content, taxonomy, media or SEO fields.
get_post_statusReturns the current state of a submitted action, including per-component outcomes.
list_scheduledLists scheduled posts across the caller's sites with their times and current state.
reschedule_postMoves a scheduled post to a new time, on WordPress as well as in Pressbotics.
cancel_scheduledCancels a scheduled post before it runs, reverting it to a draft on WordPress.
schedule_batchSchedules several posts in one call — a week of content at a time.
create_recurrenceCreates a standing cadence that generates empty scheduled slots. It does not write content.
list_recurrencesLists the cadences on a site, with their pattern, timezone and next slots.
cancel_recurrenceStops a cadence generating further slots. Slots already created remain.
get_accountReturns the connected account: workspace, masked owner email, plan, plan limits, posts used and remaining this month, and when the count resets.
get_site_insightsReturns a site's (or all sites') output, on-time reliability, live-page quality scores, weekly trend and plain-English readings for 7d, 30d or 90d. Search and traffic are null until connected.
get_site_profileReturns what Pressbotics has learned about a site — niche, audience, voice, topics, actual and wanted cadence, formats, approval and recommendation behaviour — each marked inferred or confirmed.
get_recommendationsLists open recommendation cards (fill the calendar, improve, attention, write, series) with reasoning and confidence. Cards are briefs; Pressbotics does not write content.
accept_recommendationAccepts a card and returns the full brief and a ready agent_prompt. Accepting a series also launches its campaign and holds weekly empty calendar slots (paid plans).
dismiss_recommendationDismisses a card with an optional reason; that type and topic stay hidden for 30 days.

Publish parameters

Shared by publish_post, schedule_post and update_post. publish_at applies to schedule_post only; post_id to update_post only.

ParameterTypeNotes
sitestringSite handle or URL. Required.
titlestringPost title — the on-page headline. Required.
markdownstringPost body in markdown. Converted to Gutenberg blocks. Required.
excerptstringWordPress excerpt. Does NOT set the meta description.
categoriesstring[]Category names (not ids). Matched by name or created.
tagsstring[]Tag names (not ids). Matched by name or created.
featured_image_urlstring (URL)Public URL. Downloaded and sideloaded as the featured image.
featured_image_idnumberAn attachment id already in the media library. Find one with list_media.
featured_media_refstringA file the person uploaded through the media handoff. From get_media_upload.
seo_titlestringThe title tag. Max 70 characters. Needs the companion plugin + an SEO plugin (Yoast verified; Rank Math supported, untested).
meta_descriptionstringThe search-result description. Max 200 characters. Same plugin requirement.
focus_keywordstringMax 120 characters. Same plugin requirement.
canonical_urlstring (URL)Canonical link for the post.
request_reviewbooleanForce the post into the approval queue regardless of site policy.
idempotency_keystringRequired. Repeat calls with the same key return the original action instead of duplicating.
publish_atISO 8601schedule_post only. Future publish time.
post_idnumberupdate_post only. The WordPress post to update. Required there.

Three featured-image inputs, mutually exclusive

Supplying more than one is rejected — never silently resolved.

ParameterSourceBehaviour
featured_image_urlA publicly reachable URLPressbotics downloads it and sideloads it into the media library, then sets it as the featured image.
featured_image_idAn attachment already on the siteReuse something in the media library. Find the id with list_media.
featured_media_refA file the person just uploadedProduced 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.

FilterTypeMeaning
searchstringFree-text search across post titles and content.
categorystringCategory name.
tagstringTag name.
statuspublish | draft | future | pending | private | anyDefaults to published posts. Drafts, scheduled (future), pending and private posts are read with the site's own credential, so they are listed too.
published_afterISO 8601 or YYYY-MM-DDOnly posts published on or after this moment.
published_beforeISO 8601 or YYYY-MM-DDOnly posts published before this moment.
order_bydate | title | modifiedSort field.
orderasc | descSort direction.
pagenumber1-based page number.
limitnumberResults 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.

DirectiveBlockWhat it does
:::cover <image-url>wp:coverFull-bleed hero with the enclosed content overlaid. The hero image is uploaded to the media library like any other image.
:::pullquotewp:pullquoteA large decorative quote, distinct from a normal > blockquote. A second paragraph inside becomes the citation.
:::gallerywp:galleryOne image per line — markdown image syntax or a bare URL. Produces a gallery with nested images, all uploaded.
:::columnswp:columnsColumns separated by a line containing only ---. Markdown inside each column is compiled normally.
:::groupwp:groupA 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
:::

![The new dashboard](https://cdn.example.com/dash.png "The redesigned dashboard, shipped in 2.0")

:::gallery
![Editor](https://cdn.example.com/g1.jpg)
https://cdn.example.com/g2.jpg
![Timeline](https://cdn.example.com/g3.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.mp4

Image 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.

![alt text](https://example.com/photo.jpg "This becomes the caption")

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.

KindExtensionsBlock
Video.mp4 .webm .ogv .mov .m4vwp:video
Audio.mp3 .wav .m4a .ogg .oga .flacwp: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.

FieldValuesMeaning
statequeued | published | scheduled | failed | rejected | revertedWhat happened to the post itself. Everything below describes its components.
partialbooleanTrue when the post landed but at least one component did not.
image_statusnone | ok | failedFeatured image outcome.
image_errorstringWhy the featured image failed, when it did.
taxonomy_statusnone | ok | partial | failedCategories and tags outcome.
taxonomy_errorstringWhich terms could not be applied.
seo_statusnone | ok | unsupportedWhether SEO meta was actually written.
seo_errorstringWhich piece is missing when seo_status is "unsupported".
embed_statusnone | ok | partial | failedWhether provider embeds resolved. A provider that will not embed stays a plain link and the post still publishes.
embedsarrayThe 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_urlstring (URL)The live post URL, once it exists.
alt_text_warningsarrayImages in the post (featured or inline) that have no alt text. The post still publishes; fix them with update_media.
warningsarray of { code, message }Advisory, never a refusal. no_taxonomy: the post has no categories and no tags, so WordPress files it under Uncategorized — resend with categories or tags from get_site_context, or fix it with update_post.
publish_at_utcstring (ISO 8601, Z)Scheduled posts only. The exact instant the post is due, in UTC, stored beside the timezone you sent so the record is unambiguous.
preview_urlstring (URL)A signed-in Pressbotics page showing the saved post before it goes live. Present only when there is a saved body to preview.
render_checkpass | fail | not_yetpass: 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_statusMeaningDetail
noneNo SEO fields were requested on the call.Nothing to write.
unsupportedSEO fields were requested but the site cannot write them.seo_error names the missing piece: the Pressbotics companion plugin, or a supported SEO plugin.
okThe 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.

Further reading: What is a WordPress MCP server? · The WordPress MCP plugin guide