MCP TypeScript SDK的使用

MCP TypeScript SDK 架构

概述

MCP (Model Context Protocol) TypeScript SDK 实现了模型上下文协议,用于在 LLM 和外部数据源/工具之间建立标准化的通信。


架构图

arduino 复制代码
┌─────────────────────────────────────────────────────────────────────────────┐
│                              MCP Architecture                                │
└─────────────────────────────────────────────────────────────────────────────┘

                              ┌─────────────────┐
                              │   LLM (AI)      │
                              └────────┬────────┘
                                       │
                          ┌────────────▼────────────┐
                          │      MCP Client         │
                          │  @modelcontextprotocol/ │
                          │      sdk/client         │
                          └────────────┬────────────┘
                                       │
                    ┌──────────────────┼──────────────────┐
                    │                  │                  │
          ┌─────────▼─────────┐ ┌──────▼──────┐ ┌───────▼──────┐
          │    Tools API      │ │ Resources   │ │   Prompts    │
          │  listTools()      │ │ listResources│ │ listPrompts()│
          │  callTool()       │ │ readResource │ │  getPrompt()  │
          └─────────┬─────────┘ └──────┬──────┘ └───────┬──────┘
                    │                   │                │
          ┌─────────▼───────────────────▼────────────────▼─────────┐
          │                    Transport Layer                     │
          │  ┌──────────────┐  ┌──────────────────┐  ┌──────────┐ │
          │  │    Stdio     │  │ Streamable HTTP  │  │   SSE    │ │
          │  │  (Local)     │  │   (Remote)       │  │(Legacy)  │ │
          │  └──────────────┘  └──────────────────┘  └──────────┘ │
          └──────────────────────────┬──────────────────────────────┘
                                    │
                    ┌───────────────┴───────────────┐
                    │                               │
          ┌─────────▼─────────┐         ┌─────────▼─────────┐
          │   MCP Server      │         │   MCP Client      │
          │  (Provider)       │◄───────►│  (Consumer)       │
          └─────────┬─────────┘   RPC   └───────────────────┘
                    │
          ┌─────────▼─────────────────────────────────────────┐
          │                  Capability Layer                   │
          │  ┌─────────┐  ┌──────────┐  ┌────────┐  ┌───────┐ │
          │  │ Tools   │  │ Resources │  │Prompts │  │Sampling│ │
          │  │         │  │          │  │        │  │Elicit │ │
          │  └─────────┘  └──────────┘  └────────┘  └───────┘ │
          └────────────────────────────────────────────────────┘

组件说明

组件 作用 职责说明
LLM 消费方 大语言模型,通过 MCP Client 发现和使用外部工具、资源。解析用户意图,决定调用哪些工具,处理返回结果
MCP Client 连接管理 SDK 客户端库,负责:① 与服务器建立连接 ② 发现并列出可用工具/资源/提示器 ③ 调用工具并传递参数 ④ 读取资源内容 ⑤ 处理服务器通知
MCP Server 能力提供 SDK 服务器端,负责:① 注册和暴露 Tools(可执行函数)② 注册和暴露 Resources(可读数据)③ 注册和暴露 Prompts(提示模板)④ 处理客户端请求并返回结果
Transport 通信通道 传输层,负责客户端与服务器之间的消息传递。支持多种传输方式:① Stdio - 本地进程间通信 ② HTTP Streamable - 远程 HTTP 通信,支持双向流 ③ SSE - 服务器单向推送事件
Tools 执行能力 服务器暴露的可调用函数,用于执行具体操作(如计算、查询、创建等)。带输入参数,返回执行结果
Resources 数据暴露 服务器暴露的只读数据,支持客户端读取和订阅变更。可以是配置文件、数据库记录、文件内容等
Prompts 模板复用 预定义的提示模板,支持参数化。客户端可以获取填充参数后的完整消息,用于标准化常见任务的提示
Sampling LLM 代理 允许服务器向客户端请求 LLM 推理能力。服务器可以请客户端的 LLM 生成文本、总结内容等
Elicitation 交互代理 允许服务器向客户端请求用户输入。用于需要用户确认、填写表单或做出选择的场景

SDK 模块结构

本项目使用 v1 版本的 @modelcontextprotocol/sdk 统一包。

模块 导入路径 用途
Client @modelcontextprotocol/sdk/client/index.js MCP 客户端实现,连接服务器、调用工具、读取资源
Server @modelcontextprotocol/sdk/server/mcp.js MCP 服务器实现,暴露工具、资源、提示器

协议层设计

Transport 层

Transport 层负责客户端与服务器之间的底层通信。

传输类型 适用场景
Stdio StdioServerTransport / StdioClientTransport 本地进程通信,同一系统内 spawn 子进程
HTTP Streamable StreamableHTTPClientTransport 远程服务器,支持 SSE 事件流(推荐)
SSE SSEClientTransport Server-Sent Events 单向事件流
Stdio 传输

适合本地场景,服务器作为子进程启动:

typescript 复制代码
// 服务器
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const transport = new StdioServerTransport();
await server.connect(transport);

// 客户端
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
const transport = new StdioClientTransport({ command: 'node', args: ['server.js'] });
HTTP Streamable 传输

适合远程场景,服务器独立运行:

typescript 复制代码
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';

const transport = new StreamableHTTPClientTransport(new URL('http://localhost:3000/mcp'));
await client.connect(transport);

Capability 层

MCP 协议定义了四种主要能力。

Tools(工具)

工具是服务器暴露的可调用函数,LLM 可以通过工具执行实际操作。

服务器注册

typescript 复制代码
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import * as z from 'zod';

