MCP 协议让 AI 工具链从「玩具」变成「生产力」——我的 3 个真实集成案例
背景:我用 Claude 做自动化发布工具时,最头疼的是让 AI 直接操作 WordPress、微信公众号和本地文件系统,而不是每次写完东西我还得手动复制粘贴。
问题是什么
AI 写代码确实强,但让它真正「做事」就难了。
以前我的工作流长这样:AI 生成文章 → 我手动复制到 WordPress → 我打开公众号后台粘贴 → 我提交 Git。说白了 AI 就是个高级打字机,脏活累活全是我干。
痛点就一个:AI 能理解上下文,但碰不了外部系统。想让它发文章、查数据库、操作文件,要么靠人肉中转,要么写一堆胶水代码把每个 API 单独封装成工具。维护成本极高,而且每接一个新系统就得重写一遍。
解决思路
MCP(Model Context Protocol)解决的就是这个问题:给 AI 一个标准化的「手」,让它通过统一的协议去调用外部工具。
当时我能选的方案有三条路:
| 方案 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| Function Calling(原生) | 每个 API 写一个函数定义,塞进 prompt | 无额外依赖 | 每个工具都要手写,prompt 越长越不稳定 |
| LangChain Toolkits | 框架封装好的工具集 | 生态丰富 | 抽象层太重,出了问题很难排查 |
| MCP 协议 | 统一协议层,Server/Client 架构 | 标准化、可复用、语言无关 | 生态还在早期,文档不够完善 |
我选了 MCP。原因很简单:我不想每次接一个新系统就把整堆工具代码重写一遍。MCP 的 Server/Client 架构让我可以把工具能力做成独立服务,AI 客户端通过协议发现和调用它们。
操作步骤
步骤 1:搭 MCP 标准 Server 骨架
MCP 的核心是 Server 端提供工具列表 + 工具执行能力。我用 TypeScript 写了一个通用 MCP Server:
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server(
{ name: "my-toolkit", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
// 注册工具:AI 通过这个接口发现我能做什么
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "wp_post",
description: "发布文章到 WordPress",
inputSchema: {
type: "object",
properties: {
title: { type: "string" },
content: { type: "string" },
status: { type: "string", enum: ["draft", "publish"] },
},
required: ["title", "content"],
},
},
],
}));
// 工具执行入口
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
switch (name) {
case "wp_post": return await handleWpPost(args);
// 其他工具...
}
});
const transport = new StdioServerTransport();
await server.connect(transport);
注意:
ListToolsRequestSchema和CallToolRequestSchema是 MCP SDK 定义的两个核心协议接口。前者让 AI 发现能力,后者让 AI 调用能力。这两个接口就是 MCP 协议的「握手协议」。
这一步最坑的是 SDK 版本兼容问题。我一开始装的 @modelcontextprotocol/sdk 是 0.5.x,但文档里不少示例用的是 0.3.x 的 API,命名空间和类型定义全不一样。折腾了两小时才发现是版本对不上。
解决方案就一句话:锁版本,盯死一个稳定的 release 来写代码。
步骤 2:写一个「发文章到 WordPress」的工具
我实际最需要的工具是发布文章。WordPress 有 REST API,直接封装:
async function handleWpPost(args: { title: string; content: string; status?: string }) {
const WP_URL = process.env.WP_URL;
const WP_USER = process.env.WP_USER;
const WP_APP_PASSWORD = process.env.WP_APP_PASSWORD;
const response = await fetch(`${WP_URL}/wp/v2/posts`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Basic " + Buffer.from(`${WP_USER}:${WP_APP_PASSWORD}`).toString("base64"),
},
body: JSON.stringify({
title: args.title,
content: args.content,
status: args.status || "draft",
}),
});
if (!response.ok) {
const err = await response.text();
return {
content: [{ type: "text", text: `发布失败: ${err}` }],
isError: true,
};
}
const post = await response.json();
return {
content: [{ type: "text", text: `发布成功!文章 ID: ${post.id}, 链接: ${post.link}` }],
};
}
这里有个细节:MCP 的工具返回值必须用 content 数组包装,每条 content 有 type 字段。这个结构是协议规定的,AI 客户端会解析这些返回值来决定下一步操作。
第一次跑的时候我犯了个低级错误:WordPress 现在已经不支持普通密码认证了,必须用 Application Password(应用密码)。在 WordPress 后台 → 用户 → 应用密码 里生成一个,然后在环境变量里配置。这个坑 WordPress 官方文档写得很清楚,但第一次搞的人很容易忽略。
步骤 3:同时接微信公众号
WordPress 搞定了,但文章还要同步到公众号。微信公众号的素材管理 API 长这样:
async function handleWechatNews(args: { title: string; content: string; author?: string }) {
const APP_ID = process.env.WECHAT_APP_ID;
const APP_SECRET = process.env.WECHAT_APP_SECRET;
// Step 1: 获取 access_token(有效期 2 小时)
const tokenResp = await fetch(
`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APP_ID}&secret=${APP_SECRET}`
);
const { access_token } = await tokenResp.json();
// Step 2: 上传为草稿
const resp = await fetch(
`https://api.weixin.qq.com/cgi-bin/draft/add?access_token=${access_token}`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
articles: [{
title: args.title,
content: args.content,
author: args.author || "",
need_open_comment: 1,
only_fans_can_comment: 0,
}],
}),
}
);
const result = await resp.json();
if (result.errcode !== 0) {
return {
content: [{ type: "text", text: `微信发布失败: ${result.errmsg}` }],
isError: true,
};
}
return {
content: [{ type: "text", text: `微信草稿创建成功,media_id: ${result.media_id}` }],
};
}
注意: 微信公众号 API 有个很恶心的限制——
access_token有效期只有 2 小时,而且每天获取次数有限(2000 次)。我最初每次调用都去拿新的 token,后来加了本地缓存,token 过期前 5 分钟才刷新。
步骤 4:用 Claude Desktop 配置启动
Server 写好之后,关键一步是把 MCP Server 注册到 AI 客户端。我用的是 Claude Desktop,配置文件在 ~/.claude/settings.json:
{
"mcpServers": {
"my-toolkit": {
"command": "node",
"args": ["D:/projects/mcp-server/dist/index.js"],
"env": {
"WP_URL": "https://yourblog.com/wp-json",
"WP_USER": "admin",
"WP_APP_PASSWORD": "xxxx xxxx xxxx xxxx",
"WECHAT_APP_ID": "wx...",
"WECHAT_APP_SECRET": "..."
}
}
}
}
这里要注意:环境变量是在配置文件里传的,不是在 Server 代码里写死。好处是同一个 Server 代码可以给不同项目用,只需要改配置文件就行。
配置好之后,重启 Claude Desktop,打开 MCP 面板就能看到 my-toolkit 处于绿色「已连接」状态。这时候你在对话里说「把这篇发到博客」,AI 就会自动调用 wp_post 工具。
第一次成功的时候我愣了下——AI 写了一段 Markdown,然后自动调了我的工具,几秒后 WordPress 后台就出现了一篇新文章。那种感觉就像招了个实习生,第一天就能帮你干活了。
步骤 5:加一个实用小工具——Git 自动提交
文章发布后,我还想自动把源文件提交到 Git 仓库。这个工具极其简单,但每天用:
async function handleGitCommit(args: { message: string }) {
const { execSync } = await import("child_process");
try {
execSync("git add -A", { cwd: process.env.REPO_PATH });
execSync(`git commit -m "${args.message}"`, { cwd: process.env.REPO_PATH });
return {
content: [{ type: "text", text: "Git 提交成功" }],
};
} catch (e: any) {
return {
content: [{ type: "text", text: `提交失败: ${e.message}` }],
isError: true,
};
}
}
然后注册进 tools 列表。现在我的完整流程是:AI 写文章 → 发到 WordPress → 发到公众号草稿箱 → Git 提交——一句指令搞定。
结果与总结
这套 MCP 工具链跑了 3 周,稳定度出乎意料。以前发一篇跨平台文章要 10-15 分钟的手动操作,现在一句话的事。
最让我意外的是:AI 调用工具的成功率比我想象的高得多,几乎没出现过参数传错的情况。
几个不得不说的坑:
延伸思考
MCP 真正的想象力不在「替代手工操作」,而在 AI 之间互相调用。想象一下:我的发布 MCP Server 可以被别的 AI Agent 调用,别人写文章时也能用我的发布能力,而不需要知道 WordPress 和微信 API 的任何细节。
协议标准化之后,可以预见的几个方向:
不过说实话,MCP 现在还处在「早期采用者」阶段,SDK 不稳定、文档不完整、调试工具匮乏是常态。如果你只想快速实现一个功能,直接写 Function Calling 可能更快。但如果你在搭建一套长期维护的 AI 工具链,现在上车 MCP 正好——等生态成熟了,你就落后了。

评论已关闭!