乐于分享
好东西不私藏

Vercel AI SDK + MCP:把远端 MCP 工具变成本地 Tool

Vercel AI SDK + MCP:把远端 MCP 工具变成本地 Tool

前面三篇文章分别解决了两个问题:第一篇讲清楚了 Vercel AI SDK 里的 Tool 是什么,以及为什么它适合在一个 Next.js 或 Node.js 项目里快速把业务函数暴露给模型;第二篇和第三篇则把视角抬高,解释了 MCP 为什么会出现,它解决的不是“怎么在一个项目里定义工具”,而是“怎么让不同 AI 宿主共享同一套工具能力”。

到了这一篇,终于轮到最关键的一步:把两者串起来。如果说 MCP Server 负责“对外标准化地提供工具”,那么 Vercel AI SDK 则可以在应用内部把这些远端工具重新变成模型可直接使用的本地 Tool。

这篇文章只做一件事:用一个最简单的 HTTP 汇率查询例子,把“纯 Tool 实现”和“MCP Server + AI SDK Host 实现”并排讲清楚,让你真正理解它们的区别、联系,以及迁移路径。

为什么需要这一层转换

如果只看 Vercel AI SDK 的开发体验,最简单的方式当然是直接在项目里写一个 tool(...),在 execute 里发 HTTP 请求,完成后把结果返回给模型。

这种方式的优点非常明显:

 所有逻辑都在一个项目里,理解成本低。

 TypeScript 类型、参数校验、前端集成都在同一套开发体验里完成。

但一旦这个汇率查询能力不只给一个 Web 应用使用,而是还想给 IDE 插件、内部 Agent、另一个团队的 AI 工具复用,就会遇到老问题:每个宿主都要重复封装一层自己的 Tool。

MCP 的价值就在这里:它把“汇率查询”这件事抽成一个独立的 MCP Tool,由 MCP Server 统一暴露;而 Vercel AI SDK 则通过 MCP Client 把远端工具拿回来,再作为本地 Tool 交给模型使用。

换句话说:

 MCP 负责“工具如何被别的系统发现和调用”。

 Vercel AI SDK 负责“模型如何在当前应用里使用这些工具”。

这一层“变成本地 Tool”的动作,正是两者结合后最有价值的地方。

先看方案 A:纯 Vercel AI SDK Tool

先从最简单的方案开始。假设已经有一个普通的 HTTP API:

GET /api/exchange-rate?from=USD&to=CNY

 返回:{ "from": "USD", "to": "CNY", "rate": 6.80}

如果只想在自己的 Next.js 应用里使用这个能力,完全可以直接写一个本地 Tool:

import { tool } from 'ai';import { z } from 'zod';export const getExchangeRate = tool({  description: '查询两种货币之间的实时汇率',  inputSchema: z.object({    from: z.string().describe('源货币代码,例如 USD'),    to: z.string().describe('目标货币代码,例如 CNY'),  }),  execute: async ({ from, to }) => {    const res = await fetch(      `https://example.com/api/exchange-rate?from=${from}&to=${to}`    );    if (!res.ok) {      throw new Error('failed to fetch exchange rate');    }    return await res.json();  },});

然后在 generateText 或 streamText 里把它作为 tools 传给模型即可。

const result = await generateText({  model: openai('gpt-4o'),  prompt: '100 美元大约等于多少人民币?',  tools: {    getExchangeRate,  },});

这一套写法的核心特点是:

 工具定义、HTTP 请求、模型调用都在同一个代码库里。

 模型看到的是一个本地 Tool,而不是某个“远端协议对象”。

 如果以后别的宿主也需要这个能力,就得在别的项目里再写一遍类似封装。

所以方案 A 很适合:

 只有一个 Web 应用要用这个工具。

 工具逻辑比较轻,不打算对外提供标准接口。

 当前阶段更重视开发速度,而不是跨宿主复用。

再看方案 B:MCP Server + Vercel AI SDK Host

现在把同一个需求换一种拆法:

 汇率查询能力不再直接写成某个项目里的本地 Tool。

 它先被放进一个 MCP Server,作为标准化的 MCP Tool 对外暴露。

 你的 Next.js / Node.js 应用不再亲自实现汇率查询,而是作为 MCP Host 去连接这个 Server,再把它转换成本地 Tool 给模型。

