Skip to main content
Glama

local-wp-mcp

MCP server providing WP-CLI, MySQL, and filesystem access for Local by Flywheel WordPress sites.

Unlike REST API-based WordPress MCP servers, this connects directly through Local's native filesystem and process architecture — no application passwords, HTTP endpoints, or network requests needed.

Features

  • WP-CLI execution via Local's bundled PHP binary with command allowlisting

  • Direct MySQL queries via Unix socket connection pooling

  • Filesystem operations with path validation and WordPress core protection

  • Multi-site support with automatic site detection from sites.json

  • Security-first: spawn() only (no exec()), symlink-safe path validation, tiered command permissions

Related MCP server: wp-cli-mcp

Tools

Tool

Description

wp_cli_run

Execute any WP-CLI command

wp_site_info

Get WordPress version, URL, themes, plugins

wp_list_sites

List all Local by Flywheel sites

mysql_query

Run SQL queries (read-only by default)

mysql_schema

Inspect database tables and columns

wp_active_plugins

Get active plugins via direct DB query

read_site_file

Read files from the site directory

write_site_file

Write files (wp-content only, core protected)

list_site_directory

List directory contents

search_site_files

Search for files by name pattern

Setup

There are two ways to run this MCP server: from npm (recommended for general use) or from a local clone (for development or customization).

Important: All env values must be strings (e.g., "true" not true).


This is the simplest approach. npm downloads and caches the package automatically — no cloning or building required.

Automatic setup (Claude Code)

From your Local site's project directory:

cd ~/Local\ Sites/mysite/app/public
npx -y @chrisfromthelc/local-wp-mcp --setup

This will auto-detect the Local site, create a .mcp.json (or merge into an existing one), and pre-fill SITE_NAME with write permissions set to false. Restart Claude Code to connect.

Manual setup

Choose your agent below. Each example uses npx to run the server — replace "My Site Name" with the name shown in Local.

Add a .mcp.json to your project root (e.g., ~/Local Sites/mysite/app/public/.mcp.json):

{
  "mcpServers": {
    "local-wp": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@chrisfromthelc/local-wp-mcp"],
      "env": {
        "SITE_NAME": "My Site Name",
        "WPCLI_ALLOW_WRITES": "false",
        "MYSQL_ALLOW_WRITES": "false",
        "FS_ALLOW_WRITES": "false"
      }
    }
  }
}

Or add via the CLI:

claude mcp add -s project local-wp -- npx -y @chrisfromthelc/local-wp-mcp

Then set environment variables with claude mcp add-json or by editing .mcp.json directly.

Edit the config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "local-wp": {
      "command": "npx",
      "args": ["-y", "@chrisfromthelc/local-wp-mcp"],
      "env": {
        "SITE_NAME": "My Site Name",
        "WPCLI_ALLOW_WRITES": "false",
        "MYSQL_ALLOW_WRITES": "false",
        "FS_ALLOW_WRITES": "false"
      }
    }
  }
}

Restart Claude Desktop to connect.

Add a .cursor/mcp.json to your project root, or edit ~/.cursor/mcp.json for global config:

{
  "mcpServers": {
    "local-wp": {
      "command": "npx",
      "args": ["-y", "@chrisfromthelc/local-wp-mcp"],
      "env": {
        "SITE_NAME": "My Site Name",
        "WPCLI_ALLOW_WRITES": "false",
        "MYSQL_ALLOW_WRITES": "false",
        "FS_ALLOW_WRITES": "false"
      }
    }
  }
}

Or add from Cursor Settings > Tools & MCP > New MCP Server.

Add a .vscode/mcp.json to your workspace root:

{
  "servers": {
    "local-wp": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@chrisfromthelc/local-wp-mcp"],
      "env": {
        "SITE_NAME": "My Site Name",
        "WPCLI_ALLOW_WRITES": "false",
        "MYSQL_ALLOW_WRITES": "false",
        "FS_ALLOW_WRITES": "false"
      }
    }
  }
}

Note: VS Code uses "servers" (not "mcpServers") and requires "type": "stdio".

Or use the Command Palette: MCP: Add Server.

Edit the config file:

  • macOS: ~/.codeium/windsurf/mcp_config.json

  • Windows: %USERPROFILE%\.codeium\windsurf\mcp_config.json

