references/cli.md
## Playground CLI workflows
Use this reference for local WordPress Playground runs with `@wp-playground/cli`: disposable or persisted local servers, mounted plugins/themes, Blueprint execution, snapshots, version switching, and local smoke tests.
## Prerequisites
- Node.js 20.18+ with `npm`/`npx` available.
- A local project, plugin, theme, Blueprint file, or Blueprint bundle path.
- A free local port when using `server`; the default is `9400`.
Check the installed CLI help when exact flags matter:
```bash
npx @wp-playground/cli@latest --help
npx @wp-playground/cli@latest start --help
npx @wp-playground/cli@latest server --help
```
## Quick local development
Use `start` for the common local plugin/theme workflow. It detects the project type, mounts the project, opens a browser, enables admin auto-login, and persists the site between sessions.
```bash
cd <plugin-or-theme-root>
node -v
npx @wp-playground/cli@latest start
```
- Use `npx @wp-playground/cli@latest start --reset` when the persisted site should be recreated from scratch.
- Use `server` with explicit `--wp=<version>` and `--php=<version>` when reproducing compatibility issues instead of relying on moving defaults.
## Advanced local server
Use `server` when you need full manual control, a disposable site, CI-style behavior, custom mounts, or a Blueprint-backed server:
```bash
npx @wp-playground/cli@latest server --auto-mount
```
- `--auto-mount[=<path>]` detects a WordPress directory, plugin, theme, wp-content directory, or PHP/HTML directory.
- Add `--port=<free-port>` when the default port is busy.
- For existing WordPress files, prefer `--wordpress-install-mode=install-from-existing-files-if-needed` to skip setup when a site is already present.
- Use `--wordpress-install-mode=do-not-attempt-installing` only when WordPress files and database integration are already handled by the mounted tree.
## Manual mounts
Use explicit mounts when auto-mount is not enough:
```bash
npx @wp-playground/cli@latest server \
--mount=/absolute/host/path:/wordpress/wp-content/plugins/my-plugin
```
- Use absolute host paths.
- Repeat `--mount=` for multiple plugins, mu-plugins, themes, or custom content.
- Use `--mount-before-install` when installer or Blueprint steps need mounted files before WordPress setup completes.
- On Windows or when colon-separated mappings are awkward, use `--mount-dir "/host/path" "/vfs/path"` or `--mount-dir-before-install "/host/path" "/vfs/path"`.
## Run a Blueprint
For headless setup or CI-style validation:
```bash
npx @wp-playground/cli@latest run-blueprint --blueprint=<file-or-url>
```
- Use the `blueprint` skill for Blueprint JSON structure and schema details.
- Add `--blueprint-may-read-adjacent-files` when a local Blueprint directory or bundle references nearby files.
- Add `--verbosity=debug` when step execution needs inspection.
## Start a server from a Blueprint
```bash
npx @wp-playground/cli@latest server --blueprint=<file-or-url>
```
For local directory bundles:
```bash
npx @wp-playground/cli@latest server \
--blueprint=./my-bundle/ \
--blueprint-may-read-adjacent-files
```
ZIP bundles are self-contained and do not need adjacent-file access.
## Build a snapshot
```bash
npx @wp-playground/cli@latest build-snapshot \
--blueprint=<file-or-url> \
--outfile=./site.zip
```
- Use snapshots for shareable repro cases or CI artifacts.
- Re-run with `--verbosity=debug` if the generated site does not contain the expected state.
## Version switching
- Use `--wp=<version>` to pin WordPress.
- Use `--php=<version>` to pin PHP.
- Prefer explicit versions for bug reproduction and compatibility testing.
- Use the CLI help or current Playground docs to confirm supported version values and defaults.
## Verification
- Confirm the plugin appears in the admin plugin list and is active when expected.
- Confirm the selected theme is active when testing themes.
- For Blueprints, verify expected options, pages, plugins, themes, or files after the run.
- For snapshots, load the ZIP in a fresh Playground instance before sharing it as a repro artifact.
## Failure modes
- **Node version error**: upgrade to Node.js 20.18+.
- **Mount not applied**: use an absolute path, verify the virtual path, and rerun with `--verbosity=debug`.
- **Blueprint cannot read local assets**: add `--blueprint-may-read-adjacent-files` for local directory bundles.
- **Port already used**: pass `--port=<free-port>`.
- **Need a fresh persisted `start` site**: rerun with `start --reset`.
- **Need breakpoints or runtime logs**: return to the `wp-playground` routing procedure and select the debugging workflow.
references/debugging.md
## Debugging WordPress Playground
- Start CLI with Xdebug: `server --auto-mount --xdebug`. The CLI prints host/port and IDE key to configure your debugger; if the installed CLI help differs, follow `npx @wp-playground/cli@latest server --help`.
- If breakpoints are not hit, confirm:
- IDE listens on the port shown by CLI.
- Path mappings include the mounted VFS path used by Playground.
- For slow or stuck runs:
- Add `--verbosity=debug` to see step-level logs.
- Use `--debug` to print the PHP error log when boot fails.
- Adjust request workers with `--workers=<n|auto>`; use `--workers=1` to isolate worker-related behavior.
- For mount issues:
- Prefer absolute paths in `--mount`.
- Use `--mount-before-install` when installer steps need files present early.
- To inspect runtime state:
- Open the Playground browser console; the Service Worker logs network/FS events.
- Use the “Terminal” tab (if available) to run WP-CLI inside the instance.
references/mcp.md
## Playground MCP
Use this reference when the user requests Playground MCP, or when the [interaction router](website.md#choose-an-interaction-method) selects an available MCP connection as a fallback.
## Connect to the intended site
Playground MCP uses a local MCP server and WebSocket bridge. Its website connection parameters are `mcp=yes` and optionally `mcp-port=<port>`; the default port is `7999`. These parameters belong to Playground MCP, not WebMCP.
Prefer an existing connection targeting the intended site. Do not reload an existing tab, create a replacement site, or discard current work merely to enable the bridge. If a connection is unavailable, return to the interaction router for an available fallback; if the user requires MCP specifically, report the missing connection instead of silently changing methods.
## Discover and call tools
1. Inspect the tools exposed by the connected Playground MCP server and their descriptions and input schemas. Do not reuse WebMCP tool names or arguments without checking the MCP interface.
2. Confirm that the connection targets the intended site with a harmless information/read operation before making changes.
3. Use the available tool that supports the requested operation. If no suitable tool exists, return to the interaction router for a fallback consistent with the user's requested method.
## Verification
Check tool results and verify the requested state through the same site connection before claiming success. Preserve the active browser site when switching connection methods.
references/sites-api.md
## Sites API and active site client
Use this reference for browser JavaScript operations on the Playground website when selected by the [interaction router](website.md#choose-an-interaction-method).
- `window.playgroundSites` manages saved browser sites and the active site selection.
- `window.playground` is the `PlaygroundClient` for the active WordPress runtime; `playgroundSites.getClient()` returns that client after the site is ready.
## Manage browser sites with `window.playgroundSites`
Use `window.playgroundSites` on the top-level `https://playground.wordpress.net/` page. It is not available immediately during page load, so wait for the global and then call `isReady()` before site-manager work.
```js
while (!window.playgroundSites) {
await new Promise((resolve) => setTimeout(resolve, 50));
}
await window.playgroundSites.isReady();
```
Available site-manager operations:
- `list()`: inspect known sites, active site, names, slugs, and storage types.
- `createNewTemporarySite(slug?, settings?)`: create and switch to a fresh in-memory site. Settings use `phpVersion`, `wpVersion`, `networking`, `language`, and `multisite`.
- `setActiveSite(slug)`: switch to an existing site and wait for it to boot.
- `isReady()`: wait until the active site and its client are ready.
- `getClient()`: get the active site's `PlaygroundClient`.
- `saveInBrowser(name?)`: persist the active site to OPFS browser storage.
- `saveToLocalFileSystem(name?, handle?)`: persist the active site to a user-selected local directory when the browser supports it.
- `rename(newName)`: rename the active saved site.
- `setPhpVersion(version)`: change PHP version and reboot the active saved site.
- `setNetworking(enabled)`: toggle outbound networking and reboot the active saved site.
- `delete(slug)`: delete a saved site when the user explicitly asked for deletion.
Storage behavior:
- `temporary`: in memory only; resets on reload.
- `opfs`: saved in browser storage for `playground.wordpress.net`; survives reloads.
- `local-fs`: saved to a user-selected local directory; Chromium/File System Access API only.
Important constraints:
- `createNewTemporarySite()` accepts only version/site boot settings: `phpVersion`, `wpVersion`, `networking`, `language`, and `multisite`. The JS names are `phpVersion` and `wpVersion`, not `php` and `wp`.
- It does not install plugins/themes or run Blueprints; use a URL/Blueprint workflow for that.
- `saveInBrowser()` and `saveToLocalFileSystem()` are safe on already-saved sites.
- `rename()`, `setPhpVersion()`, and `setNetworking()` operate on the active saved site. Switch with `setActiveSite(slug)` first when targeting a specific site. Save a temporary site first.
- `delete(slug)` deletes a saved site's persisted data; do not call it unless the user asked for deletion.
## Interact with the active WordPress site
Use the active `PlaygroundClient` after the site is booted. If the user says `window.palyground`, treat it as a typo for `window.playground`.
```js
await window.playgroundSites?.isReady();
const client = window.playgroundSites?.getClient() || window.playground;
await client.isReady();
```
Available active-site operations:
- File inspection: `listFiles`, `readFileAsText`, `readFileAsBuffer`, `fileExists`, `isFile`, `isDir`, `isSymlink`, `readlink`, and `realpath` in the `/wordpress` virtual filesystem.
- File mutation: `mkdir`, `mkdirTree`, `writeFile`, `mv`, `cp`, `chmod`, `symlink`, `unlink`, `rmdir`, and `unzip`. `mv` moves or renames files. unlink deletes files, while `playgroundSites.delete(slug)` deletes a saved site. `rmdir` is for empty directories.
- PHP execution: run PHP snippets with `run({ code })`; inspect the returned output/status/error fields. Require `/wordpress/wp-load.php` before using WordPress APIs such as `wp_insert_post`, `get_option`, `get_stylesheet`, or `wp_get_theme`.
- Web requests: call WordPress routes with `request({ path, method, headers, body })` and inspect status/body. Use it for admin pages such as `/wp-admin/` and REST routes such as `/wp-json/wp/v2/posts`; remember admin/nonce behavior depends on login state.
- Browser navigation: send the visible Playground frame to a WordPress path with `goTo(path)`.
- State checks: verify installed/active plugins and themes through WordPress PHP APIs or filesystem checks before claiming setup succeeded.
- MU plugins: write files under `/wordpress/wp-content/mu-plugins/`, then request or navigate to a WordPress route to force loading.
Keep the distinction clear:
- `playgroundSites` manages site records and persistence.
- `window.playground` / `getClient()` manipulates the active WordPress runtime.
- Query API / `blueprint-url` sets up a site at page load.
## Verification
- Before changes, inspect `window.playgroundSites.list()` to confirm the intended active site.
- After site-manager operations, verify `window.playgroundSites.list()` shows the expected active site and storage type.
- For client operations, run a harmless read first, such as `await client.listFiles('/wordpress')`, before writing files or changing state. Verify the requested state after the operation.
- After switching sites or rebooting, wait for readiness and reacquire the active client before further operations.
references/webmcp.md
## WebMCP site tools
Use this reference when interacting with the open Playground page through callable WebMCP tools. For setup or connection-method selection, use [website workflows](website.md).
## Discover and call tools
1. Use the intended Playground tab, wait for WordPress to load, and discover the site's tools through the browser environment's tool discovery mechanism (sometimes called **Site tools**).
2. Inspect each discovered tool's description and input schema before calling it. Do not assume that Playground MCP and WebMCP expose identical interfaces.
3. Confirm the target site with a harmless information/read operation, then use the discovered tool for the requested operation.
WebMCP exposes tools through the open webpage. It does not require the local Playground MCP server, its WebSocket bridge, or `mcp=yes`.
Examples to look for during discovery include:
| Purpose | Example WebMCP tools |
| --- | --- |
| Site information and persistence | `playground_get_site_info`, `playground_list_sites`, `playground_rename_site`, `playground_save_in_browser` |
| PHP and WordPress requests | `playground_execute_php`, `playground_request` |
| Navigation | `playground_navigate`, `playground_get_current_url` |
| Filesystem operations | `playground_read_file`, `playground_write_file`, `playground_list_files`, `playground_mkdir` |
Use the discovered tool set as the source of truth. Playground can also proxy tools registered by plugins inside the WordPress iframe onto the outer page; rediscover tools after navigation or a site switch when needed. A WordPress ability registration alone does not make it a WebMCP tool.
Background: [WordPress Playground and WebMCP: bringing AI agents into your browser workflow](https://make.wordpress.org/playground/2026/09/05/wordpress-playground-and-webmcp-bringing-ai-agents-into-your-browser-workflow/).
## Unsupported operations
If WebMCP is unavailable or lacks an operation, return to the [interaction router](website.md#choose-an-interaction-method) and read the selected fallback reference. Preserve the intended site when changing methods; do not create a replacement or reload away current work.
## Verification
Check tool results and verify the requested state in the same site before claiming success. After navigation or a site switch, confirm the active site and rediscover tools when needed.
references/website.md
## Playground website workflows
Use this reference for `https://playground.wordpress.net/` setup and sharing, and to choose how to interact with an existing browser site.
## Route first
- For Blueprint JSON structure, schema, resources, steps, or bundles, use the `blueprint` skill; it is the source of truth for Blueprint details.
- For local filesystem mounts, snapshots, Xdebug, or headless validation, return to the `wp-playground` routing procedure and select the local CLI or debugging workflow.
- For a new site or share link, use the Query API and Blueprint URL setup below. Setup URLs apply at page load; do not reload an existing site just to perform a runtime operation.
## Choose an interaction method
Respect a connection method explicitly requested by the user. Otherwise, prefer available WebMCP tools for supported operations. Availability means tools are exposed and callable in this session, not merely that the browser can open Playground.
Read only the reference needed for the selected method:
| Method | When to use | Reference |
| --- | --- | --- |
| WebMCP | Default for supported operations through the open page's site tools. | [WebMCP](webmcp.md) |
| Playground MCP | The user requests it, or WebMCP is unavailable or lacks an operation and a suitable MCP connection is available. | [Playground MCP](mcp.md) |
| Sites API and active site client | The user requests browser JavaScript APIs, or available site tools/MCP do not support the operation. | [Sites API](sites-api.md) |
Fall back per operation, loading the fallback reference only when needed. Keep the intended site when changing methods: do not create a replacement site or reload away the user's current work. Confirm the target with a harmless information/read operation before making changes, and verify the result in that same site.
## Create or open a site with a URL
For a blank disposable Playground site, use `https://playground.wordpress.net/` with no query parameters.
Use Query API URLs when the setup is simple enough to express as URL parameters:
```text
https://playground.wordpress.net/?php=8.4&wp=latest&plugin=gutenberg&networking=yes&url=/wp-admin/post-new.php
```
Practical URL parameters for agents:
- `php=<version>` and `wp=<version>`: choose runtime versions.
- `plugin=<slug>` and `theme=<slug>`: install WordPress.org assets; repeat the parameter for multiple assets, such as `?plugin=gutenberg&plugin=woocommerce&networking=yes`.
- `networking=yes|no`: allow or block downloads for plugins, themes, translations, imports, and PR builds. Use `networking=no` or omit networking for offline/simple tests.
- `login=yes|no`: control admin auto-login. Use `login=no` to prevent automatic admin login; admin pages will require manual login.
- `multisite=yes|no`: choose single-site or multisite mode at boot.
- `url=/path/`: choose the first page to show. Use `/wp-admin/` for the dashboard or `/wp-admin/site-editor.php` for the Site Editor.
- `language=<locale>`: set a WordPress locale such as `de_DE`; pair with `networking=yes` so translations can download.
- `import-site=<zip-url>`: import a public, URL-encoded, CORS-enabled site ZIP.
- `import-wxr=<wxr-url>`: import a public, URL-encoded, CORS-enabled WordPress export XML/WXR file.
- `site-slug=<slug>`: select a saved browser site by slug. Use the selected interaction method to discover existing slugs first.
- `if-stored-site-missing=prompt`: ask the user whether to save a new site when `site-slug` is missing.
- `blueprint-url=<url>`: load a public Blueprint JSON file or Blueprint bundle ZIP.
- `lazy`: show a Run button and defer loading until clicked, useful for tutorials and click-to-run demos.
- `mode=browser-full-screen|seamless`: choose browser UI or a full-width WordPress view.
- `page-title=<title>`: customize the browser tab title when comparing instances.
- `can-save=no`: remove save options from the UI.
- `overlay=blueprints`: open the Blueprint Gallery on load.
Use these rules:
- Use Query API links for simple, shareable setup.
- Use Blueprint URLs/fragments for multi-step setup, files, content creation, custom code, or bundled assets.
- Do not explain Blueprint schema here; delegate the Blueprint body to the `blueprint` skill.
- Hosted Blueprint JSON, ZIP bundles, imports, and referenced assets must be public and served with `Access-Control-Allow-Origin: *`.
- Browser URLs cannot read arbitrary local files or local directory bundles. Use hosted assets or the CLI for local paths.
- If a missing `site-slug` prompt appears, confirm the user's intent before creating or saving a new browser site.
Small inline Blueprints can be shared with a URL fragment:
```text
https://playground.wordpress.net/#<encodeURIComponent(JSON.stringify(blueprint))>
```
Large Blueprints and bundles should use:
```text
https://playground.wordpress.net/?blueprint-url=<public-json-or-zip-url>
```
Base64-encoded Blueprint fragments are also supported when a channel rewrites JSON characters.
Other URL capabilities the agent may need:
- Experimental builds: `core-pr=<number>` for WordPress core PRs, `gutenberg-pr=<number>` for Gutenberg PRs, `gutenberg-branch=<branch>` such as `trunk`.
- Runtime extension: `php-extension=<manifest-url>`; accepts HTTP(S) URLs and may be repeated.
- GitHub export form prefill: `gh-ensure-auth=yes`, `ghexport-repo-url=<repo-url>`, `ghexport-pr-action=create|update`, `ghexport-playground-root=<path>`, `ghexport-repo-root=<path>`, `ghexport-content-type=plugin|theme|wp-content|custom-paths`, `ghexport-plugin=<plugin-path>`, `ghexport-theme=<theme-dir>`, repeatable ghexport-path (`ghexport-path=<relative-path>`), `ghexport-commit-message=<message>`, `ghexport-allow-include-zip=yes|no`.
## Verification and browser limitations
- For a generated URL, open it in a fresh browser session and confirm versions, login state, installed assets, and landing page.
- If a hosted Blueprint/import fails, verify the URL is public and CORS-enabled.
- For existing-site operations, follow the verification guidance in the selected interaction reference.
- Treat `playground.wordpress.net` as a browser demo/sandbox, not production hosting or guaranteed durable infrastructure.
- Escalate to the CLI or a full WordPress stack when the task needs local filesystem mounts, snapshots, headless validation, durable production-like persistence, native database access, server integration, or production availability guarantees.
SKILL.md
---
name: wp-playground
description: "Use as the WordPress Playground routing wrapper for ambiguous Playground work, local CLI runs with @wp-playground/cli, playground.wordpress.net share links, browser previews, WebMCP site tools, snapshots, mounts, version switching, and Xdebug. For Blueprint JSON authoring or review, use the blueprint skill directly."
compatibility: "Targets WordPress 7.0+, PHP 7.4.0+. Playground CLI requires Node.js 20.18+; runs WordPress in WebAssembly with SQLite."
---
# WordPress Playground
This is a thin routing wrapper. Use it to pick the right Playground workflow, then load only the focused reference or skill needed for the task.
## Procedure
1. Identify the user intent: Blueprint authoring/review, local CLI execution, browser-only website/share link workflow, Xdebug/stuck CLI run, or a mixed Playground request.
2. Route to the focused source below, loading more than one only when the request has multiple distinct parts.
3. For mixed requests, delegate Blueprint JSON work to `blueprint`, then return here for runtime, CLI, debugging, or sharing guidance.
- **Blueprint JSON, schema, steps, resources, bundles, or Blueprint review**: use the `blueprint` skill directly. Do not duplicate Blueprint schema details here.
- **Local CLI execution**: read `references/cli.md` for `@wp-playground/cli` server, `run-blueprint`, `build-snapshot`, mounts, version switching, and local validation.
- **Xdebug or stuck CLI runs**: read `references/debugging.md` for Xdebug, runtime logs, worker flags, and stuck CLI runs.
- **Browser-only Playground website workflows**: read `references/website.md` for Query API and Blueprint URL setup, share links, and browser limitations. It routes existing-site operations to separate WebMCP, Playground MCP, and Sites API references; load only the selected method. Unless the user requests a specific connection method, prefer available WebMCP tools for supported browser operations.
## Inputs required
- The intended workflow: Blueprint authoring, local CLI run, website/share link, snapshot, or debugging.
- Project or bundle path if local code must be mounted or packaged.
- Desired WordPress/PHP versions if compatibility matters.
- Port preference if a local server is needed.
- Whether browser-only sharing or local filesystem access is required.
## Guardrails
- Playground instances are disposable, SQLite-backed environments; never point them at production data.
- Keep Blueprint JSON guidance in `blueprint` so the schema and examples have one source of truth.
- For local CLI work, verify Node.js 20.18+ and `npm`/`npx` before running commands.
- Browser-only Playground cannot read local filesystem paths; use public URLs, hosted ZIP bundles, or inline Blueprint JSON.
## Verification
- For Blueprint content, validate against the published schema and follow the `blueprint` skill verification.
- For local CLI runs, verify the mounted plugin/theme or Blueprint side effects in the Playground instance.
- For share links, open the generated URL and confirm the expected landing page and installed assets load.
## Failure modes
- **Blueprint work routed here**: stop and use the `blueprint` skill for schema keys, steps, resources, bundles, validation, or Blueprint review.
- **Local filesystem needed in a browser-only workflow**: use `references/cli.md`; `playground.wordpress.net` cannot read local filesystem paths.
- **Shareable browser link requested from a local CLI workflow**: use `references/website.md`; local server URLs are not portable share links.
- **Debugging treated as a second-hop reference**: read `references/debugging.md` directly for Xdebug, logs, worker flags, and stuck CLI runs.
## Escalation
- If the task needs PHP extensions, native database access, persistence, or production-like infrastructure that Playground cannot provide, use a full WordPress stack such as wp-env, Docker, or the project-provided environment.