第一步:在 MCP Server 中暴露工具

按照 MCP 的工具规范,Server 至少要提供工具名、描述和输入 schema,并支持 tools/list 与 tools/call 这两类操作。

概念上,这个汇率工具长这样:

{  "name": "get_exchange_rate",  "description": "查询两种货币之间的实时汇率",  "inputSchema": {    "type": "object",    "properties": {      "from": {        "type": "string",        "description": "源货币代码,例如 USD"      },      "to": {        "type": "string",        "description": "目标货币代码,例如 CNY"      }    },    "required": ["from", "to"]  }}

当 Host 发送 tools/call 时,MCP Server 在内部再去调用原来的 HTTP API。

也就是说,MCP Server 才是真正知道“汇率数据从哪来”的那一层;Host 只知道“这里有个叫 get_exchange_rate 的工具可以调用”。

第二步:在 Vercel AI SDK 中创建 MCP Client

AI SDK 从 4.2 开始支持 MCP Client,并提供了专门的 createMCPClient 能力,用来连接 MCP Server。

Cookbook 中给出的模式非常直接:创建客户端、连接远端 MCP Server、拉取工具列表、把它们交给 generateText 或 streamText

代码大致如下:

import { createMCPClient } from '@ai-sdk/mcp';import { generateText } from 'ai';import { openai } from '@ai-sdk/openai';const mcpClient = await createMCPClient({  transport: {    type: 'sse',    url: 'https://example.com/mcp/sse',  },});const result = await generateText({  model: openai('gpt-4o'),  prompt: '100 美元大约等于多少日元?',  tools: await mcpClient.tools(),});await mcpClient.close();

这里最值得注意的一点是:mcpClient.tools() 返回的是已经兼容 AI SDK Tool 形态的对象,因此可以直接注入模型配置。

这正是本文标题所说的“把远端 MCP 工具变成本地 Tool”。它不要求你手写一层巨大的适配器;AI SDK 的 MCP Client 本身就是为“工具转换”这件事设计的。

第三步:模型看来,它们几乎一样

到了模型那一层,方案 A 和方案 B 的体验其实非常接近:

 模型都会看到一个带名字、描述和参数 schema 的工具。

 模型都会自己判断要不要调用、该传什么参数。

 最终都会拿到结构化结果,再生成自然语言回复。

不同之处在于:

 在方案 A 中,这个工具的执行逻辑就在你的项目里。

 在方案 B 中,这个工具背后其实是一次 tools/call 到远端 MCP Server 的协议交互。

对业务代码而言,方案 B 相当于给当前应用加了一层“远端工具市场”。

两种实现放在一起比较

把同一个汇率查询能力放到两种方案中,对比会很清楚:

维度
纯 Tool
MCP + AI SDK
工具定义位置
当前应用代码库中定义。
MCP Server 中定义,对外标准化暴露。
执行逻辑位置
execute
 里直接调 HTTP/API。
MCP Server 内部执行,Host 只负责协议调用。
模型接入方式
直接把本地 Tool 传给 tools
通过 mcpClient.tools() 获取后传给 tools
复用范围
通常局限在当前项目内。
可被多个 MCP Host 复用。
改造成本
低,最适合快速起步。
更高,需要维护 MCP Server。
平台化潜力
弱,容易项目级重复封装。
强,适合统一工具层。

如果用一句话概括:

 纯 Tool 更像“在本项目里原地写函数”。

 MCP + AI SDK 更像“先把能力发布成标准服务,再在本项目里按 Tool 的方式消费它”。

一个更真实的架构图应该怎么理解

如果把这一层组合关系画成一条链路,可以这样理解:

1. 用户在 Web 界面里问:“100 美元等于多少人民币?”

2. Next.js 后端收到消息,并调用 generateText

3. AI SDK 发现当前可用工具来自 mcpClient.tools()

4. 模型决定调用 get_exchange_rate

5. AI SDK 通过 MCP Client 向远端 MCP Server 发起 tools/call

6. MCP Server 内部再去请求汇率 HTTP API,拿到结果后返回。