{
  "mcpServers": {
    "local-wp": {
      "command": "npx",
      "args": ["-y", "@chrisfromthelc/local-wp-mcp"],
      "env": {
        "SITE_NAME": "My Site Name",
        "WPCLI_ALLOW_WRITES": "false",
        "MYSQL_ALLOW_WRITES": "false",
        "FS_ALLOW_WRITES": "false"
      }
    }
  }
}

Or use the Command Palette: MCP: Add Server.


Option B: Install from source (development)

Use this if you want to modify the server, run tests, or contribute changes. You clone the repo, build it once, and point .mcp.json at your local build output.

1. Clone and build

git clone https://github.com/chrisfromthelc/local-wp-mcp.git
cd local-wp-mcp
npm install
npm run build

2. Configure your agent

Point your agent's config at the local dist/index.js instead of using npx. Use the same config format shown in the manual setup section for your agent, but replace command and args:

"command": "node",
"args": ["/absolute/path/to/local-wp-mcp/dist/index.js"]

Note: The path must be absolute (e.g., /Users/you/Projects/local-wp-mcp/dist/index.js). Relative paths won't resolve correctly when the agent spawns the process.

3. Rebuild after changes

After editing source files, rebuild before restarting your agent:

npm run build

You can also use npm run dev to watch for changes and rebuild automatically during development.

Development commands

npm run lint            # ESLint
npm run build           # TypeScript compile
npm test                # unit tests (single run)
npm run test:watch      # unit tests (watch mode)
npm run test:coverage   # unit tests with coverage report

Switching between npm and local

To switch from npm to local (or vice versa), update command and args in your agent's config:

Method

command

args

npm (npx)

"npx"

["-y", "@chrisfromthelc/local-wp-mcp"]

Local clone

"node"

["/absolute/path/to/dist/index.js"]

Everything else (env, server name) stays the same. Restart your agent after switching.


Environment variables

Variable

Description

Default

SITE_NAME

Site name as shown in Local (e.g., "My Site")

Auto-detected if only one site exists

SITE_ID

Site ID from Local (takes precedence over SITE_NAME)

WPCLI_ALLOW_WRITES

Enable write WP-CLI commands (plugin install, post create, etc.)

"false"

MYSQL_ALLOW_WRITES

Enable INSERT/UPDATE/DELETE/ALTER queries

"false"

FS_ALLOW_WRITES

Enable writing files via write_site_file (WordPress core dirs are always read-only)

"false"

WPCLI_SAFE_COMMANDS

Comma-separated list of additional read-only commands (see Plugin CLI commands)

If only one site exists in Local, SITE_NAME and SITE_ID can both be omitted — the server will connect to it automatically.

Plugin CLI commands

This MCP server isn't limited to core WP-CLI commands — it automatically supports commands registered by plugins (WooCommerce, ACF, Yoast, Elementor, etc.).

How it works

WP-CLI commands are classified using a three-tier system:

Tier

Behavior

Examples

Blocked

Always rejected (arbitrary code execution)

eval, eval-file, shell

Read-only

Always allowed

Core safe commands + any command with a read-only action verb

Write

Requires WPCLI_ALLOW_WRITES=true

Everything else

Read-only action verbs — any command whose subcommand is one of these is automatically allowed, regardless of whether it's a core or plugin command:

list, get, search, check, status, path, info, version, is-installed, check-update, pluck, has

This means commands like wc product list, acf field get my-group, or yoast index status work out of the box — no configuration needed.

Commands with write-action verbs like wc product create, acf field delete, or yoast index run are blocked unless WPCLI_ALLOW_WRITES=true is set.

Custom safe commands

If a plugin has read-only commands that don't match the built-in verb patterns (e.g., wc report sales), you can whitelist them with the WPCLI_SAFE_COMMANDS environment variable:

{
  "mcpServers": {
    "local-wp": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@chrisfromthelc/local-wp-mcp"],
      "env": {
        "SITE_NAME": "My Site Name",
        "WPCLI_ALLOW_WRITES": "false",
        "MYSQL_ALLOW_WRITES": "false",
        "WPCLI_SAFE_COMMANDS": "wc report sales,wc report customers,my-plugin dump-config"
      }
    }
  }
}

Commands in WPCLI_SAFE_COMMANDS are always allowed without writes enabled. Use comma-separated values, matching the first 2–3 words of the command.

