Skip to content

3.1 MCP 服务器开发流程

在了解了 MCP 服务器如何使用、MCP 协议的实现细节之后,你是不是跃跃欲试,想要开发一个 MCP 服务器。

本节内容,我们来详细讲解 MCP 服务器开发的完整流程。

3.1.1 选择开发语言

MCP 协议支持使用任意编程语言开发 MCP 服务器。

在前面的章节,我们介绍了 MCP 协议的核心架构、连接生命周期和 JSON-RPC 通信消息格式,在开发一个 MCP 服务器时,至少需要实现在连接生命周期内,按照协议约定的格式,与客户端通信。

MCP 协议官方目前开放了多种编程语言的 SDK(Software Development Kit,软件开发工具包),包括:

我们可以选择其中一种 SDK,使用对应的编程语言来开发 MCP 服务器。除此之外,也有第三方的 SDK 支持使用其他编程语言来开发 MCP 服务器,比如:

MCP 协议发布之后,开源社区迅速发展,开发者积极贡献各类开发工具,让 MCP 服务器的开发变得越来越简单。我们只需选择自己擅长的编程语言和对应的 SDK,即可快速上手 MCP 服务器开发。

在本节内容,我们选择 typescript 作为开发语言,通过一个查询天气的例子,来演示 MCP 服务器开发的完整流程。

3.1.2 初始化开发环境

根据选择的开发语言,在我们的电脑上初始化对应的开发环境。比如选择 typescript 作为开发语言,在进行 MCP 服务器开发之前,我们需要安装 Node.js 及其包管理工具 npm。

Node.js 的详细安装步骤参见 1.4.1 小节

在安装完 Node.js 之后,通过以下命令验证,输出的 Node.js 版本大于 16 即可。

Terminal window
node --version
npm --version

接下来我们就可以使用 typescript 开发 MCP 服务器了。

3.1.3 创建 MCP 服务器项目

使用 typescript 开发 MCP 服务器,有两种创建项目的方式:

  1. 使用命令行工具快速创建项目

MCP 协议官方开发了一个叫做 create-server 的命令行工具,可以通过执行以下命令快速创建一个 MCP 服务器:

Terminal window
npx @modelcontextprotocol/create-server weather

创建的项目结构如图 3-1 所示:

图 3-1:MCP 服务器项目结构

  1. 手动创建项目

我们也可以手动创建 MCP 服务器项目:

Terminal window
# 创建项目目录
mkdir weather
cd weather
# 初始化项目
npm init -y
# 安装项目依赖
npm install @modelcontextprotocol/sdk zod
npm install -D @types/node typescript
# 创建项目文件
mkdir src
touch src/index.ts

编辑项目根目录下的 package.json,写入内容:

{
"type": "module",
"bin": {
"weather": "./build/index.js"
},
"scripts": {
"build": "tsc && chmod 755 build/index.js"
},
"files": ["build"]
}

在项目根目录下创建 tsconfig.json,写入内容:

{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}

MCP 服务器项目创建成功后,接下来就可以专注实现 MCP 服务器功能了。

3.1.4 实现 MCP 服务器功能

在创建 MCP 服务器项目时,我们安装了 typescript 编程语言开发 MCP 服务器的 SDK:@modelcontextprotocol/sdk,接下来就在这个 SDK 的基础上,一步步实现这个 MCP 服务器的功能。

  1. 定义 MCP 服务器

打开 MCP 服务器项目的 src/index.ts 文件,写入以下内容:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
// 定义服务器
const server = new McpServer({
name: "weather",
version: "1.0.0",
capabilities: {
tools: {},
},
});

上面的逻辑,引入了 SDK 中的 McpServer 类,通过 new McpServer 定义了一个 MCP 服务器,这个服务器的名称是 weather,当前版本定义为 1.0.0,只支持 tools 一项能力,暴露工具方法给到客户端调用。

接下来,我们在 MCP 服务器实现一个查天气的工具方法。

  1. 准备查询天气的接口

我们在 聚合数据 平台找到查询天气的 API,开通服务,充值后得到调用服务的 apikey。

调试一下这个查询天气的 API,可以看到 API 的请求参数和响应数据,如图 3-2 所示。

图 3-2:聚合数据查询天气 API 调试

  1. 实现查询天气的方法

根据上一步 API 调试的请求和响应字段,我们创建一个 src/api.ts 文件,实现一个查询天气的函数:

