1. Overview
The simplest useful WP-MCP tool: take a title + content + optional status, post it, return the new post's id and url.
2. Input schema
tools/posts.create.ts typescript
import { z } from 'zod'
export const PostsCreateInput = z.object({
title: z.string().min(1).max(160),
content: z.string().min(1),
status: z.enum(['draft', 'publish', 'private']).default('draft'),
excerpt: z.string().max(280).optional(),
tags: z.array(z.string()).max(20).optional(),
}) 3. Validation & permissions
Server-side, always
Zod stops malformed input. The WordPress user backing your auth header is what stops privilege escalation. Use a scoped Editor account, not an admin.
4. Implementation
Request
request.json json
{
"method": "tools/call",
"params": {
"name": "posts.create",
"arguments": {
"title": "Hello world",
"content":"Body of the post",
"status": "draft"
}
}
} Response
response.json json
{
"content": [
{ "type":"text", "text":"Created post #128: https://example.com/?p=128" }
]
} 5. Error handling
Return a structured isError: true with content describing the failure. Don't let the agent guess from HTTP codes.
6. Testing the tool
test/posts.create.test.ts typescript
import { describe, it, expect } from 'vitest'
import { handle } from '../src/tools/posts.create'
describe('posts.create', () => {
it('rejects missing title', async () => {
const r = await handle({ content: 'x' } as any)
expect(r.isError).toBe(true)
})
})