Security

  • All commands use spawn() with argument arrays — no shell interpretation

  • Shell metacharacters rejected in both commands and arguments as defense-in-depth

  • WP-CLI eval, eval-file, and shell are always blocked

  • Dangerous flags (--exec, --require, --ssh, etc.) are blocked in all commands

  • Write operations require explicit opt-in via env vars

  • Plugin commands with read-only verbs are auto-detected and allowed

  • File paths are validated with realpath() to prevent symlink traversal

  • File reads and writes use open handles to mitigate TOCTOU race conditions

  • WordPress core directories (wp-admin/, wp-includes/) are read-only

  • Child processes inherit only necessary environment variables

  • Directory searches are capped at 10,000 files to prevent resource exhaustion

  • Output is truncated at 25,000 characters to preserve context windows

Requirements

  • Local by Flywheel installed

  • Node.js 18+

  • Site must be running in Local (services started)

License

MIT

Available Tools

10 tools
list_site_directoryList Site DirectoryA
Read-only

List files and directories in a Local by Flywheel site directory. Path is relative to the site root. Returns file names, types, and sizes.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoRelative path from site root (default: site root). E.g., "app/public/wp-content/plugins".
siteNoSite name, ID, or domain. Uses env var if not specified.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description does not contradict these. It adds useful behavioral details: returns file names, types, and sizes, and clarifies that the path is relative to the site root, which goes beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded with the primary action in the first sentence. Each sentence adds value (scope, path constraint, return types), with no unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple listing tool with detailed annotations and schema, the description covers the essential behavior: listing, path, and return contents. It lacks specifics like recursion depth or error handling, but overall it is complete enough for an agent to select and invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% as both parameters have descriptions. The tool description only restates that the path is relative (already in the schema) and doesn't add new parameter-specific meaning, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'List files and directories in a Local by Flywheel site directory.' The verb 'List' and resource are specific, and it distinguishes itself from siblings like read_site_file (reads a single file) and search_site_files (searches) by focusing on directory listing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context on when to use the tool: to enumerate files/directories with a path relative to the site root. It does not explicitly mention alternatives or exclusions, but the scope is well-defined and the example path guides usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mysql_queryRun MySQL QueryA

Execute a SQL query against the WordPress database. SELECT, SHOW, DESCRIBE, and EXPLAIN are always allowed. INSERT, UPDATE, DELETE require MYSQL_ALLOW_WRITES=true.

ParametersJSON Schema
NameRequiredDescriptionDefault
siteNoSite name, ID, or domain. Uses env var if not specified.
queryYesSQL query to execute (e.g., "SELECT * FROM wp_options WHERE option_name = 'siteurl'")

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations set readOnlyHint=false, indicating writes are possible. The description adds the specific condition (MYSQL_ALLOW_WRITES=true) and lists the always-allowed query types, which is valuable behavioral context beyond the annotations. It does not mention result format or side effects, but the write permission gating is a key disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the main purpose and followed by a constraint. Every sentence contributes essential information without redundancy or fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (arbitrary SQL execution) and lack of output schema, the description covers the core purpose and critical permission constraints. Some details like return format or handling of non-listed DDL queries are omitted, but the description is sufficient for basic use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already describes both parameters (site and query) with 100% coverage, including an example for query. The description does not add meaning beyond the schema; it only repeats that it executes a SQL query, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Execute a SQL query against the WordPress database', using the specific verb 'Execute' and identifying the resource. It also enumerates allowed query types (SELECT, SHOW, DESCRIBE, EXPLAIN) and write conditions, which distinguishes this tool from siblings like wp_cli_run (WP-CLI commands) and mysql_schema (schema browsing).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context on when the tool can be used: read-only queries are always allowed, while write operations (INSERT, UPDATE, DELETE) are gated behind MYSQL_ALLOW_WRITES=true. It does not explicitly name alternative tools or exclusions, but it gives sufficient guidance for safe usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mysql_schemaGet Database SchemaA
Read-only

Get the schema of the WordPress database. Without a table name, lists all tables. With a table name, shows column details.

