大模型的得力干将MCP(2) - 开发服务

今天我们将继续学习,基于model context protocol的SDK来开发自己的MCP服务。

等系列课学习完成,你将能了解什么是MCP,如何开发MCP和如何实际使用它(当然我们会回归到Dify中,配合LLM,更加完善我们的AI应用适用场景)。

**01.**动手准备

今天就来展开说说开发MCP应用,应该如何做。既然是开发,那就离不开代码了。处理的顺序正好和概念反过来,我们先来实现一个MCP服务端。

同时需要理解两个重要的概念:

1 通信机制

MCP协议支持两种主要的通信机制:基于标准输入输出的本地通信和基于SSE(Server-Sent Events)的远程通信。

也就是说MCP服务端,根据和客户端连接时所在的位置不同,分成本地通信和远程通信。

本地通信是通过stdio传输数据,即数据是本地机器的进程间通信。适合AI助手工具等软件使用。

而远程通信则是利用SSE技术,通过HTTP来通信和传输数据。适合于共享MCP服务,在企业内使用或者服务给互联网用户。

2 运行语言和环境

一般涉及到开发,必定是要和开发语言有关。但是MCP协议是和语言无关的,也就是说大家可以尽量使用自己熟悉的开发语言。

Anthropic提供了TypeScript SDK,Python SDK,Java SDK,C# SDK,甚至Swift SDK和Rust SDK。也就是说基本上任何语言都可以实现MCP服务。

为了降低难度,我们不用挑战从零开始,用全新的语言做开发,就从typescript-sdk开始吧。

**02.**动手做一做

创建一个空的npm项目

1
npm init

输入如下信息

图片

修改package.json文件,增加依赖包和运行脚本。

图片

创建一个src目录并添加一个index.ts文件。内容如下,并替换自己的高德密钥。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import { z } from "zod";
import https from 'https';
// 环境变量中的API密钥
const GAODE_API_KEY = process.env.GAODE_API_KEY? process.env.GAODE_API_KEY: "高德密钥";
// 通用HTTP请求函数
async function makeRequest(url: string): Promise<any> {
return new Promise((resolve, reject) => {
https.get(url, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
try {
resolve(JSON.parse(data));
} catch (e) {
reject(e);
}
});
}).on('error', (err) => {
reject(err);
});
});
}
// 创建MCP服务器
const server = new McpServer({
name: "gaode-weather-mcp",
version: "0.0.1"
});
// 实现天气查询
server.tool("getWeather",
{
city: z.string().describe("城市编码"),
extensions: z.enum(["base", "all"]).optional().describe("气象类型:base(实况天气)、all(预报天气)")
},
async (params) => {
if (!GAODE_API_KEY) {
throw new Error("高德地图API密钥未设置");
}
const { city, extensions = "all" } = params;
const url = `https://restapi.amap.com/v3/weather/weatherInfo?key=${GAODE_API_KEY}&city=${encodeURIComponent(city)}&extensions=${extensions}&output=json`;
const result = await makeRequest(url);
return {
content: [{ type: "text", text: JSON.stringify(result) }]
};
}
);

// 启动服务器
async function main() {
const transport = new StdioServerTransport();
//const transport = new SSEServerTransport();
await server.connect(transport);
console.log("高德地图MCP服务已启动");
// 保持运行
await new Promise(() => { });
}

main().catch(console.error);

这时在终端执行npm run build,会在src目录下编译生成index.js文件,这个就是MCP服务端代码了。

如果上一篇教程正常跑通,那这里就简单了,依葫芦画瓢。在Cursor的设置,添加一个新的MCP服务,或者通过.cursor/mcp.json增加。如下图:

图片

测试一下是否工作正常。切换到Agent模式,然后输入问题:”请问虹口区310109的天气怎么样?”。此时就会调用MCP tool getWeather,并得到正确的回答。

图片

**03.**补充说明

MCP因为概念还比较新,各方的实现也是五花八门。特别是针对不同的语言,不同的运行环境(指的是Windows,Mac OS或者Linux),支持的不同客户端(实际上是主机,含客户端,像Claude,Cursor,IDE等各种助手类软件),想要自己本地跑起来第一个成功的案例,需要克服种种困难。

但是,随着MCP概念的兴起,这些问题会逐步解决。以后使用起来也会更加的顺滑,同时也给广大的开发者,带了很多新的机会,早期介入都会有红利期。

麦金叔也是非常感谢读者粉丝们的热情支持,期望大家都能从这一系列的讲解中,得到一个清晰的认识。同时意识到,做这些的技术并非凭空出现的,比如node开发,SSE技术,实际上都已经是比较成熟的东西。但是嫁接到MCP上,又能焕发出第二春。

虽然当前的SSE应用在MCP架构上,也是有不同的声音,比如认证,单向通讯等问题限制了一定的使用场景。但如果一切都已经那么完美了,那参与开发的人也就没有发展的空间了,是不是呢?

总结

今天学习了第一个自动实现的MCP服务,高德天气查询的例子。理解最简单的MCP服务开发的方法。但是,还有更多的MCP的概念没有引入,后面的文章将继续探讨,敬请期待。