🚀 快速安装
复制以下命令并运行,立即安装此 Skill:
npx skills add https://github.com/mcp-use/mcp-use --skill mcp-apps-builder
💡 提示:需要 Node.js 和 NPM
重要提示:如何使用此技能
此文件仅提供导航指南。在实现任何 MCP 服务器功能之前,您必须:
- 阅读此概述,了解哪些参考文件是相关的
- 始终阅读您正在实现的功能的特定参考文件
- 将这些文件中的详细模式应用到您的实现中
不要仅依赖此文件中的快速参考示例 – 它们只是最小示例。参考文件包含关键的最佳实践、安全注意事项和高级模式。
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 工作时,始终先阅读这些。之后在需要澄清架构/概念时参考。
- concepts.md – MCP 原语(工具、资源、提示、小部件)以及何时使用每种
- architecture.md – 服务器结构(基于 Hono)、中间件系统、server.use() vs server.app
- quickstart.md – 脚手架生成、设置和第一个工具示例
- deployment.md – 部署到 Manufact Cloud、自托管、Docker、管理部署
在深入工具/资源/小部件部分之前,请先阅读这些文件。
🔐 需要添加身份验证?
何时阅读: 使用 OAuth(WorkOS、Supabase 或自定义)保护您的服务器
- overview.md
- 何时:首次添加身份验证、了解
ctx.auth或选择提供商 - 涵盖:
oauth配置、用户上下文结构、提供商比较、常见错误
- 何时:首次添加身份验证、了解
- workos.md
- 何时:使用 WorkOS AuthKit 进行身份验证
- 涵盖:设置、环境变量、DCR 与预注册、角色/权限、WorkOS API 调用
- supabase.md
- 何时:使用 Supabase 进行身份验证
- 涵盖:设置、环境变量、HS256 与 ES256、支持行级安全性的 API 调用
- custom.md
- 何时:使用任何其他身份提供商(GitHub、Okta、Azure AD、Google 等)
- 涵盖:自定义验证、用户信息提取、提供商示例
🔧 构建服务器后端(无 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、显式会话、采样路由
🎨 构建可视化小部件(交互式 UI)?
何时阅读: 创建基于 React 的可视化界面,用于浏览、比较或选择数据
- basics.md
- 何时:创建您的第一个小部件或为现有工具添加 UI
- 涵盖:小部件设置、
useWidget()钩子、isPending检查、属性处理
- state.md
- 何时:在小部件内管理 UI 状态(选择、过滤器、标签页)
- 涵盖:
useState、setState、状态持久性、何时使用工具状态 vs 小部件状态
- interactivity.md
- 何时:在小部件内添加按钮、表单或调用工具
- 涵盖:
useCallTool()、表单处理、操作按钮、乐观更新
- ui-guidelines.md
- 何时:为小部件设置样式以支持主题、响应式布局或可访问性
- 涵盖:
useWidgetTheme()、亮色/暗色模式、autoSize、布局模式、CSS 最佳实践
- advanced.md
- 何时:构建具有异步数据、错误边界或性能优化的复杂小部件
- 涵盖:加载状态、错误处理、记忆化、代码分割
📚 需要完整示例?
何时阅读: 您希望看到常见用例的完整实现
- common-patterns.md
- 端到端示例:天气应用、待办事项列表、食谱浏览器
- 展示:服务器代码 + 小部件代码 + 上下文中的最佳实践
决策树
您需要什么?
├─ 从头开始的新项目
│ └─> quickstart.md(脚手架生成 + 设置)
│
├─ OAuth / 用户身份验证
│ └─> authentication/overview.md → 特定提供商的指南
│
├─ 简单的后端操作(无 UI)
│ └─> 使用工具:server/tools.md
│
├─ 供客户端使用的只读数据
│ └─> 使用资源:server/resources.md
│
├─ 可重用的提示模板
│ └─> 使用提示:server/prompts.md
│
├─ 可视化/交互式 UI
│ └─> 使用小部件:widgets/basics.md
│
└─ 部署到生产环境
└─> deployment.md(云部署、自托管、Docker)
核心原则
- 工具用于操作 – 带输入/输出的后端操作
- 资源用于数据 – 客户端可以获取的只读数据
- 提示用于模板 – 可重用的消息模板
- 小部件用于 UI – 在有用时提供可视化界面
- 先使用模拟数据 – 快速原型设计,之后再连接 API
❌ 常见错误
避免在生产环境的 MCP 服务器中出现的这些反模式:
工具定义
- ❌ 返回原始对象而不是使用响应辅助函数
- ✅ 使用
text()、object()、widget()、error()辅助函数
- ✅ 使用
- ❌ 跳过每个字段的 Zod 模式
.describe()- ✅ 为所有模式字段添加描述,以便 AI 更好地理解
- ❌ 没有输入验证或清理
- ✅ 使用 Zod 验证输入,清理用户提供的数据
- ❌ 抛出错误而不是返回
error()辅助函数- ✅ 使用
error("消息")进行优雅的错误响应
- ✅ 使用
小部件开发
- ❌ 在未检查
isPending的情况下访问props- ✅ 始终检查
if (isPending) return <Loading/>
- ✅ 始终检查
- ❌ 小部件处理服务器状态(过滤器、选择项)
- ✅ 小部件使用
useState管理自己的 UI 状态
- ✅ 小部件使用
- ❌ 缺少
McpUseProvider包装器或autoSize- ✅ 包装根组件:
<McpUseProvider autoSize>
- ✅ 包装根组件:
- ❌ 没有主题感知的内联样式
- ✅ 使用
useWidgetTheme()支持亮色/暗色模式
- ✅ 使用
安全与生产
- ❌ 代码中硬编码的 API 密钥或密钥
- ✅ 使用
process.env.API_KEY,在.env.example中记录
- ✅ 使用
- ❌ 工具处理程序中无错误处理
- ✅ 包装在 try/catch 中,失败时返回
error()
- ✅ 包装在 try/catch 中,失败时返回
- ❌ 没有缓存的昂贵操作
- ✅ 缓存 API 调用、计算,并设置 TTL
- ❌ 缺少 CORS 配置
- ✅ 为生产部署配置 CORS
🔒 黄金法则
架构设计指导原则:
1. 一个工具 = 一项能力
将宽泛的操作拆分为专注的工具:
- ❌
manage-users(过于模糊) - ✅
create-user、delete-user、list-users
2. 预先返回完整数据
工具调用成本高。避免延迟加载:
- ❌
list-products+get-product-details(2 次调用) - ✅
list-products返回包含详细信息的完整数据
3. 小部件拥有自己的状态
UI 状态存在于小部件中,而不是单独的工具中:
- ❌
select-item工具、set-filter工具 - ✅ 小部件使用
useState或setState进行管理
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:从模式变量推断属性类型
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: "我的服务器",
version: "1.0.0"
});
server.tool(
{
name: "greet",
description: "问候用户",
schema: z.object({ name: z.string().describe("用户的名字") })
},
async ({ name }) => text("你好 " + name + "!"),
);
server.listen();
响应辅助函数
| 辅助函数 | 何时使用 | 示例 |
|---|---|---|
text() |
简单字符串响应 | text("成功!") |
object() |
结构化数据 | object({ status: "ok" }) |
markdown() |
格式化文本 | markdown("# 标题\n内容") |
widget() |
可视化 UI | widget({ props: {...}, output: text(...) }) |
mix() |
多个内容 | mix(text("你好"), image(url)) |
error() |
错误响应 | error("获取数据失败") |
resource() |
嵌入资源引用 | resource("docs://guide", "text/markdown") |
服务器方法:
server.tool()– 定义可执行的工具server.resource()– 定义静态/动态资源server.resourceTemplate()– 定义参数化资源server.prompt()– 定义提示模板server.proxy()– 组合/代理多个 MCP 服务器server.uiResource()– 定义小部件资源server.listen()– 启动服务器
📄 原始文档
完整文档(英文):
https://skills.sh/mcp-use/mcp-use/mcp-apps-builder
💡 提示:点击上方链接查看 skills.sh 原始英文文档,方便对照翻译。

评论(0)