ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

在 CommonJS 项目中加载 ESM-only 的 @mcp-use/client:动态 import() 实战指南

在 CommonJS 项目中加载 ESM-only 的 @mcp-use/client:动态 import() 实战指南 在 CommonJS 项目中加载 ESM-only 的 mcp-use/client动态 import() 实战指南【免费下载链接】mcp-useThe fullstack MCP framework to develop MCP Apps for ChatGPT / Claude MCP Servers for AI Agents.项目地址: https://gitcode.com/gh_mirrors/mc/mcp-use本篇指南围绕 mcp-use 仓库中 CommonJS 宿主加载示例 展开讲解如何在.cjs/ CommonJS 环境中使用以 ESM 形式发布的mcp-use/client包。你将掌握动态import()的标准写法、HTTP 与 stdio 两种 MCP Server 连接的启动方式以及 Node 与浏览器环境下 OAuth 导出的差异从而在传统 CJS 工程中顺畅接入 mcp-use v2 的 MCP 客户端。为什么 mcp-use/client 是 ESM-onlymcp-use/client是 mcp-use v2 框架的官方 MCP 客户端负责与 Model Context Protocol 服务器建立连接、管理会话与 OAuth 鉴权。它从设计上就只提供 ESM 构建产物不提供 CommonJSCJS构建因此不能用require(mcp-use/client)直接加载。这一点可以从包配置中得到直接印证。查看 packages/client/package.json顶层声明type: module整个包按 ESM 语义解析exports字段中每个条件的产物类型都只有import入口./dist/index.js、./dist/index-browser.js等不存在require条件Node 在解析require()时无法命中任何构建产物。这是许多现代 npm 包的常见发布策略ESM 便于静态分析、tree-shaking 和顶层 await代价则是传统 CommonJS 宿主需要借助异步加载手段。Node 官方对 ESM 与 CJS 互操作的支持路径是CommonJS 文件可以通过动态import()加载 ESM 模块而require()仅能同步加载 CJS 模块无法加载纯 ESM 包。核心模式用动态 import() 代替 require在 CommonJS.cjs或type: commonjs的.js文件中加载mcp-use/client的标准做法是把import调用放在async函数内部并解构出所需导出async function main() { const { MCPClient } await import(mcp-use/client); const client new MCPClient({ mcpServers: { demo: { url: http://127.0.0.1:3102/mcp }, }, }); const connection await client.connect(demo); console.log(await connection.listTools()); await client.close(); } main().catch((error) { console.error(Fatal error:, error); process.exit(1); });这个模式有三个关键点await import(...)返回的是模块命名空间对象从中解构MCPClient构造函数用法与 ESM 中的静态import { MCPClient } from mcp-use/client完全一致动态 import 是异步的因此main()必须声明为async并在入口处用.catch()兜底避免未处理的 Promise 拒绝只加载一次Node 会对 ESM 模块进行缓存多次调用import()不会重复执行模块副作用其./telemetry/configure-node.js等启动逻辑只会运行一次该副作用在 packages/client/src/index.ts 中可见。完整可运行示例commonjs_example.cjs仓库在 examples/browser/commonjs/commonjs_example.cjs 提供了开箱即用的完整示例展示了比最小模式更完整的生命周期连接、列出工具、调用工具、关闭连接、错误处理。async function runCommonJSExample() { const { MCPClient } await import(mcp-use/client); console.log( CommonJS MCP Example \n); const useStdio process.env.USE_STDIO_EVERYTHING 1; const url process.env.MCP_SERVER_URL ?? http://127.0.0.1:3102/mcp; const client new MCPClient({ mcpServers: useStdio ? { everything: { command: npx, args: [-y, modelcontextprotocol/server-everything], }, } : { demo: { url }, }, }); try { const name useStdio ? everything : demo; const connection await client.connect(name); console.log(✓ Connected, (era${connection.protocolEra ?? ?})); const tools await connection.listTools(); console.log(✓ Found ${tools.length} tools); for (const tool of tools.slice(0, 5)) { console.log( - ${tool.name}); } if (tools.some((t) t.name echo)) { const result await connection.callTool(echo, { message: cjs }); console.log(✓ echo -, JSON.stringify(result.content)); } console.log(\n CommonJS Example Completed Successfully ); } catch (error) { console.error(Error:, error.message); process.exitCode 1; } finally { await client.close(); } } runCommonJSExample().catch((error) { console.error(Fatal error:, error); process.exit(1); });该示例展示了几个值得复用的工程细节环境变量驱动的连接配置MCP_SERVER_URL指定 HTTP 端点USE_STDIO_EVERYTHING1切换到 stdio 服务器二者互斥且可覆盖默认值connection.protocolEramcp-use 客户端会自动协商传统会话式legacy与无会话sessionless两种 MCP 服务器时代SDK 能力在 packages/client/src/index.ts 中描述为自动协商 legacy sessionful 与 modern sessionless MCP servers此处打印出协商结果便于观测finally中关闭连接无论成功失败都调用await client.close()释放资源避免进程悬挂错误码传递失败时设置process.exitCode 1方便 CI 等自动化场景捕获失败。运行方式HTTP 与 stdio 两种服务器方式一连接本地 HTTP 演示服务器仓库在 examples/_demo-servers 提供了两个最小演示服务器分别模拟两代 Streamable HTTP 协议v1-http.tslegacy 时代2025 Streamable HTTP服务器PORT3101 pnpm v1启动提供echo与add两个工具v2-http.tsmcp-use v2 无会话 Streamable HTTP 服务器PORT3102 pnpm v2启动同样提供echo与add工具且可通过LEGACYreject强制拒绝旧协议请求。在examples/browser/commonjs/目录下分别执行# 先启动演示服务器cd ../_demo-servers PORT3102 pnpm v2 MCP_SERVER_URLhttp://127.0.0.1:3101/mcp node commonjs_example.cjs MCP_SERVER_URLhttp://127.0.0.1:3102/mcp node commonjs_example.cjs两条命令分别验证客户端与 v1、v2 两种协议时代的服务器握手——这正是connection.protocolEra发挥作用的地方。运行成功后应依次看到连接成功、工具数量与名称列表以及echo工具调用返回的结果。方式二通过 stdio 连接 server-everything如果不想先启动 HTTP 服务器可以直接用 stdio 方式拉起 npm 生态中的modelcontextprotocol/server-everythingUSE_STDIO_EVERYTHING1 node commonjs_example.cjs此时示例内部会改用npx -y modelcontextprotocol/server-everything作为子进程命令见commonjs_example.cjs中的 stdio 配置分支客户端通过标准输入输出与该进程通信无需任何网络端口。这在本地快速验证、或者 CI 无端口环境下非常实用。方式三从 packages/client 目录直接运行如果你已在本地构建过mcp-use/client执行过pnpm build也可以从包目录直接运行示例node examples/browser/commonjs/commonjs_example.cjs此时包解析会命中 packages/client/package.json 中exports[.].node.import指向的./dist/index.js即 Node 专用入口。关键注意事项绝不要 require(mcp-use/client)如前所述包没有 CJS 构建require()会直接抛错ERR_REQUIRE_ESM或模块解析失败。判断某个包能否被require的快速方法检查其package.json的exports是否包含require条件——mcp-use/client只有import明确不支持同步加载。Node 与浏览器的 OAuth 导出不同OAuth 相关辅助函数分环境导出Node 入口exports[.].node即./dist/index.js导出NodeOAuthClientProvider以及createOAuthProvider、completeOAuthFlow、isOAuthInteractionRequired、isUnauthorized等见 packages/client/src/auth/node.ts 与 packages/client/src/index.ts。它支持完整的发现、动态客户端注册DCR、PKCE 回环回调与令牌持久化仓库在 examples/node/auth/oauth-flow.ts 提供了无需外部身份提供商的端到端演示浏览器 OAuth 提供方不会从 Node 入口导出浏览器场景应使用浏览器构建exports[.].browser/default指向./dist/index-browser.js中对应的 OAuth 提供方Node 构建中不存在该导出。因此如果你在 CommonJS 的 Node 宿主中需要 OAuth应使用NodeOAuthClientProvider需要浏览器侧 OAuth 时请切换到浏览器入口并采用对应的浏览器 OAuth 提供方。版本与运行环境前提以当前仓库为准mcp-use/client版本为 2.3.2见 packages/client/package.json声明engines: { node: 22.22.2 }依赖modelcontextprotocol/client、modelcontextprotocol/core与modelcontextprotocol/ext-apps均为 2.0.0。动态import()从 Node 12.17 即可使用但请以包的 engines 声明为准选择运行环境react、zod、e2b/code-interpreter为可选 peer 依赖不使用对应能力时无需安装。小结在 CommonJS 宿主中使用 ESM-only 的mcp-use/client核心只有一条规则把require换成 async 函数内的动态import()。配合MCP_SERVER_URL/USE_STDIO_EVERYTHING环境变量即可灵活切换 HTTP 与 stdio 服务器Node 与浏览器入口在 OAuth 导出上的差异则决定了鉴权代码应该写在哪个构建产物之上。将 commonjs_example.cjs 作为模板你的 CJS 工程即可无缝接入 mcp-use v2 的完整 MCP 客户端能力。【免费下载链接】mcp-useThe fullstack MCP framework to develop MCP Apps for ChatGPT / Claude MCP Servers for AI Agents.项目地址: https://gitcode.com/gh_mirrors/mc/mcp-use创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表