mcpField
M
MCP Local WP

MCP Local WP

本地服务
verygoodplugins.com数据库342 周前更新

关于 MCP Local WP

MCP Local WP 是一个 MCP 服务,让 AI 助手以只读方式访问 Local by Flywheel 管理的 WordPress 数据库。它可执行 MySQL 查询并查看表结构,适合 WordPress 开发者在编写 SQL 前先核对真实数据结构。

主要功能

  1. 01只读执行 MySQL 查询
  2. 02查看表结构、列与索引
  3. 03自动识别 Local 站点与 MySQL 实例
  4. 04支持按站点名称或 ID 选择站点
  5. 05查看当前连接站点信息

适用场景

  1. 01让 AI 助手核对 WordPress 表结构后再编写查询
  2. 02调试 LearnDash、WooCommerce 等插件的自定义表
  3. 03在 Claude Code 或 Cursor 中按当前目录连接对应站点数据库

MCP 相关

该项目是一个 MCP 服务,向 MCP 客户端暴露 mysql_query、mysql_schema、mysql_current_site 和 mysql_list_sites 等工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"verygoodplugins-mcp-local-wp": {
"command": "npx",
"args": [
"-y",
"@verygoodplugins/mcp-local-wp"
]
}
}
}
启动命令npx -y @verygoodplugins/mcp-local-wp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@verygoodplugins/mcp-local-wp2.0.0

工具

4

收录的工具列表 · 更新于 2 周前

参数类型必填说明
sqlstring是一条 SQL 语句;禁止使用可执行注释。
paramsarray否SQL 占位符 (?) 的值。

详细介绍

MCP Server Local WP

🎯 如果你的 AI 助手真的能看到你的 WordPress 数据库,会怎样?

一个模型上下文协议(MCP)服务,可让 Claude 和 Cursor 等 AI 助手直接以只读方式访问你的 Local by Flywheel WordPress 数据库。不再猜测表结构,不再盲目编写 SQL 查询。现在,你的 AI 可以了解你的实际数据。

升级到 2.0

2.0 版本要求使用 Node.js 24 或更高版本,并使用 MCP SDK v2。现有工具名称和站点选择器仍然可用。查询结果现在为 { "rows": [...] };架构列表返回 { "tables": [...], "hasMore": false, "nextAfter": null },其中表名分页有数量限制。成功调用的工具会返回相匹配的结构化结果和 JSON 文本结果;失败时会设置 isError: true。

数据库和 Local 配置会延迟解析,因此即使没有正在运行的站点,也可以发现 MCP 工具。显式设置 MYSQL_HOST 或 MYSQL_SOCKET_PATH 会选择手动连接。请保持 stdin 打开,直到收到所有工具响应;EOF 会关闭会话。父级 watchdog 也会清理已弃用的 stdio 服务。

🤔 什么是 MCP 服务?

可以把 MCP(模型上下文协议)看作 AI 助手与开发工具之间的安全桥梁。无需复制粘贴数据库架构或查询结果,MCP 服务就能让 AI 助手直接与你的工具交互,同时让你完全掌控整个过程。

不使用 MCP:“嘿,AI,我觉得有个表叫 wp_something,其中可能有个列名是 user_meta……你能写个查询吗?”
使用 MCP:“嘿,AI,看看我的数据库里有什么,并写出我需要的准确查询。”

💡 WordPress 开发者的两难

想象一下:你正在调试 LearnDash 集成问题。测验结果无法正常同步。你启动 Cursor 来帮忙诊断问题,但没有数据库访问权限,即使是最先进的 AI,也只能根据表结构做出有根据的猜测。

真实影响

下面是我们处理过的一张实际支持工单。任务很简单:从 LearnDash 表中获取测验活动数据。

❌ 使用 MCP 服务前(AI 盲目摸索):

Very Good Plugins  Cursor+Diagnose LearnDash quiz field syncing issue — wp-fusion (Workspace)  2025-09-09 at 12 34 38

AI 尽力尝试,给出了这个查询建议:

$quiz_activities = $wpdb->get_results(
  $wpdb->prepare(
    'SELECT post_id, activity_meta FROM ' . esc_sql( LDLMS_DB::get_table_name( 'user_activity' ) ) . '
     WHERE user_id=%d AND activity_type=%s AND activity_status=1 AND activity_completed IS NOT NULL',
    $user_id,
    'quiz'
  ),
  ARRAY_A
);

问题在哪? activity_meta 列并不存在!LearnDash 将元数据存储在一个结构完全不同的独立表中。由于无法访问数据库,AI 做出了合理但错误的假设。你接下来得花 20 分钟手动修正表名、找出表之间的关系,并重写查询。