ParametersJSON Schema
NameRequiredDescriptionDefault
siteNoSite name, ID, or domain. Uses env var if not specified.
tableNoTable name to inspect (e.g., "wp_options"). Omit to list all tables.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, covering safety. The description adds the conditional behavior (list all vs. column details), but much of that is already present in the input schema's table parameter description. It doesn't add information about return format, site resolution (env var fallback), or potential edge cases, making this a baseline score.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the main purpose and followed by concise conditional behavior. Every word contributes meaning; no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity, two parameters, and read-only annotations, the description adequately covers the main behavior. The only gap is the absence of return format details, but with no output schema, this is not critical. The description is complete enough for an agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both parameters thoroughly. The description largely restates the table parameter behavior ('With a table name, shows column details') without adding new semantics beyond what the schema provides. Thus, the description adds minimal value over the structured schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Get') and clearly identifies the resource ('the schema of the WordPress database'), which distinguishes it from sibling tools like mysql_query (queries) and wp_site_info (site metadata). It also communicates two distinct behaviors based on the table parameter, reinforcing its purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly explains when to use each mode: without a table name, list all tables; with a table name, show column details. This provides clear context for using the tool effectively, though it does not explicitly exclude alternatives or compare to sibling tools. That nuance keeps it at a 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_site_fileRead Site FileA
Read-only

Read a file from the Local by Flywheel site directory. Path is relative to the site root (e.g., "app/public/wp-config.php"). Files are limited to 512KB. All paths are validated against the site directory.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesRelative path from site root (e.g., "app/public/wp-content/themes/mytheme/style.css")
siteNoSite name, ID, or domain. Uses env var if not specified.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is clear. The description adds valuable constraints beyond annotations: 512KB file size limit and path validation against the site directory, which inform potential failure modes. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences: first states the purpose, second conveys constraints. Every word earns its place; no redundancy or fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read operation with full schema coverage and read-only annotations, the description covers all necessary behavioral aspects: path semantics, size cap, and validation. Siblings are clearly distinct, so no additional context is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters have descriptions. The description reinforces the relative path semantics with a concrete example ('app/public/wp-config.php') and adds practical constraints (size limit), providing value beyond the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'read' with a clear resource ('a file from the Local by Flywheel site directory') and provides a concrete path example. This distinguishes it from sibling tools like write_site_file, list_site_directory, and search_site_files.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives practical usage context: path is relative to site root, files limited to 512KB, and paths are validated. It does not explicitly name alternative tools, but the sibling names make the intended use obvious. Lacks explicit 'when not to use' guidance, so not a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_site_filesSearch Site FilesA
Read-only

Search for files by name pattern within the Local site directory. Searches recursively up to 10 levels deep, max 100 results. Skips node_modules, vendor, and dotfiles.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoDirectory to start search from, relative to site root.
siteNoSite name, ID, or domain. Uses env var if not specified.
patternYesFile name pattern to search for (e.g., "functions.php", ".css")

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral details beyond annotations: it searches recursively to a maximum depth of 10 levels, returns at most 100 results, and skips common directories (node_modules, vendor) and dotfiles. This gives the agent a clear picture of outcome limitations and filtering behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, tightly packed sentence that front-loads the core purpose and then immediately lists key constraints (recursive depth, result limit, exclusions). Every clause earns its place with no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple search tool with 3 parameters and no output schema, the description covers the essential behavior: what is searched, how deep, result cap, and exclusions. It does not explicitly state what the return value looks like (e.g., list of file paths), but given the tool's simplicity and the clarity of the operation, this is a minor gap. The description is sufficiently complete for an agent to select and invoke the tool confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all three parameters (pattern, path, site). The description does not add additional parameter-level meaning beyond what the schema provides. It references 'name pattern' in the description, aligning with the pattern parameter, but no further semantics are added. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: searching for files by name pattern within the site directory. It specifies the resource ('files'), the action ('search'), and the scope ('Local site directory'), while also differentiating from sibling tools by noting recursive search, depth limit, and exclusions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool (when you need to find files by name pattern) but does not explicitly mention alternatives or exclusions. For example, it does not say 'Use list_site_directory to browse files' or 'Use search_site_files when you need to locate a file by pattern.' The usage context is clear from the description but not explicitly differentiated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wp_active_pluginsGet Active Plugins (DB)A
Read-only

Query the database directly to get the list of active WordPress plugins.

