wp_create_post: create a post
Creates a post or a public custom post type. The gentlest write in the server: it adds a record and touches nothing existing.
Arguments
| Argument | Default | Meaning |
|---|---|---|
post_type |
post |
Any public post type |
title |
— | The title |
content |
— | The body |
excerpt |
— | The excerpt |
slug |
— | The slug; derived from the title when omitted |
status |
draft |
The post status |
dry_run |
— | Report without creating |
Permissions
Allow content writes must be open.
Capability edit_posts, or edit_pages when creating a page. Scopes mcp:read, mcp:write, wp:content:read, wp:content:write.
It creates a draft unless told otherwise
Omitting status produces a draft. This is deliberate: an assistant cannot publish something by forgetting to say what state it should be in.
Publishing is therefore always an explicit act, either by passing status at creation or by a later wp_update_post. Making it a separate step is the safer pattern — it puts a human between "content exists" and "content is public".
Use the dry run
dry_run returns would_create with the payload the tool would send, without creating anything.
It is most useful for confirming the post type and status are what you intended before a batch:
Use a dry run for the first one and show me the payload.
What it returns
The created post in the standard shape, including content and the new id.
Keep the ID. Every later step — terms, featured image, SEO fields, publishing — refers to it.
What it does not set
Creating a post sets the fields above and nothing else. Not:
- categories or tags — see Taxonomy tools;
- the featured image — see Media tools;
- post meta — see Comment and meta tools;
- SEO fields, which are separate meta.
A post created and reviewed still has none of these unless you add them as their own steps.
Content is stored as given
The content argument is stored without the sanitisation applied to titles and slugs, so builder shortcodes survive intact.
That also means invalid builder markup is stored as happily as valid markup. Validate first — see pom_validate_builder_content.
Using it well
Create a draft post titled "Spring maintenance checklist" with this content: … Leave it as a draft and give me the ID.
For several:
Create the first two as drafts, show me the IDs, then stop.
Writes are capped at 20 per minute, so a large batch is paced regardless.
Common problems
| Symptom | Cause |
|---|---|
| The write is refused | Content write gate closed |
pom_ai_mcp_post_type_denied |
The post type is not public |
pom_ai_mcp_forbidden |
No edit_posts, or edit_pages for a page |
| It published immediately | status was passed as publish |
| The slug is not what you wanted | Derived from the title; pass slug |
| The layout is broken | Builder content was not validated first |