chatgpt-app-builder

chatgpt-app-builder

热门

**所有MCP服务器工作的必读内容**——mcp-use框架最佳实践与模式。 **在进行任何MCP服务器工作之前,请先阅读本文**,包括: - 创建新的MCP服务器 - 修改现有MCP服务器(添加/更新工具、资源、提示、组件) - 调试MCP服务器问题或错误 - 审查MCP服务器代码的质量、安全性或性能 - 回答关于MCP开发或mcp-use模式的问题 - 对server.tool()、server.resource()、server.prompt()或组件进行任何更改 本技能包含关键的架构决策、安全模式和常见陷阱。 在实现MCP功能之前,请务必查阅相关的参考文件。

1万Star
1359Fork
更新于 2026/7/11
SKILL.md
readonly只读
name
chatgpt-app-builder
description

**所有MCP服务器工作的必读内容**——mcp-use框架最佳实践与模式。 **在进行任何MCP服务器工作之前,请先阅读本文**,包括: - 创建新的MCP服务器 - 修改现有MCP服务器(添加/更新工具、资源、提示、组件) - 调试MCP服务器问题或错误 - 审查MCP服务器代码的质量、安全性或性能 - 回答关于MCP开发或mcp-use模式的问题 - 对server.tool()、server.resource()、server.prompt()或组件进行任何更改 本技能包含关键的架构决策、安全模式和常见陷阱。 在实现MCP功能之前,请务必查阅相关的参考文件。

重要:如何使用本技能

本文件仅提供导航指南。在实现任何MCP服务器功能之前,您必须:

  1. 阅读本概述,了解哪些参考文件是相关的
  2. 始终阅读您要实现的功能对应的具体参考文件
  3. 将那些文件中的详细模式应用到您的实现中

不要仅依赖本文件中的快速参考示例——它们只是最小示例。参考文件包含关键的最佳实践、安全考虑和高级模式。


MCP服务器最佳实践

使用mcp-use构建生产就绪的MCP服务器(包含工具、资源、提示和组件)的综合指南。

⚠️ 首先:新项目还是现有项目?

在做任何其他事情之前,请确定您是否在现有的mcp-use项目中。

检测: 检查工作区中是否存在将"mcp-use"列为依赖项的package.json,或者任何从"mcp-use/server"导入的.ts文件。

├─ 找到mcp-use项目 → 不要搭建脚手架。您已经在项目中。
│  └─ 跳转到下面的“快速导航”以添加功能。
│
├─ 没有mcp-use项目(空目录、不相关的项目或全新项目)
│  └─ 首先使用npx create-mcp-use-app搭建脚手架,然后添加功能。
│     请参阅下面的“搭建新项目”。
│
└─ 在不相关的项目中(例如Next.js应用),用户想要一个MCP服务器
   └─ 询问用户在哪里创建,然后在该目录中搭建脚手架。
      不要在不相关的现有项目根目录内搭建脚手架。

永远不要手动创建MCPServer样板代码、package.json或项目结构。 CLI会设置TypeScript配置、开发脚本、检查器集成、热重载和组件编译,这些很难手动复制。


搭建新项目

npx create-mcp-use-app my-server
cd my-server
npm run dev

有关完整的搭建细节和CLI标志,请参阅**quickstart.md**。


快速导航

根据您要构建的内容选择路径:

🚀 基础

何时: 在新对话中开始MCP工作时,始终先阅读这些。稍后参考以澄清架构/概念。

  1. concepts.md - MCP原语(工具、资源、提示、组件)以及何时使用每种
  2. architecture.md - 服务器结构(基于Hono)、中间件系统、server.use()与server.app
  3. quickstart.md - 搭建、设置和第一个工具示例
  4. deployment.md - 部署到Manufact Cloud、自托管、Docker、管理部署

在深入工具/资源/组件部分之前,请先加载这些内容。


🔐 添加身份验证?

