动手学Agent应用开发(TS/JS 最简实践指南)

一、学习心得

作为一名全栈开发者,接触 MCP(Model Context Protocol)协议后,最直观的感受是它为 TS/JS/Node.js 生态打通了 "大模型到智能 Agent" 的最后一公里。此前使用 LangChain JS 等框架开发 Agent 时,常被工具调用、Prompt 管理、资源访问的耦合问题困扰 ------ 前端需适配后端接口,后端需兼容大模型输出格式,全栈协同成本高。而 MCP 通过标准化协议将工具、Prompt、资源抽象分离,配合官方 TypeScript SDK 的全栈支持(含并发管理、日志、资源调度),让 Node.js 后端、前端甚至跨端项目都能无缝集成 Agent 能力。

另一个深刻体会是 MCP 的 "轻量集成" 特性:无需重构现有 Node.js 服务,只需通过注解 / 装饰器即可将业务接口封装为 MCP 工具,这对企业级全栈项目的迭代非常友好。同时,TS 的强类型特性与 MCP 的工具定义天然契合,类型注解不仅能提升代码可读性,还能让大模型更精准地识别工具参数,减少格式错误。此外,MCP 生态中丰富的调试工具(如 OpenMCP Client)支持 TS/JS 项目的全流程调试,极大降低了全栈开发的心智负担。

最后,意识到 2024 年 Agent 时代的核心是 "工程化落地",TS/JS 作为全栈领域的主流技术栈,MCP 的官方 TS SDK 完美适配 Node.js 微服务、前端项目,为全栈开发者提供了从原型到生产环境的完整解决方案,而 "高分高能"(从基准测试到业务落地)的转型,正是 MCP+TS/JS 的核心价值所在。

二、内容归纳整理

(一)MCP 核心逻辑:由来与原理

  1. 技术基石:Function Calling(OpenAI 接口协议),允许大模型调用工具成为任务执行者,通过 XML 指令引导解码器实现输出约束,是 AI Agent 的核心能力。
  2. 开发痛点:业务规模扩大导致代码耦合度高、维护难、不确定性增加,现有 Agent 框架需标准化抽象。
  3. 核心抽象:函数调用→工具(Tool)、引导文本→提示词(Prompt)、运行时输出→资源(Resource)。
  4. 协议价值:MCP 协议实现 Agent 与后端服务的解耦,工具 / Prompt / 资源通过 MCP Server 统一管理,支持跨语言、跨服务调用,尤其适配 TS/JS 全栈项目。

(二)TS/JS/Node.js 开发核心资源

1. 核心框架:TypeScript SDK
语言 框架 / 库 核心优势 GitHub 地址
TypeScript typescript-sdk 官方 TS SDK,支持工具 / 资源 / Prompt / 日志 / 并发管理,适配 Node.js/ 全栈项目 modelcontextprotocol/typescript-sdk

注意:

MCP TypeScript SDK 1.25.1及之前版本存在安全漏洞,该漏洞源于UriTemplate类处理RFC 6570爆炸数组模式时存在正则表达式拒绝服务,可能导致CPU消耗过高和拒绝服务攻击。

2. 调试工具(适配 TS/JS 项目)
工具名称 核心作用 支持 MCP 协议 支持大模型调试 适配场景
OpenMCP Client VS Code 插件,MCP 服务端调试 + 大模型调用验证 TS/JS 项目本地开发调试
MCP-CLI 命令行工具,调用测试 MCP 工具 / Prompt × Node.js 服务端自动化测试
Cherry Studio 跨平台客户端,统一管理 LLM 服务商 × 多模型联调 TS/JS 客户端项目
3. 开发流程(TS/JS 视角)
  1. 环境准备:Node.js 16+、TypeScript、OpenMCP 插件、大模型 API Token。
  2. 依赖安装:安装 typescript-sdk 及相关依赖(如 @modelcontextprotocol/sdk)。
  3. 定义工具 / Prompt:通过 TS 装饰器 / 接口定义 MCP 工具和 Prompt 模板。
  4. 启动 MCP Server:基于 Node.js 启动服务,暴露接口供 Agent 调用。
  5. 调试验证:通过 OpenMCP Client 或 MCP-CLI 测试工具 / Prompt 调用。
  6. 部署上线:集成到 Node.js 微服务 / 全栈项目,支持 SSE / 并发调用。

