↓推荐关注↓
Anthropic开源了一套MCP协议,它为连接AI系统与数据源提供了一个通用的、开放的标准,用单一协议取代了碎片化的集成方式。本文教你从零打造一个MCP客户端。
如何让大语言模型与外部系统交互,一直是AI系统需要解决的问题:
一个企业,面对不同的框架或系统,可能都需要参考他们的协议,去开发对应Tool,这其实是一个非常重复的工作。
面对这种问题,Anthropic开源了一套MCP协议(Model Context Protocol),
https://www.anthropic.com/news/model-context-protocol
https://modelcontextprotocol.io/introduction
它为连接AI系统与数据源提供了一个通用的、开放的标准,用单一协议取代了碎片化的集成方式。其结果是,能以更简单、更可靠的方式让人工智能系统获取所需数据。
-
MCP Hosts:
像 Claude Desktop、Cursor这样的程序,它们通过MCP访问数据。
-
MCP Clients:
与服务器保持 1:1 连接的协议客户端。
-
MCP Servers:
轻量级程序,每个程序都通过标准化的模型上下文协议公开特定功能。
结合AI模型,以一个Java应用为例,架构是这样:
可以看到传输层有两类:
首先看一个最简单的MCP Server例子:
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "Demo",
version: "1.0.0"
});
server.tool("add",
'Add two numbers',
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }]
})
);
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
main()
代码头部和底部都是一些样板代码,主要变化的是在tool这块,这个声明了一个做加法的工具。这就是一个最简单的可运行的Server了。
同时也可以使用官方的脚手架,来创建一个完整复杂的Server:
npx @modelcontextprotocol/create-server my-server
从上面代码可以看到很多模块都是从
@modelcontextprotocol/sdk
这个SDK里导出的。
SDK封装好了协议内部细节(JSON-RPC 2.0),包括架构分层,开发者直接写一些业务代码就可以了。
https://github.com/modelcontextprotocol/typescript-sdk
MCP服务器可以提供三种主要功能类型:
-
Resources:
可以由客户端读取的类似文件的数据(例如API响应或文件内容)
-
Tools:
LLM可以调用的功能(在用户批准下)
-
Prompts:
可帮助用户完成特定任务的预先编写的模板
Resources
和
Prompts
可以让客户端唤起,供用户选择,比如用户所有的笔记,或者最近订单。
重点在Tools,其他很多客户端都不支持。
如果写好了代码,怎么调试这个Server呢?官方提供了一个调试器:
npx @modelcontextprotocol/inspector
1.
连接Server
2.
获取工具
3.
执行调试
如果运行结果没错,就可以上架到支持MCP协议的客户端使用了,比如Claude、Cursor,这里以Cursor为例:
在Cursor Composer中对话,会自动识别这个Tool,并寻求用户是否调用
点击运行,就可以调用执行:
import express from "express";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import { z } from "zod";
const server = new McpServer({
name: "demo-sse",
version: "1.0.0"
});
server.tool("exchange",
'人民币汇率换算',
{ rmb: z.number() },
async ({ rmb }) => {
const usdRate = 0.14;
const hkdRate = 1.09;
const usd = (rmb * usdRate).toFixed(2);
const hkd = (rmb * hkdRate).toFixed(2);
return {
content: [{
type: "text",
text: `${rmb}人民币等于:\n${usd}美元\n${hkd}港币`
}]
}
},
);
const app = express();
const sessions: Record<string, { transport: SSEServerTransport; response: express.Response }> = {}
app.get("/sse", async (req, res) => {
console.log(`New SSE connection from ${req.ip}`);
const sseTransport = new SSEServerTransport("/messages", res);
const sessionId = sseTransport.sessionId;
if (sessionId) {
sessions[sessionId] = { transport: sseTransport, response: res }
}
await server.connect(sseTransport);
});
app.post("/messages", async (req, res) => {
const sessionId = req.query.sessionId as string;
const session = sessions[sessionId];
if (!session) {
res.status(404).send("Session not found");
return;
}
await session.transport.handlePostMessage(req, res);
});
app.listen(3001);
核心的差别在于需要提供一个sse服务,对于Tool基本一样,但是sse类型就可以部署在服务端了。上架也和command类型相似:
操作浏览器执行自动化流程。
可以操作浏览器,Cursor秒变Devin。想象一下,写完代码,编辑器自动打开浏览器预览效果,然后截图给视觉模型,发现样式不对,自动修改。
如果对接好内部系统,贴一个需求地址,自动连接浏览器,打开网页,分析需求,分析视觉稿,然后自己写代码,对比视觉稿,你就喝杯咖啡,静静的看着它工作。
有很多写好的Server,可以直接复用。
一般MCP Host以一个Chat box为入口,对话形式去调用。
那我们怎么在自己的应用里支持MCP协议呢?这里需要实现MCP Client。