何时: 使用OAuth保护您的服务器(Auth0、Better Auth、Clerk、WorkOS、Supabase、Keycloak或任何其他提供商)

  • overview.md

    • 何时:首次添加身份验证、理解ctx.auth或选择提供商/集成模式
    • 涵盖:远程身份验证与OAuth代理、oauth配置、ctx.auth形状、提供商比较、常见错误
  • auth0.md

    • 何时:使用Auth0——DCR(早期访问)或通过oauthProxy的标准常规Web应用
    • 涵盖:两种模式的设置、extraAuthorizeParams.audience、通过rfc9068_profile_authz的权限
  • better-auth.md

    • 何时:使用带有@better-auth/oauth-provider插件的Better Auth(自托管OAuth 2.1)
    • 涵盖:oauthBetterAuthProvider、身份验证URL/元数据路由、登录和同意流程
  • clerk.md

    • 何时:使用Clerk(基于DCR的OAuth)
    • 涵盖:oauthClerkProvider、启用DCR、前端API URL、组织上下文
  • workos.md

    • 何时:使用WorkOS AuthKit(仅DCR)
    • 涵盖:设置、环境变量、角色/权限、多租户组织过滤、WorkOS API调用
  • supabase.md

    • 何时:使用Supabase的OAuth 2.1服务器
    • 涵盖:设置、可发布密钥、ES256与HS256、托管同意UI、RLS感知的SDK调用
  • keycloak.md

    • 何时:通过原生DCR使用Keycloak
    • 涵盖:DCR受信任主机+Web来源、受众强制执行、领域与资源角色、用户信息
  • custom.md

    • 何时:任何其他提供商——通过oauthCustomProvider支持DCR,或通过oauthProxy预注册(Google、GitHub、Okta、Azure AD)
    • 涵盖:oauthCustomProvideroauthProxy + jwksVerifier、提供商示例、不透明令牌验证

🔧 构建服务器后端(无UI)?

何时: 实现MCP功能(操作、数据、模板)。阅读您要构建的原语对应的具体文件。

  • tools.md

    • 何时:创建AI可以调用的后端操作(发送邮件、获取数据、创建用户)
    • 涵盖:工具定义、模式、注释、上下文、错误处理
  • resources.md

    • 何时:公开客户端可以获取的只读数据(配置、用户配置文件、文档)
    • 涵盖:静态资源、动态资源、参数化资源模板、URI补全
  • prompts.md

    • 何时:创建用于AI交互的可重用消息模板(代码审查、总结)
    • 涵盖:提示定义、参数化、参数补全、提示最佳实践
  • response-helpers.md

    • 何时:格式化工具/资源的响应(文本、JSON、Markdown、图像、错误)
    • 涵盖:text()object()markdown()image()error()mix()
  • proxy.md

    • 何时:将多个MCP服务器组合成一个统一的聚合服务器
    • 涵盖:server.proxy()、配置API、显式会话、采样路由
  • architecture.md

    • 何时:添加跨多个工具/资源的横切逻辑(日志记录、身份验证检查、速率限制、工具过滤)
    • 涵盖:server.use('mcp:...')中间件、MiddlewareContext(方法、参数、身份验证、状态)、模式匹配、HTTP与MCP中间件

🎨 构建可视化组件(交互式UI)?

何时: 创建基于React的可视化界面,用于浏览、比较或选择数据

  • basics.md

    • 何时:创建您的第一个组件或向现有工具添加UI
    • 涵盖:组件设置、useWidget()钩子、isPending检查、属性处理
  • state.md

    • 何时:管理组件内的UI状态(选择、过滤器、标签页)
    • 涵盖:useStatesetState、状态持久化、何时使用工具与组件状态
  • interactivity.md

    • 何时:添加按钮、表单或从组件内调用工具
    • 涵盖:useCallTool()、表单处理、操作按钮、乐观更新
  • ui-guidelines.md

    • 何时:为组件设置样式以支持主题、响应式布局或可访问性
    • 涵盖:useWidgetTheme()、亮/暗模式、autoSize、布局模式、CSS最佳实践
  • advanced.md

    • 何时:构建具有异步数据、错误边界或性能优化的复杂组件
    • 涵盖:加载状态、错误处理、记忆化、代码分割
  • model-context.md

    • 何时:让AI模型了解用户当前看到的内容(活动标签页、悬停项、所选产品),而无需工具调用
    • 涵盖:<ModelContext>组件、modelContext.set/remove命令式API、嵌套、树序列化、生命周期规则
  • files.md

    • 何时:从组件内上传或下载文件(仅限ChatGPT Apps SDK)
    • 涵盖:useFiles()钩子、isSupported守卫、模型可见性(modelVisible)、存储fileId、临时下载URL