7. AI SDK 把结果回填给模型,模型生成最终回复。

这里最值得体会的是“分层”:

 汇率查询是工具层能力,由 MCP Server 管理。

 聊天会话、模型选择、UI 流式输出是应用层能力,由 Vercel AI SDK 所在应用管理。

这意味着未来如果还有别的宿主——比如 IDE 插件或内部自动化 Agent——它们也可以直接连接这个 MCP Server,而不用复制当前 Web 应用里的 Tool 代码。

什么时候值得把 Tool 迁移到 MCP

不是所有 Tool 都值得立刻搬到 MCP。更现实的做法,是把它当成一种架构升级,而不是“新技术来了就全量重写”。

下面这几个信号通常说明:你已经接近需要 MCP 的阶段了。

信号一:同一个工具要被多个宿主使用

如果一个工具不只给 Web 用,还要给 Cursor、Claude Desktop、自研 CLI Agent 或公司内部总控台使用,那么继续在每个项目里各写一份 Tool 封装,维护成本会越来越高。

这时,把它提升成 MCP Tool 会更自然:

 工具定义只维护一次。

 不同 Host 通过协议统一接入。

 权限、监控、审计更容易收敛在 Server 一层处理。

信号二:工具开始脱离某个具体应用

如果某个能力本质上已经不是“这个页面的一个函数”,而更像“公司内部的一项基础设施能力”,那它就不该继续深埋在某个 Next.js 项目里。

例如:

 统一订单查询

 通用知识库搜索

 Git 仓库操作

 文件系统访问

这些能力越独立、越通用,就越适合放到 MCP Server 中,变成被多个应用消费的通用工具。

信号三:希望工具层与前端/模型层解耦

在纯 Tool 模式下,工具层和模型层天然耦合在同一个项目里:

 你改工具,往往要顺手改聊天服务代码。

 你换前端宿主,也要迁移相同的工具定义。

而在 MCP 模式下,工具层和宿主层可以独立演进:

 MCP Server 负责能力暴露。

 Web 应用、IDE 插件、桌面端各自负责自己的体验。

 AI SDK 则成为消费这些工具的其中一种宿主实现。

渐进式迁移:不必一步到位

对多数团队来说,最合理的路线并不是“从第一天就把所有工具做成 MCP”,而是先从纯 Tool 起步,再把真正值得复用的能力抽出来。

一个比较稳妥的演进方式是:

1. 先在当前 Next.js 项目里用纯 Tool 把业务跑通。

2. 观察哪些 Tool 开始被多个项目反复复制。

3. 把这些重复出现的能力抽成 MCP Server。

4. 在原项目里改为通过 mcpClient.tools() 接回这些工具。

5. 保留一部分强耦合的本地 Tool,只把“共享能力”协议化。

这也是 Vercel AI SDK + MCP 很实际的地方:它不要求你在“纯 Tool”和“纯 MCP”之间二选一,而是允许你在一个项目里同时使用两类工具。

例如:

 本地 Tool 负责当前会话特有的操作,如读取用户当前页面状态。

 MCP Tool 负责通用能力,如汇率、工单、知识库、Git 操作。这种混合模式,通常比“一刀切重构”更适合真实团队。

最后

到这里,Vercel AI SDK Tool 和 MCP 的关系其实已经非常清晰了:

 Vercel AI SDK Tool 是模型调用工具时的应用内抽象

 MCP Tool 是跨宿主、跨项目共享工具时的协议级抽象

 AI SDK 的 MCP Client 则充当了一座桥:把远端 MCP 工具转换成当前应用可直接使用的 Tool。

所以,这一篇真正要传达的并不是“用了 MCP 就不用 Tool”,而是:

MCP 负责把工具带到你的应用门口,Vercel AI SDK 负责把这些工具顺手递给模型。

如果只做一个应用,纯 Tool 往往就够了。如果要做多宿主复用、统一工具层、平台化演进,那么 MCP + AI SDK 的组合会更自然。

从函数到 Tool:用 Vercel AI SDK 打开工具调用的大门

当工具越来越多:Vercel AI SDK Tool 的边界与痛点

走进 MCP:为 AI 工具接上通用「USB 接口」