server.registerTool(
  'calculate-bmi',
  {
    title: 'BMI Calculator',
    description: 'Calculate Body Mass Index',
    inputSchema: z.object({
      weightKg: z.number().describe('Weight in kilograms'),
      heightM: z.number().describe('Height in meters')
    }),
    outputSchema: z.object({ bmi: z.number() })
  },
  async ({ weightKg, heightM }) => {
    const bmi = weightKg / (heightM * heightM);
    return {
      content: [{ type: 'text', text: `BMI: ${bmi.toFixed(2)}` }],
      structuredContent: { bmi }
    };
  }
);

客户端调用

typescript 复制代码
const result = await client.callTool({
  name: 'calculate-bmi',
  arguments: { weightKg: 70, heightM: 1.75 }
});

Resources(资源)

资源是服务器暴露的二进制或文本数据,客户端可以读取和订阅。

服务器注册

typescript 复制代码
server.registerResource(
  'config://app',
  {
    title: 'App Config',
    description: 'Application configuration',
    mimeType: 'application/json'
  },
  async () => ({
    contents: [{
      uri: 'config://app',
      text: JSON.stringify({ theme: 'dark', language: 'en' })
    }]
  })
);

客户端操作

typescript 复制代码
// 列出资源
const { resources } = await client.listResources();

// 读取资源
const { contents } = await client.readResource({ uri: 'config://app' });

// 订阅变更
await client.subscribeResource({ uri: 'config://app' });
client.setNotificationHandler('notifications/resources/updated', handler);

Prompts(提示器)

提示器是预定义的提示模板,可以携带参数生成消息。

服务器注册

typescript 复制代码
server.registerPrompt(
  'review-code',
  {
    title: 'Code Review',
    description: 'Review code for best practices',
    argsSchema: z.object({ code: z.string() })
  },
  ({ code }) => ({
    messages: [{
      role: 'user',
      content: { type: 'text', text: `Please review:\n\n${code}` }
    }]
  })
);

客户端调用

typescript 复制代码
const { messages } = await client.getPrompt({ name: 'review-code', arguments: { code: '...' } });

Sampling(采样)

Sampling 允许服务器向客户端请求 LLM 推理。

服务器端请求

typescript 复制代码
server.registerTool(
  'summarize',
  { inputSchema: z.object({ text: z.string() }) },
  async ({ text }, ctx) => {
    const response = await ctx.mcpReq.requestSampling({
      messages: [{ role: 'user', content: { type: 'text', text: `Summarize: ${text}` } }],
      maxTokens: 500
    });
    return { content: [{ type: 'text', text: JSON.stringify(response.content) }] };
  }
);

客户端处理

typescript 复制代码
client.setRequestHandler('sampling/createMessage', async request => {
  const lastMessage = request.params.messages.at(-1);
  // 转发给 LLM 并返回
  return { model: 'claude-3-5-sonnet', role: 'assistant', content: { type: 'text', text: '...' } };
});

Elicitation(请求用户输入)

Elicitation 允许服务器向客户端请求用户交互式输入。

服务器端请求

typescript 复制代码
const result = await ctx.mcpReq.elicitInput({
  mode: 'form',
  message: 'Please rate this:',
  requestedSchema: {
    type: 'object',
    properties: { rating: { type: 'integer', minimum: 1, maximum: 5 } },
    required: ['rating']
  }
});

客户端处理

typescript 复制代码
client.setRequestHandler('elicitation/create', async request => ({
  action: 'accept',
  content: { rating: 5 }
}));

Auth 层

SDK 支持 OAuth 2.0 认证。

Provider 用途
ClientCredentialsProvider 客户端凭证流,适用于服务间认证
PrivateKeyJwtProvider 私钥 JWT,适用于更安全的场景
typescript 复制代码
import { ClientCredentialsProvider } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';

const authProvider = new ClientCredentialsProvider({
  clientId: 'my-service',
  clientSecret: 'my-secret'
});

const transport = new StreamableHTTPClientTransport(
  new URL('http://localhost:3000/mcp'),
  { authProvider }
);

错误处理

SDK 提供 ProtocolErrorSdkError

typescript 复制代码
import { ProtocolError } from '@modelcontextprotocol/sdk/client/index.js';

if (error instanceof ProtocolError) {
  console.log(error.code); // 错误码
  console.log(error.message); // 错误消息
}
相关推荐
东小西5 小时前
第8篇:《白嫖社区生态:一行配置接入GitHub的MCP Server,AI直接读我的代码仓库》
openai·ai编程
雨辰AI6 小时前
全集实战:企业级大模型服务化部署全栈指南|FastAPI 封装 + Nginx 负载均衡 + 高可用架构 从单机到生产一步到位
人工智能·ai·负载均衡·fastapi·ai编程
chaors9 小时前
DeepResearchSystem 0x01:Agent 基础
langchain·aigc·ai编程
sweet丶10 小时前
移动端轻量级AI Agent自动化UI验证:sim-use
ai编程
东小西10 小时前
第7篇:《工具的USB接口:我把Function Calling升级成了MCP》
openai·ai编程
腻害兔11 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:CRM 客户关系模块深度解析——从线索到回款,一套完整的 B2B 销售闭环是怎么搭的?
java·前端·javascript·vue.js·产品经理·ai编程
大数据点灯人11 小时前
【AI编程】Vibe Coding 模型选型:越贵越好吗?效果/速度/成本平衡指南
编程·ai编程·claude·codex·vibe coding
oort12311 小时前
吃上了自家的细糠,还挺丝滑,用起来手感还行,OortCloud发布新版AI编程平台,下载 OortCodex,Token多,免费薅
大数据·开发语言·人工智能·ai编程
小虎AI生活12 小时前
WorkBuddy 自动化实战,TTS 配音从安装到跑通
ai编程
小虎AI生活14 小时前
workbuddy 短视频获客的终极形态,不是做内容,是建工厂
ai编程