📚 需要完整示例?

何时: 您想查看常见用例的完整实现

  • common-patterns.md
    • 端到端示例:天气应用、待办事项列表、食谱浏览器
    • 展示:服务器代码+组件代码+上下文中的最佳实践

🔁 从终端测试(代理反馈循环)

何时: 您想在没有检查器UI的情况下验证工具或组件——这是AI代理迭代MCP服务器的标准流程。

  • mcp-use client — 从终端驱动MCP服务器。在401时自动运行OAuth,将已保存的服务器持久化到短名称下,一次性子命令干净退出,因此从框架中生成是安全的。

    npx mcp-use client connect dev http://localhost:3000/mcp
    npx mcp-use client dev tools list
    npx mcp-use client dev tools call get-weather city=Tokyo --screenshot
    

    每个服务器命令都将保存的名称作为第一个位置参数(mcp-use client <name> <scope> <action>)——没有“活动会话”。参数使用key=value(嵌套值使用key:='<json>')或单个JSON对象。当工具渲染组件时,传递--screenshot以同时保存PNG(默认./<view>-<timestamp>.png,或使用--screenshot-output <path>覆盖)。

  • mcp-use client screenshot — 将组件工具无头渲染为PNG。当您想在不打开检查器的情况下视觉验证组件更改时使用此命令,特别是在循环中调用工具、截图、检查输出并编辑时。两种形式:

    # 已保存服务器形式——重用来自`mcp-use client connect`的身份验证
    npx mcp-use client dev screenshot --tool get-weather city=Tokyo \
      --width 800 --height 600 --theme light \
      --output ./weather.png
    
    # 临时形式——内联连接(在需要身份验证的服务器上使用-H添加标头)
    npx mcp-use client screenshot --mcp http://localhost:3000/mcp \
      --tool get-weather city=Tokyo
    

    添加--device-scale-factor 2以获得Retina输出,或使用--cdp-url <ws>加上--inspector <publicly-reachable-url>从没有本地Chrome安装的沙箱驱动远程Chromium(例如Notte)。

两个命令的完整文档位于docs/typescript/client/cli


决策树

您需要什么?

├─ 从头开始的新项目
│  └─> quickstart.md(搭建+设置)
│
├─ OAuth/用户身份验证
│  └─> authentication/overview.md → 提供商特定指南
│
├─ 简单的后端操作(无UI)
│  └─> 使用工具:server/tools.md
│
├─ 客户端的只读数据
│  └─> 使用资源:server/resources.md
│
├─ 可重用的提示模板
│  └─> 使用提示:server/prompts.md
│
├─ 横切逻辑(日志记录、身份验证检查、速率限制、工具过滤)
│  └─> 使用中间件:architecture.md#mcp-middleware
│
├─ 可视化/交互式UI
│  └─> 使用组件:widgets/basics.md
│
├─ 让模型了解用户在组件中看到的内容
│  └─> widgets/model-context.md
├─ 在组件中上传/下载文件
│  └─> widgets/files.md(仅限ChatGPT Apps SDK)
│
├─ 从终端验证工具或组件(代理反馈循环)
│  └─> 请参阅上面的“从终端测试”——`mcp-use client`用于工具运行,
│      `mcp-use client <server> screenshot --tool <tool>`用于无头组件PNG
│
└─ 部署到生产环境
   └─> deployment.md(云部署、自托管、Docker)

核心原则

  1. 工具用于操作 - 具有输入/输出的后端操作
  2. 资源用于数据 - 客户端可以获取的只读数据
  3. 提示用于模板 - 可重用的消息模板
  4. 组件用于UI - 在需要时提供可视化界面
  5. 先使用模拟数据 - 快速原型,稍后连接API

❌ 常见错误

避免在生产MCP服务器中发现的这些反模式:

工具定义

  • ❌ 返回原始对象而不是使用响应助手
    • ✅ 使用text()object()widget()error()助手
  • ❌ 跳过每个字段的Zod模式.describe()
    • ✅ 为所有模式字段添加描述,以便AI更好地理解
  • ❌ 没有输入验证或清理
    • ✅ 使用Zod验证输入,清理用户提供的数据
  • ❌ 抛出错误而不是返回error()助手
    • ✅ 使用error("message")进行优雅的错误响应