export async function queryWeather(city: string) {
try {
const apiKey = process.env.WEATHER_API_KEY || "";
if (!apiKey) {
throw new Error("WEATHER_API_KEY is not set");
}
const apiUrl = `http://apis.juhe.cn/simpleWeather/query?city=${city}&key=${apiKey}`;
const response = await fetch(apiUrl);
if (!response.ok) {
throw new Error(`query weather failed with status ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.log("query weather error:", error);
throw error;
}
}

在此函数中,从环境变量读取查询天气的 WEATHER_API_KEY,接收一个 city 参数,查询指定城市的天气信息后返回给调用方。

  1. 实现查询天气的工具

我们给在第 1 步定义的服务 server 添加一个工具:query-weather,用于查询指定城市的天气:

import { z } from "zod";
import { queryWeather } from "./api.js";
server.tool(
"query-weather",
"查询指定城市的天气",
{
city: z.string().describe("需要查询天气的城市"),
},
async ({ city }) => {
if (!city) {
throw new Error("城市不能为空");
}
try {
const info = await queryWeather(city);
return {
content: [
{
type: "text",
text: `查询天气结果: ${JSON.stringify(info)}`,
},
],
};
} catch (error: any) {
throw new Error(`查询天气失败: ${error.message}`);
}
}
);

在此工具的实现逻辑中,接收请求参数 city,调用第 3 步实现的 queryWeather 方法,查询对应城市的天气后返回数据。

  1. 定义 MCP 服务器运行方式

src/index.ts 文件的最后,我们引入 SDK 中的 StdioServerTransport,让这个查询天气的 MCP 服务器,基于 stdio 传输运行:

import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Weather MCP Server running on stdio");
}
main().catch((error) => {
console.error("Fatal error in main():", error);
process.exit(1);
});

至此,这个查询天气的 MCP 服务器就开发完成了,我们通过下面的命令运行这个服务器:

Terminal window
npm run build
node build/index.js

服务运行成功,输出日志,如图 3-3 所示、

图 3-3:运行 MCP 服务器

3.1.5 调试 MCP 服务器功能

在开发 MCP 服务器的过程中,我们需要调试 MCP 服务器内部实现的功能。有两种常用的调试方法:

  1. 通过调试工具,测试 MCP 服务器的工具调用

MCP 协议官方开发了一个 inspector 工具,可以帮助开发者调试 MCP 服务器的工具调用。

在 MCP 服务器根目录下运行:

Terminal window
npx @modelcontextprotocol/inspector node build/index.js

点击输出的调试地址,进入 MCP 服务器调试面板,可以对 MCP 服务器内部实现的工具进行测试调用:

  1. 通过大模型客户端,测试 MCP 服务器的工具调用

选择一个大模型客户端,比如 Claude 桌面版,写入 MCP 服务器的配置:

{
"mcpServers": {
"weather": {
"command": "node",
"args": ["/Users/idoubi/code/all-in-aigc/chatmcp/weather/build/index.js"],
"env": {
"WEATHER_API_KEY": "xxx"
}
}
}
}

重启 Claude 桌面版之后,可以看到配置的工具已经被正常读取到了:

接下来我们在 Claude 桌面版通过对话查询天气,如图所示:

通过上面的测试,我们验证了这个新开发的 MCP 服务器功能正常。接下来就可以发布上线了。

3.1.6 发布 MCP 服务器

把开发完成的 MCP 服务器公开发布,可以让更多的用户,在更多的场景用上。对于开发者来说,也是一件很有成就感的事情。

  1. 发布到 Github

我们可以选择以开源的形式发布 MCP 服务器的源代码。在 Github 创建一个仓库,把本地代码上传:

Terminal window
git init
git add .
git commit -m "first version"
git remote add origin git@github.com:chatmcp/mcp-server-weather.git
git push origin main

其他人就可以通过源码的方式,在本地运行这个查询天气的 MCP 服务器。

  1. 发布到 npm

修改 MCP 服务器的 package.json,让其可以公开发布:

{
"name": "@chatmcp/weather",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"private": false,
"bin": {
"weather": "./build/index.js"
}
}

然后执行命令发布到 npm

Terminal window
npm publish --access=public

发布成功后,其他用户就可以在不拉取此 MCP 服务器源代码的情况下,在本地运行这个服务器:

{
"mcpServers": {
"weather": {
"command": "npx",
"args": ["-y", "@chatmcp/weather"],
"env": {
"WEATHER_API_KEY": "xxx"
}
}
}
}
  1. 发布到第三方 MCP 服务器应用市场

把新开发的 MCP 服务器提交到第三方应用市场,可以让更多的用户看到和使用。

mcp.so 是全球知名的第三方 MCP 应用市场,可以自行提交发布自己的 MCP 服务器。

3.1.7 总结

本节内容,用一个查询天气的 MCP 服务器举例,演示了 MCP 服务器开发的完整流程。

作为开发者,我们可以选择任意自己熟悉的编程语言,使用一个兼容 MCP 协议的 SDK,快速完成 MCP 服务器的功能开发。

把开发完成的 MCP 服务器发布到公共市场,可以让全世界的用户使用上我们的创意作品。

在接下来的几节内容,我们会用更多实际的案例,来详细讲解不同类型的 MCP 服务器开发的思路和过程。