内容
<div align="center">
<img src="assets/wpmcp-icon.svg" width="112" alt="wpmcp logo">
# wpmcp
### 构建和编辑WordPress网站的AI代理,物理上无法破坏它。
带有快照和一键回滚功能的WordPress MCP服务器。
[](https://github.com/fahdi/wpmcp/actions/workflows/ci.yml)
[](LICENSE)
[](https://php.net)
[](https://wordpress.org)
[](CONTRIBUTING.md)
</div>
---
给一个AI代理(Claude、Cursor或任何MCP客户端)你的WordPress网站的权限,有一件事令人恐惧:在一个实时客户端网站上进行一个糟糕的编辑,你无法撤销。所有其他的WordPress AI工具都要求你信任模型。**wpmcp则相反:它假设代理会出错,并确保它做的任何事情都不是永久的。**
每次写入操作都会快照。如果更改破坏了页面,它会自动回滚。如果您不喜欢代理执行的操作,您可以通过一次点击撤销一个操作或整个会话。这是整个产品:一个您可以放心让其接近实时网站的AI网站构建器。
> **状态:** 早期MVP。安全引擎和首批工具已经交付和测试。有关下一步计划,请参见[路线图](#roadmap)。
## 为什么选择wpmcp
- **设计可恢复。** 除非通过包装器快照,否则任何变异工具都无法触及数据库。这是在代码中强制执行的,而不是按照惯例。
- **构建者无关的安全。** 快照是在WordPress数据层(帖子内容、元数据、选项)中进行的,因此回滚适用于任何页面构建器,而无需解析其格式。
- **在WordPress中运行。** 一个插件,位于官方[WordPress Abilities API](https://developer.wordpress.org/)上,而不是一个单独的本地代理进程。一个安装程序,与任何MCP客户端一起工作。
- **免费和开源。** GPL-2.0。整个安全引擎和Gutenberg工具都是免费的。
## 工作原理
所有变异工具都通过一个协调器`Safe_Mutation::run()`:
```
快照(之前)-> 应用更改 -> 验证 -> 确认?
| | |
存储在 失败时: 返回
wp_wpmcp_snapshots 自动回滚 操作ID
(按操作+会话键控) + 引发错误
```
1. **快照。** 在任何写入操作之前,wpmcp捕获目标的快照图像(帖子内容、标题、状态和所有元数据),并将其压缩存储在一个专用表中,按操作ID和代理会话ID键控。
2. **应用。** 工具执行其编辑。
3. **验证。** 运行一个轻量级检查(对于Gutenberg,块标记必须仍然解析)。如果失败,则更改立即回滚,并引发错误。
4. **按需回滚。** 撤销单个操作,或将代理的整个会话回滚到其会话前状态,包括清除代理添加的任何元数据。
您可以通过AI(`rollback-operation`和`rollback-session`工具)或从wp-admin中的**wpmcp**屏幕驱动回滚,每个代理操作都列出一个单击恢复按钮。
## 要求
| 依赖 | 版本 |
| --- | --- |
| WordPress | >= 6.9(捆绑了Abilities API) |
| PHP | >= 8.1 |
| Composer | 用于从源代码安装 |
## 安装
wpmcp尚未在wp.org插件目录上(计划中)。目前,请从源代码安装:
```bash
git clone https://github.com/fahdi/wpmcp.git wp-content/plugins/wpmcp
cd wp-content/plugins/wpmcp
composer install --no-dev
```
然后在wp-admin的插件屏幕中激活**wpmcp**。
## 连接您的AI客户端
wpmcp通过Model Context Protocol公开其工具。使用WordPress[应用程序密码](https://make.wordpress.org/core/2020/11/05/application-passwords-integration-guide/)(用户->配置文件->应用程序密码)进行身份验证。
Claude Code示例,在您的项目中的`.mcp.json`:
```json
{
"mcpServers": {
"wpmcp": {
"type": "http",
"url": "https://your-site.com/wp-json/mcp/wpmcp-server",
"headers": {
"Authorization": "Basic BASE64_OF_username:application-password"
}
}
}
}
```
使用以下命令生成凭证:
```bash
echo -n "your-username:xxxx xxxx xxxx xxxx xxxx xxxx" | base64
```
与Cursor、Claude Desktop和任何MCP兼容的客户端相同的端点。
## 可用工具
| 工具 | 类型 | 功能 |
| --- | --- | --- |
| `get-page` | 读取 | 读取页面的标题、内容和是否为Elementor页面 |
| `update-blocks` | 写入(安全) | 替换页面的Gutenberg块标记,快照和验证 |
| `list-operations` | 安全 | 列出最近的代理操作(无快照有效载荷泄露) |
| `rollback-operation` | 安全 | 按ID撤销单个操作 |
| `rollback-session` | 安全 | 将整个代理会话回滚到其会话前状态 |
| `list-post-types` | 读取 | 列出注册的帖子类型(帖子、页面、自定义帖子类型) |
| `list-taxonomies` | 读取 | 列出注册的分类法(类别、标签、自定义分类法) |
| `create-post` | 写入 | 创建帖子、页面或自定义帖子类型,带有术语和元数据 |
| `get-post` | 读取 | 读取帖子的完整内容、状态、术语、元数据和特色图像 |
| `update-post` | 写入(安全) | 部分更新帖子的字段、术语、元数据或特色图像 |
| `delete-post` | 写入(安全强制) | 默认情况下将帖子放入回收站,或使用`force: true`永久删除 |
| `list-posts` | 读取 | 按类型、状态、搜索文本、作者或父级搜索/列出帖子 |
| `set-post-terms` | 写入(安全) | 将分类法术语分配给帖子:替换、追加或删除 |
| `get-media` | 读取 | 读取媒体库附件的完整详细信息:大小、尺寸、元数据、替代文本、标题、描述 |
| `update-media` | 写入(安全) | 更新附件的标题、替代文本、标题和/或描述 |
| `delete-media` | 写入(安全) | 删除媒体库附件。默认情况下禁用,需要`confirm: true` |
| `sideload-image` | 写入 | 从URL将图像下载到媒体库作为新附件 |
| `get-settings` | 读取 | 读取站点设置(常规、阅读、写作、讨论、媒体、永久链接)及其组/类型/可写元数据 |
| `update-settings` | 写入(安全) | 更新允许的站点设置;验证/强制每个值并应用有效子集 |
| `list-users` | 读取 | 列出用户为安全摘要行(ID、用户名、显示名称、电子邮件、角色);永远不会返回密码哈希 |
| `get-user` | 读取 | 读取一个用户的配置文件详细信息以及从实时功能派生的`is_admin`标志;永远不会返回密码哈希 |
| `create-user` | 写入 | 创建非管理员用户;自动生成强密码(永远不会返回)并向用户发送电子邮件;拒绝管理员和未知角色 |
| `update-user` | 写入(安全) | 更新非管理员用户的配置文件字段;拒绝具有管理员权限的用户;永远不会更改角色或密码 |
| `list-plugins` | 读取 | 列出已安装的插件及其活动状态、受保护包标志和待更新信息 |
| `activate-plugin` | 写入(安全) | 激活已安装的插件;快照之前的`active_plugins`选项 |
| `deactivate-plugin` | 写入(安全) | 停用插件;拒绝受保护的包(wpmcp、Elementor);快照之前的`active_plugins`选项 |
| `install-plugin` | 写入 | 从wordpress.org安装插件,按slug,可选激活 |
| `search-plugins` | 读取 | 按关键字搜索wordpress.org插件目录,带有可选标签/作者过滤器和上限`per_page` |
| `get-plugin-info` | 读取 | 为slug获取完整的wordpress.org插件目录信息:版本、评分、安装量、主页、下载链接和兼容性 |
| `update-plugin` | 写入(不可逆) | 更新wordpress.org的已安装插件。默认情况下禁用,需要`confirm: true`;不可回滚 |
| `delete-plugin` | 写入(不可逆) | 永久删除已安装插件的文件。默认情况下禁用,需要`confirm: true`;拒绝受保护或活动的插件;不可回滚 |
| `list-themes` | 读取 | 列出已安装的主题及其活动状态、父主题和待更新信息 |
| `switch-theme` | 写入(安全) | 激活(切换到)已安装的主题;快照之前的`template`/`stylesheet`选项 |
| `install-theme` | 写入 | 从wordpress.org安装主题,按slug,可选激活 |
| `update-theme` | 写入(不可逆) | 更新wordpress.org的已安装主题。默认情况下禁用,需要`confirm: true`;不可回滚 |
| `delete-theme` | 写入(不可逆) | 永久删除已安装主题的文件。默认情况下禁用,需要`confirm: true`;拒绝活动主题(或其活动父主题);不可回滚 |
| `list-tables` | 读取 | 列出数据库表及其估计的行数和大小 |
| `describe-table` | 读取 | 返回数据库表的列、类型和键 |
| `query` | 读取 | 运行只读SQL查询(`SELECT`/`SHOW`/`DESCRIBE`/`EXPLAIN`/`WITH`);写入、DDL、堆叠语句和文件访问SQL在执行前被拒绝;结果上限 |
| `insert-row` | 写入 | 通过`$wpdb->insert()`将行插入表中。默认情况下禁用;拒绝受保护的表 |
| `update-rows` | 写入(不可逆) | 通过`$wpdb->update()`更新匹配强制等式WHERE的行。默认情况下禁用;拒绝受保护的表;捕获快照到写入审计日志但诚实地表示不可恢复(`recoverable: false`) |
| `delete-rows` | 写入(不可逆) | 通过`$wpdb->delete()`删除匹配强制等式WHERE的行。默认情况下禁用,需要`confirm: true`;拒绝受保护的表;捕获快照到写入审计日志但诚实地表示不可恢复(`recoverable: false`) |
| `read-file` | 读取 | 读取WordPress安装内部的文件(核心、插件、主题、上传);路径仅限于安装根目录 |
| `list-directory` | 读取 | 列出目录的条目(文件/目录,带大小和mtime);可选的有界递归列表 |
| `search-files` | 读取 | 在目录树中搜索文件内容以获取子字符串;可按扩展名过滤,结果上限 |
| `write-file` | 写入(安全) | 创建或覆盖文件。默认情况下禁用;备份现有文件以使更改可恢复 |
| `edit-file` | 写入(安全) | 替换文件中的确切字符串(必须完全匹配,除非`replace_all`)。默认情况下禁用;备份原始文件 |
| `delete-file` | 写入(安全) | 删除文件。默认情况下禁用,需要`confirm: true`;备份文件以使删除可恢复 |
| `analyze-performance` | 读取 | 扫描服务器配置、WordPress内部(数据库大小、自动加载选项、cron积压、对象缓存、OPcache、插件数量)和目标页面(默认为首页)是否存在性能问题;返回一个得分报告(0-100,分为A-F)及排名建议 |
| `get-cache-status` | 读取 | 报告哪些缓存层是活动的:持久对象缓存后端、OPcache和任何活动页面缓存插件(WP Rocket、W3 Total Cache、WP Super Cache、LiteSpeed Cache、WP Fastest Cache) |
| `clear-cache` | 写入(安全) | 清除对象缓存、删除所有瞬时变量、重置OPcache(如果启用)和清除任何检测到的页面缓存插件;返回每个层的总结。安全且幂等,因此不快照 |
| `get-connection-info` | 读取 | 返回此站点的MCP端点URL和克劳德代码、Cursor和克劳德桌面的一键粘贴连接片段,每个片段使用占位符应用程序密码(永远不是真正的凭证) |
| `list-tool-catalog` | 读取 | 列出此站点注册的每个wpmcp能力,按域分组,每个条目的层级、操作、功能和只读/破坏提示,以及每个域的总结计数 |
除`create-post`、`sideload-image`、`create-user`、`install-plugin`、`install-theme`和`insert-row`外,每个写入工具都包装在安全引擎中;每个工具仅创建一个全新的对象,因此没有预先存在的快照或回滚。读取和回滚由`edit_posts`能力控制。`create-user`和`update-user`另外由`create_users`和`edit_users`能力控制;包工具由其匹配的WordPress能力控制(`activate_plugins`、`install_plugins`、`update_plugins`、`delete_plugins`、`switch_themes`、`install_themes`、`update_themes`、`delete_themes`);所有六个数据库工具(包括读取)由`manage_options`控制,因为原始表/行访问等同于phpMyAdmin级别的站点访问权限。 `delete-media`另外要求站点通过`wpmcp_enable_delete_media`过滤器选择加入才能运行;`update-plugin`、`delete-plugin`、`update-theme`和`delete-theme`默认情况下也禁用,通过它们自己的`wpmcp_enable_*`过滤器,并且始终需要`confirm: true`,因为更新或删除文件不可回滚(无文件备份,见问题#24)并且每个响应都诚实地表示文件不可恢复(`files_recoverable: false`)。`update-settings`快照每个更改的选项,`update-user`快照用户的配置文件字段和用户元数据,`activate-plugin`/`deactivate-plugin`/`switch-theme`快照它们更改的选项(),因此可以通过`rollback-operation`撤销批处理写入的子集。故意没有删除用户或角色更改工具。`insert-row`、`update-rows`和`delete-rows`默认情况下通过`wpmcp_enable_db_writes`过滤器禁用;`update-rows`和`delete-rows`另外需要非空的`where`(并且`delete-rows`需要`confirm: true`),并拒绝`wp_users`/`wp_usermeta`表(通过`wpmcp_db_protected_tables`过滤器扩展)。由于通用任意表回滚超出安全引擎的快照/还原逻辑的范围,因此这两个捕获快照到上限审计日志并报告`recoverable: false`而不是声称无法执行的撤销。所有六个文件系统工具(包括读取)由`manage_options`控制,原因与数据库工具相同:原始文件系统访问至少与原始表访问一样敏感。每个文件路径通过`Filesystem_Guard::resolve_path()`限制在WordPress安装根目录(`ABSPATH`)内,该目录通过`realpath()`规范化,因此路径遍历(`../`)、指向根目录外部的符号链接、空字节和绝对路径逃出根目录都被拒绝。 `wp-config.php`和`.htaccess`对于每个写入/编辑/删除操作都被拒绝,无论路径如何(通过`wpmcp_fs_protected_paths`过滤器扩展)。`write-file`、`edit-file`和`delete-file`默认情况下通过`wpmcp_enable_fs_writes`过滤器禁用,还需要`edit_files`能力,并遵守`DISALLOW_FILE_EDIT`;与数据库写入工具不同,文件写入操作的快照图像是完整的字节对字节备份副本(不是审计日志记录),因此响应中的`recoverable: true`是一个真正的、经过测试的保证:原始文件可以恢复确切,不仅仅是记录。`analyze-performance`是只读的,由`manage_options`控制,原因与数据库和文件系统工具相同:它暴露了服务器、数据库和页面内部。它的可选页面获取是SSRF安全的:目标必须解析为此站点的自己的主机,任何主机名,其解析的IP地址属于私有、环回、链接本地或保留范围,在尝试任何HTTP请求之前被拒绝,并且实际请求通过`wp_safe_remote_get()`作为第二层防御。 `get-cache-status`和`clear-cache`由`manage_options`控制。 `clear-cache`故意不通过安全引擎路由,不触及安全核心:清除缓存没有有意义的快照恢复(数据按需再生)并且操作是安全且幂等的,因此带有`destructiveHint: false`而不是被视为破坏性写入。每个第三方页面缓存插件通过其签名函数/常量检测并仅通过其自己的公共API清除(`rocket_clean_domain()`、`w3tc_flush_all()`、`wp_cache_clear_cache()`、`litespeed_purge_all`操作、`wpfc_clear_all_cache()`),每个调用都由`function_exists`/`defined`保护,因此不存在插件永远不会致命。 `get-connection-info`和`list-tool-catalog`都是只读的,由`manage_options`控制,并且永远不会触及安全核心:前者仅发出占位符凭证文本(永远不是真正的应用程序密码),而后者仅读取每个注册的`Ability`对象上的元数据,从不调用工具的处理程序。 为克劳德桌面生成一键`.mcpb`安装包是`get-connection-info`的范围外(见问题#18);它记录手动`claude_desktop_config.json`的手动路径。
## 免费版 vs 专业版
免费插件(此仓库)具有完整的功能:安全引擎、Gutenberg 编辑、一步回滚和最近 20 次历史操作。
专业版(计划中,通过 [Freemius](https://freemius.com/))将添加无限历史和会话回滚、Elementor 深度编辑、更改预览和优先支持。专业版门户(`WPMCP\Pro\Gate`)和 Freemius 启动程序从一开始就已连接;如果没有专业版 SDK,插件将优雅地降级。
Freemius 仅在集成级别选择加入:`anonymous_mode` 默认启用(参见 `WPMCP\Freemius\Bootstrap::config()`),因此在激活时不会强制选择加入遥测。要上线专业版,需要两个步骤:在 freemius.com 上注册插件并在 `wpmcp.php` 中填写 `WPMCP_FS_ID` / `WPMCP_FS_PUBLIC_KEY`,然后在 `vendor/freemius/start.php` 处提供 Freemius SDK。
## 路线图
- [ ] Elementor 深度编辑(专业版)
- [ ] `preview-change` 应用前的干运行差异
- [ ] 会话感知的保留,以便大型代理会话在免费层上保持完全可逆
- [ ] 更广泛的快照捕获(摘录、父级)
- [ ] 编辑页面上的视觉前后回归
- [ ] 多站点舰队管理
- [ ] wp.org 列表
## 已知限制
免费层历史记录保留最近 20 次操作,这可能会限制 `rollback-session` 在非常大的代理运行时能达到的范围。快照捕获目前涵盖帖子内容、标题、状态、元数据和分类法术语,但不是每个帖子字段(例如摘录、父级)。强制删除媒体(或在未启用 `MEDIA_TRASH` 的情况下删除)会在回滚时恢复媒体记录,但不会恢复物理文件字节,直到问题 #24 解决;默认情况下,媒体强制删除已禁用。详细信息和缓解措施在 [设计规格](docs/superpowers/specs/2026-07-12-wpmcp-mvp-design.md#known-limitations-mvp) 中。
## 开发
```bash
composer install # 安装开发依赖
composer test # 运行 PHPUnit + WordPress 集成套件
composer lint # PSR-12 与 WordPress 特定命名
```
测试套件需要一个 MySQL 或 MariaDB 数据库用于 WordPress 集成测试框架。有关 CI 使用的确切设置,请参见 `.github/workflows/ci.yml`。
## 贡献
问题和拉取请求均受欢迎。请保持安全不变性:除非通过 `Safe_Mutation::run()`,否则任何工具都不允许写入数据库,并且每次更改都附带测试。如果存在,请参见 [CONTRIBUTING.md](CONTRIBUTING.md),或者先打开问题讨论较大的更改。
## 安全
wpmcp 编辑实时站点并执行代理指令,因此安全是首要关注点:管理员操作会检查权限并保护_nonce,所有输出都会转义,所有数据库访问都会参数化。如果您发现漏洞,请打开私人安全咨询而不是公开问题。
## 许可证
[GPL-2.0-or-later](LICENSE)。学习它,fork 它,发布它。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器