3大痛点解决!TypeScript SDK掌控模型上下文协议全指南
你是否在为LLM开发中的上下文管理而头疼?还在寻找标准化的模型交互方式?想快速构建兼容MCP协议的应用却不知从何入手?本文将带你从零开始,掌握Model Context Protocol(模型上下文协议)TypeScript SDK的核心功能,轻松应对LLM开发中的上下文管理挑战,实现标准化的模型交互。
为什么选择MCP TypeScript SDK?
MCP TypeScript SDK是Model Context Protocol(模型上下文协议)的官方TypeScript实现,它将上下文提供与LLM交互的关注点分离,让你能够以标准化方式为大语言模型提供上下文。通过这个SDK,你可以轻松创建MCP服务器、构建MCP客户端,并使用多种传输方式进行通信,彻底解决LLM应用开发中的上下文管理难题。
MCP知识图谱
graph TD
A[MCP核心] --> B[McpServer]
A --> C[McpClient]
B --> D[工具系统]
B --> E[资源系统]
B --> F[提示系统]
A --> G[传输层]
G --> H[Streamable HTTP]
G --> I[Stdio]
G --> J[Websocket]
D --> K[工具注册]
D --> L[工具调用]
E --> M[静态资源]
E --> N[动态资源]
F --> O[提示模板]
F --> P[参数处理]
如何快速搭建你的第一个MCP服务器?
环境准备
在开始之前,请确保你的开发环境满足以下要求:
- Node.js 14或更高版本
- npm 6或更高版本
首先,克隆项目仓库:
git clone https://gitcode.com/GitHub_Trending/ty/typescript-sdk
cd typescript-sdk
然后安装项目依赖:
npm install
✅ 完成这一步后,你的开发环境就准备好了!
创建基础服务器
创建一个名为server.ts的文件,输入以下代码:
// 导入必要的模块
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import express from 'express';
import { z } from 'zod';
// 创建MCP服务器实例,就像开了一家提供特定服务的公司
const server = new McpServer({
name: 'demo-server', // 服务器名称,相当于公司名称
version: '1.0.0' // 版本号,用于管理API变更
});
// 注册一个加法工具,就像公司添加了一项新服务
server.registerTool(
'add', // 工具名称,用于在API中标识该工具
{
title: '加法工具', // 工具的友好名称
description: '将两个数字相加', // 工具功能描述
inputSchema: { a: z.number(), b: z.number() }, // 输入数据结构验证
outputSchema: { result: z.number() } // 输出数据结构验证
},
// 工具实现函数,处理实际业务逻辑
async ({ a, b }) => {
const output = { result: a + b };
return {
content: [{ type: 'text', text: JSON.stringify(output) }],
structuredContent: output
};
}
);
// 设置Express应用,就像搭建公司的接待前台
const app = express();
app.use(express.json());
// 定义MCP接口端点,相当于公司的服务窗口
app.post('/mcp', async (req, res) => {
// 创建HTTP传输实例,处理网络通信
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined, // 不生成会话ID,每次请求都是独立的
enableJsonResponse: true // 支持JSON格式响应
});
// 当客户端断开连接时关闭传输
res.on('close', () => {
transport.close();
});
// 连接服务器和传输层
await server.connect(transport);
// 处理请求
await transport.handleRequest(req, res, req.body);
});
// 启动服务器,开始对外提供服务
const port = parseInt(process.env.PORT || '3000');
app.listen(port, () => {
console.log(`MCP服务器运行在 http://localhost:${port}/mcp`);
});
启动服务器:
npx -y tsx server.ts
✅ 恭喜!你已经成功搭建了一个基础的MCP服务器!
📌 要点回顾:
- MCP服务器是通过
McpServer类创建的 - 工具是服务器的核心功能,通过
registerTool方法注册 - Streamable HTTP是推荐的传输方式,适用于大多数场景
- 每个工具需要定义输入输出验证规则,确保数据安全
MCP核心概念深度解析
什么是McpServer?
McpServer是MCP协议的核心接口,负责管理连接、确保协议合规性和路由消息。把它想象成一家公司的总经理,负责协调各个部门(工具、资源、提示)的工作,确保客户(LLM)的需求得到满足。
问题:如何确保LLM与工具之间的通信标准化? 方案:McpServer定义了统一的接口规范,所有工具和资源都遵循相同的交互模式。 验证:通过注册工具和资源,McpServer能够自动处理请求验证和路由,确保通信符合MCP协议规范。
核心代码位于packages/server/src/server/mcp.ts。
工具(Tools)如何让AI拥有超能力?
工具允许LLM通过服务器执行操作,如计算、获取数据或产生副作用。把工具想象成公司的各个部门,每个部门负责处理特定类型的任务,如计算部门、数据查询部门等。
// BMI计算器工具示例
server.registerTool(
'calculate-bmi', // 工具唯一标识符
{
title: 'BMI计算器', // 工具的友好名称
description: '计算身体质量指数', // 详细描述工具功能
inputSchema: {
weightKg: z.number().description('体重(公斤)'), // 体重参数
heightM: z.number().description('身高(米)') // 身高参数
},
outputSchema: { bmi: z.number().description('身体质量指数') } // 输出BMI值
},
// 工具实现函数,接收输入参数并返回结果
async ({ weightKg, heightM }) => {
const bmi = weightKg / (heightM * heightM); // BMI计算公式
const output = { bmi: parseFloat(bmi.toFixed(2)) }; // 保留两位小数
return {
content: [{ type: 'text', text: `BMI计算结果: ${output.bmi}` }],
structuredContent: output
};
}
);
💡 思考问题:为什么工具需要同时定义输入输出模式(schema)?这对LLM使用工具有什么帮助?
📌 要点回顾:
- 工具通过
registerTool方法注册,需要唯一名称 - 每个工具必须定义清晰的描述,帮助LLM理解其功能
- 输入输出模式使用zod验证,确保数据格式正确
- 工具实现函数处理实际业务逻辑并返回结果
资源(Resources)如何为AI提供上下文数据?
资源向LLMs公开数据,但不像工具那样执行大量计算或产生副作用。可以把资源想象成公司的资料库或数据库,LLM可以查询这些资料来获取完成任务所需的信息。
// 静态资源示例 - 应用配置
server.registerResource(
'config', // 资源名称
'config://app', // 资源URI
{
title: '应用配置', // 资源标题
description: '应用的基本配置数据', // 资源描述
mimeType: 'text/plain' // 数据格式
},
// 资源获取函数
async uri => ({
contents: [
{
uri: uri.href,
text: '{"theme":"dark","notifications":true,"language":"zh-CN"}'
}
]
})
);
// 动态资源示例 - 用户资料
server.registerResource(
'user-profile', // 资源名称
new ResourceTemplate('users://{userId}/profile', { list: undefined }), // 带参数的URI模板
{
title: '用户资料',
description: '获取指定用户的个人资料信息'
},
// 资源获取函数,接收URI参数
async (uri, { userId }) => {
// 在实际应用中,这里会从数据库获取用户数据
const mockUserData = {
id: userId,
name: '张三',
email: 'zhangsan@example.com',
joinDate: '2023-01-15'
};
return {
contents: [
{
uri: uri.href,
text: JSON.stringify(mockUserData, null, 2)
}
]
};
}
);
📌 要点回顾:
- 资源通过
registerResource方法注册 - 资源可以是静态的(固定内容)或动态的(根据参数生成)
- URI模板允许创建参数化的资源访问路径
- 资源主要提供数据,不执行复杂计算或副作用操作
提示(Prompts)如何引导AI交互?
提示是可重用的模板,帮助人类提示模型与服务器交互。可以把提示想象成公司的服务指南,告诉客户如何最有效地使用公司提供的服务。
import { completable } from '@modelcontextprotocol/sdk/server/completable.js';
// 代码审查提示示例
server.registerPrompt(
'review-code', // 提示名称
{
title: '代码审查', // 提示标题
description: '审查代码以获取最佳实践和潜在问题', // 提示描述
argsSchema: { code: z.string().description('需要审查的代码') } // 提示参数
},
// 提示生成函数
({ code }) => ({
messages: [
{
role: 'user',
content: {
type: 'text',
text: `请作为资深代码审查员,审查以下代码并提供改进建议:
${code}
审查要点:
1. 代码可读性和可维护性
2. 潜在的性能问题
3. 错误处理是否完善
4. 是否遵循最佳实践`
}
}
]
})
);
📌 要点回顾:
- 提示通过
registerPrompt方法注册 - 提示为LLM提供预定义的交互模板
- 提示可以接收参数,动态生成内容
- 提示帮助用户更有效地与LLM和MCP服务器交互
实战操作:从基础到专家
基础级:实现多传输方式的MCP服务器
除了Streamable HTTP,MCP还支持Stdio传输方式,适用于本地进程间通信。下面实现一个同时支持两种传输方式的服务器:
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import express from 'express';
import { z } from 'zod';
// 创建MCP服务器
const server = new McpServer({
name: 'multi-transport-server',
version: '1.0.0'
});
// 添加基础工具
server.registerTool(
'greet',
{
title: '问候工具',
description: '向用户发送问候消息',
inputSchema: { name: z.string() },
outputSchema: { message: z.string() }
},
async ({ name }) => ({
content: [{ type: 'text', text: `你好,${name}!` }],
structuredContent: { message: `你好,${name}!` }
})
);
// 启动Stdio传输
async function startStdioTransport() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.log('Stdio传输已启动');
}
// 启动HTTP传输
async function startHttpTransport() {
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);
});
const port = 3000;
app.listen(port, () => {
console.log(`HTTP传输已启动,地址: http://localhost:${port}/mcp`);
});
}
// 启动两种传输方式
startStdioTransport();
startHttpTransport();
启动服务器后,你可以通过两种方式与其交互:
- HTTP方式:发送POST请求到http://localhost:3000/mcp
- Stdio方式:通过标准输入输出与进程交互
✅ 基础级挑战完成!你现在可以使用多种方式与MCP服务器通信了。
进阶级:构建完整的MCP客户端
下面创建一个完整的MCP客户端,实现与服务器的交互:
import { McpClient } from '@modelcontextprotocol/sdk/client/client.js';
import { StreamableHttpClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
async function main() {
// 创建HTTP传输
const transport = new StreamableHttpClientTransport({
url: 'http://localhost:3000/mcp' // 服务器地址
});
// 创建MCP客户端
const client = new McpClient(transport);
try {
// 连接到服务器
console.log('连接到MCP服务器...');
await client.connect();
console.log('成功连接到服务器');
// 获取服务器能力
console.log('\n获取服务器能力...');
const capabilities = await client.getCapabilities();
console.log('服务器能力:', JSON.stringify(capabilities, null, 2));
// 调用工具
console.log('\n调用greet工具...');
const result = await client.callTool('greet', { name: 'MCP开发者' });
console.log('工具调用结果:', result.structuredContent);
// 获取资源
console.log('\n获取config资源...');
const resource = await client.getResource('config://app');
console.log('资源内容:', resource.contents[0].text);
} catch (error) {
console.error('发生错误:', error);
} finally {
// 断开连接
await client.disconnect();
console.log('\n已断开与服务器的连接');
}
}
main();
运行客户端:
npx tsx client.ts
✅ 进阶级挑战完成!你现在可以构建能够与MCP服务器完整交互的客户端了。
专家级:实现多节点部署架构
在生产环境中,你可能需要部署多个MCP服务器节点以提高可用性和处理能力。下面是一个多节点部署的实现方案:
// 无状态服务器配置 (server-stateless.ts)
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import express from 'express';
import { z } from 'zod';
import { RedisEventStore } from './stores/redis-event-store.js'; // 假设的Redis事件存储
// 创建Redis事件存储,用于在多节点间共享会话数据
const eventStore = new RedisEventStore({
url: process.env.REDIS_URL || 'redis://localhost:6379'
});
// 创建MCP服务器
const server = new McpServer({
name: 'stateless-mcp-server',
version: '1.0.0'
});
// 注册工具... (与前面示例类似)
// 设置Express应用
const app = express();
app.use(express.json());
// MCP端点
app.post('/mcp', async (req, res) => {
// 创建带会话管理的传输
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => {
// 从请求头获取会话ID,或生成新的
return req.headers['x-session-id'] as string || crypto.randomUUID();
},
eventStore: eventStore, // 使用Redis事件存储
enableJsonResponse: true
});
res.setHeader('X-Session-ID', transport.sessionId);
res.on('close', () => transport.close());
await server.connect(transport);
await transport.handleRequest(req, res, req.body);
});
// 启动服务器
const port = parseInt(process.env.PORT || '3000');
app.listen(port, () => {
console.log(`无状态MCP服务器运行在 http://localhost:${port}/mcp`);
});
多节点部署架构示意图:
┌─────────────────────────────────────────────┐
│ Client │
└─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ Load Balancer │
└─────────────────────────────────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────────┐
│ MCP Server #1 │◄───►│ MCP Server #2 │
│ (无状态节点) │ │ (无状态节点) │
└─────────────────┘ └─────────────────────┘
▲│ ▲│
│▼ │▼
┌─────────────────────────────────────────────┐
│ Redis 集群 │
│ (共享事件存储/会话数据) │
└─────────────────────────────────────────────┘
✅ 专家级挑战完成!你现在掌握了MCP服务器的高级部署策略。
常见问题诊断指南
连接问题:无法连接到MCP服务器
症状:客户端提示"连接超时"或"无法建立连接"
可能原因及解决方案:
-
服务器未运行
- 检查服务器进程是否正在运行
- 重新启动服务器:
npx tsx server.ts
-
端口被占用
- 更换端口:
PORT=3001 npx tsx server.ts - 查找并终止占用端口的进程:
lsof -i :3000
- 更换端口:
-
网络问题
- 检查防火墙设置,确保端口开放
- 验证服务器地址和端口是否正确
工具调用问题:工具返回错误或无响应
症状:调用工具时返回错误,或长时间没有响应
可能原因及解决方案:
-
工具未正确注册
- 检查工具名称是否拼写正确
- 确保工具在服务器启动前完成注册
-
输入参数验证失败
- 检查输入数据是否符合工具的inputSchema
- 查看服务器日志,获取详细的验证错误信息
-
工具实现有bug
- 添加日志到工具实现函数,调试问题
- 确保工具函数正确返回格式正确的响应
性能问题:服务器响应缓慢
症状:服务器响应时间长,处理请求缓慢
可能原因及解决方案:
-
工具实现效率低
- 优化工具函数中的算法
- 对耗时操作实现异步处理
-
资源获取耗时
- 实现资源缓存机制
- 考虑使用分布式缓存提高性能
-
服务器负载过高
- 实施负载均衡,增加服务器节点
- 优化服务器代码,提高并发处理能力
生态扩展资源
官方文档和示例
开发工具
- 代码规范配置:common/eslint-config/
- 测试框架配置:common/vitest-config/
- TypeScript配置:common/tsconfig/
高级功能
- 认证扩展:packages/client/src/client/authExtensions.ts
- 中间件:packages/middleware/
- 实验性功能:packages/core/src/experimental/
进阶挑战任务
-
任务一:实现一个文件处理工具,支持上传、转换和下载文件
- 提示:使用zod验证文件元数据,实现分块上传逻辑
-
任务二:构建一个实时通知系统,使用Websocket传输
-
任务三:实现完整的OAuth2认证流程,保护MCP服务器API
通过这些资源和挑战,你可以不断扩展自己的MCP技能,构建更复杂和强大的LLM应用。无论你是刚开始接触MCP,还是已经有一定经验,这个SDK都能帮助你实现标准化的LLM上下文管理,为你的AI应用提供强大支持。
📌 最终要点回顾:
- MCP TypeScript SDK提供了标准化的LLM上下文管理方案
- 核心组件包括服务器、客户端、工具、资源和提示
- 支持多种传输方式,适应不同部署场景
- 从简单应用到分布式系统,MCP都能满足需求
- 丰富的生态资源和示例代码加速开发过程
现在,你已经准备好使用MCP TypeScript SDK构建自己的LLM应用了。开始你的MCP开发之旅吧!
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 StartedRust0133- DDeepSeek-V4-ProDeepSeek-V4-Pro(总参数 1.6 万亿,激活 49B)面向复杂推理和高级编程任务,在代码竞赛、数学推理、Agent 工作流等场景表现优异,性能接近国际前沿闭源模型。Python00
GLM-5.1GLM-5.1是智谱迄今最智能的旗舰模型,也是目前全球最强的开源模型。GLM-5.1大大提高了代码能力,在完成长程任务方面提升尤为显著。和此前分钟级交互的模型不同,它能够在一次任务中独立、持续工作超过8小时,期间自主规划、执行、自我进化,最终交付完整的工程级成果。Jinja00
MiniCPM-V-4.6这是 MiniCPM-V 系列有史以来效率与性能平衡最佳的模型。它以仅 1.3B 的参数规模,实现了性能与效率的双重突破,在全球同尺寸模型中登顶,全面超越了阿里 Qwen3.5-0.8B 与谷歌 Gemma4-E2B-it。Jinja00
MiniMax-M2.7MiniMax-M2.7 是我们首个深度参与自身进化过程的模型。M2.7 具备构建复杂智能体应用框架的能力,能够借助智能体团队、复杂技能以及动态工具搜索,完成高度精细的生产力任务。Python00
MusicFreeDesktop插件化、定制化、无广告的免费音乐播放器TypeScript00