资讯动态

91个工具封装成MCP服务:从npm发布到魔搭托管的实战指南

发布时间:2026/9/8 22:15:34 来源:尧图企业网站定制
我从今年年初开始密集接触 MCP 协议当时就有个想法能不能把手头常用的 90 多个工具统一做成 MCP 服务让 Claude、Codex 这类支持 MCP 的客户端直接调用。折腾了大概两周踩了无数坑最终把 91 个工具全部封装上线通过 npm 发布同时托管到了魔搭社区。整个过程里踩过的坑和梳理出的方法我觉得值得单独写一篇记录下来。这篇文章会完整还原我的技术选型思路、工具封装方案、npm 发布流程、魔搭托管的实操过程以及最关键的——那些文档里根本不会写的报错排障实录。如果你也打算做一套自己的 MCP 工具集或者正在纠结怎么选择托管方案这篇文章应该能帮你少走很多弯路。1. 项目背景为什么我要把 91 个工具做成 MCP1.1 MCP 协议解决了什么问题MCPModel Context Protocol模型上下文协议本质上是一套标准化接口让 AI 大模型能够以统一方式调用外部工具和数据源。在没有 MCP 之前每个 AI 应用要接一个工具就得单独写一套工具调用代码参数格式、鉴权方式、返回结构全都各搞各的维护成本非常高。用生活里的事儿来类比MCP 就像 USB-C 接口。以前每个设备都有自己的充电口现在有了统一标准只要设备支持 USB-C一根线就能搞定所有设备。MCP 对 AI 生态的意义也是如此——模型应用客户端只需要实现 MCP 客户端工具提供方只需要实现 MCP 服务端两边按照统一协议沟通就能打通任意工具和任意模型。我个人的核心需求其实很朴素我电脑里常年躺着 91 个命令行小工具有处理文本的、操作文件的、查询系统信息的、调 HTTP 接口的、跟 Git 仓库交互的…… 平时自己敲命令行没什么问题但我想让 Claude 和 Codex 这类 AI 编程助手也能直接调用它们。这样一来AI 在分析仓库、写代码、跑测试的时候就不只是读我的项目还能真正操作我的项目帮我完成参数调整、日志查看、环境检查这些脏活累活。1.2 为什么选择 npm 和魔搭托管这 91 个工具我原本是散落在各个脚本里的有 bash、Python、Node.js 三种语言。要做成 MCP首先得解决分发和安装的问题。我的技术栈里 Node.js 生态最顺手所以选 TypeScript Node.js 实现 MCP Server。选择 npm 作为分发渠道三个原因第一npm 是 JavaScript 生态默认的包管理器只要有 Node.js 环境就是自带能力用户获得成本几乎为零第二MCP SDK 官方就有 Node.js 版本modelcontextprotocol/sdk这个包可以直接复用不需要从零实现协议细节第三npm 天然支持二进制命令分发装完包以后可以直接在终端里执行命令这对 MCP Server 这类需要常驻运行的进程来说非常方便。魔搭托管的逻辑更多是从国内开发者的实际体验出发的。MCP Server 的配置文件中需要一个 URL 地址虽然让用户本地运行也不是不行但如果直接提供一个公网可访问的服务地址用户拿到就能用配置成本会低很多。我一开始尝试过自建服务器但国内访问和稳定性都不理想后来发现魔搭社区是支持部署 AI 应用的就试着把 MCP Server 作为独立服务部署上去实测对国内用户友好得多也不怎么受网络波动影响。2. 整体架构设计91 个工具怎么组织才不会变成一团乱麻2.1 一个进程还是拆成多个服务这是第一个需要拍板的问题。91 个工具如果全部塞进一个 MCP Server 进程客户端一启动就得加载 91 个工具的定义不仅速度慢而且工具列表会非常臃肿。像 Claude Desktop 这类客户端的工具选择面板一次展示 91 个工具用户体验非常糟糕。如果拆成 91 个独立的 MCP Server那配置文件的维护成本又让人崩溃每个 Server 要写一段配置用户光是填配置就得疯掉。我最终采用的是按功能域分组、每组一个 MCP Server的方案。把 91 个工具按照功能分成 8 个组mcp-tools-file文件读写、目录遍历、文件搜索共 15 个工具mcp-tools-httpHTTP 请求、接口测试、JSON 处理共 12 个工具mcp-tools-gitGit 操作、提交历史、分支管理共 10 个工具mcp-tools-process进程查看、系统信息、资源监控共 11 个工具mcp-tools-text文本处理、正则匹配、格式转换共 14 个工具mcp-tools-code代码分析、AST 解析、编码转换共 12 个工具mcp-tools-network网络连通性测试、DNS 查询、端口检测共 8 个工具mcp-tools-misc其他零散但高频使用的工具共 9 个工具这样每个 Server 的工具数量都在 815 个之间客户端加载速度快工具选择面板也不会太拥挤。而这 8 个 Server 全部放在一个 npm monorepo 里统一管理一次性安装全部依赖。2.2 工具注册的标准化封装工具的组织方式定了之后最核心的问题就是91 个工具怎么高效地注册到 MCP Server 里。如果按 MCP SDK 的原始 API 来写每个工具都要写一遍参数定义inputSchema、处理函数callback、错误处理error handling代码量非常大。而且 91 个工具里至少有一半是给一个 shell 命令或者一个函数调用传几个参数进去的模式完全可以抽象成一个通用的注册框架。我做了一层非常薄的封装核心抽象是命令工具和函数工具两类命令工具本质上执行一个外部命令如git status、ps aux需要定义命令名、参数映射、输出解析方式。函数工具直接调用封装好的函数适合那些不需要 shell 的纯逻辑操作如文本格式化、JSON 转换。我给每个工具定义统一的结构/** * 工具注册的标准化结构 */ interface ToolDefinition { /** 工具名称需全局唯一 */ name: string; /** 工具描述会被发给大模型用于理解工具用途 */ description: string; /** 参数 JSON Schema 定义 */ inputSchema: Recordstring, unknown; /** 实际执行函数返回字符串或对象 */ handler: (args: Recordstring, unknown) Promiseunknown; /** 是否需要确认后才能执行危险操作标记 */ dangerous?: boolean; }有了这层封装添加一个新工具只需要写 2030 行代码定义好参数和执行函数就能立即对接进 MCP 生态效率和直接用原生 SDK 相比提高了五六倍。2.3 参数命名与描述规范MCP 工具要想让 AI 用得好参数命名和描述极其重要这一点是我在实测中反复迭代出来的经验。大模型不像人一样能猜参数含义它只能靠描述文字来理解如果描述写得含糊AI 调工具时就会传错参数。我最终总结出了一套规范参数命名必须从语义出发比如查文件用path不要用p或者filePathString这种不规范的名字。每个描述里必须带上参数格式示例比如文件路径支持绝对路径或相对路径例如/home/user/test.txt。枚举值必须在描述里穷举出来比如日志级别参数不能只写日志级别要写成日志级别可选值debug、info、warn、error。如果是危险操作必须在描述里强调比如删除文件不可恢复请谨慎使用。这套规范的初衷其实很简单MCP 工具的描述不是给人看的是给大模型看的你得用大模型能理解的语言去描述每一个参数。3. npm 发布全流程从本地调试到上线3.1 项目结构设计我在 monorepo 里采用了 npm workspaces 组织结构packages/目录下每个子目录就是一个独立的 MCP Server 包。每个包的核心结构如下packages/ mcp-tools-file/ src/ index.ts // 入口创建 MCP Server tools.ts // 工具定义和注册 handlers/ // 各工具的执行函数 package.json tsconfig.json README.md这个结构的好处是每个包都可以单独发布、单独测试依赖关系清晰。root package.json里配置了 workspaces一条命令就能安装所有包的依赖不需要手动逐个cd进去安装。3.2 package.json 配置注意事项npm 发布时最容易被忽略但最容易出问题的是package.json里的几个关键字段。我踩过的坑主要集中在下面几个{ name: mcp-tools-file, version: 1.0.0, description: MCP server for file operations, type: module, main: ./dist/index.js, types: ./dist/index.d.ts, bin: { mcp-tools-file: ./dist/index.js }, files: [ dist, README.md ], engines: { node: 18.0.0 }, publishConfig: { access: public }, scripts: { build: tsc, prepublishOnly: npm run build } }这里有几个关键点需要展开说files 字段必须显式列出要发布到 npm 的文件。如果不配会把src、node_modules、.git这些东西全发上去包体积会非常臃肿。我只发布dist目录和README.md这样用户下载的包是干净的。prepublishOnly 脚本发布前自动执行构建确保发布出去的代码是最新编译产物。如果忘了这步发布上去的可能是旧版本的dist用户npm install以后跑的是过期代码。bin 字段把包注册成命令行命令。用户在全局安装npm install -g mcp-tools-file后就可以在终端直接执行mcp-tools-file来启动这个 MCP Server。MCP 客户端配置里只需要填这个命令不需要让用户手动指定 Node 脚本路径。publishConfig.access因为 scoped 包yourname/mcp-tools-file默认是私有的如果忘记设置access: public发布时会直接报错403 Forbidden这个坑我踩过很多次。3.3 npm 包名冲突与版本管理npm 有一个非常严格的规定包名必须是全球唯一的。我一开始想用mcp-tools-file这类简洁的名字结果一查几乎所有好名字都已经被注册了。npm 的包名检查规则挺有意思名字长度有限制214 个字符以内不能有大写字母不能以点或下划线开头不能用中文。我最终决定用作用域包mcp-tools/file、mcp-tools/http、mcp-tools/git这样的结构。作用域包的优势是只要你的组织名或用户名没有被抢注就可以在这个命名空间下自由命名不需要去抢那种通用的单名包。版本管理我直接用了0.0.1起步每次发布前手动更新package.json里的版本号同时同步更新 changelog。如果你习惯自动化可以用semantic-release这类工具自动打版本但我个人在这种小项目里觉得没必要引入那么重的流程手动维护几个包的版本号也就几分钟的事。3.4 本地安装与调试的两种方式开发期间需要反复调试完整的发布 → 安装流程太慢了我用的是两种本地调试方案第一种npm link。在某个包目录下执行npm link这个包就会被链接到全局 node_modules 里你的 MCP 客户端配置文件里直接写mcp-tools-file命令就能启动。调试完代码重新构建一次客户端重新连接时跑的就是最新代码。第二种直接配置 node 执行。在 MCP 客户端配置里写node /path/to/your/project/dist/index.js指定脚本的绝对路径。这样连npm link都不用做改完代码直接重新构建就行。我个人用第二种多一点因为 MCP 客户端配置文件中可以直接填这个路径调试链路最短环境变量也不会因为全局链接而出问题。3.5 首次 npm 发布的完整命令流程发布的全套命令如下已经验证过可以直接用# 1. 登录 npm如果已经登录过会提示 Already logged in npm login # 2. 在项目根目录安装依赖 npm install # 3. 构建所有包 npm run build # 4. 进入到要发布的包目录 cd packages/mcp-tools-file # 5. 发布prepublishOnly 会自动执行构建 npm publish发布后的验证步骤也非常关键。用npm view命令可以快速确认包是否已经发布成功npm view mcp-tools/file version如果返回的版本号和本地一致说明发布成功。接着可以在干净的目录里做一次安装测试mkdir /tmp/test-install cd /tmp/test-install npm init -y npm install mcp-tools/file npx mcp-tools-file最后一步npx mcp-tools-file会启动服务进程正常情况下会打印出 MCP 协议握手信息比如MCP server running on stdio之类的输出说明整个包从安装到运行全链路正常。4. 魔搭托管实操把 MCP Server 部署成公网服务4.1 为什么不在本地跑一定要托管到云端MCP Server 有两种运行模式stdio标准输入输出和 HTTP基于 Streamable HTTP 协议。stdio 模式适合本地工具客户端直接启动一个子进程通过标准输入输出通信HTTP 模式则适合远程服务客户端通过 HTTP 请求调用远端的工具。我的目标是让使用者不需要装任何一个工具包只需要在 MCP 客户端配置里填一个 URL就能用上全部 91 个工具。这就必须走 HTTP 模式把服务部署到公网。选魔搭主要看中的是三点国内访问延迟低、可以部署 Node.js 应用、不需要单独备案。4.2 魔搭应用托管的基本流程魔搭的应用托管我实际操作下来的步骤大概是注册并登录魔搭账号进入我的应用。创建新应用输入名称和描述。上传代码可以直接通过 Git 推送。配置启动命令设置环境变量。部署等待分配服务地址。关键点在于你的应用必须是一个 HTTP 服务监听在某个端口上比如 3000启动命令即为服务的启动入口。我部署的实际是一个 Node.js HTTP 服务核心逻辑很简单——把 MCP Server 挂到一个 Express 应用上。使用官方 SDK 的StreamableHTTPServerTransport可以非常方便地桥接 MCP 协议和 HTTP。安装 Express 和 MCP SDK 后核心代码如下npm install express modelcontextprotocol/sdk// server.ts import express from express; import { McpServer } from modelcontextprotocol/sdk/server/mcp.js; import { StreamableHTTPServerTransport } from modelcontextprotocol/sdk/server/streamableHttp.js; const app express(); app.use(express.json()); const server new McpServer({ name: mcp-tools-cloud, version: 1.0.0 }); // 注册所有工具按功能域加载 registerFileTools(server); registerHttpTools(server); registerGitTools(server); registerProcessTools(server); registerTextTools(server); registerCodeTools(server); registerNetworkTools(server); registerMiscTools(server); const transports: Recordstring, StreamableHTTPServerTransport {}; app.post(/mcp, async (req, res) { const sessionId req.headers[mcp-session-id] as string; if (sessionId transports[sessionId]) { // 已有会话复用 transport 继续处理 await transports[sessionId].handleRequest(req, res); return; } const transport new StreamableHTTPServerTransport({ sessionIdGenerator: () crypto.randomUUID() }); transports[transport.sessionId] transport; res.locals.transport transport; await server.connect(transport); await transport.handleRequest(req, res); }); app.get(/mcp, async (req, res) { const sessionId req.headers[mcp-session-id] as string; const transport transports[sessionId]; if (!transport) { res.status(404).json({ error: Session not found }); return; } await transport.handleRequest(req, res); }); app.delete(/mcp, async (req, res) { const sessionId req.headers[mcp-session-id] as string; const transport transports[sessionId]; if (!transport) { res.status(404).json({ error: Session not found }); return; } await transport.handleRequest(req, res); delete transports[sessionId]; }); app.listen(3000, () { console.log(MCP server listening on port 3000); });这段代码里有几个细节值得展开McpServer是 SDK 提供的高层封装可以把它理解成一个工具管理容器所有工具注册到它上面由它统一处理协议逻辑。StreamableHTTPServerTransport是 SDK 提供的 HTTP 传输层会自动处理 MCP 协议的请求封装、响应格式、错误码等不需要自己解析协议细节。我需要手动管理transports映射因为 HTTP 协议是无状态的每个客户端会话需要一个独立的 transport 实例否则会话状态会互相串。4.3 魔搭部署中踩过的配置坑魔搭部署过程里我踩了好几个很典型的坑逐个列出来端口问题。本地调试时一般习惯固定写3000端口但魔搭的部署环境里服务端口往往是通过环境变量PORT动态分配的写死端口会导致健康检查失败。我的解决方式是const port process.env.PORT || 3000; app.listen(port);启动命令。魔搭虽然支持 Node.js 应用但启动命令需要显式指定。一般是node dist/server.js。如果你忘了构建或者启动命令写成了npm start而package.json里没配好 start 脚本部署状态会一直是启动失败。内存限制。魔搭的免费实例内存通常有限MCP Server 里注册 91 个工具进程启动时会有一定的内存开销。我在部署初期遇到过进程被 OOMOut of Memory杀掉的报错。解决方式是把 Node.js 的堆内存上限调低防止系统误杀NODE_OPTIONS--max-old-space-size5124.4 MCP 客户端配置远程服务的方法部署完成后不需要再让用户安装任何 npm 包。在 Claude Desktop、Codex、Cherry Studio 等支持 MCP 的客户端里按如下格式配置远程 MCP 服务{ mcpServers: { mcp-tools-cloud: { url: https://your-app-endpoint.example.com/mcp } } }配置完成后客户端会先通过 GET 请求进行会话初始化然后通过 POST 发送工具调用请求。如果你在客户端里能看到工具列表加载出来说明整个链路已经通了。5. 高频报错与排查技巧实录这一部分是我最想分享的因为很多报错非常隐蔽网上也很难搜到完整方案。我把整个过程中最折磨人的几个报错整理成了速查表报错信息原因解决方案npm ERR! code E403npm 包名被占用或 scoped 包没有设置 access换包名或给publishConfig.access设为publicnpm ERR! code CERT_HAS_EXPIRED本地 npm 配置的镜像源证书过期切换回官方源npm config set registry https://registry.npmjs.org/npm : 无法加载文件 ... npm.ps1 ... 禁止运行脚本Windows 执行策略限制 PowerShell 运行脚本以管理员身份用Set-ExecutionPolicy -ExecutionPolicy RemoteSigned放开策略npm : 无法将npm项识别为 cmdlet...Node.js 没有加入 PATH 或安装不完整重新安装 Node.js或手动把C:\Program Files\nodejs加入 PATHCannot find native binding依赖的原生模块编译失败执行npm rebuild重新编译依赖ERR! code EUNSUPPORTEDPROTOCOLnpm 尝试通过不支持的协议下载依赖检查.npmrc里的 registry 配置是否用了git://等协议改成https://5.1 npm 源证书过期的清理方法CERT_HAS_EXPIRED这个报错值得一提。这个报错通常是因为很久以前配置了淘宝镜像registry.npm.taobao.org而那个源现在已经不维护了证书自然过期。排查方法是执行npm config get registry如果回显的是https://registry.npm.taobao.org那问题基本就定位了。需要把它改回官方源或者换成新的镜像源npm config set registry https://registry.npmjs.org/实测换成官方源后CERT_HAS_EXPIRED报错就再也没出现过。5.2 PowerShell 脚本执行策略的坑这个报错在 Windows 上非常普遍尤其是新装 Node.js 后直接跑 npm 命令。原因不是 npm 没装好而是 PowerShell 默认的脚本执行策略为Restricted禁止任何.ps1脚本运行。而 npm 在 Windows 上就是一个.ps1脚本所以就会报因为在此系统上禁止运行脚本。解决方式很简单管理员权限的 PowerShell 里执行Set-ExecutionPolicy -ExecutionPolicy RemoteSigned执行完最好验证一下当前策略Get-ExecutionPolicy如果回显RemoteSigned说明策略已经放开。这条命令的含义是本地创建的脚本可以运行从网络下载的脚本必须经过签名校验既可以解决开发需求又保留了一定的安全边界。5.3 npm warn deprecated 是什么信号开发过程中经常看到npm warn deprecated node-domexception1.0.0: use your platforms native DOMException这类警告。刚开始我以为是项目自己的问题排查半天才发现是某个依赖的依赖版本过老。这类警告通常分三种情况传递依赖的过时版你并没有直接安装这个包是某个依赖引用的旧版本。处理方式是在 package.json 里加overrides强制指定新版本。当前 Node.js 已经内置比如node-domexception这个包纯粹是为了给老版本 Node 提供兼容现代 Node 已经不需要了。这种可以无视。SDK 未来会移除的 API需要关注是否有新的 replacement有就及时升级。判断是否值得处理的标准是如果只是构建时有警告、运行和功能不受影响先保留如果影响功能或占用大量磁盘空间再动手修。5.4 会话管理导致的 404 问题HTTP 模式的 MCP Server 部署到魔搭以后我遇到的第一个问题是客户端连接后报404 Not Found。排查下来原因很有意思魔搭对自定义路由有前缀处理应用实际收到的请求路径会带上应用名这就导致/mcp路由匹配不上。解决方式有两种在 Express 中配置前缀适配例如对包含应用名的路径做重写。向魔搭确认是否有自定义路由前缀配置把前缀关掉。我最后是做了层路由兼容把带不带前缀的路径都映射到同一个处理逻辑上。这样不管客户端配置什么地址都不会因为路由前缀不匹配而出 404。5.5 首次请求超时的排查思路部署完魔搭后第一次连接 MCP 时经常遇到超时。后来发现是客户端和服务端对超时时间理解不一致造成的服务端注册 91 个工具需要几秒钟时间远端配置超时阈值往往比较短握手期间连接被中断了。优化方向有两条增加 HTTP 服务器的超时限制让握手期间的连接存活时间更长app.use((req, res, next) { req.setTimeout(30000); res.setTimeout(30000); next(); });减少握手阶段的耗时如启用代码分拆的懒加载。把少量不会立即使用的工具做成按需注册而不是启动时一次性全部注册。实测下来把超时限制调到 30 秒并把一部分重量级工具改成延迟注册后首次连接速度明显提升没有再因超时而中断。6. 实测效果Claude 和 Codex 中的真实表现6.1 Claude Desktop 里调用 MCP 工具的实际体验部署完成后我在 Claude Desktop 里配置了本地stdio模式的几个包和远程的mcp-tools-cloudURL。实际使用的感受是AI 在接到任务描述后会自动解析需要哪个工具、应该传什么参数然后直接发起调用。举个例子我让 Claude 查看当前目录下最大的 5 个文件并输出它们的绝对路径。Claude 就自动调用了mcp-tools-file里的list_large_files工具参数传了limit: 5返回的结果被它整理成了一张表格。这个结果我是非常满意的——如果没有 MCP这种任务需要我手动去敲命令或者让 AI 生成代码后我再去跑。有了 MCPAI 自己就能完成看 → 判断 → 操作 → 汇报的完整链路。6.2 Codex 接入 MCP 时的上下文差异Codex 接入 MCP 的方式和 Claude Desktop 不太一样它更偏终端环境。我通过配置.codex/config.toml把 MCP Server 注册进去实测中最大的感受是Codex 对工具描述的长度更敏感。Claude 对长度冗余的描述容忍度比较高但 Codex 描述写得过长会导致工具调用率变低、响应变慢。我把描述精简到只包含必要的参数说明和示例后工具调用准确率明显提升。这说明了一个问题同一套 MCP 工具在不同客户端的表现策略差异很大实测后的调优很有必要。不要指望能跑就等于用得好还是得逐个客户端做适配。6.3 Cherry Studio 等客户端的兼容性验证除了主流客户端我还顺手在 Cherry Studio 里验证了远程 MCP 的兼容性。因为协议层是标准化的只要客户端实现了 MCP 客户端规范不管是开源还是商业产品接上之后都能正常使用。这是一个非常好的生态信号——你只要做好一次标准实现就能让所有兼容客户端都获得能力。7. 维护经验91 个工具怎么长期迭代不失控7.1 工具全量的登记与健康检查91 个工具如果纯粹靠记忆管理早晚会失控。我维护了一份工具登记表markdown 表格记录了每个工具的名字、所属包、描述、依赖命令、是否需要权限、是否已废弃。每次新增工具先查表确认没有重复再登记后开发。同时我写了一个健康检查脚本循环启动每个 MCP Server发一个最简单的工具调用请求校验能否正确返回// healthCheck.ts import { spawn } from child_process; const servers [mcp-tools-file, mcp-tools-http, mcp-tools-git]; for (const serverName of servers) { const child spawn(npx, [serverName], { stdio: [pipe, pipe, pipe] }); // 发送 MCP 初始化请求等返回结果 child.stdin.write(JSON.stringify({ jsonrpc: 2.0, method: initialize, params: { protocolVersion: 2024-11-05 } })); }这个脚本在每次发布前跑一遍能有效发现某个工具悄悄坏了的问题防止把一个带病版本发出去。7.2 依赖升级时怎么控制风险MCP SDK 迭代很快版本升级时需要非常谨慎。我这里总结了两条原则每次只升一个包不要一次性升级多个包的依赖否则到时候出问题定位不到是哪个包引起的。升级后立刻跑完整工具集的自测确认注册、调用、返回结果全链路 OK 再发布。有一次我升级了modelcontextprotocol/sdk的版本结果发现新版本对参数校验更严格了之前有一些宽松的参数定义开始报错。这属于典型的语义化兼容但行为不兼容的问题只有跑完整自测才能发现。7.3 自动化的一键发布模式为了解决手工发布 8 个包的痛苦我写了脚本一键完成全量测试 → 版本自增 → 构建 → 发布#!/bin/bash npm run test npm run build for package in packages/*; do cd $package npm version patch npm publish cd ../.. done echo All packages published successfully!这个脚本有个前置条件8 个包的版本号增量保持在同步状态发布后用同一个 tag 拉取即可全部更新。这样每次工具更新只需要跑一次脚本8 个包可以同时上新版本。8. 最后的建议和心得回看整个项目从最开始的试试水到最终落地 91 个工具的完整 MCP 封装最让我觉得有价值的收获其实不是技术本身而是对工具化这件事有了更深的理解。第一好的工具封装一定是无感的。用户在 AI 对话里发出指令背后 MCP 工具自动完成操作这是最理想的状态。如果用户需要频繁手动干预、告诉 AI 该调用哪个工具那说明封装层还有优化空间。第二标准协议的力量被低估了。以前每接一个工具都要考虑这个工具在哪个平台、用什么语言、怎么认证现在只要实现一次 MCP 标准所有兼容 MCP 的客户端都能直接使用这种杠杆效应是非常值得投入的。第三分发方式会决定用户上手成本。我最初想做纯本地方案后来转向npm 包 远程托管的混合模式用户配置成本低了不止一个量级。给别人提供工具永远要多想想用户拿到手之后第一步怎么做最省事。根据我这几周的实战体验MCP 生态还在快速演进最好的学习方式就是把一个真实场景端到端跑通——从本地封装到线上托管哪怕只做 3 个工具也能把整个链路里的坑都踩一遍。等你想做 30 个、90 个工具的时候这套流程和方法论就可以直接复用了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价