ParametersJSON Schema
NameRequiredDescriptionDefault
siteNoSite name, ID, or domain. Uses env var if not specified.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is clear. The description adds the context that the tool queries the database 'directly', implying a direct DB access rather than a WP-CLI call. However, it does not disclose return format, performance implications, or any other behavioral details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence, front-loaded with the action and object. Every word adds value and there is no redundancy or embellishment.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (one optional parameter, clear intent) and good annotations, the description is nearly complete. The absence of an output schema means the description could specify the return format, but the purpose is transparent enough that this is not a critical gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% coverage for its single parameter 'site', with a clear description. The tool description does not add any additional parameter semantics beyond what the schema already provides, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Query the database directly to get the list of active WordPress plugins.' The verb 'get' and resource 'active WordPress plugins' are specific, and the addition of 'directly to database' distinguishes it from sibling tools like wp_cli_run.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives such as mysql_query or wp_cli_run. The description gives no context for choosing this tool, no exclusions, and no mention of alternative approaches.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wp_cli_runRun WP-CLI CommandA

Execute a WP-CLI command against a Local by Flywheel WordPress site. Commands like "plugin list", "option get siteurl", "core version" are always allowed. Write commands require WPCLI_ALLOW_WRITES=true. Commands "eval", "eval-file", and "shell" are blocked for security.

ParametersJSON Schema
NameRequiredDescriptionDefault
argsNoAdditional arguments to pass to the command
siteNoSite name, ID, or domain to target. Uses SITE_NAME/SITE_ID env var if not specified.
formatNoOutput format (e.g., "json" for structured data). Only applies to commands that support it (list, get, search). Do not use with write commands like create, update, delete.
commandYesWP-CLI subcommand to run (e.g., "plugin list", "option get siteurl", "core version", "user list")

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses that arbitrary WP-CLI commands can be executed with constraints: writes require an environment variable and certain commands are blocked for security. This adds significant behavioral context beyond the generic annotations (readOnlyHint=false, destructiveHint=false). No contradiction is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each carrying essential information: purpose, allowed commands, and write/security constraints. No wasted words and effectively front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the key aspects of the tool: allowed commands, write gate, and blocked commands. With no output schema, a note about return value would improve completeness, but the description is adequate for a command runner with well-documented parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already describes all 4 parameters (100% coverage), giving a baseline of 3. The description enriches parameter understanding by specifying allowed command examples and warning that format should not be used with write commands, adding value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Execute a WP-CLI command against a Local by Flywheel WordPress site', specifying both the verb and resource. It also lists example commands and security restrictions, which distinguishes it from sibling tools like wp_list_sites or mysql_query.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context: read-only commands are always allowed, write commands require WPCLI_ALLOW_WRITES=true, and eval/eval-file/shell are blocked. However, it does not explicitly name alternative tools for the blocked cases, so it falls short of the highest bar.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wp_list_sitesList Local SitesA
Read-only

List all WordPress sites configured in Local by Flywheel, including their names, domains, IDs, and service versions.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds the return content (names, domains, IDs, service versions), but does not disclose other behaviors like pagination or performance. This aligns with the calibration example where read-only tools with some added context score 3.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that is concise and informative. It includes all necessary details without redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple zero-parameter list tool with no output schema, the description adequately covers what the tool does and what information it returns. No additional context is needed for an agent to select and invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The description doesn't need to add parameter meaning; it focuses on the output, which is appropriate. No parameter information is missing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'List', the resource 'WordPress sites configured in Local by Flywheel', and the included output fields (names, domains, IDs, service versions). It distinguishes itself from sibling tools like wp_site_info, which likely targets a single site.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: it lists all sites, implying use when an overview of configured sites is needed. It does not explicitly mention when not to use or name alternatives, but the scope is obvious given the tool name and sibling context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wp_site_infoGet WordPress Site InfoA
Read-only

Get detailed information about the current Local by Flywheel WordPress site, including the site URL, WordPress version, active theme, and PHP version.

