AI摘要:本文介绍了一个基于Node.js的MCP Server项目,该项目实现了自动化发布博客文章和动态到Typecho博客系统。文章详细描述了项目背景、技术架构、关键问题与解决方案、核心代码实现、认证优化、测试结果以及安全注意事项。通过遵循JSON-RPC标准、处理表单参数、动态获取token、探索正确的API路径和优化认证策略,项目成功实现了博客自动化发布功能。
Powered by AISummary.
MCP Server 开发与调试实战:Typecho 博客自动化发布
一、项目背景
MCP (Model Context Protocol) 是一种用于连接 AI 模型与外部工具的协议。本项目实现了一个基于 Node.js 的 MCP Server,可以自动化发布博客文章和动态到 Typecho 博客系统。
问题起源
最初遇到的问题是 MCP Server 连接超时:
MCP server "xmprpc" connection timed out after 30000ms
经过排查,发现是 JSON-RPC 协议实现问题和登录流程错误导致的。
二、技术架构
MCP Server 架构
┌─────────────┐ JSON-RPC ┌─────────────┐ HTTP ┌─────────────┐
│ AI Model │ ────────────────> │ MCP Server│ ───────────> │ Typecho │
│ (Trae) │ <─────────────── │ (Node.js) │ <────────── │ Blog │
└─────────────┘ stdio └─────────────┘ └─────────────┘核心技术栈
- Node.js - MCP Server 运行环境
- Axios - HTTP 请求库
- JSON-RPC - 协议通信标准
- Typecho - 目标博客系统
三、关键问题与解决方案
问题 1:JSON-RPC 协议实现错误
现象:服务器无法正确响应 MCP 协议请求
分析:协议格式不正确,缺少必要的方法实现
解决方案:实现标准的 JSON-RPC 方法:
initialize- 协议初始化tools/list- 返回工具列表tools/call- 调用具体工具
问题 2:登录流程错误
现象:登录失败,提示密码错误
分析:登录表单的 referer 字段值设置错误,应该为空字符串而不是完整 URL
解决方案:修改登录请求参数:
formData.append('referer', ''); // 改为空字符串问题 3:动态 Token 处理
现象:表单提交 URL 包含动态生成的 token
分析:Typecho 的表单 action URL 包含时间戳参数 ?_=xxx,需要动态获取
解决方案:每次请求前先获取页面,提取最新的表单 action:
const formActionMatch = writeHtml.match(/<form[^>]*action="([^"]+)"/i);
const postUrl = formActionMatch[1]; // 动态获取包含 token 的 URL问题 4:博客发布按钮缺失
现象:文章保存为草稿而不是发布
分析:缺少发布按钮参数,默认行为是保存草稿
解决方案:添加发布按钮字段:
formData.append('do', 'publish'); // 触发发布操作问题 5:API 路径错误
现象:后台管理路径返回 404
分析:管理后台路径不是 /index.php/action/admin,而是 /login/
解决方案:更新 API 路径映射:
- 写文章:
/login/write-post.php - 发布处理:
/action/contents-post-edit
四、核心代码实现
登录方法
async function login() {
// 1. 获取登录页面
const loginPageResponse = await axios.get('/login/login.php', { headers });
// 2. 提取动态 token
const html = loginPageResponse.data.toString();
const formActionMatch = html.match(/<form[^>]*action="([^"]+)"/i);
const tokenMatch = loginUrl.match(/[?&]_=([a-f0-9]+)/);
const token = tokenMatch[1];
// 3. 提交登录请求
const formData = new URLSearchParams();
formData.append('name', username);
formData.append('password', password);
formData.append('remember', '1');
formData.append('referer', ''); // 关键修复
const loginResponse = await axios.post('/index.php/action/login?_=' + token, formData, {
headers: { ...headers, 'Cookie': sessionCookies },
maxRedirects: 0
});
}发布博客方法
'create_post': async () => {
// 1. 获取写文章页面(动态 token)
const writePageResponse = await axios.get('/login/write-post.php', { headers });
const formActionMatch = writeHtml.match(/<form[^>]*action="([^"]+)"/i);
const postUrl = formActionMatch[1];
// 2. 构建表单数据
const formData = new URLSearchParams();
formData.append('title', title);
formData.append('text', content);
formData.append('category[]', category);
formData.append('allowComment', '1');
formData.append('allowPing', '1');
formData.append('allowFeed', '1');
formData.append('do', 'publish'); // 关键:触发发布
// 3. 提交发布请求
const response = await axios.post(postUrl, formData, {
headers,
maxRedirects: 0
});
// 4. 判断发布结果
return response.status === 302 ||
response.headers['refresh'] ||
noticeCookie.includes('已发布');
}五、认证优化
按需认证机制
最初所有方法都强制登录,导致公共接口也失败。优化后:
async function callMethod(method, params) {
const authRequired = ['create_post', 'create_dynamic', 'get_posts', 'get_page'];
let cookies = '';
if (authRequired.includes(method)) {
cookies = await getCookies(); // 仅需要认证的方法才登录
}
}六、测试结果
| 功能 | 状态 | 说明 |
|---|---|---|
| 协议初始化 | ✅ | JSON-RPC 正常响应 |
| 健康检查 | ✅ | 网站在线检测 |
| 用户登录 | ✅ | 获取认证 cookies |
| 获取动态 | ✅ | 返回动态列表 |
| 发布动态 | ✅ | 成功发布动态 |
| 发布博客 | ✅ | 成功发布文章 |
七、安全注意事项
1. 凭据管理
使用环境变量存储敏感信息,避免硬编码:
XMRPC_HOST=https://your-blog.com
XMRPC_USERNAME=your-username
XMRPC_PASSWORD=your-password2. 请求头模拟
模拟浏览器请求头,防止被识别为机器人:
const headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Referer': host + '/login/write-post.php',
'Origin': host
};3. Token 动态更新
每次操作前获取最新 token,避免过期:
const writePageResponse = await axios.get('/login/write-post.php', { headers });八、总结
本次开发过程中遇到了多个典型问题:
- 协议实现问题 - 需要严格遵循 JSON-RPC 标准
- 表单参数问题 - 字段值必须与页面一致
- 动态 token 问题 - 需要实时获取最新值
- 路径映射问题 - 需要实际探索正确的 API 路径
- 认证策略问题 - 公共接口不应强制登录
通过系统的调试和分析,最终成功实现了完整的博客自动化发布功能。
技术栈:Node.js | Axios | Typecho | MCP Protocol
关键字:MCP Server | Typecho API | 博客自动化 | JSON-RPC | 接口调试
