WordPress

Lightweight, dependency-free, in-memory fake of the WordPress REST API v2 for testing code that talks to /wp-json/wp/v2/....

Default port: 4844

Quick start

import { WordpressServer } from "./services/wordpress/src/server.js";

const server = new WordpressServer(4844);
await server.start();
// ... run your app/tests ...
await server.stop();

Create a post (writes require Basic auth with an application password):

const auth = "Basic " + Buffer.from("parlel:app-password").toString("base64");
await fetch("http://127.0.0.1:4844/wp-json/wp/v2/posts", {
  method: "POST",
  headers: { Authorization: auth, "Content-Type": "application/json" },
  body: JSON.stringify({ title: "Hello World", content: "Body", status: "publish" }),
});

Access via MCP / preview URL

When run inside a parlel pool, reachable at its mapped preview URL (e.g. http://127.0.0.1:4844). MCP clients drive posts, pages, categories, and users using WORDPRESS_USERNAME / WORDPRESS_APP_PASSWORD for Basic auth. Reads are public; writes require Basic auth.

Implemented operations

State is in-memory and ephemeral. Routes live under /wp-json/wp/v2/.... An Uncategorized category (id 1) is seeded.

Posts / Pages

Categories

Users

Service & inspection (parlel extensions)

Surface coverage

This emulator faithfully replicates the API surface most application code and agents exercise. Anything below the supported lines is either an intentional design choice for a fast, zero-cost local emulator (✓ By design) or a candidate for a future release (⟳ Roadmap) — never a silent inaccuracy.

Legend: ✅ fully supported · ◐ accepted (stored, not strictly enforced) · ✓ by design · ⟳ on the roadmap.

FeatureStatus
Posts/pages list / create / get / update / delete✅ Supported
Categories list / create / get✅ Supported
users/me (Basic / application password)✅ Supported
rendered title/content/excerpt envelopes, X-WP-Total headers✅ Supported
Basic auth validity / capabilities✓ By design — Intentional for a local, zero-cost test emulator
Media uploads, comments, tags, taxonomies, custom post types⟳ Roadmap
Block rendering, revisions, autosaves⟳ Roadmap
Real persistence✓ By design — In-memory by design — fast, isolated, resets cleanly between tests

Error shapes

WordPress uses { code, message, data:{ status } }:

StatusWhen
401write/users/me without Basic auth
400missing required param (e.g. category name)
404unknown post/page/category id, or unknown route

Manifest

See services/wordpress/manifest.json — name wordpress, port 4844, protocol http, healthcheck /health, env WORDPRESS_USERNAME, WORDPRESS_APP_PASSWORD, WORDPRESS_BASE_URL.

<!-- parlel:testenv:start -->

Configuration — test.env

Copy these into your test.env (used by the bridge sidecar flow). Tokens are Parlel's seeded test credentials — any non-empty value is accepted by the emulator, so you rarely need to change them. Swap in real credentials only when pointing at the live service in prod.env.

WORDPRESS_USERNAME=parlel
WORDPRESS_APP_PASSWORD=parlel
WORDPRESS_BASE_URL=http://parlel-bridge:4844
<!-- parlel:testenv:end -->