✅ 使用 MCP 服务后(AI 如同拥有 X 射线视力):

Very Good Plugins  Cursor+Diagnose LearnDash quiz field syncing issue — wp-fusion (Workspace)  2025-09-09 at 12 54 07

有了数据库访问权限,AI 立即看到了实际的表结构,并写出了:

$quiz_activities = $wpdb->get_results(
  $wpdb->prepare(
    'SELECT ua.post_id, ua.activity_id, uam.activity_meta_key, uam.activity_meta_value
     FROM ' . esc_sql( LDLMS_DB::get_table_name( 'user_activity' ) ) . ' ua
     LEFT JOIN ' . esc_sql( LDLMS_DB::get_table_name( 'user_activity_meta' ) ) . ' uam
     ON ua.activity_id = uam.activity_id
     WHERE ua.user_id=%d AND ua.activity_type=%s AND ua.activity_completed IS NOT NULL
     AND uam.activity_meta_key IN (%s, %s, %s)',
    $user_id,
    'quiz',
    'percentage',
    'points',
    'total_points'
  ),
  ARRAY_A
);

区别在哪? AI 能看到元数据存储在独立的 user_activity_meta 表中,理解它们通过 activity_id 关联,也清楚有哪些 meta 键。一次成功,无需猜测。问题解决。

🚀 为什么这会改变一切

当你的 AI 助手可以读取数据库时:

  • 不再猜测架构 — 它能看到实际的表和列
  • 准确执行 JOIN 操作 — 它能理解表之间的关系
  • 验证真实数据 — 在建议查询前,它可以确认数据是否存在
  • 适配插件开发 — 它能适应任何插件的自定义表(WooCommerce、LearnDash 等)
  • 即时调试 — “显示所有尚未完成 ID 为 42 的测验的用户”只需 5 秒

🔧 我们解决的 Local by Flywheel 难题

在 Local by Flywheel 中使用原版 mcp-server-mysql 时,开发者会遇到几个难题:

  1. 动态路径:Local by Flywheel 会为每个站点生成唯一标识符(例如 lx97vbzE7),站点重启后标识符会改变
  2. 套接字与端口混淆:Local 同时使用 Unix 套接字和 TCP 端口,但配置起来可能比较棘手
  3. 硬编码配置:大多数设置都要求每次 Local 重启后手动更新路径

我们的解决方案

此 MCP 服务会自动检测当前运行的 Local by Flywheel MySQL 实例,方法如下:

  1. 进程检测:扫描正在运行的进程,查找活动的 mysqld 实例
  2. 配置解析:从活动的 Local 站点中提取 MySQL 配置
  3. 动态连接:自动使用正确的套接字路径或端口进行连接
  4. 回退支持:对于非 Local 设置,回退使用环境变量

多站点支持

当你有多个 Local 站点时,服务会使用基于优先级的站点选择,确保始终连接到正确的数据库:

选择优先级
  1. SITE_ID 环境变量 - 直接指定站点 ID(最高优先级)
  2. SITE_NAME 环境变量 - 根据易读的站点名称查找
  3. 工作目录检测 - 如果当前工作目录位于 Local 站点路径下,则使用该站点
  4. 进程检测 - 使用找到的第一个正在运行的 Local mysqld
  5. 文件系统回退 - 使用最近修改的套接字
明确选择站点

在 MCP 配置中指定要连接的站点:

{
  "mcpServers": {
    "wordpress-dev": {
      "command": "npx",
      "args": ["-y", "@verygoodplugins/mcp-local-wp@latest"],
      "env": {
        "SITE_NAME": "dev"
      }
    }
  }
}

或者直接使用站点 ID:

{
  "env": {
    "SITE_ID": "lx97vbzE7"
  }
}
工作目录检测

使用 Claude Code 或 Cursor 时,服务会根据当前目录自动检测你正在使用的站点。如果你正在编辑 /Users/.../Local Sites/dev/app/public/wp-content/plugins/my-plugin/ 中的文件,服务会自动连接到“dev”站点的数据库。

验证连接

使用 mysql_current_site 工具查看当前连接的站点:

{
  "siteName": "dev",
  "siteId": "lx97vbzE7",
  "sitePath": "/Users/.../Local Sites/dev",
  "domain": "dev.local",
  "selectionMethod": "cwd_detection",
}

使用 mysql_list_sites 查看所有可用站点及其状态。

可用工具

mysql_query

对 Local WordPress 数据库执行只读 SQL 查询。

