标签: NPS

  • 从零打通 WordPress + MCP:部署、反代、真实 CRUD 与可复用工具整理

    这篇文章想解决一个很具体的问题:怎么把一套 WordPress 博客,从本地部署、到公网访问、再到接入 MCP / AI 工具做文章增删改查,完整打通,并整理成可以上传 Git、让其他电脑直接复用的方案

    如果你刚接触 WordPress、Docker、反向代理,或者还不熟悉 MCP,这篇文章会尽量按“现象 → 原因 → 处理方式 → 注意事项”的顺序讲清楚。文中的敏感信息已经做过脱敏处理,例如:

    • 正式域名统一写成 your-blog.example
    • 服务器 IP 写成 your-server-ip
    • WordPress 用户名写成 your-wordpress-username
    • 应用密码写成 xxxx xxxx xxxx xxxx xxxx xxxx
    • 本地绝对路径写成 /path/to/project
    • 历史冲突域名写成 old-host.example

    一、这次最终达成了什么

    先看结果,再看过程。

    • 本地有一套稳定的 WordPress Docker 环境
    • 公网可以通过正式域名访问博客
    • Codex / MCP 可以对文章做真实的创建、读取、更新、删除
    • 工具目录已经整理成可直接上传 Git 的状态
    • 别人换一台电脑,也能按文档快速跑起来

    二、整体架构长什么样

    这套链路最终不是“直接把本地 8016 端口暴露出去”,而是做了一层更稳定的收口:

    your-blog.example
    -> 服务器 Nginx / 反向代理
    -> http://127.0.0.1:7412/
    -> nps / npc 隧道
    -> 本机 127.0.0.1:8016
    -> WordPress 容器

    这条链路的好处是:

    • 本地 WordPress 只监听在回环地址,不直接暴露在公网
    • 公网入口只有正式域名和服务器反代,访问路径更统一
    • 本地开发和线上访问逻辑可以分开处理,不容易混乱

    三、本地 WordPress 是怎么部署的

    本地 WordPress 使用 Docker 跑起来,最后固定在:

    http://127.0.0.1:8016

    为什么不用常见的 8080?原因很简单:开发环境里 8080 太常见,容易和已有服务、浏览器缓存、历史代理配置混在一起。换成一个明确的本地端口,可以减少排查成本。

    这一步的核心原则有两个:

    • 只监听本机:例如 127.0.0.1:8016:80
    • 本地端口只给本地和隧道使用,不要让它直接成为用户访问入口

    四、遇到的第一个坑:域名能打开,但会自动跳到 :8080 或 :8016

    这是整个过程中最容易让人误以为“浏览器坏了”或者“反向代理配置错了”的问题。

    1. 现象

    • 访问 https://your-blog.example,页面打不开
    • 浏览器地址栏会自动变成 https://your-blog.example:8080/:8016
    • 有时候域名本身能返回 200,但页面里资源、链接、跳转目标还是旧端口

    2. 原因

    根因通常不在浏览器,而在 WordPress 自己认错了“站点地址”。

    WordPress 有两个特别关键的概念:

    • WP_HOME
    • WP_SITEURL

    如果这两个值还保留着本地开发地址,比如 http://127.0.0.1:8016,那么用户虽然是通过正式域名进来的,WordPress 仍然会坚持把页面里的链接和重定向指回本地端口。

    3. 正确做法

    正式对外访问后,站点地址必须改成正式域名:

    define('WP_HOME', 'https://your-blog.example');
    define('WP_SITEURL', 'https://your-blog.example');

    一旦改对,再去验证:

    • 响应头里的 Link 是否已经变成正式域名
    • 页面 HTML 里的文章链接、静态资源、RSS 地址是否都换成正式域名

    4. 小白注意事项

    • 不要只看浏览器打开了没,要看响应头和页面源码
    • 如果你刚改完还在跳旧端口,先排除浏览器缓存和旧标签页
    • 如果你已经切换成正式域名,就不要再让文章内、配置内继续出现本地开发端口

    五、遇到的第二个坑:7412 端口反代后访问不了

    这个问题一开始看起来像“WordPress 没起来”,但实际并不是。

    1. 现象

    • 本地 127.0.0.1:8016 能访问
    • 服务器反向代理目标写的是 http://127.0.0.1:7412/
    • 但外部访问域名时仍然打不开

    2. 排查思路

    这个问题不能直接猜,要按链路一段一段排:

    1. 先确认 WordPress 容器是不是正常监听在本机端口
    2. 再确认 npc 当前转发目标是不是还是旧端口
    3. 再确认远端 nps 暴露的端口到底是不是你想要的那个端口
    4. 最后看服务器上的 Nginx 是否真的反代到了正确的本地入口

    3. 这次实际遇到的问题

    • 本地 WordPress 端口从 8080 切到了 8016
    • npc 配置文件里仍然保留着旧目标
    • 中途还有一条旧的 host 配置(这里脱敏写成 old-host.example)在服务端冲突,导致 npc 重连时报错

    换句话说,问题不是只有一层,而是“旧端口残留”和“旧反代项冲突”叠在了一起。

    4. 处理方式

    • 把本地服务统一切到 127.0.0.1:8016
    • npc 的 TCP 目标改成 127.0.0.1:8016
    • 把服务器端对外入口统一收口到 7412
    • 把正式域名只指向服务器反代,不再直接暴露本地开发端口

    5. 小白注意事项

    • “本地能访问”和“公网能访问”是两回事,别混在一起
    • 每改一层,就只验证这一层,不要一次改三四个地方
    • 端口切换后,一定把旧配置文件、旧代理项、旧浏览器缓存一起排查

    六、遇到的第三个坑:MCP / REST 明明配置好了,为什么还是 401

    这一段是最容易让人误判成“代码有问题”的地方。

    1. 现象

    • 读文章可以,写文章不行
    • 调用创建文章接口时返回 401
    • 错误像“不能创建文章”“未登录”“无权限”等

    2. 真正原因

    WordPress 写入接口最关键的不是普通账号密码,而是 Application Password

    这次排查里实际发现了两个问题:

    • 账号虽然是管理员,但用户下面根本没有实际生成的应用密码记录
    • 后来密码更新了,MCP 旧进程没重启,继续拿旧密码在请求

    3. 正确验证方式

    不要一上来就测创建文章,先测:

    /wp-json/wp/v2/users/me

    只有当它返回 200,并且用户身份正确时,才说明这套凭据真的可以用于后续写操作。

    4. 小白注意事项

    • 能登录 WordPress 后台,不等于能写 REST API
    • 应用密码要在对应用户资料页里单独生成
    • 密码更新后,如果工具进程是长驻的,记得重启进程

    七、MCP Server 和 Skill 到底各自做什么

    为了让整套方案更稳定,我把能力拆成了两层:

    • MCP Server:直接提供文章 CRUD 工具
    • Skill:告诉 Codex 在什么场景下优先走 MCP,在什么情况下可以回退 REST API

    这样做的好处是:

    • 在 Codex 里可以直接“像工具一样”管理文章
    • 就算某次会话里的内置 MCP transport 断了,也不影响独立验证服务是否正常
    • 工具目录可以独立迁移到其他电脑使用

    八、真实 CRUD 到底有没有跑通

    有,而且不是只做了“读一下列表”这种浅层验证,而是做了真正的闭环测试。

    1. REST API 闭环

    • 创建文章:成功
    • 读取文章:成功
    • 更新文章:成功
    • 删除文章:成功

    2. 独立 MCP 客户端闭环

    还额外写了一个独立测试脚本 test-mcp-client.mjs,通过 MCP 协议直接连接 wordpress-mcp.js,跑通了:

    • create_post
    • get_post
    • update_post
    • delete_post

    这说明问题真正的边界已经很清楚:

    • WordPress 站点没问题
    • 应用密码没问题
    • MCP 服务本身没问题
    • 如果某次会话仍然报 transport closed,那多半是“会话 transport 状态”坏了,不是你的博客坏了

    九、为什么还要专门整理成 Git 可上传状态

    因为“自己电脑上能跑”不等于“这套东西可以长期复用”。如果后续要放到 Git,给别的电脑继续使用,必须把敏感信息和环境耦合清掉。

    这次收尾主要做了这些事:

    • 去掉示例配置里的真实域名、用户名、密码
    • 把测试脚本改成只读取环境变量
    • 新增 .env.example
    • 让别人只需要复制一份 .env 就能跑
    • 新增 npm run start:envnpm run test:mcp:env

    十、如果你是第一次照着做,最短步骤是什么

    如果只是想先把工具跑起来,而不是一次性把所有细节都吃透,可以按下面这条最短路径走:

    cd wordpress-ai-tools/mcp-server
    cp .env.example .env
    # 把 .env 里的站点地址、用户名、应用密码改成你自己的
    npm install
    npm run start:env

    如果还想确认整条 MCP 链路真的能写文章,再执行:

    npm run test:mcp:env

    十一、这次最值得记住的几个注意事项

    • 正式域名上线后,WordPress 站点地址一定要改成正式域名,不要留本地端口
    • 反代问题排查要一层一层来,不要混着猜
    • REST API 写入靠的是 Application Password,不是后台登录密码
    • 进程是长驻的,密码变了不重启,工具可能还在用旧凭据
    • 上传 Git 前一定做脱敏,不要把密码、用户名、绝对路径、内网信息带进去

    结语

    这次最大的价值,不是“我把 WordPress 跑起来了”,而是把它整理成了一条真正可重复、可迁移、可验证的工作流:本地部署可控、公网访问稳定、AI 工具可写、目录结构可复用

    如果后续继续扩展,这套基础还可以往媒体上传、页面管理、分类标签自动化、自动发布工作流继续延伸。对个人博客来说,这已经不只是一个站点,而是一套可以长期积累的内容工具链。