(三)从大模型到 AI Agent 的演进

  1. 技术积累(2015-2021):硬件(NVIDIA CUDA)、算法(Transformer)、框架(DeepSpeed)、数据四大支柱成型,为 TS/JS 生态的 Agent 开发提供底层支持。
  2. 大规模验证(2020-2023):GPT-3、ChatGPT 爆火,LLM 能力成熟,TS/JS 社区涌现 LangChain JS 等框架,MCP 协议填补标准化空白。
  3. Agent 时代(2024 - 至今):从 "文本输出" 到 "任务执行",TS/JS 的全栈优势 + MCP 的标准化,推动 Agent 落地到 Web/Node.js 服务场景。

(四)MCP 与 AI Agent 的未来

  1. 全生命周期管理:大模型部门与 Agent 开发部门协同,TS/JS 项目可通过 MCP 实现工具 / Prompt 的迭代与数据回流。
  2. 核心挑战:真实业务场景验证、反馈迭代机制标准化,TS/JS 生态需完善 MCP 与微服务、前端框架的集成方案。

三、TS/JS/Node.js 代码运行记录

(一)环境配置

1. 基础环境要求
  • Node.js:v16.14.0+(推荐 v18 LTS)
  • npm:v8+ 或 yarn v1.22+
  • TypeScript:v4.9+
  • VS Code:最新版 + OpenMCP 插件(搜索 "OpenMCP" 安装)
2. 依赖安装
复制代码
# 初始化Node.js项目
mkdir mcp-ts-demo && cd mcp-ts-demo
npm init -y

# 安装核心依赖:MCP TypeScript SDK、TypeScript、@types/node
npm install @modelcontextprotocol/sdk typescript @types/node --save
npm install ts-node nodemon --save-dev

