零门槛掌握MCP TypeScript SDK:从实战到架构师的LLM上下文协议实现指南
1.LLM开发痛点分析:为什么标准化上下文协议成为刚需
在大语言模型(LLM)应用开发中,开发者正面临着日益复杂的技术挑战。随着LLM能力的不断增强,如何高效管理模型上下文、确保不同系统间的互操作性、以及构建可扩展的AI应用架构,已成为行业普遍面临的核心问题。让我们深入分析当前LLM开发中的三大痛点:
1.1 上下文管理混乱:LLM应用的"数据沼泽"
行业案例:某金融科技公司在开发智能投顾系统时,由于缺乏标准化的上下文管理方案,导致用户对话历史、市场数据、投资组合信息等分散在不同的系统模块中。当LLM需要综合分析这些信息时,开发团队不得不编写大量胶水代码来整合数据,不仅增加了系统复杂度,还导致响应延迟增加了300%。
当前LLM应用开发中,上下文管理主要面临以下挑战:
- 数据来源多样化:上下文可能来自数据库、API调用、用户输入、文件系统等多个渠道
- 格式不统一:不同来源的上下文数据格式各异,增加了处理难度
- 生命周期管理复杂:需要跟踪上下文的创建、更新、过期和清理
这种混乱的上下文管理方式,不仅增加了开发难度,还可能导致LLM生成不准确或不一致的响应。
1.2 系统集成困境:LLM应用的"巴别塔"
行业案例:一家电商企业尝试将LLM集成到其客户服务系统中,却发现LLM与现有CRM系统、订单管理系统、库存系统之间的通信需要定制化开发。每个系统都有自己的数据格式和API规范,导致集成工作耗时超过预期三倍,且维护成本极高。
系统集成的主要痛点包括:
- 接口不兼容:不同系统间的数据交换格式和协议差异大
- 通信效率低:缺乏针对LLM特点的优化通信机制
- 版本控制难:API和数据结构的变更难以管理,容易引发兼容性问题
这种系统间的"语言障碍"严重阻碍了LLM技术的落地应用,增加了企业的数字化转型成本。
1.3 扩展性瓶颈:从原型到生产的"鸿沟"
行业案例:某初创公司开发的AI助手原型在小规模测试中表现出色,但当尝试扩展到数万用户时,却遭遇了严重的性能问题。由于缺乏可扩展的架构设计,系统在高并发场景下频繁崩溃,响应时间从几百毫秒飙升至数秒。
扩展性挑战主要体现在:
- 资源消耗不可控:LLM推理需要大量计算资源,难以有效分配和管理
- 会话状态管理:多用户并发场景下,会话状态的维护变得异常复杂
- 部署策略受限:传统部署方式难以满足LLM应用的弹性扩展需求
这些扩展性问题使得许多有前景的LLM应用难以从实验室走向实际生产环境。
2.MCP协议核心解决方案:标准化LLM上下文管理的技术架构
面对上述挑战,Model Context Protocol(MCP,模型上下文协议) 应运而生。MCP是一种标准化协议,旨在为LLM应用提供统一的上下文管理和通信机制。MCP TypeScript SDK作为该协议的官方实现,为开发者提供了构建MCP兼容服务器和客户端的完整工具集。
2.1 MCP协议技术原理:LLM上下文的"交通规则"
MCP协议的核心思想是将LLM上下文管理标准化,定义了四个关键组件:
- 工具(Tools):允许LLM执行特定操作的功能模块,如数据查询、计算处理等
- 资源(Resources):向LLM提供上下文数据的信息源,如用户资料、文档内容等
- 提示(Prompts):引导LLM生成特定响应的模板,帮助标准化交互流程
- 传输(Transports):实现客户端与服务器之间通信的机制,如HTTP、Stdio等
MCP协议的工作流程可以类比为餐厅服务:
顾客(LLM) → 服务员(客户端) → 菜单(工具/资源列表) → 厨房(服务器)
顾客通过服务员查看菜单并点餐,服务员将订单传达给厨房,厨房准备食物后通过服务员将餐点送达顾客。在这个过程中,菜单和点餐流程就是一种"协议",确保了整个服务的顺畅进行。
2.2 MCP架构设计:模块化与灵活性的完美平衡
MCP TypeScript SDK采用模块化架构设计,主要包含以下核心模块:
graph TD
A[MCP核心模块] --> B[服务器模块]
A --> C[客户端模块]
A --> D[协议处理模块]
B --> E[工具管理]
B --> F[资源管理]
B --> G[提示管理]
C --> H[通信客户端]
C --> I[认证处理]
D --> J[消息验证]
D --> K[数据序列化]
E --> L[工具注册]
E --> M[工具执行]
F --> N[资源注册]
F --> O[资源访问]
核心组件说明:
- McpServer:MCP服务器核心类,负责管理工具、资源和提示,处理客户端请求
- McpClient:MCP客户端类,提供与MCP服务器交互的接口
- Transports:通信传输层,支持多种通信协议
- Validation:数据验证模块,确保消息格式符合MCP协议规范
这种架构设计的优势在于:
- 关注点分离:将上下文管理与LLM交互逻辑分离,提高代码可维护性
- 模块化扩展:可以根据需求添加新的工具、资源或传输方式
- 协议兼容性:确保不同实现之间的互操作性
3.分级实践指南:从零开始的MCP开发之旅
3.1 入门级:搭建基础MCP服务器与客户端
目标:创建一个具有基本加法工具的MCP服务器,并使用客户端与之交互
前置条件:
- Node.js 14+环境
- TypeScript基础知识
- npm或yarn包管理器
步骤1:项目初始化
# 克隆仓库
git clone https://gitcode.com/GitHub_Trending/ty/typescript-sdk
cd typescript-sdk
# 安装依赖
npm install
步骤2:创建基础MCP服务器
创建文件 examples/server/basicServer.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: 'basic-calculator-server',
version: '1.0.0'
});
// 注册加法工具
server.registerTool(
'add', // 工具名称
{
title: '加法工具',
description: '将两个数字相加并返回结果',
inputSchema: z.object({ a: z.number(), b: z.number() }), // 输入验证 schema
outputSchema: z.object({ result: z.number() }) // 输出验证 schema
},
async ({ a, b }) => { // 工具实现函数
const result = a + b;
return {
content: [{ type: 'text', text: `计算结果: ${a} + ${b} = ${result}` }],
structuredContent: { result }
};
}
);
// 设置Express服务器
const app = express();
app.use(express.json());
// 添加MCP端点
app.post('/mcp', async (req, res) => {
// 创建Streamable HTTP传输
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(`MCP服务器运行在 http://localhost:${port}/mcp`);
console.log('可用工具: add(a: number, b: number)');
});
步骤3:创建MCP客户端
创建文件 examples/client/basicClient.ts:
import { McpClient } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHttpClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
async function main() {
// 创建客户端传输
const transport = new StreamableHttpClientTransport({
url: 'http://localhost:3000/mcp'
});
// 创建MCP客户端
const client = new McpClient(transport);
try {
// 连接到服务器
await client.connect();
console.log('已连接到MCP服务器');
// 调用加法工具
const result = await client.callTool('add', { a: 5, b: 3 });
// 输出结果
console.log('工具调用结果:', result);
// 预期输出: 工具调用结果: { result: 8 }
} catch (error) {
console.error('发生错误:', error);
} finally {
// 断开连接
await client.disconnect();
}
}
// 运行客户端
main();
步骤4:运行与测试
# 启动服务器
npx tsx examples/server/basicServer.ts
# 另开终端,运行客户端
npx tsx examples/client/basicClient.ts
执行效果: 服务器终端将显示"服务器运行在 http://localhost:3000/mcp" 客户端终端将显示"已连接到MCP服务器"和"工具调用结果: { result: 8 }"
应用场景:
- 快速原型验证
- 简单工具服务
- 本地开发与测试
避坑指南:
- 确保服务器先于客户端启动
- 检查端口是否被占用
- 输入参数类型需与schema定义一致
3.2 进阶级:构建带认证和资源管理的MCP系统
目标:实现一个具有用户认证、动态资源和高级工具的MCP服务器
步骤1:添加认证中间件
创建文件 examples/server/authMiddleware.ts:
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { AuthMiddleware } from '@modelcontextprotocol/sdk/server/middleware/auth.js';
// 创建认证中间件
const authMiddleware = new AuthMiddleware({
validateToken: async (token) => {
// 在实际应用中,这里应该验证JWT或其他类型的令牌
return token === 'valid-token';
}
});
// 创建带认证的MCP服务器
export const createAuthenticatedServer = () => {
const server = new McpServer({
name: 'authenticated-server',
version: '1.0.0',
middleware: [authMiddleware]
});
return server;
};
步骤2:实现动态资源
扩展服务器代码,添加用户资料资源:
// 在basicServer.ts中添加
import { ResourceTemplate } from '@modelcontextprotocol/sdk/core/types.js';
import { createAuthenticatedServer } from './authMiddleware.js';
// 使用带认证的服务器
const server = createAuthenticatedServer();
// 注册用户资料资源
server.registerResource(
'user-profile',
new ResourceTemplate('users://{userId}/profile', { list: undefined }),
{
title: '用户资料',
description: '获取指定用户的个人资料信息'
},
async (uri, { userId }) => {
// 在实际应用中,这里应该从数据库获取用户信息
const mockUserData = {
userId,
name: '示例用户',
email: 'user@example.com',
joinDate: '2023-01-01'
};
return {
contents: [
{
uri: uri.href,
text: JSON.stringify(mockUserData, null, 2)
}
]
};
}
);
步骤3:创建高级工具
添加一个计算BMI的工具:
// 注册BMI计算器工具
server.registerTool(
'calculate-bmi',
{
title: 'BMI计算器',
description: '根据身高和体重计算身体质量指数(BMI)',
inputSchema: z.object({
weightKg: z.number().positive().description('体重(公斤)'),
heightM: z.number().positive().description('身高(米)')
}),
outputSchema: z.object({
bmi: z.number().description('身体质量指数'),
category: z.enum(['偏瘦', '正常', '超重', '肥胖']).description('BMI分类')
})
},
async ({ weightKg, heightM }) => {
const bmi = weightKg / (heightM * heightM);
let category;
if (bmi < 18.5) category = '偏瘦';
else if (bmi < 24) category = '正常';
else if (bmi < 28) category = '超重';
else category = '肥胖';
return {
content: [{
type: 'text',
text: `BMI计算结果: ${bmi.toFixed(2)} (${category})`
}],
structuredContent: { bmi: parseFloat(bmi.toFixed(2)), category }
};
}
);
步骤4:更新客户端以支持认证和资源访问
// 在basicClient.ts中添加认证和资源访问代码
// ... 之前的代码 ...
// 连接到服务器时添加认证头
const transport = new StreamableHttpClientTransport({
url: 'http://localhost:3000/mcp',
headers: {
'Authorization': 'Bearer valid-token'
}
});
// ... 连接代码 ...
// 调用BMI工具
const bmiResult = await client.callTool('calculate-bmi', {
weightKg: 70,
heightM: 1.75
});
console.log('BMI计算结果:', bmiResult);
// 访问用户资源
const userProfile = await client.getResource('users://123/profile');
console.log('用户资料:', userProfile);
应用场景:
- 需要用户认证的企业应用
- 个性化推荐系统
- 健康管理应用
避坑指南:
- 认证中间件应在工具和资源注册前添加
- 资源URI模板参数需与回调函数参数匹配
- 敏感资源访问需添加适当的权限检查
3.3 专家级:MCP服务器的K8s容器化部署与性能优化
目标:实现MCP服务器的容器化部署、水平扩展和性能优化
步骤1:创建Dockerfile
在项目根目录创建 Dockerfile:
FROM node:18-alpine as builder
WORKDIR /app
# 复制依赖文件
COPY package*.json ./
COPY pnpm-lock.yaml ./
# 安装依赖
RUN npm install -g pnpm && pnpm install
# 复制源代码
COPY . .
# 构建项目
RUN pnpm build
# 生产阶段
FROM node:18-alpine
WORKDIR /app
# 复制构建产物
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package.json ./
# 暴露端口
EXPOSE 3000
# 启动命令
CMD ["node", "dist/examples/server/basicServer.js"]
步骤2:创建Kubernetes部署配置
创建 k8s/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-server
spec:
replicas: 3
selector:
matchLabels:
app: mcp-server
template:
metadata:
labels:
app: mcp-server
spec:
containers:
- name: mcp-server
image: mcp-server:latest
ports:
- containerPort: 3000
resources:
limits:
cpu: "1"
memory: "1Gi"
requests:
cpu: "500m"
memory: "512Mi"
env:
- name: NODE_ENV
value: "production"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: mcp-server-service
spec:
selector:
app: mcp-server
ports:
- port: 80
targetPort: 3000
type: LoadBalancer
步骤3:实现会话持久化
创建基于Redis的会话存储:
import { RedisEventStore } from '@modelcontextprotocol/sdk/server/stores/redis.js';
import { createClient } from 'redis';
// 创建Redis客户端
const redisClient = createClient({
url: process.env.REDIS_URL || 'redis://localhost:6379'
});
await redisClient.connect();
// 创建Redis事件存储
const eventStore = new RedisEventStore({
client: redisClient,
prefix: 'mcp-sessions:'
});
// 在传输配置中使用事件存储
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => crypto.randomUUID(),
eventStore: eventStore
});
步骤4:性能优化实现
添加工具执行缓存和请求批处理:
import { CachedTool } from '@modelcontextprotocol/sdk/server/optimizations/cache.js';
// 使用缓存包装工具实现
const cachedAddTool = new CachedTool({
toolName: 'add',
ttl: 300, // 缓存5分钟
implementation: async ({ a, b }) => {
// 原始工具实现
const result = a + b;
return {
content: [{ type: 'text', text: `计算结果: ${a} + ${b} = ${result}` }],
structuredContent: { result }
};
}
});
// 注册缓存工具
server.registerTool(
cachedAddTool.name,
cachedAddTool.definition,
cachedAddTool.handler
);
// 启用请求批处理
server.configureBatchProcessing({
enabled: true,
maxBatchSize: 10,
timeoutMs: 100
});
步骤5:部署与扩展
# 构建Docker镜像
docker build -t mcp-server:latest .
# 推送镜像到仓库
docker tag mcp-server:latest your-registry/mcp-server:latest
docker push your-registry/mcp-server:latest
# 部署到Kubernetes
kubectl apply -f k8s/deployment.yaml
# 扩展副本数量
kubectl scale deployment mcp-server --replicas=5
应用场景:
- 高并发生产环境
- 多区域部署
- 企业级LLM应用平台
避坑指南:
- 确保会话存储与K8s扩展策略匹配
- 合理设置资源限制,避免OOM错误
- 缓存策略需考虑数据一致性要求
4.通信协议对比分析:选择最适合的MCP传输方式
MCP协议支持多种传输方式,每种方式都有其适用场景和优缺点。选择合适的传输方式对于构建高效、可靠的MCP应用至关重要。
4.1 Streamable HTTP:远程通信的首选方案
技术原理:基于HTTP的流式通信协议,支持请求/响应和服务器推送模式
优势:
- 兼容性好:可通过标准HTTP基础设施传输
- 双向通信:支持客户端请求和服务器主动推送
- 会话支持:可配置会话管理或无状态模式
劣势:
- 连接开销:相比Stdio有更高的连接建立开销
- 配置复杂:需要处理CORS、身份验证等HTTP相关问题
适用场景:
- 远程服务器部署
- 跨网络通信
- 需要通过负载均衡器的场景
实现示例:
// 服务器端
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined, // 无状态模式
enableJsonResponse: true
});
// 客户端
const transport = new StreamableHttpClientTransport({
url: 'https://api.example.com/mcp'
});
4.2 Stdio:本地进程间通信的轻量级选择
技术原理:通过标准输入/输出流进行进程间通信
优势:
- 低延迟:本地通信,无网络开销
- 简单可靠:无需处理网络问题
- 资源占用少:轻量级实现
劣势:
- 仅限本地:无法跨机器通信
- 单向通信:主要支持客户端到服务器的请求
- 调试困难:流数据难以捕获和分析
适用场景:
- 本地工具集成
- CLI应用
- 容器内进程通信
实现示例:
// 服务器端
const transport = new StdioServerTransport();
await server.connect(transport);
// 客户端
const transport = new StdioClientTransport({
command: 'node',
args: ['server.js']
});
4.3 WebSocket:实时双向通信的最佳选择
技术原理:基于TCP的全双工通信协议,支持持久连接
优势:
- 低延迟:持久连接,减少连接建立开销
- 全双工:同时支持双向通信
- 实时性好:适合需要频繁交互的场景
劣势:
- 资源占用高:长期保持连接消耗资源
- 兼容性问题:部分网络环境可能阻止WebSocket连接
- 实现复杂:需要处理连接维护和重连
适用场景:
- 实时协作工具
- 聊天机器人
- 实时数据流处理
实现示例:
// 服务器端 (使用Express)
import { WebSocketServerTransport } from '@modelcontextprotocol/sdk/server/websocket.js';
import http from 'http';
import { Server } from 'ws';
const app = express();
const server = http.createServer(app);
const wss = new Server({ server });
const transport = new WebSocketServerTransport({ wss });
await server.connect(transport);
server.listen(8080);
// 客户端
import { WebSocketClientTransport } from '@modelcontextprotocol/sdk/client/websocket.js';
const transport = new WebSocketClientTransport({
url: 'ws://localhost:8080/mcp'
});
4.4 协议选择决策指南
| 评估因素 | Streamable HTTP | Stdio | WebSocket |
|---|---|---|---|
| 通信距离 | 远程 | 本地 | 远程 |
| 延迟 | 中 | 低 | 低 |
| 带宽效率 | 中 | 高 | 高 |
| 实现复杂度 | 中 | 低 | 高 |
| 防火墙穿透 | 好 | N/A | 一般 |
| 状态管理 | 支持 | 有限 | 支持 |
决策流程图:
graph TD
A[选择传输协议] --> B{通信范围}
B -->|本地| C[使用Stdio]
B -->|远程| D{实时性要求}
D -->|高| E[使用WebSocket]
D -->|一般| F[使用Streamable HTTP]
F --> G{是否需要会话}
G -->|是| H[启用会话管理]
G -->|否| I[无状态模式]
5.性能优化:提升MCP系统吞吐量与响应速度
构建高性能的MCP系统需要综合考虑多个方面,包括代码优化、资源管理、缓存策略等。以下是提升MCP系统性能的关键策略:
5.1 工具执行优化:减少计算密集型操作的影响
异步处理:将耗时操作放入异步队列,避免阻塞主线程
import { createQueue } from 'kue';
// 创建任务队列
const queue = createQueue({
redis: {
host: process.env.REDIS_HOST || 'localhost'
}
});
// 注册异步工具
server.registerTool(
'heavy-computation',
{
title: '复杂计算工具',
description: '执行复杂的计算任务',
inputSchema: z.object({ data: z.array(z.number()) }),
outputSchema: z.object({ result: z.number() })
},
async (input) => {
// 创建任务并添加到队列
return new Promise((resolve, reject) => {
const job = queue.create('computation', input)
.save((err) => {
if (err) reject(err);
});
// 监听任务完成
job.on('complete', (result) => {
resolve({
content: [{ type: 'text', text: `计算结果: ${result}` }],
structuredContent: { result }
});
});
job.on('failed', (err) => {
reject(err);
});
});
}
);
// 工作进程处理队列任务
queue.process('computation', (job, done) => {
// 执行复杂计算
const result = performHeavyComputation(job.data.data);
done(null, result);
});
资源池化:对于需要频繁创建和销毁的资源(如数据库连接),使用连接池
import { Pool } from 'pg';
// 创建数据库连接池
const pool = new Pool({
user: 'dbuser',
host: 'database.server.com',
database: 'mydb',
password: 'secretpassword',
port: 5432,
max: 20, // 最大连接数
idleTimeoutMillis: 30000
});
// 在工具中使用连接池
server.registerTool(
'db-query',
{
title: '数据库查询工具',
description: '执行数据库查询',
inputSchema: z.object({ query: z.string() }),
outputSchema: z.object({ results: z.array(z.object({})) })
},
async ({ query }) => {
const client = await pool.connect();
try {
const res = await client.query(query);
return {
content: [{ type: 'text', text: `查询结果: ${JSON.stringify(res.rows)}` }],
structuredContent: { results: res.rows }
};
} finally {
client.release(); // 释放连接回池
}
}
);
5.2 缓存策略:减少重复计算和数据获取
工具结果缓存:对相同输入的工具调用结果进行缓存
import NodeCache from 'node-cache';
// 创建缓存实例
const cache = new NodeCache({ stdTTL: 300 }); // 默认缓存5分钟
// 创建带缓存的工具包装器
const withCache = (toolName, handler, ttl = 300) => {
return async (input) => {
// 创建唯一缓存键
const cacheKey = `${toolName}:${JSON.stringify(input)}`;
// 尝试从缓存获取
const cachedResult = cache.get(cacheKey);
if (cachedResult) {
return cachedResult;
}
// 缓存未命中,执行工具
const result = await handler(input);
// 存入缓存
cache.set(cacheKey, result, ttl);
return result;
};
};
// 使用缓存包装工具
server.registerTool(
'add-with-cache',
{
title: '带缓存的加法工具',
description: '将两个数字相加并缓存结果',
inputSchema: z.object({ a: z.number(), b: z.number() }),
outputSchema: z.object({ result: z.number() })
},
withCache('add', async ({ a, b }) => {
console.log('实际执行加法计算'); // 仅在缓存未命中时输出
const result = a + b;
return {
content: [{ type: 'text', text: `计算结果: ${a} + ${b} = ${result}` }],
structuredContent: { result }
};
})
);
资源预加载:提前加载频繁访问的资源
// 预加载常用资源
const preloadResources = async () => {
const popularResources = [
'config://app/settings',
'docs://api-reference'
];
for (const uri of popularResources) {
try {
const resource = await fetchResource(uri); // 实际的资源获取逻辑
cache.set(`resource:${uri}`, resource, 3600); // 缓存1小时
} catch (error) {
console.error(`预加载资源失败: ${uri}`, error);
}
}
};
// 服务器启动时预加载资源
preloadResources().then(() => {
console.log('常用资源预加载完成');
});
5.3 并发控制:平衡系统负载与响应速度
请求限流:防止系统过载
import rateLimit from 'express-rate-limit';
// 创建限流中间件
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: 100, // 每个IP限制100个请求
standardHeaders: true,
legacyHeaders: false,
message: { error: '请求过于频繁,请稍后再试' }
});
// 应用到MCP端点
app.post('/mcp', apiLimiter, async (req, res) => {
// 处理MCP请求...
});
动态扩缩容:根据系统负载自动调整资源
在Kubernetes环境中,可以配置HPA(Horizontal Pod Autoscaler):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: mcp-server-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: mcp-server
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
6.安全最佳实践:保护MCP系统与用户数据
MCP系统处理可能包含敏感信息的上下文数据,因此安全性至关重要。以下是保护MCP系统的关键安全措施:
6.1 认证与授权:控制访问权限
JWT认证实现:
import jwt from 'jsonwebtoken';
import { AuthMiddleware } from '@modelcontextprotocol/sdk/server/middleware/auth.js';
// JWT验证中间件
const jwtAuthMiddleware = new AuthMiddleware({
validateToken: async (token) => {
try {
// 验证JWT
const decoded = jwt.verify(token, process.env.JWT_SECRET);
// 检查令牌是否过期
if (decoded.exp && Date.now() >= decoded.exp * 1000) {
return false;
}
// 返回用户信息,将在后续中间件和工具中可用
return {
userId: decoded.sub,
roles: decoded.roles || []
};
} catch (error) {
return false;
}
}
});
// 基于角色的授权中间件
const roleBasedAuthMiddleware = new AuthMiddleware({
async authorize(context) {
// 获取从JWT中间件传递的用户信息
const user = context.auth;
// 检查用户是否有权限访问
if (!user) {
return { allowed: false, error: '未认证' };
}
// 检查工具访问权限
if (context.toolName === 'admin-tool' && !user.roles.includes('admin')) {
return { allowed: false, error: '权限不足' };
}
return { allowed: true };
}
});
// 将中间件添加到服务器
const server = new McpServer({
name: 'secure-server',
version: '1.0.0',
middleware: [jwtAuthMiddleware, roleBasedAuthMiddleware]
});
6.2 数据安全:保护敏感信息
数据加密传输:
// 使用HTTPS配置Express服务器
import https from 'https';
import fs from 'fs';
const options = {
key: fs.readFileSync('path/to/private-key.pem'),
cert: fs.readFileSync('path/to/certificate.pem')
};
// 创建HTTPS服务器
https.createServer(options, app).listen(443, () => {
console.log('HTTPS服务器运行在端口443');
});
敏感数据脱敏:
// 创建数据脱敏工具
const sanitizeSensitiveData = (data) => {
if (typeof data !== 'object' || data === null) return data;
// 递归处理对象
const sanitized = Array.isArray(data) ? [...data] : { ...data };
// 脱敏敏感字段
const sensitiveFields = ['password', 'creditCard', 'ssn', 'apiKey'];
sensitiveFields.forEach(field => {
if (sanitized[field]) {
sanitized[field] = '***[已脱敏]***';
}
});
// 递归处理嵌套对象
Object.keys(sanitized).forEach(key => {
if (typeof sanitized[key] === 'object' && sanitized[key] !== null) {
sanitized[key] = sanitizeSensitiveData(sanitized[key]);
}
});
return sanitized;
};
// 在工具响应中使用脱敏
server.registerTool(
'user-info',
{
title: '用户信息工具',
description: '获取用户信息',
inputSchema: z.object({ userId: z.string() }),
outputSchema: z.object({ user: z.object({}) })
},
async ({ userId }) => {
// 获取原始用户数据
const userData = await getUserData(userId);
// 脱敏敏感信息
const sanitizedData = sanitizeSensitiveData(userData);
return {
content: [{ type: 'text', text: `用户信息: ${JSON.stringify(sanitizedData)}` }],
structuredContent: { user: sanitizedData }
};
}
);
6.3 安全监控与审计:及时发现并响应安全事件
请求日志记录:
// 添加请求日志中间件
app.use((req, res, next) => {
const start = Date.now();
// 记录响应完成
res.on('finish', () => {
const duration = Date.now() - start;
const logEntry = {
timestamp: new Date().toISOString(),
method: req.method,
path: req.path,
status: res.statusCode,
duration,
ip: req.ip,
userId: req.user?.userId || 'unauthenticated',
tool: req.body?.toolName || 'unknown'
};
// 记录到日志系统
console.log(JSON.stringify(logEntry));
// 异常检测 - 记录慢请求
if (duration > 5000) {
console.warn(`慢请求警报: ${JSON.stringify(logEntry)}`);
}
// 异常检测 - 频繁失败
if (res.statusCode >= 400) {
console.warn(`请求失败: ${JSON.stringify(logEntry)}`);
}
});
next();
});
7.总结:MCP TypeScript SDK的价值与未来展望
MCP TypeScript SDK通过标准化LLM上下文管理,为开发者提供了构建强大、可扩展和安全的AI应用的工具集。从简单的工具调用到复杂的多节点部署,MCP SDK都能提供一致的开发体验和可靠的运行时表现。
7.1 MCP SDK的核心价值
- 标准化:统一的上下文管理和通信协议,降低系统集成成本
- 灵活性:支持多种传输方式和部署策略,适应不同应用场景
- 可扩展性:模块化设计和水平扩展能力,满足从原型到生产的需求
- 安全性:内置的认证授权机制和安全最佳实践,保护敏感数据
7.2 未来发展方向
- AI原生优化:进一步优化针对LLM特点的上下文管理策略
- 多模态支持:扩展协议以支持图像、音频等多模态上下文
- 边缘计算支持:优化在边缘设备上的运行效率
- 更丰富的中间件生态:提供更多领域特定的中间件和工具
通过掌握MCP TypeScript SDK,开发者可以更专注于构建创新的AI应用,而不必重复解决上下文管理和系统集成等基础问题。无论是构建企业级AI助手,还是开发特定领域的智能应用,MCP SDK都提供了坚实的技术基础。
随着LLM技术的不断发展,MCP协议和SDK将继续演进,为AI应用开发提供更加完善的标准化解决方案。现在就开始探索MCP TypeScript SDK,开启你的LLM应用开发之旅吧!
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 StartedRust098- 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