MCP 服务器和客户端示例 (TypeScript)
该项目演示了使用 TypeScript 和@modelcontextprotocol/sdk
创建和交互简单的模型上下文协议 (MCP) 服务器和独立的 MCP 客户端。
设置包括:
my-mcp-greeter-server
:提供与问候相关的工具、资源和提示的 MCP 服务器。my-mcp-client-script
:一个简单的命令行客户端脚本,用于启动服务器、连接服务器并以编程方式与其功能进行交互。
本例中客户端和服务器之间的通信使用**stdio(标准输入/输出)**传输机制。
流程概述
该项目建设主要分为以下几个阶段:
- 服务器开发:创建 MCP 服务提供商。
- 客户端开发:创建脚本来使用服务器的服务。
- 测试和交互:运行客户端脚本,启动服务器并演示通信。
- (可选)集成:讨论如何将服务器与现有的 MCP 客户端(如 VS Code 扩展)集成。
先决条件
开始之前,请确保已安装以下软件:
- Node.js (建议使用 v16 或更高版本)
- npm (通常包含在 Node.js 中)
- 文本编辑器或 IDE(如 VS Code)
npx
(通常包含在 npm 中)——适用于使用 MCP Inspector 进行测试。
第一阶段:搭建 MCP 服务器 ( my-mcp-greeter-server
)
- 项目设置:
- 创建了目录
my-mcp-greeter-server
。 - 初始化一个 npm 项目:
npm init -y
。 - 安装了必要的依赖项:
npm install @modelcontextprotocol/sdk zod
。 - 已安装开发依赖项:
npm install -D typescript @types/node
。 - 初始化 TypeScript 配置:
npx tsc --init
。 - 配置
tsconfig.json
(设置"module": "Node16"
、"target": "ES2022"
、"outDir": "./build"
、"rootDir": "./src"
等)。 - 更新了
package.json
以包含"type": "module"
并添加了build
/start
脚本。 - 创建源文件
src/index.ts
。
- 创建了目录
- 服务器实现(
src/index.ts
) :- 导入所需的模块(
McpServer
、StdioServerTransport
、z
)。 - 定义服务器
name
和version
的常量。 - 实例化
McpServer
,传递名称、版本并声明其功能(工具、资源、提示)。 - 定义了一个工具 (
greet
) :使用server.tool()
创建了一个可供客户端调用的函数。其中包含描述,使用 Zod 定义了输入参数 (name
,politeness
),并实现了处理程序以返回个性化的问候字符串。 - 定义了一个资源 (
server-info
) :使用server.resource()
暴露静态数据。提供了一个唯一的 URI (info://greeter/about
),并实现了处理程序以返回服务器的名称和版本。 - 定义了一个提示 (
suggest-greeting
) :使用server.prompt()
创建了一个可重用的交互模板。模板中包含了描述,并实现了处理程序,用于返回一组预定义的用户/助手消息,以指导 LLM 交互。 - 使用 Stdio Transport :实例化
StdioServerTransport
作为通信方法。 - 已连接:调用
await server.connect(transport)
以使服务器准备就绪。 - 日志记录:添加了
console.error
语句以便在执行期间可见,这对于使用 stdout 来传输协议消息的 stdio 传输尤其重要。 - 保持活动:确保 Node.js 进程在连接后不会立即退出。
- 导入所需的模块(
- 建筑与修缮:
- 运行
npm run build
在build
目录中将 TypeScript 编译为 JavaScript。 - 修复了与直接访问服务器版本相关的 TypeScript 错误,选择使用预定义常量。
- 运行
第 2 阶段:构建 MCP 客户端脚本 ( my-mcp-client-script
)
- 项目设置:
- 创建了一个单独的目录
my-mcp-client-script
。 - 初始化一个 npm 项目:
npm init -y
。 - 安装了必要的依赖项:
npm install @modelcontextprotocol/sdk
。 - 已安装开发依赖项:
npm install -D typescript @types/node
。 - 与服务器项目类似初始化并配置
tsconfig.json
。 - 使用
"type": "module"
和build
/start
脚本更新了package.json
。 - 创建源文件
src/client-script.ts
。
- 创建了一个单独的目录
- 客户端实现(
src/client-script.ts
) :- 导入所需的模块(
Client
,StdioClientTransport
,path
,url
)。 - 确定的服务器路径:计算服务器编译的
index.js
文件的路径(相对或绝对)。 - 配置 Stdio Transport :实例化
StdioClientTransport
,提供command
(node
)和args
(服务器脚本的路径)。此配置至关重要,因为客户端传输会启动服务器进程。 - 实例化客户端:创建一个
Client
实例,赋予它一个身份并声明其使用工具和资源的意图。 - Connected :调用
await client.connect(transport)
,启动服务器进程并通过其 stdio 流建立 MCP 连接。 - 与服务器交互:
- 使用
await client.callTool()
调用greet
工具。 - 使用
await client.readResource()
读取server-info
资源。 - 使用
await client.getPrompt()
获取suggest-greeting
提示。
- 使用
- 记录结果:使用
console.log
显示从服务器收到的响应。 - 关闭连接:在
finally
块中使用await client.close()
来彻底关闭连接并终止服务器进程。
- 导入所需的模块(
第三阶段:构建和运行
- 构建两个项目:
cd my-mcp-greeter-server && npm run build
cd ../my-mcp-client-script && npm run build
- 运行客户端:
cd my-mcp-client-script
npm run start
(或node build/client-script.js
)- 观察客户端(
console.log
)和服务器(console.error
)的交叉输出,确认工具/资源/提示的通信和执行成功。
角色说明
- 服务器(
GreeterServer
) :- 提供服务:公开特定功能(问候工具、服务器信息、提示模板)。
- 被动监听器(在 stdio 中) :等待客户端通过其标准流进行连接。
- 执行逻辑:当客户端请求时运行与工具/资源/提示相关的代码。
- 发送结果:根据 MCP 规范格式化结果并将其发送回客户端。
- 客户端(
client-script.ts
) :- 使用服务:使用服务器提供的功能。
- 发起程序(在 stdio 中) :启动服务器进程并建立连接。
- 发送请求:决定调用哪个工具、读取哪个资源或获取哪个提示,并发送适当的 MCP 请求。
- 接收结果:处理服务器发回的响应。
- 控制流:管理交互的顺序并决定何时关闭连接。
交互式测试服务器
当客户端脚本测试程序交互时,您可以使用 MCP 检查器单独测试服务器的功能:
Copy
This server cannot be installed
提供问候工具、资源和提示的模型上下文协议服务器,演示使用 TypeScript 的客户端-服务器交互。