首页
/ 零门槛掌握MCP TypeScript SDK:从实战到架构师的LLM上下文协议实现指南

零门槛掌握MCP TypeScript SDK:从实战到架构师的LLM上下文协议实现指南

2026-04-28 10:26:20作者:裘晴惠Vivianne

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应用开发之旅吧!

登录后查看全文
热门项目推荐
相关项目推荐