ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

使用 mcp-use 五分钟构建你的第一个 MCP Server:CopilotKit 仓库 open-mcp-client 快速上手实战

使用 mcp-use 五分钟构建你的第一个 MCP Server:CopilotKit 仓库 open-mcp-client 快速上手实战 使用 mcp-use 五分钟构建你的第一个 MCP ServerCopilotKit 仓库 open-mcp-client 快速上手实战【免费下载链接】CopilotKitThe Frontend Stack for Agents Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit本指南以 quickstart.md 为核心骨架讲解如何用mcp-use框架在 5 分钟内完成脚手架搭建、模板选择、开发调试并逐步实现工具Tool、模拟数据、结构化响应与资源Resource四大基础能力。读完你可以在本地跑通一个带 Inspector 调试面板的完整 MCP Server并为后续接入 ChatGPT、Claude 等 MCP Apps 兼容客户端的 Widget 可视化界面打好基础。一、先认识 mcp-use 与本文的实战环境本文的实操对象是 CopilotKit 仓库中的 open-mcp-client 展示项目其核心是一个基于mcp-use框架实现的 MCP Server 示例服务器入口index.ts —— 创建MCPServer实例并注册工具工具实现tools/product-search.ts —— 一个返回 Widget 可视化界面的完整工具示例依赖清单package.json —— 声明了mcp-use、zod、react等运行时依赖。从依赖与源码结构看mcp-use是一个把 MCP 协议模型上下文协议与 HTTP 服务器能力融为一体的 TypeScript 框架它基于 Hono Web 框架构建开发者通过server.tool()、server.resource()、server.prompt()声明 MCP 原语同时还能通过server.app直接添加自定义 HTTP 路由。想深入了解这一架构可以参考同目录下的 architecture.md 与 concepts.md。在动手之前请确认本地环境已安装Node.js建议 18与 npm或 pnpmMCP 生态相关的类型定义与依赖都会由脚手架自动安装。二、Setup脚手架搭建一个全新项目创建一个全新的 mcp-use 项目只需三条命令npx create-mcp-use-app my-server cd my-server npm run dev执行第一条命令时脚手架会自动完成依赖安装npm run dev会启动开发服务器默认监听 3000 端口并自动打开内置调试器Inspector——地址为http://localhost:3000/inspector。关于端口与启动细节仓库中的 package.json 给出了脚手架生成项目的真实脚本参考scripts: { build: mcp-use build --inline, dev: mcp-use build --inline cross-env NODE_ENVproduction npx tsx index.ts, start: mcp-use start, deploy: mcp-use deploy }dev先构建 Widget--inline表示内联打包再用tsx直接运行 TypeScript 入口支持热重载build/start生产构建与启动deploy一键部署到生产环境。提示示例仓库 index.ts 中通过process.env.MCP_URL与process.env.PORT支持环境变量覆盖默认端口为 3109server.listen(parseInt(process.env.PORT ?? 3109, 10))。这意味着脚手架默认 3000 端口并非硬编码你可以随时用环境变量调整方便与本机其他服务错开端口。三、选择一个合适的模板脚手架内置了四种模板应根据你要构建的内容来选择模板命令适用场景starter默认npx create-mcp-use-app my-server功能完整的服务器自带 tools、resources、prompts 与 widget 示例mcp-appsnpx create-mcp-use-app my-server --template mcp-apps面向 ChatGPT、Claude 等 MCP Apps 兼容客户端的 Widget 专注型模板blanknpx create-mcp-use-app my-server --template blank空白模板——只含带注释示例的裸服务器GitHub reponpx create-mcp-use-app my-server --template owner/repo从任意 GitHub 仓库拉取自定义或社区模板不确定选哪个时直接选mcp-apps。它是官方推荐默认值内置了对 ChatGPT、Claude 等 MCP Apps 兼容客户端的 Widget 支持后续若要给工具添加可视化界面可以省去大量配置工作。常见命令行参数Common Flags# 选择包管理器 npx create-mcp-use-app my-server --npm npx create-mcp-use-app my-server --pnpm # 跳过交互式提问 npx create-mcp-use-app my-server --install --skills # 列出所有可用模板 npx create-mcp-use-app --list-templates参数说明--npm/--pnpm指定依赖安装工具不传时按默认策略选择--install跳过安装确认直接安装依赖--skills同时写入脚手架自带的开发技能文件例如本仓库.agent/skills/目录下这套 mcp-apps-builder 文档就是此类技能--list-templates查看当前版本全部可用模板与 GitHub 仓库模板列表。经验之谈仓库中 SKILL.md 反复强调一个原则——不要手写MCPServer样板代码、package.json 或项目结构。脚手架一次性配置好了 TypeScript、dev 脚本、Inspector 集成、热重载与 Widget 编译这些手动复制极易出错务必优先使用脚手架。四、每个模板会生成什么脚手架产物的目录结构决定了你的开发组织方式下面是三个内置模板的标准产物starter 模板my-server/ ├── index.ts # 服务器入口含 tool、resource、prompt 示例 ├── resources/ # Widget 目录含 display-weather.tsx 示例 ├── public/ # 静态资源favicon、icon ├── package.json # 预配置脚本dev、build、start、deploy └── tsconfig.jsonmcp-apps 模板my-server/ ├── index.ts # 服务器入口含返回 Widget 的工具 ├── resources/ # Widget 目录含 product-search-result/ 示例 │ └── product-search-result/ │ ├── widget.tsx # React Widget轮播卡片 UI │ └── components/ # 可复用 Widget 组件 ├── public/ ├── package.json └── tsconfig.jsonblank 模板my-server/ ├── index.ts # 裸 MCPServer示例均为注释 ├── public/ ├── package.json └── tsconfig.json对照仓库源码可以印证这套结构的真实性index.ts 顶部注释详细说明了添加一个新 MCP App Widget 的三步流程——在resources/widget-name/widget.tsx创建 React 组件、在tools/tool-name.ts导出注册函数、最后在入口文件 import 并调用register()。而 tools/product-search.ts 正是这一流程的完整落地范例可作为你编写第一个自定义工具时的对照样板。五、脚手架搭建后的开发工作流完成脚手架之后标准开发循环如下npm run dev—— 启动带热重载 Inspector 的服务器编辑index.ts添加 tools、resources、prompts在resources/目录下以.tsx文件添加 Widget在http://localhost:3000/inspector中测试一切功能npm run build—— 生成生产构建npm run deploy—— 部署到生产环境。这套循环的核心价值在于热重载保存.ts/.tsx文件后服务端会自动重建 Widget 并重启服务器无需手动中断进程非常适合快速迭代。六、你的第一个工具greet脚手架生成的index.ts已经包含一个基础服务器现在给它加一个最简单的工具——greet接收一个名字参数并返回问候语import { MCPServer, text } from mcp-use/server; import { z } from zod; const server new MCPServer({ name: my-server, title: My Server, version: 1.0.0, baseUrl: process.env.MCP_URL || http://localhost:3000, }); // 新增这个工具 server.tool( { name: greet, description: Greet a user by name, schema: z.object({ name: z.string().describe(Users name), }), }, async ({ name }) { return text(Hello, ${name}! Welcome to MCP.); }, ); server.listen();代码要点拆解MCPServer构造参数中的name/title/version是服务器元信息baseUrl用process.env.MCP_URL提供默认值兜底这正是仓库 index.ts 采用的环境变量模式schema使用zod声明入参结构每个字段都要调用.describe()补充描述——模型依赖这些描述理解参数含义这也是 SKILL.md 中列出的第一条 Tool 定义最佳实践返回值必须用响应辅助函数text()包装而不是直接return一个普通字符串。保存文件——服务器会自动重载在 Inspector 中测试打开 Inspectorhttp://localhost:3000/inspector点击List Tools找到greet工具点击Call Tool输入参数{name: Alice}看到响应Hello, Alice! Welcome to MCP.Inspector 是 mcp-use 开发体验的核心它能列出全部已注册工具、资源和提示词也能直接发起工具调用是验证每个新功能的第一站。七、添加模拟数据一个天气工具开发阶段的惯例是Mock 数据优先之后再接真实 API。下面用一段硬编码数据实现天气查询// 模拟天气数据 const mockWeather: Recordstring, { temp: number; conditions: string } { New York: { temp: 22, conditions: Partly Cloudy }, London: { temp: 15, conditions: Rainy }, Tokyo: { temp: 28, conditions: Sunny }, Paris: { temp: 18, conditions: Overcast }, }; server.tool( { name: get-weather, description: Get current weather for a city, schema: z.object({ city: z.string().describe(City name), }), }, async ({ city }) { const weather mockWeather[city]; if (!weather) { return text(No weather data for ${city}); } return text(Weather in ${city}: ${weather.temp}°C, ${weather.conditions}); }, );测试方法与上一节相同用{city: Tokyo}调用工具期望响应Weather in Tokyo: 28°C, Sunny。这段代码展示了工具处理的两个典型分支数据命中返回正常结果、数据未命中返回友好的兜底文本。真实的工具实现通常在此基础上补充异常捕获与参数校验可参考 tools/product-search.ts 中get-fruit-details的写法用outputSchema声明结构化输出并对未找到的水果返回默认字段。八、添加结构化数据object() 返回文本返回适合对话场景但 AI 或客户端需要解析结构化信息时应使用object()辅助函数返回 JSONimport { MCPServer, text, object } from mcp-use/server; server.tool( { name: get-weather-detailed, description: Get detailed weather information, schema: z.object({ city: z.string().describe(City name), }), }, async ({ city }) { const weather mockWeather[city]; if (!weather) { return object({ error: No data for ${city} }); } return object({ city, temperature: weather.temp, conditions: weather.conditions, unit: celsius, timestamp: new Date().toISOString(), }); }, );注意这里的错误分支同样用object()返回结构化错误对象而不是抛出异常——这是 mcp-use 的约定错误应作为响应的一部分优雅返回让模型能读懂失败原因。从源码层面看response-helpers.md 列出了完整的辅助函数族text()、object()、markdown()、image()、error()、widget()、mix()、resource()。它们统一负责正确设置 MIME 类型、保证序列化并支持多内容响应。永远用辅助函数包装返回值不要直接 return 原始对象——这是该文档反复强调的第一原则。九、添加一个资源ResourceResource 用于向客户端暴露只读数据适合配置信息、静态列表等场景server.resource( { name: available_cities, uri: weather://available-cities, title: Available Cities, description: List of cities with weather data, }, async () object({ cities: Object.keys(mockWeather), }), );在 Inspector 中测试打开 Inspector →List Resources找到 Available Cities点击Read Resource看到{cities: [New York, London, Tokyo, Paris]}。Resource 与 Tool 的定位差异很关键Tool 是 AI 可调用的动作Resource 是客户端可拉取的只读数据。如果数据需要参数化例如按城市 ID 取详情则应使用 Resource 模板动态 URI具体可参考 resources.md。十、进阶路线从工具到可视化 Widget掌握了 Tool、结构化响应与 Resource 之后你的下一个能力跃迁点是Widget——让工具返回可视化 React 界面。在 concepts.md 中Widget 被定义为返回视觉 UI 的工具本质仍是server.tool()但声明了widget: { name }配置并在处理器中通过widget({ props, output })返回组件所需数据与模型可见的文本摘要。仓库里 tools/product-search.ts 就是完整的 Widget 工具范例search-tools工具返回widget({ props: { query, results }, output: text(...) })并通过_meta[ui/previewData]提供尚未调用时的预览数据配套的get-fruit-details数据工具则供 Widget 内部通过useCallTool()调用演示了Widget 外壳 数据工具的组合模式。建议按以下顺序继续学习均位于本仓库的 skills 文档体系内学习响应辅助函数→ response-helpers.md构建你的第一个 Widget→ basics.md查看完整示例→ common-patterns.md如果只想在本地快速跑通一个带 Widget 的成品可以直接运行仓库中的 mcp-use-server 示例package.json 中的npm run dev在 Inspector 中调用search-tools观察轮播式水果卡片如何渲染。十一、开发建议与常见误区综合 quickstart 与 SKILL.md 的实践总结快速上手阶段最容易踩的坑如下场景❌ 错误做法✅ 正确做法返回值直接return { data }原始对象用object()/text()等辅助函数包装参数描述Zod schema 字段不加说明所有字段调用.describe()错误处理throw new Error(...)抛出异常返回error(...)优雅降级工具粒度一个manage-users大而全拆成create-user、list-users等单一职责工具数据获取list-productsget-product-details两次调用一次返回完整数据避免懒加载Widget 状态用select-item工具管理 UI 状态Widget 内部用useState自行管理Mock 数据优先是快速上手阶段最重要的方法论先用硬编码数据把工具链路跑通、把界面效果调好再在后续迭代中替换为真实 API——tools/product-search.ts 中的水果目录就是这么做的切换数据源时只需改动fruits常量即可。【免费下载链接】CopilotKitThe Frontend Stack for Agents Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表