MCP TypeScript SDK从零上手实战指南
你是否在寻找一种标准化方式为大语言模型提供上下文?还在为构建兼容MCP的服务器和客户端而烦恼?Model Context Protocol TypeScript SDK(简称MCP TypeScript SDK)正是为解决这些问题而生。本文将通过"问题-解决方案"的实战模式,带你快速掌握这个官方TypeScript实现的核心功能,从环境搭建到高级部署,构建完整的MCP应用。
🌱 入门:MCP SDK基础与环境准备
为什么需要MCP SDK?
当你尝试为LLM构建上下文服务时,是否遇到过这些问题:不同模型接口不兼容、上下文管理混乱、工具调用方式各异?MCP TypeScript SDK通过标准化协议解决了这些痛点,将上下文提供与LLM交互解耦,让你专注于业务逻辑而非通信细节。
环境搭建步骤
# 克隆项目仓库
git clone https://gitcode.com/GitHub_Trending/ty/typescript-sdk
cd typescript-sdk
# 安装依赖
npm install
# 验证安装
npm run test
💡 核心价值:MCP SDK提供统一的通信协议和接口,使你的AI应用具有更好的可维护性和扩展性,同时兼容各种LLM模型和传输方式。
🔧 实战:核心组件与基础应用
McpServer:解决服务端统一管理问题
问题:如何高效管理工具、资源和会话,确保协议合规性?
解决方案:使用McpServer作为服务端核心,统一处理连接、消息路由和协议验证。
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
// 创建服务器实例
const server = new McpServer({
name: 'my-first-mcp-server',
version: '1.0.0'
});
// 注册工具示例
server.registerTool(
'calculate-bmi',
{
title: 'BMI计算器',
description: '计算身体质量指数',
inputSchema: {
weightKg: z.number(),
heightM: z.number()
},
outputSchema: { bmi: z.number() }
},
async ({ weightKg, heightM }) => {
const bmi = weightKg / (heightM * heightM);
return {
content: [{ type: 'text', text: `BMI值: ${bmi.toFixed(2)}` }],
structuredContent: { bmi }
};
}
);
核心实现:packages/server/src/server/mcp.ts
客户端交互:解决服务调用复杂性
问题:如何简化与MCP服务器的通信过程,处理不同传输方式?
解决方案:使用McpClient统一接口,屏蔽底层传输细节。
import { McpClient } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHttpClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
async function callBmiTool() {
const transport = new StreamableHttpClientTransport({
url: 'http://localhost:3000/mcp'
});
const client = new McpClient(transport);
await client.connect();
try {
const result = await client.callTool('calculate-bmi', {
weightKg: 70,
heightM: 1.75
});
console.log('BMI计算结果:', result.structuredContent.bmi);
} finally {
await client.disconnect();
}
}
callBmiTool().catch(console.error);
🔄 传输方式选型:选择最适合你的通信方案
三种传输方式对比
| 传输方式 | 适用场景 | 优势 | 局限 | 实现文件 |
|---|---|---|---|---|
| Streamable HTTP | 远程服务、Web应用 | 双向通信、会话支持 | 需要HTTP服务器 | packages/server/src/server/streamableHttp.ts |
| Stdio | 本地进程通信 | 简单轻量、低延迟 | 仅限本地应用 | packages/server/src/server/stdio.ts |
| WebSocket | 实时交互场景 | 全双工、低延迟 | 需WebSocket支持 | packages/client/src/client/websocket.ts |
实战配置:无状态Streamable HTTP服务器
import express from 'express';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
const app = express();
app.use(express.json());
app.post('/mcp', async (req, res) => {
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined, // 禁用会话管理
enableJsonResponse: true
});
res.on('close', () => transport.close());
await server.connect(transport);
await transport.handleRequest(req, res, req.body);
});
app.listen(3000, () => {
console.log('MCP服务器运行在 http://localhost:3000/mcp');
});
🚀 进阶:架构设计与高级部署
资源与提示:丰富LLM上下文能力
问题:如何高效为LLM提供结构化上下文数据和交互模板?
解决方案:使用资源(Resources)提供上下文数据,使用提示(Prompts)提供交互模板。
// 注册动态资源
server.registerResource(
'user-profile',
new ResourceTemplate('users://{userId}/profile'),
{
title: '用户资料',
description: '获取用户个人资料信息'
},
async (uri, { userId }) => {
// 从数据库获取用户信息
const user = await db.getUser(userId);
return {
contents: [{
uri: uri.href,
text: JSON.stringify(user)
}]
};
}
);
// 注册代码审查提示
server.registerPrompt(
'review-code',
{
title: '代码审查',
description: '审查代码质量和潜在问题',
argsSchema: { code: z.string() }
},
({ code }) => ({
messages: [{
role: 'user',
content: { type: 'text', text: `请审查以下代码:\n\n${code}` }
}]
})
);
多节点部署策略
问题:如何在生产环境中扩展MCP服务,保证高可用和负载均衡?
解决方案:根据业务需求选择合适的部署模式:
- 无状态模式:适合简单API代理,每个请求独立处理
- 持久存储模式:使用数据库存储会话状态,支持服务重启
- 分布式消息路由:结合消息队列实现会话路由,支持水平扩展
// 持久存储模式配置示例
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => randomUUID(),
eventStore: new DatabaseEventStore({
connectionString: process.env.DB_CONNECTION
})
});
🔍 常见问题诊断
问题1:工具调用参数验证失败
错误表现:客户端收到"invalid_input"错误,工具调用失败
解决方案:检查工具输入模式定义,确保Zod模式正确,客户端参数类型匹配
// 错误示例:缺少必要参数
server.registerTool('add', {
inputSchema: { a: z.number() } // 缺少b参数
}, async ({ a, b }) => ({ /* ... */ }));
// 正确示例:完整定义所有参数
server.registerTool('add', {
inputSchema: { a: z.number(), b: z.number() }
}, async ({ a, b }) => ({ /* ... */ }));
问题2:会话连接中断
错误表现:客户端频繁断开连接,无法维持长会话
解决方案:检查传输配置,实现心跳机制,确保正确处理连接关闭事件
// 添加连接关闭处理
transport.on('close', () => {
console.log('连接已关闭');
// 清理资源和状态
});
// 实现心跳机制
setInterval(() => {
if (transport.isConnected()) {
transport.sendHeartbeat();
}
}, 30000);
问题3:资源访问权限问题
错误表现:客户端收到"access_denied"错误,无法访问资源
解决方案:实现认证中间件,验证用户权限
server.use(async (context, next) => {
const token = context.request.headers.authorization?.split(' ')[1];
if (!isValidToken(token)) {
return { status: 'error', code: 'access_denied', message: '未授权访问' };
}
return next();
});
开发资源卡
- 官方文档:README.md
- 核心源码:
- 示例代码:
- 服务器示例:examples/server/
- 客户端示例:examples/client/
- 测试工具:test/integration/
通过本文的实战指南,你已经掌握了MCP TypeScript SDK的核心功能和最佳实践。从基础的服务器搭建到高级的分布式部署,MCP SDK提供了一套完整的解决方案,帮助你构建强大而灵活的AI上下文服务。现在就开始动手实践,体验标准化AI上下文管理的魅力吧!
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust099- DDeepSeek-V4-ProDeepSeek-V4-Pro(总参数 1.6 万亿,激活 49B)面向复杂推理和高级编程任务,在代码竞赛、数学推理、Agent 工作流等场景表现优异,性能接近国际前沿闭源模型。Python00
MiMo-V2.5-ProMiMo-V2.5-Pro作为旗舰模型,擅⻓处理复杂Agent任务,单次任务可完成近千次⼯具调⽤与⼗余轮上 下⽂压缩。Python00
GLM-5.1GLM-5.1是智谱迄今最智能的旗舰模型,也是目前全球最强的开源模型。GLM-5.1大大提高了代码能力,在完成长程任务方面提升尤为显著。和此前分钟级交互的模型不同,它能够在一次任务中独立、持续工作超过8小时,期间自主规划、执行、自我进化,最终交付完整的工程级成果。Jinja00
Kimi-K2.6Kimi K2.6 是一款开源的原生多模态智能体模型,在长程编码、编码驱动设计、主动自主执行以及群体任务编排等实用能力方面实现了显著提升。Python00
MiniMax-M2.7MiniMax-M2.7 是我们首个深度参与自身进化过程的模型。M2.7 具备构建复杂智能体应用框架的能力,能够借助智能体团队、复杂技能以及动态工具搜索,完成高度精细的生产力任务。Python00