ParametersJSON Schema
NameRequiredDescriptionDefault
siteNoSite name, ID, or domain. Uses env var if not specified.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the tool's read-only nature is clear. The description adds transparency by specifying exactly which site details are returned, giving the agent expectation of output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is one well-crafted sentence that frontloads the action and resource, then lists concrete examples of returned data. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only info tool with one optional parameter and annotations covering safety, this description is complete. It clearly states the tool's purpose, what it retrieves, and the source (Local by Flywheel WordPress site), which is sufficient for an agent to select and invoke it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter 'site' is fully described in the schema ('Site name, ID, or domain. Uses env var if not specified.'). The description does not add information about parameter formatting or defaults beyond what the schema provides, so it relies on the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'Get' and names the resource as 'detailed information about the current Local by Flywheel WordPress site', enumerating key fields (URL, version, theme, PHP). This clearly distinguishes it from sibling tools like wp_list_sites (which lists sites) and mysql_query (which queries database).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for retrieving site details but does not explicitly state when to choose it over alternatives such as wp_cli_run or mysql_query. There is no mention of exclusions or alternative contexts, leaving room for interpretation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

write_site_fileWrite Site FileA
Destructive

Write content to a file in the Local by Flywheel site directory. Requires FS_ALLOW_WRITES=true. Cannot write to wp-admin/ or wp-includes/ (WordPress core). Path is relative to the site root.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesRelative path from site root (e.g., "app/public/wp-content/themes/mytheme/functions.php")
siteNoSite name, ID, or domain. Uses env var if not specified.
contentYesFile content to write

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already indicate destructiveHint=true and readOnlyHint=false. The description adds meaningful behavioral context by specifying the FS_ALLOW_WRITES environment requirement and the core directory restrictions, which are not fully captured by the annotations. No contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three short sentences that front-load the primary action and then compactly list requirements and restrictions. Every word earns its place, with no fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a write tool without an output schema, the description covers the key prerequisites (FS_ALLOW_WRITES), restrictions (wp-admin/ and wp-includes/), and path semantics. It doesn't mention overwrite behavior or error responses, but given the tool's simplicity and the annotation coverage, it is adequately complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with all three parameters (path, site, content) fully described in the input schema. The description's note that path is relative to site root is redundant with the schema's path description, so it adds no additional semantic value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool writes content to a file in the Local by Flywheel site directory, using a specific verb and resource. It distinguishes itself from sibling tools like read_site_file by specifying the write operation and includes constraints on wp-admin/ and wp-includes/, which further clarifies its purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context by requiring FS_ALLOW_WRITES=true and explicitly stating cannot-write-to conditions for wp-admin/ and wp-includes/. While it doesn't name alternative tools directly, the write-vs-read distinction relative to read_site_file and file-related siblings is implied through the tool's purpose and sibling context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 10 tool updatesv1.0.2
    • First observedlist_site_directory
    • First observedmysql_query
    • First observedmysql_schema
    • First observedread_site_file
    • First observedsearch_site_files
    • First observedwp_active_plugins
    • First observedwp_cli_run
    • First observedwp_list_sites
    • First observedwp_site_info
    • First observedwrite_site_file

TDQS

A4.1/5.0

Scored across 10 tools

Disambiguation4/5

Most tools target distinct resources (sites, WP-CLI, database, files). The main overlap is wp_active_plugins vs wp_cli_run 'plugin list', but descriptions clarify the direct database query vs CLI execution. Otherwise, each tool serves a clear purpose.

Naming Consistency4/5

Tools use clear prefixes for domains (wp_*, mysql_*) and consistent verb_noun for file operations (read_site_file, write_site_file). Minor inconsistency: wp_cli_run is noun_verb rather than verb_noun, and file operations lack a prefix, but the pattern is still predictable.

Tool Count5/5

10 tools is well-scoped for a local WordPress development server covering sites, WP-CLI, database, and file operations. Each tool earns its place without feeling redundant or excessive.

Completeness4/5

The surface covers core workflows: read/write files, query database, run WP-CLI, list sites, and inspect schema. A minor gap is the lack of a tool to switch the 'current site' referenced by wp_site_info, but overall the lifecycle is adequately covered.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that enables AI agents to discover, manage, and interact with LocalWP sites through integrated WP-CLI, SQL access, and backup workflows. It provides cross-platform site diagnostics and environment resolution for seamless local WordPress development.
    13 npm
    1
    ISC
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for WordPress content management that provides a secure interface for AI assistants to interact with WordPress sites, enabling content creation, editing, and media management without destructive operations.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Turns any WordPress site into an MCP server, allowing AI clients to directly control files, database, WP-CLI, PHP, content, and more through declarative abilities without writing code.
    1
    GPL 2.0