输入字段:

  • sql(string):单条只读语句(SELECT,包括 WITH CTE,或 SHOW/DESCRIBE/EXPLAIN)
  • params((string | number | boolean | null)[]):可选的 ? 占位符参数值

使用示例:

-- With parameters
SELECT * FROM wp_posts WHERE post_status = ? ORDER BY post_date DESC LIMIT ?;
-- params: ["publish", "5"]

-- Direct queries
SELECT option_name, option_value FROM wp_options WHERE option_name LIKE '%theme%';
SHOW TABLES;
DESCRIBE wp_users;

-- Common table expression (CTE)
WITH published AS (SELECT ID, post_title FROM wp_posts WHERE post_status = ?)
SELECT * FROM published LIMIT 10;
-- params: ["publish"]
mysql_schema

使用 INFORMATION_SCHEMA 检查数据库架构。

  • 无参数:按二进制名称排序,最多列出 100 个表名,并返回 hasMore 和 nextAfter
  • 列表选项:prefix(区分大小写的字面前缀)、limit(1–200)、after(上一页的 nextAfter)和 includeStats(默认为 false)
  • 使用 table:返回该表的列和索引

当 hasMore 为 true 时,将 nextAfter 作为 after 传入,并保持使用相同的前缀,以获取下一页。最后一页的 hasMore 为 false,且 nextAfter 为 null。默认情况下,列表行仅包含 table_name;includeStats: true 会额外返回引擎、估算行数、数据字节数和索引字节数。前缀中的 % 和 _ 是字面字符。使用 table 单独进行详细检查;它不能与列表选项组合使用。每一页反映的是当前架构,因此请求之间的表变更可能会影响列表。

示例:

// First page of table names
{
  "tool": "mysql_schema",
  "args": {}
}

// Filter to WordPress tables and include statistics
{
  "tool": "mysql_schema",
  "args": { "prefix": "wp_", "limit": 50, "includeStats": true }
}

// Continue a filtered listing using the previous response's nextAfter
{
  "tool": "mysql_schema",
  "args": { "prefix": "wp_", "limit": 50, "after": "wp_posts" }
}

// Inspect a specific table
{
  "tool": "mysql_schema",
  "args": { "table": "wp_posts" }
}
mysql_current_site

获取当前连接的 Local WordPress 站点信息。

返回站点名称、ID、路径、域名、套接字路径,以及站点的选择方式(环境变量、当前工作目录检测或自动检测)。

{
  "tool": "mysql_current_site",
  "args": {},
}
// Returns:
// {
//   "siteName": "dev",
//   "siteId": "lx97vbzE7",
//   "sitePath": "/Users/.../Local Sites/dev",
//   "domain": "dev.local",
//   "selectionMethod": "cwd_detection",
//   "socketPath": "/Users/.../Local/run/lx97vbzE7/mysql/mysqld.sock"
// }
mysql_list_sites

列出所有可用的 Local WordPress 站点及其运行状态。

{
  "tool": "mysql_list_sites",
  "args": {},
}
// Returns:
// {
//   "sites": [
//     { "id": "lx97vbzE7", "name": "dev", "domain": "dev.local", "running": true },
//     { "id": "WP7lolWDi", "name": "staging", "domain": "staging.local", "running": false }
//   ],
//   "currentSiteId": "lx97vbzE7"
// }

安装

先决条件
  • 已安装并运行 Local by Flywheel
  • 有一个正在运行的活动 Local 站点
  • Node.js 24+

快速设置(推荐)

最简单的入门方式——无需安装:

Cursor IDE 配置

将以下内容添加到 Cursor MCP 配置文件(.cursor/mcp.json)中:

{
  "mcpServers": {
    "mcp-local-wp": {
      "command": "npx",
      "args": ["-y", "@verygoodplugins/mcp-local-wp@latest"]
    }
  }
}
Claude Desktop 配置

将以下内容添加到 Claude Desktop 配置文件中:

macOS:~/Library/Application Support/Claude/claude_desktop_config.json Windows:%APPDATA%\\Claude\\claude_desktop_config.json

{
  "mcpServers": {
    "mcp-local-wp": {
      "command": "npx",
      "args": ["-y", "@verygoodplugins/mcp-local-wp@latest"]
    }
  }
}

高级设置(本地开发)

如需自定义或进行本地开发:

从源代码安装
git clone https://github.com/verygoodplugins/mcp-local-wp.git
cd mcp-local-wp
npm install
npm run build
本地配置
{
  "mcpServers": {
    "mcp-local-wp": {
      "command": "node",
      "args": ["/full/path/to/mcp-local-wp/dist/index.js"]
    }
  }
}
自定义环境变量