组件开发

  • ❌ 在不检查isPending的情况下访问props
    • ✅ 始终检查if (isPending) return <Loading/>
  • ❌ 组件处理服务器状态(过滤器、选择)
    • ✅ 组件使用useState管理自己的UI状态
  • ❌ 缺少McpUseProvider包装器或autoSize
    • ✅ 包装根组件:<McpUseProvider autoSize>
  • ❌ 没有主题感知的内联样式
    • ✅ 使用useWidgetTheme()支持亮/暗模式

安全与生产

  • ❌ 在代码中硬编码API密钥或秘密
    • ✅ 使用process.env.API_KEY,在.env.example中记录
  • ❌ 工具处理程序中没有错误处理
    • ✅ 使用try/catch包装,失败时返回error()
  • ❌ 没有缓存的昂贵操作
    • ✅ 使用TTL缓存API调用、计算
  • ❌ 缺少CORS配置
    • ✅ 为生产部署配置CORS

🔒 黄金法则

有主见的架构指南:

1. 一个工具 = 一个能力

将广泛的操作拆分为专注的工具:

  • manage-users(太模糊)
  • create-userdelete-userlist-users

2. 一次性返回完整数据

工具调用成本高。避免延迟加载:

  • list-products + get-product-details(2次调用)
  • list-products返回包括详细信息在内的完整数据

3. 组件拥有自己的状态

UI状态存在于组件中,而不是单独的工具中:

  • select-item工具、set-filter工具
  • ✅ 组件使用useStatesetState管理

4. exposeAsTool默认为false

组件默认仅注册为资源。使用自定义工具(推荐)或设置exposeAsTool: true将组件暴露给模型:

// ✅ 需要所有4个步骤以获得正确的类型推断:

// 步骤1:单独定义模式
const propsSchema = z.object({
  title: z.string(),
  items: z.array(z.string())
});

// 步骤2:在元数据中引用模式变量
export const widgetMetadata: WidgetMetadata = {
  description: "...",
  props: propsSchema,  // ← 不是内联的z.object()
  exposeAsTool: false
};

// 步骤3:从模式变量推断Props类型
type Props = z.infer<typeof propsSchema>;

// 步骤4:使用带类型的Props与useWidget
export default function MyWidget() {
  const { props, isPending } = useWidget<Props>();  // ← 添加<Props>
  // ...
}

⚠️ 常见错误: 只做了步骤1-2,但跳过了步骤3-4(失去类型安全)

5. 仅在边界验证

  • 信任内部代码和框架保证
  • 验证用户输入、外部API响应
  • 不要为不可能发生的场景添加错误处理

6. 优先使用组件进行浏览/比较

有疑问时,添加组件。可视化UI改进:

  • 浏览多个项目
  • 并排比较数据
  • 交互式选择工作流

快速参考

最小服务器

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"
});

server.tool(
  {
    name: "greet",
    description: "Greet a user",
    schema: z.object({ name: z.string().describe("User's name") })
  },
  async ({ name }) => text("Hello " + name + "!"),
);

server.listen();

响应助手

助手 使用时机 示例
text() 简单字符串响应 text("Success!")
object() 结构化数据 object({ status: "ok" })
markdown() 格式化文本 markdown("# Title\nContent")
widget() 可视化UI widget({ props: {...}, output: text(...) })
mix() 多个内容 mix(text("Hi"), image(url))
error() 错误响应 error("Failed to fetch data")
resource() 嵌入资源引用 resource("docs://guide", "text/markdown")

服务器方法:

  • server.tool() - 定义可执行工具
  • server.resource() - 定义静态/动态资源
  • server.resourceTemplate() - 定义参数化资源
  • server.prompt() - 定义提示模板
  • server.proxy() - 组合/代理多个MCP服务器
  • server.uiResource() - 定义组件资源
  • server.listen() - 启动服务器
  • server.use('mcp:tools/call', fn) - MCP中间件(工具、资源、提示、列表操作)
  • server.use('mcp:*', fn) - 捕获所有MCP中间件
  • server.use(fn) - HTTP中间件(Hono)