# 初始化tsconfig.json
npx tsc --init
3. 配置 tsconfig.json(关键参数)
复制代码
{
  "compilerOptions": {
    "target": "ES2020",                          /* 适配Node.js 16+ */
    "module": "CommonJS",                        /* Node.js模块系统 */
    "moduleResolution": "Node",                  /* 模块解析方式 */
    "esModuleInterop": true,                     /* 兼容CommonJS/ES模块 */
    "forceConsistentCasingInFileNames": true,
    "strict": true,                              /* 开启严格类型检查 */
    "skipLibCheck": true                         /* 跳过依赖类型检查 */
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

(二)最简 MCP Server 开发(Node.js+TS)

1. 项目结构
复制代码
mcp-ts-demo/
├── src/
│   ├── server.ts       # MCP Server核心代码
│   └── config.ts       # 配置(大模型API、端口等)
├── tsconfig.json
└── package.json
2. 核心代码
(1)src/config.ts
复制代码
// 配置文件:MCP Server信息、大模型API
export const MCP_CONFIG = {
  serverName: "TS-MCP-Demo-Server",
  version: "1.0.0",
  port: 8000,
  llm: {
    baseUrl: "https://api.deepseek.com",
    apiKey: "<你的DeepSeek API Key>" // 替换为实际API Key
  }
};
(2)src/server.ts
复制代码
import { FastMCP, McpTool, McpPrompt } from "@modelcontextprotocol/sdk";
import { MCP_CONFIG } from "./config";

// 1. 创建MCP Server实例
const mcpServer = new FastMCP({
  name: MCP_CONFIG.serverName,
  version: MCP_CONFIG.version,
  port: MCP_CONFIG.port
});

// 2. 定义MCP工具:两数相加(带类型注解和描述)
@McpTool({
  description: "对两个数字进行实数域的加法运算,返回结果",
  parameters: {
    type: "object",
    properties: {
      a: { type: "number", description: "第一个加数" },
      b: { type: "number", description: "第二个加数" }
    },
    required: ["a", "b"]
  }
})
async function add(a: number, b: number): Promise<number> {
  return a + b;
}

// 3. 定义MCP Prompt:文本翻译(中文→英文)
@McpPrompt({
  description: "将输入的中文文本翻译成自然流畅的英文"
})
async function translateToEnglish(chineseText: string): Promise<string> {
  // Prompt模板:大模型将基于此模板生成翻译结果
  return `请将以下中文文本翻译成英文,要求准确、自然、符合英文表达习惯:\n\n${chineseText}`;
}

// 4. 注册工具和Prompt到MCP Server
mcpServer.registerTool(add);
mcpServer.registerPrompt(translateToEnglish);

// 5. 启动MCP Server
async function startServer() {
  try {
    await mcpServer.start();
    console.log(`✅ MCP Server启动成功!地址:http://127.0.0.1:${MCP_CONFIG.port}`);
    console.log(`📦 已注册工具:add`);
    console.log(`📦 已注册Prompt:translateToEnglish`);
  } catch (error) {
    console.error(`❌ MCP Server启动失败:`, error);
  }
}

// 启动服务
startServer();
3. 配置 package.json 脚本
复制代码
{
  "scripts": {
    "dev": "nodemon src/server.ts",
    "build": "tsc",
    "start": "node dist/server.js"
  }
}
4. 运行 MCP Server
复制代码
# 开发模式(实时热更新)
npm run dev

# 输出日志(成功标识)
✅ MCP Server启动成功!地址:http://127.0.0.1:8000
📦 已注册工具:add
📦 已注册Prompt:translateToEnglish

(三)MCP Client 调用示例(Node.js+TS)

1. 新增 src/client.ts
复制代码
import { McpClient } from "@modelcontextprotocol/sdk";
import { MCP_CONFIG } from "./config";

// 创建MCP Client实例,连接本地Server
const mcpClient = new McpClient({
  serverUrl: `http://127.0.0.1:${MCP_CONFIG.port}`
});

// 测试工具调用和Prompt获取
async function testMcpClient() {
  try {
    // 1. 调用add工具
    const addResult = await mcpClient.callTool("add", { a: 10, b: 20 });
    console.log(`🔧 工具add调用结果:10 + 20 = ${addResult}`);

    // 2. 获取translateToEnglish Prompt模板
    const promptTemplate = await mcpClient.getPrompt("translateToEnglish", {
      chineseText: "MCP协议让Node.js全栈项目快速集成AI Agent能力"
    });
    console.log(`📝 Prompt模板生成结果:\n${promptTemplate}`);

    // 3. (可选)调用大模型执行翻译(需集成LLM SDK)
    const { OpenAI } = require("@ai-app/agent-llm"); // 或其他LLM SDK
    const llmClient = new OpenAI({
      baseURL: MCP_CONFIG.llm.baseUrl,
      apiKey: MCP_CONFIG.llm.apiKey
    });
    const translationResult = await llmClient.chat.completions.create({
      model: "deepseek-chat",
      messages: [{ role: "user", content: promptTemplate }]
    });
    console.log(`🌐 翻译结果:${translationResult.choices[0].message.content}`);
  } catch (error) {
    console.error(`❌ Client调用失败:`, error);
  }
}

// 执行测试
testMcpClient();
2. 运行 Client 测试
复制代码
# 新开终端,运行Client
npx ts-node src/client.ts

# 输出结果
🔧 工具add调用结果:10 + 20 = 30
📝 Prompt模板生成结果:
请将以下中文文本翻译成英文,要求准确、自然、符合英文表达习惯:

MCP协议让Node.js全栈项目快速集成AI Agent能力
🌐 翻译结果:The MCP protocol enables Node.js full-stack projects to quickly integrate AI Agent capabilities.

(四)OpenMCP 插件调试(VS Code)

  1. 打开 VS Code,启动 OpenMCP 插件(左侧面板找到 "OpenMCP")。
  2. 点击 "Connect to MCP Server",输入地址http://127.0.0.1:8000
  3. 调试工具 add:输入参数{ "a": 5, "b": 3 },点击调用,返回8
  4. 调试 Prompt:选择translateToEnglish,输入中文文本,生成 Prompt 模板,验证格式正确性。

四、踩坑填坑记录

(一)环境配置类

  1. 坑:Node.js 版本低于 v16 导致 typescript-sdk 安装失败或运行报错

    • 原因:TS SDK 依赖 ES2020 + 特性,Node.js v14 及以下不支持

    • 填坑:升级 Node.js 到 v16.14.0+(推荐 v18 LTS),可通过 nvm 管理版本: bash

      运行

      复制代码
      # 安装nvm(Node版本管理器)
      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
      # 安装v18 LTS
      nvm install 18
      # 切换到v18
      nvm use 18
  2. 坑:TS 编译报错 "Cannot find module '@modelcontextprotocol/sdk'"

    • 原因:模块解析路径配置错误,或依赖未安装完整
    • 填坑:
      1. 确认依赖已安装:npm ls @modelcontextprotocol/sdk,缺失则重新安装

      2. 检查 tsconfig.json 的moduleResolution设置为NodeesModuleInterop设为true

      3. 若仍报错,手动添加类型声明文件(src/types/mcp.d.ts): typescript

        运行

        复制代码
        declare module "@modelcontextprotocol/sdk";
  3. 坑:OpenMCP 插件无法连接本地 MCP Server

    • 原因:端口被占用,或 Server 启动时绑定地址不是 127.0.0.1

    • 填坑:

      1. 检查端口占用:lsof -i :8000(Mac/Linux)或netstat -ano | findstr :8000(Windows),杀死占用进
      复制代码
         // server.ts中启动配置
         await mcpServer.start({ host: "0.0.0.0" });
      1. 重启 VS Code 和 OpenMCP 插件,重新连接

(二)开发编码类

  1. 坑:工具函数未加@McpTool装饰器导致注册失败

    • 原因:TS SDK 依赖装饰器识别工具元数据,缺失则无法注册
    • 填坑:确保所有工具函数都添加@McpTool装饰器,且装饰器内配置descriptionparameters(必填)
  2. 坑:异步工具函数未返回 Promise 导致调用超时

    • 原因:TS SDK 默认工具为异步执行,同步函数可能导致阻塞

    • 填坑:即使工具逻辑是同步的,也建议声明为async并返回 Promise:

      复制代码
      @McpTool(/* 配置 */)
      async add(a: number, b: number): Promise<number> {
        return Promise.resolve(a + b); // 显式返回Promise
      }
  3. 坑:Prompt 模板中参数替换失败

    • 原因:Prompt 函数参数名与模板中的变量名不一致

    • 填坑:确保 Prompt 函数参数名与模板变量名完全匹配,例如:

      复制代码
      // 正确:参数名chineseText与模板${chineseText}一致
      async function translateToEnglish(chineseText: string): Promise<string> {
        return `翻译:${chineseText}`;
      }

(三)调试部署类

  1. 坑:Node.js 微服务部署后,MCP Server 无法被外部 Agent 访问

    • 原因:默认绑定本地地址(127.0.0.1),或防火墙 / 安全组未开放端口
    • 填坑:
      1. 启动时绑定 0.0.0.0:mcpServer.start({ host: "0.0.0.0" })

      2. 云服务器需配置安全组,开放 MCP Server 端口(如 8000)

      3. 生产环境建议使用 HTTPS,可通过 Nginx 反向代理: nginx

        复制代码
        server {
          listen 443 ssl;
          server_name mcp.your-domain.com;
          ssl_certificate your-cert.pem;
          ssl_certificate_key your-key.pem;
          location / {
            proxy_pass http://127.0.0.1:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
          }
        }
  2. 坑:并发调用工具时出现资源竞争(如数据库连接池耗尽)

    • 原因:TS SDK 默认支持并发调用,但未限制并发数

    • 填坑:利用 TS SDK 的并发管理功能,设置最大并发数:

      复制代码
      // 创建Server时配置并发限制
      const mcpServer = new FastMCP({
        name: MCP_CONFIG.serverName,
        version: MCP_CONFIG.version,
        port: MCP_CONFIG.port,
        concurrency: {
          maxWorkers: 10 // 限制最大并发数为10
        }
      });

五、知识点扩展说明

(一)TS SDK 核心特性深度解析

  1. 并发管理实现:TS SDK 基于 Node.js 的worker_threads模块实现并发,通过maxWorkers控制并发数,避免单线程阻塞,适合 CPU 密集型工具(如数据处理、文件转换)。

  2. 日志功能:支持自定义日志输出(控制台、文件、ELK),可通过配置开启:

    复制代码
    const mcpServer = new FastMCP({
      // ...其他配置
      logger: {
        level: "info", // 日志级别:trace/debug/info/warn/error
        transport: {
          type: "file", // 输出到文件
          filename: "logs/mcp-server.log",
          rotation: { size: "100MB" } // 日志轮转
        }
      }
    });
  3. 资源管理:支持数据库、API 等资源的统一管理,通过@McpResource装饰器注册资源,工具可直接注入使用:

    复制代码
    import { McpResource } from "@modelcontextprotocol/sdk";
    import { Pool } from "mysql2/promise";
    
    // 注册MySQL资源
    @McpResource({
      name: "mysqlPool",
      description: "MySQL数据库连接池"
    })
    async function createMysqlPool(): Promise<Pool> {
      return new Pool({
        host: "localhost",
        user: "root",
        password: "123456",
        database: "test"
      });
    }
    
    // 工具中注入资源
    @McpTool(/* 配置 */)
    async queryData(sql: string, @McpResource("mysqlPool") pool: Pool): Promise<any[]> {
      const [rows] = await pool.execute(sql);
      return rows;
    }

(二)MCP 与 Node.js 全栈框架集成

1. 与 NestJS 集成(企业级 Node.js 框架)

NestJS 的依赖注入和模块化特性与 MCP 高度契合,可通过自定义模块集成 TS SDK:

复制代码
// src/mcp/mcp.module.ts
import { Module } from "@nestjs/common";
import { FastMCP } from "@modelcontextprotocol/sdk";
import { MCP_CONFIG } from "../config";

@Module({
  providers: [
    {
      provide: "MCP_SERVER",
      useFactory: async () => {
        const mcpServer = new FastMCP(MCP_CONFIG);
        // 注册工具和Prompt...
        await mcpServer.start();
        return mcpServer;
      }
    }
  ],
  exports: ["MCP_SERVER"]
})
export class McpModule {}
2. 与 Express 集成(轻量 Node.js 框架)
复制代码
import express from "express";
import { FastMCP } from "@modelcontextprotocol/sdk";
import { MCP_CONFIG } from "./config";

const app = express();
const port = 3000;

// 初始化MCP Server
const mcpServer = new FastMCP(MCP_CONFIG);
mcpServer.registerTool(add);
mcpServer.registerPrompt(translateToEnglish);

// 将MCP Server挂载到Express路由
app.use("/mcp", mcpServer.getExpressRouter());

// 启动Express服务
app.listen(port, () => {
  console.log(`Express服务启动:http://127.0.0.1:${port}`);
  console.log(`MCP接口地址:http://127.0.0.1:${port}/mcp`);
});

(三)Prompt 模板在 TS/JS 中的高级用法

对于复杂 Prompt,可使用ejsnunjucks替代字符串拼接,提升可维护性:

复制代码
# 安装ejs
npm install ejs --save

import ejs from "ejs";

@McpPrompt({ description: "生成小红书爆款笔记" })
async function redbookNote(data: { title: string; content: string; tags: string[] }): Promise<string> {
  // EJS模板
  const template = `
  # <%= title %>
  <%= content %>
  
  🏷️ 标签:<%= tags.join("、") %>
  #小红书爆款 #<%= tags[0] %>
  `;
  // 渲染模板
  return ejs.render(template, data);
}

// 调用示例
const prompt = await mcpClient.getPrompt("redbookNote", {
  title: "Node.js+MCP开发AI Agent太香了!",
  content: "无需复杂配置,快速集成工具调用和Prompt管理...",
  tags: ["AI Agent", "Node.js", "MCP协议"]
});

(四)MCP 与 LangChain JS 对比

框架 核心定位 耦合度 适配场景 优势
MCP(TS SDK) 标准化协议层 全栈项目、微服务、多 Agent 协作 解耦性强、跨语言支持、并发管理
LangChain JS 工具链框架 快速原型开发、单一 Agent 生态丰富、集成多种 LLM、开箱即用

选择建议:小型原型用 LangChain JS 快速验证;全栈项目、微服务或需要多语言协作时,优先 MCP+TS SDK,可复用现有 Node.js 服务。

(五)Node.js MCP Server 容器化部署(Docker)

  1. 创建 Dockerfile:

    FROM node:18-alpine

    WORKDIR /app

    COPY package*.json ./
    RUN npm install --production

    COPY dist/ ./dist/

    EXPOSE 8000

    CMD ["npm", "start"]

  2. 构建并运行容器:

    构建镜像

    docker build -t mcp-ts-server .

    运行容器

    docker run -d -p 8000:8000 --name mcp-server mcp-ts-server

六、总结

MCP 协议的标准化抽象的与 TypeScript SDK 的全栈适配,为 Node.js 开发者打开了 AI Agent 工程化落地的便捷通道。通过 TS 的强类型特性,我们能更精准地定义工具和 Prompt,配合 SDK 的并发管理、日志、资源调度功能,可快速将 Node.js 服务升级为 MCP Server,实现与 AI Agent 的解耦集成。

从环境配置、最简开发、调试验证到部署上线,TS/JS/Node.js 生态为 MCP 提供了完善的支撑,而踩坑填坑的过程也让我们更深入理解了协议的设计思想。未来,随着 MCP 生态的持续完善,以及 Node.js 微服务与 Agent 的深度融合,"高分高能" 的全栈 Agent 应用将越来越普及。

七、参考

相关推荐
好大哥呀1 小时前
Java 中的 Spring 框架
java·开发语言·spring
charlie1145141912 小时前
输入法处理杂谈——Windows 下的 IMM32 输入法处理机制和Chrome如何桥接TSF输入法
开发语言·chrome·windows·学习·输入法
froginwe112 小时前
Ruby Dir 类和方法
开发语言
代码游侠2 小时前
学习笔记——ARM Cortex-A 裸机开发实战指南
linux·运维·开发语言·前端·arm开发·笔记
星火开发设计2 小时前
表达式与语句:C++ 程序的执行逻辑基础
java·开发语言·c++·学习·知识·表达式
纵有疾風起2 小时前
【Linux 系统开发】基础开发工具详解:软件包管理器、编辑器。编译器开发实战
linux·服务器·开发语言·经验分享·bash·shell
Amumu121382 小时前
React扩展(二)
前端·javascript·react.js
郝学胜-神的一滴2 小时前
Qt与Web混合编程:CEF与QCefView深度解析
开发语言·前端·javascript·c++·qt·程序人生·软件构建
冬奇Lab2 小时前
【Kotlin系列08】泛型进阶:从型变到具体化类型参数的类型安全之旅
android·开发语言·windows·安全·kotlin