用于非 Local 设置或自定义配置:

{
  "mcpServers": {
    "mcp-local-wp": {
      "command": "npx",
      "args": ["-y", "@verygoodplugins/mcp-local-wp@latest"],
      "env": {
        "MYSQL_DB": "local",
        "MYSQL_HOST": "localhost",
        "MYSQL_PORT": "3306",
        "MYSQL_USER": "root",
        "MYSQL_PASS": "root"
      }
    }
  }
}
站点选择变量
变量说明示例
SITE_ID显式指定站点 ID(优先级最高)lx97vbzE7
SITE_NAME用于查找的站点名称dev
LOCAL_SITES_JSON覆盖 Local 的 sites.json 路径/custom/path/sites.json
LOCAL_RUN_DIR覆盖 Local 的运行目录/custom/run/path

与 Local by Flywheel 的工作原理

创建此 MCP 服务,是因为使用现有 MCP 服务连接到 Local by Flywheel MySQL “有点难以正常运行”。以下是我们解决问题的过程:

最初的问题

首次尝试将 mcp-server-mysql 与 Local by Flywheel 配合使用时,我们遇到了几个问题:

  1. 动态套接字路径:Local 会生成类似 /Users/.../Local/run/lx97vbzE7/mysql/mysqld.sock 的路径,其中 lx97vbzE7 会在每次重启 Local 时发生变化
  2. 配置复杂:原始服务需要写死路径,每次重启 Local 都会导致路径失效
  3. 主机/端口混淆:Local 的 MySQL 配置可能比较棘手,因为它同时支持套接字和 TCP 连接
我们的解决过程

我们逐步解决了这些问题:

1. 基于进程进行检测

我们不再猜测路径,而是扫描实际运行的 MySQL 进程:

ps aux | grep mysqld | grep -v grep

这样可以找到活动的 MySQL 实例并提取其配置文件路径。

2. 动态解析路径
// From the process args: --defaults-file=/Users/.../Local/run/lx97vbzE7/conf/mysql/my.cnf
// We extract the site directory and build the socket path
const configPath = extractFromProcess();
const siteDir = path.dirname(path.dirname(path.dirname(configPath)));
const socketPath = path.join(siteDir, 'mysql/mysqld.sock');
3. 自动配置

服务会自动完成以下配置:

  • 为活动的 Local 站点设置正确的套接字路径
  • 设置正确的数据库名称(local)
  • 设置默认凭据(root/root)
  • 必要时回退到环境变量
此方法为何有效

✅ 重启后仍可使用:每次重启 Local by Flywheel 后都能正常工作
✅ 切换站点:在不同 Local 站点之间切换时会自动适配
✅ 无需维护:再也不必手动更新路径
✅ 错误处理:MySQL 未运行时会提供清晰的错误消息

我们处理的 Local 目录结构
~/Library/Application Support/Local/run/
├── lx97vbzE7/                    # Dynamic site ID (changes on restart)
│   ├── conf/mysql/my.cnf        # We read this for port info
│   └── mysql/mysqld.sock        # We connect via this socket
└── WP7lolWDi/                   # Another site (if multiple running)
    ├── conf/mysql/my.cnf
    └── mysql/mysqld.sock

服务会智能地找到活动站点,并连接到正确的 MySQL 实例。

使用示例

连接后,可以使用 mysql_query 工具,对 Local WordPress 数据库执行允许的只读 SQL 查询:

获取最近发布的文章
SELECT ID, post_title, post_date, post_status
FROM wp_posts
WHERE post_type = 'post' AND post_status = 'publish'
ORDER BY post_date DESC
LIMIT 5;
探索数据库结构
-- See all tables
SHOW TABLES;

-- Examine a table structure
DESCRIBE wp_posts;

-- Get table info
SHOW TABLE STATUS LIKE 'wp_%';
WordPress 专用查询
-- Get site options
SELECT option_name, option_value
FROM wp_options
WHERE option_name IN ('blogname', 'blogdescription', 'admin_email');

-- Find active plugins
SELECT option_value
FROM wp_options
WHERE option_name = 'active_plugins';

-- Get user information
SELECT user_login, user_email, display_name
FROM wp_users
LIMIT 10;

-- Post meta data
SELECT p.post_title, pm.meta_key, pm.meta_value
FROM wp_posts p
JOIN wp_postmeta pm ON p.ID = pm.post_id
WHERE p.post_type = 'post' AND pm.meta_key = '_edit_last';

开发设置

