《NestJS智能体开发》(七):模型上下文协议(MCP)

什么是MCP?

Model Context Protocol(MCP)是一种开放协议,旨在标准化大型语言模型(LLM)与外部数据源和工具之间的通信。它由 Anthropic 推出,允许 LLM 与服务器进行交互,以获取信息、执行操作并完成更复杂的任务。

调用外部工具

安装MCP SDK

bash 复制代码
pnpm add @modelcontextprotocol/sdk

创建MCP服务器和客户端

ts 复制代码
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";

const transport = new StdioClientTransport({
    command: "npx",
    args: [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        `${process.cwd()}/test`
    ],
    stderr: process.stderr,
});

const client = new Client(
    {
        name: "fs",
        version: "1.0.0",
    }
);
await client.connect(transport);

代码解释:

  1. new StdioClientTransport()

    • 创建一个新的 StdioClientTransport 实例,用于通过标准输入输出流(stdin/stdout)与 MCP 服务器进行通信。
  2. command: "npx"

    • 指定要运行的命令是 npx,它是 Node.js 包运行工具,用于运行安装在项目中的 npm 包的命令行工具。
  3. args

    • args 是一个数组,包含传递给命令的参数:

      • "-y":通常用于自动确认提示,避免交互式输入。
      • "@modelcontextprotocol/server-filesystem":指定要运行的 MCP 文件系统服务器包。
      • ${process.cwd()}/test:使用模板字符串插入当前工作目录下的 test 文件夹路径,作为 MCP 文件系统服务器的工作目录。
  4. stderr: process.stderr

    • 将 MCP 服务器的标准错误输出(stderr)重定向到当前 Node.js 进程的标准错误输出,以便在控制台中查看错误信息。

test目录中创建一个index.js文件,然后通过LLM调用工具读取它的内容

ts 复制代码
import { generateText, jsonSchema, tool } from "ai";

const fsTool = {
    description: "读取一个本地文件的内容",
    parameters: jsonSchema({
        type: "object",
        properties: {
            path: { type: "string", description: "文件路径" },
        },
        required: ["path"],
    }),
    execute: async (args) => {
        const result = await client.callTool({
            name: "read_file",
            arguments: args,
        });
        return JSON.stringify(result);
    },
};

const model = this.agent.createQWenModel();
const result = await generateText({
    model,
    tools: {
        fsTool
    },
    toolChoice: 'required',
    prompt: "test文件夹中index.js的内容是什么?"
});
console.log(result.toolResults);

成功调用fsTool读取了index.js的内容

json 复制代码
[
    {
      "type": "tool-result",
      "toolCallId": "call-zpJwmR2spvsUYiIppilkzHi6m0xe9aLp",
      "toolName": "fsTool",
      "args": {
        "path": "test/index.js"
      },
      "result": "{\"content\":[{\"type\":\"text\",\"text\":\"function main() {\\n    console.log('main');\\n}\"}]}"
    }
]

MCP Tool转换成AI SDK Tool

AISDK MCP Bridge 是一个桥接包,它使得模型MCPAI SDK之间能够实现无缝集成,允许MCP服务器和AI模型之间进行高效的通信和工具调用。

安装AISDK MCP Bridge

bash 复制代码
pnpm add aisdk-mcp-bridge

使用AISDK MCP Bridge我们只需创建mcp.config.json配置文件

json 复制代码
{
    "mcpServers": {
        "filesystem": {
            "command": "npx",
            "args": [
                "-y",
                "@modelcontextprotocol/server-filesystem",
                "./test"
            ]
        }
    }
}

通过桥接器自动将MCP Tool转换成AI SDK Tool

ts 复制代码
try {
    await initializeMcp({ debug: true });
    const tools = await getMcpTools({ debug: true });

    const model = this.agent.createQWenModel();
    const result = await generateText({
        model,
        tools,
        toolChoice: 'required',
        prompt: "test文件夹中index.js的内容是什么?"
    });
    console.log(result.toolResults);
} finally {
    await cleanupMcp();
}

实现了相同的效果

json 复制代码
[
  {
    "type": "tool-result",
    "toolCallId": "call-ZnX8AdWB32Pp4nT1unF5Dxpeh7AYcIo7",
    "toolName": "read_file",
    "args": {
      "path": "test/index.js"
    },
    "result": {
      "type": "function",
      "function": {
        "name": "read_file",
        "arguments": "{\"path\":\"test/index.js\"}"
      },
      "content": [
        {
          "type": "text",
          "text": "function main() {\n    console.log('main');\n}"
        }
      ]
    }
  }
]

市场中寻找可用的MCP Servers

json 复制代码
{
    "mcpServers": {
        "filesystem": {
            "command": "npx",
            "args": [
                "-y",
                "@modelcontextprotocol/server-filesystem",
                "./test"
            ]
        },
        "docker-mcp": {
            "command": "uvx",
            "args": [
                "docker-mcp"
            ]
        }
    }
}
ts 复制代码
try {
    await initializeMcp({ debug: true });
    const tools = await getMcpTools({ debug: true });

    const model = this.agent.createQWenModel();
    const result = await generateText({
        model,
        tools,
        toolChoice: 'required',
        prompt: "使用docker运行一个Nginx容器"
    });
    console.log(result.toolResults);
} finally {
    await cleanupMcp();
}
json 复制代码
[
  {
    "type": "tool-result",
    "toolCallId": "call-RkyU2khsEoXlXVq6C5SH4DNw3CrCaQCu",
    "toolName": "create-container",
    "args": {
      "image": "nginx",
      "name": "nginx_container"
    },
    "result": {
      "type": "function",
      "function": {
        "name": "create-container",
        "arguments": "{\"image\":\"nginx\",\"name\":\"nginx_container\"}"
      },
      "content": [
        {
          "type": "text",
          "text": "Created container 'nginx_container' (ID: b6bb7f0fa3a924f3d86b49de90561f3d0bff2172b49b42594bde0703948df269)"
        }
      ]
    }
  }
]

成功运行了一个Nginx容器

总结

MCP 协议为 LLM 与外部工具和数据源的集成提供了标准化、高效且安全的解决方案,通过 MCP SDK 和 AISDK MCP Bridge 等工具,可以方便地创建和调用各种 MCP 服务器,实现 LLM 在不同场景下的应用扩展,如文件操作、容器管理等,为智能体的开发和集成带来了新的可能性和便利性。

相关推荐
莱茶荼菜3 分钟前
SIFT特征点检测
人工智能·深度学习·计算机视觉
知识分享小能手6 分钟前
JavaScript学习教程,从入门到精通,Ajax数据交换格式与跨域处理(26)
xml·开发语言·前端·javascript·学习·ajax·css3
好名字08219 分钟前
el-tabs与table样式冲突导致高度失效问题解决(vue2+elementui)
前端·vue.js·elementui
qq_2780637115 分钟前
vue elementui 去掉默认填充 密码input导致的默认填充
前端·vue.js·elementui
荷塘阅色18 分钟前
【机器学习】人工智能在电力电子领域的应用
人工智能·机器学习·电力电子
James. 常德 student24 分钟前
长短期记忆网络(LSTM)
人工智能·rnn·lstm
这个懒人32 分钟前
C++后端服务器常见开发框架
c++·后端·框架
黄同学real35 分钟前
HTML5 新增的主要标签整理
前端·html·html5
liwulin050635 分钟前
【JAVAFX】实现屏幕指定区域截图,带尺寸显示
服务器·前端·python
2401_8902360441 分钟前
艺术与科技的双向奔赴——高一鑫荣获加州联合表彰
人工智能·科技