Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
WP_CLI_MCP_LOGNoSet to '0' to disable logging entirely
CLAUDE_PROJECT_DIRNoPath to the project root where .serena/wp-cli.conf is located
WP_CLI_MCP_LOG_DIRNoOverride directory for failure logs (default: system temp dir)

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
wp_init_configA

Create the server's configuration file (/.serena/wp-cli.conf) for a WordPress project. Call it FIRST when no config exists yet. Two phases: (1) DETECT — call with no arguments (write=false); it probes the environment (running Docker containers, the WordPress path inside them, and any authenticated Pantheon Terminus site) and returns what it found plus a missing list of values it could NOT determine. Ask the user for those, then (2) WRITE — call again with write=true and a complete site object to save the config. It refuses to overwrite an existing config unless overwrite=true.

wp_cliA

Run a WP-CLI command against a configured WordPress site's local Docker container (default) or its remote production environment. Configuration is read from /.serena/wp-cli.conf, which may define one or MANY sites. Pass the WP-CLI command WITHOUT a leading 'wp' (e.g. args='plugin list --status=active'). When the conf defines multiple sites, pass 'site' = the site's top-level folder name; omit it to use the configured DEFAULT_SITE or the sole site. The production TRANSPORT is chosen by the site's conf: TERMINUS_SITE routes over terminus remote:wp (run on the host, Pantheon/Terminus); otherwise REMOTE_SSH routes over WP-CLI --ssh. For Terminus sites the environment is TERMINUS_ENV (conf default) unless overridden per-call with the 'env' arg. On production, destructive commands (db reset/import, post/user delete, search-replace without --dry-run, plugin/theme delete, etc.) are blocked unless confirm=true and the guard is enabled.

wp_sync_postA

SYNC a single post's post_content onto the SAME post ID in another environment, with a mandatory md5 round-trip verification. This UPDATES an existing destination post that shares the source's ID (e.g. a multidev cloned from the same DB) — it does NOT create a post; if the destination ID is missing it fails. To copy a post that does NOT yet exist on the destination (creating a new post with a destination-assigned ID), use wp_clone_post instead. Use this instead of hand-assembling post update/eval calls to push post body content between local and production (e.g. update a front-page's block markup on a Pantheon multidev). The content NEVER passes through the caller's text: it is read from the source into the server, base64-encoded IN CODE, applied on the destination through a transport-safe PHP eval (STDIN eval-file for Docker/SSH so arbitrarily large posts work; size-guarded argv for Terminus), then re-read and md5-compared to the source. If the hashes differ, the tool reports verified=false and returns an error rather than leaving the destination silently unverified. Transport for each side (local Docker vs Terminus vs SSH) is resolved from wp-cli.conf exactly like wp_cli. Writing to a production destination requires confirm=true when the PROD_GUARD is enabled.

wp_sync_post_metaA

SYNC a post's COMPLETE meta (all custom fields) onto the SAME post ID in another environment, with a mandatory checksum round-trip verification. This UPDATES an existing destination post that shares the source's ID; it does NOT create a post (use wp_clone_post to copy a post that doesn't exist on the destination yet). Preserves EVERYTHING: multiple values per key, serialized arrays/objects (e.g. ACF repeaters), and exact scalar representations — the raw stored meta map is PHP serialize()'d on the source, base64-encoded IN CODE, and rebuilt on the destination with each stored value written back verbatim (no re-interpretation). It then re-reads the destination and compares a canonical PHP-native digest to the transferred payload; a mismatch is returned as verified=false, never silently trusted. By default ALL meta keys are synced and any destination keys not present on the source are removed (full mirror). Pass keys=[...] to sync only specific keys (destination keys outside that list are left untouched). Content never passes through the caller's text. Transport (local Docker vs Terminus vs SSH) is resolved per side from wp-cli.conf exactly like wp_cli. Writing to a production destination requires confirm=true when the PROD_GUARD is enabled.

wp_blockA

Surgically operate on ONE Gutenberg/ACF block of a single post without disturbing the rest of the body. This is the block-level primitive that whole-body wp_sync_post lacks: insert, replace, read, update-attrs, remove, or move exactly one block while every other block stays byte-identical. Use it INSTEAD of hand-written str_replace/eval surgery on post_content (which repeatedly corrupted markup: base64 transcription bugs, self-closing /--> terminators, multisite --url errors). All parsing/serialization runs in WordPress core (parse_blocks / serialize_blocks) via one PHP eval — never string surgery — so self-closing ACF blocks, inner blocks, and freeform HTML round-trip faithfully. ops: 'list' (ordered block summary: index, blockName, anchor, attr/ACF-data keys), 'get' (one block's parsed attrs + exact markup), 'insert' (add a block at a position), 'replace' (swap the matched block), 'update-attrs' (merge ACF field values into the matched block's attrs.data, preserving existing _field key pointers), 'remove' (delete the matched block), 'move' (reorder). Selectors: 'name:' (first of type), 'name:#' (Nth, 0-based), 'anchor:', or 'index:' (Nth top-level block). The block arg is either raw block markup OR an object {name, data} where data merges into the ACF attrs.data. Content never passes through the caller's text: post_content is read on the server, payloads are carried base64 in code, and every write RE-PARSES the saved post and reports verified=true only if the round-trip md5 matches. Read ops (list/get) are never guarded; write ops on target='production' require confirm=true when PROD_GUARD is enabled (a preview of the change is returned instead when blocked). Pass preview=true to get the intended change without writing. Transport (local Docker / Terminus / SSH) is resolved from wp-cli.conf exactly like wp_cli.

wp_clone_postA

COPY a source post to another environment as a NEW post — the destination assigns its own ID (returned as new_id). Use this (NOT wp_sync_post) when the post does not exist on the destination yet, e.g. pushing a locally-authored alert/notification up to a Pantheon multidev. It reads the source post's fields (title, content, excerpt, status, type, dates, parent, etc.) plus ALL meta, creates the post on the destination via wp_insert_post, writes the meta verbatim, then verifies (content md5 + meta digest). Meta values that look like ID references (e.g. _thumbnail_id, ACF relationship/image fields) are copied RAW and REPORTED in id_reference_keys for manual remapping — the tool never silently remaps IDs across databases. Pass overrides to set post fields on the new post (e.g. {"post_status":"draft"}). Content/meta never pass through the caller's text. Creating on a production destination requires confirm=true when the PROD_GUARD is enabled.

wp_create_postA

Create a NEW post from scratch on a configured site, with the body carried content-safe (base64 in code) — so you never have to hand-quote multi-line block markup into a wp post create command or write a throwaway PHP file into the container just to author a post. Returns the new post's ID (new_id), which you then build up compositionally with wp_block (insert / update-attrs). Supply the body EITHER as content (a raw post_content markup string) OR as blocks (an array of block specs — raw markup strings and/or {name, data} objects — serialized server-side with serialize_blocks() so self-closing ACF blocks and inner blocks stay byte-faithful); omit both for an empty post. fields sets any additional post columns (post_excerpt, post_author, post_parent, menu_order, post_name, ...). The new post is re-read and its content md5 is compared to the intended body (verified). Content never passes through the caller's text. Creating on target='production' requires confirm=true when PROD_GUARD is enabled. To COPY an existing post across environments use wp_clone_post instead; this tool authors a brand-new post from given values.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/EarthmanWeb/mcp-wp-cli-terminus'

If you have feedback or need assistance with the MCP directory API, please join our Discord server