从源代码运行
  1. 启动 Local 站点:确保有一个正在运行的 Local by Flywheel 活动站点

  2. 克隆并构建:

    git clone https://github.com/verygoodplugins/mcp-local-wp.git
    cd mcp-local-wp
    npm install
    npm run build
    
  3. 测试连接:

    node dist/index.js
    
开发模式
npm run dev

此模式会运行服务,并使用 TypeScript 监视更改。

代码检查与格式化
  • 代码检查:npm run lint
  • 修复代码检查问题:npm run lint:fix
  • 格式化:npm run format
  • 检查格式:npm run format:check

通过 ESLint + Prettier 统一 MCP 服务的规范。

故障排除

常见问题
  1. “未找到正在运行的 MySQL 进程”

    • 确保 Local by Flywheel 正在运行
    • 确保 Local 中至少有一个站点已启动
    • 检查该站点的数据库是否正在运行
  2. “未找到 MySQL 套接字”

    • 确认 Local 站点已完全启动
    • 尝试在 Local 中停止并重新启动该站点
    • 检查 Local 日志,查看是否存在 MySQL 启动问题
  3. 连接被拒绝

    • 确保 Local 站点的 MySQL 服务正在运行
    • 检查是否有其他进程正在使用 MySQL 端口
    • 尝试重新启动 Local by Flywheel
  4. 权限被拒绝

    • 确保 MySQL 套接字文件具有正确的权限
    • 检查你的用户是否有权访问 Local 目录
手动配置

如果自动检测失败,你可以手动配置连接:

export MYSQL_SOCKET_PATH="/path/to/your/local/site/mysql/mysqld.sock"
export MYSQL_DB="local"
export MYSQL_USER="root"
export MYSQL_PASS="root"
调试

通过设置 DEBUG 启用调试日志:

DEBUG=mcp-local-wp mcp-local-wp

安全

mysql_query 接受一条 SELECT/SHOW/DESCRIBE/DESC/EXPLAIN 语句,包括以 WITH 或 WITH RECURSIVE 开头的 SELECT 查询。CTE 查询体和最终查询表达式必须解析为 SELECT,包括嵌套的 WITH … SELECT 和带括号的查询;WITH … UPDATE/DELETE 会被拒绝。支持 MariaDB 的 CYCLE … RESTRICT 子句用于循环检测。分词器会根据连接的 SQL 模式检查实际 SQL 词元。整条语句中的可执行 MySQL/MariaDB 注释、优化器提示、文件输出、SELECT INTO、锁定读取、咨询锁函数和 EXPLAIN ANALYZE 都会被拒绝,包括 CTE 查询体。支持普通注释和带引号值中的分号。

每次读取都在专用连接上、由数据库强制执行的只读事务中运行。设置失败会停止执行;清理失败则会丢弃该连接。MYSQL_ALLOW_WRITES=true 会在单独的连接上启用 mysql_write;它不会取消对 mysql_query 的保护。写入语句允许 INSERT/UPDATE/DELETE。UPDATE/DELETE 的 WHERE 子句中必须使用列与绑定参数进行比较,且可选择用 AND/OR 组合;IN、BETWEEN 和 LIKE 也支持绑定值。仅包含裸占位符或字面值的谓词会被拒绝。架构操作和写入子查询仍会被禁止。

为获得额外保护,请配置一个仅对所选数据库具有 SELECT 权限且不具备 FILE 或 EXECUTE 权限的专用账户。MYSQL_USER 和 MYSQL_PASS 同样适用于自动检测到的 Local 站点和手动连接。服务端不会创建用户或更改授权。只读事务无法隔离临时表或任意原生扩展;对于不受信任的数据库,请使用最小权限凭据。

此服务支持本地开发;可用时使用 Unix 套接字,显式连接则使用 TCP。请通过 GitHub Security Advisories 或 [email protected] 私下报告漏洞。

贡献

欢迎贡献!欢迎提交 Pull Request。

开发指南
  1. Fork 此仓库
  2. 创建功能分支:git checkout -b feature/your-feature-name
  3. 进行更改并添加测试
  4. 确保 TypeScript 编译通过:npm run build
  5. 提交 pull request

许可证

GPL-3.0-or-later——详情请参阅 LICENSE 文件。作为一款面向 WordPress 的工具,我们秉持 copyleft 理念,确保它继续免费向社区开放。

支持

  • GitHub Issues:报告错误或请求功能
  • 文档:本 README 和内联代码文档
  • 社区:参与 Model Context Protocol 社区讨论

相关项目


由 Jack Arturo 在 Very Good Plugins 倾情打造 🧡 · 满怀热忱地献给开源社区

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。