关于 mcp-builder
mcp-builder 是面向使用 mcp-use 框架创建 MCP 服务的开发者技能,涵盖项目初始化、服务端原语、组件、测试与部署,并提供模板和实践模式。
主要功能
- 01使用模板初始化项目
- 02定义工具、资源和提示词
- 03自动注册 React 组件
- 04通过 Inspector 和隧道测试
- 05构建并部署服务
适用场景
- 01从模板启动 MCP 服务
- 02添加 MCP 工具和资源
- 03创建交互式组件应用
- 04通过 MCP 客户端测试服务
MCP 相关
该技能指导开发者创建向 MCP 客户端提供工具、资源、提示词和组件资源的 MCP 服务,也介绍通过隧道使用客户端进行测试。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mcp-use/ skills --skill mcp-builder安装后在 Claude Code 中输入/mcp-builder确认已加载。
附带文件LICENSE.txt
详细介绍
MCP 服务构建器
使用 mcp-use 框架构建可用于生产环境的 MCP 服务。本 Skill 提供创建 MCP 服务的快速入门说明和最佳实践。
快速入门
始终使用 npx create-mcp-use-app 进行初始化:
npx create-mcp-use-app my-mcp-server
cd my-mcp-server
根据需求选择模板:
--template starter- 功能齐全,包含所有 MCP 基元(工具、资源、提示词)和示例小组件--template mcp-apps- 针对 ChatGPT 小组件进行了优化,包含商品搜索示例--template blank- 为自定义实现提供最简起点
# Example: MCP Apps template
npx create-mcp-use-app my-server --template mcp-apps
cd my-server
yarn install
模板详情:
- starter:最适合学习——包含所有 MCP 功能和小组件
- mcp-apps:最适合 ChatGPT 应用——包含商品轮播图/手风琴示例
- blank:最适合专家——仅包含最少的样板代码
MCP Apps 结构
自动注册小组件
mcp-apps 和 starter 模板会自动发现并注册 resources/ 文件夹中的 React 小组件:
单文件小组件模式:
resources/
└── weather-display.tsx # Widget name becomes "weather-display"
基于文件夹的小组件模式:
resources/
└── product-search/ # Widget name becomes "product-search"
├── widget.tsx # Entry point (required name!)
├── components/ # Sub-components
├── hooks/ # Custom hooks
├── types.ts
└── constants.ts
自动执行的操作:
- 服务启动时扫描
resources/文件夹 - 查找
.tsx文件或文件夹中的widget.tsx - 从每个组件中提取
widgetMetadata - 注册为 MCP Tool(例如
weather-display) - 注册为 MCP Resource(例如
ui://widget/weather-display.html) - 使用 Vite 构建小组件包
无需手动注册! 只需导出 widgetMetadata 和一个默认组件。
定义工具
工具是 AI 模型可以调用的可执行函数:
import { MCPServer, text, object } from "mcp-use/server";
import { z } from "zod";
const server = new MCPServer({
name: "my-server",
version: "1.0.0",
description: "My MCP server"
});
// Simple tool
server.tool(
{
name: "greet-user",
description: "Greet a user by name",
schema: z.object({
name: z.string().describe("The user's name"),
formal: z.boolean().optional().describe("Use formal greeting")
})
},
async ({ name, formal }) => {
const greeting = formal ? `Good day, ${name}` : `Hey ${name}!`;
return text(greeting);
}
);
要点:
- 使用 Zod 验证架构
- 为所有参数添加
.describe() - 返回适当的响应类型(文本、对象、小组件)
定义资源
资源提供客户端可读取的数据:
import { object, text, markdown } from "mcp-use/server";
// Static resource
server.resource(
{
uri: "config://settings",
name: "Application Settings",
description: "Current configuration",
mimeType: "application/json"
},
async () => {
return object({
theme: "dark",
version: "1.0.0"
});
}
);
// Dynamic resource
server.resource(
{
uri: "stats://current",
name: "Current Stats",
description: "Real-time statistics",
mimeType: "application/json"
},
async () => {
const stats = await getStats();
return object(stats);
}
);
// Markdown resource
server.resource(
{
uri: "docs://guide",
name: "User Guide",
description: "Documentation",
mimeType: "text/markdown"
},
async () => {
return markdown("# Guide\n\nWelcome!");
}
);
可用的响应辅助函数:
text(string)- 纯文本object(data)- JSON 对象markdown(string)- Markdown 内容html(string)- HTML 内容image(buffer, mimeType)- 二进制图像audio(buffer, mimeType)- 音频文件binary(buffer, mimeType)- 二进制数据mix(...contents)- 组合多种内容类型
高级响应示例:
// Audio response
import { audio } from 'mcp-use/server';
// From base64 data
return audio(base64Data, "audio/wav");
// From file path (async)
return await audio("/path/to/audio.mp3");
// Binary data (PDFs, etc.)
import { binary } from 'mcp-use/server';
return binary(pdfBuffer, "application/pdf");
// Mix multiple content types
import { mix, text, object, resource } from 'mcp-use/server';
return mix(
text("Analysis complete:"),
object({ score: 95, status: "pass" }),
resource("report://analysis-123", text("Full report..."))
);
定义提示词
提示词是可重复使用的 AI 交互模板:
server.prompt(
{
name: "code-review",
description: "Generate a code review template",
schema: z.object({
language: z.string().describe("Programming language"),
focusArea: z.string().optional().describe("Specific focus area")
})
},
async ({ language, focusArea }) => {
const focus = focusArea ? ` with focus on ${focusArea}` : "";
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `Please review this ${language} code${focus}.`
}
}
]
};
}
);
本地测试
开发模式(热重载):
yarn dev
生产模式:
yarn build
yarn start
检查器 UI:
访问 http://localhost:3000/inspector,即可测试工具、查看资源并试用提示词。
建立隧道(部署前使用 ChatGPT 测试):
选项 1 - 自动建立隧道:
mcp-use start --port 3000 --tunnel
选项 2 - 单独建立隧道:
yarn start # Terminal 1
npx @mcp-use/tunnel 3000 # Terminal 2
你会获得一个公共 URL,例如 https://happy-cat.local.mcp-use.run/mcp
隧道详情:
- 24 小时后过期
- 闲置 1 小时后关闭
- 速率限制:每小时创建 10 个,每个 IP 最多同时启用 5 个
了解更多:https://mcp-use.com/docs/tunneling
部署
部署到 mcp-use Cloud(推荐):
# Login first (if not already)
npx mcp-use login
# Deploy
yarn deploy
如果出现身份验证错误:
npx mcp-use login
yarn deploy
部署后:
- 提供公共 URL(例如
https://your-server.mcp-use.com/mcp) - 自动扩缩容并进行监控
- 已启用 HTTPS
- 部署期间零停机
最佳实践
工具设计:
- ✅ 一个工具 = 一项专注的能力
- ✅ 使用描述清晰的名称和说明
- ✅ 对所有 Zod 字段使用
.describe() - ✅ 妥善处理错误
- ✅ 返回有帮助的错误消息
资源设计:
- ✅ 使用清晰的 URI 方案(config://、docs://、stats://)
- ✅ 选择合适的 MIME 类型
- ✅ 使用响应辅助函数,让代码更简洁
- ✅ 在需要时将资源设为动态资源
提示词设计:
- ✅ 保持提示词可复用
- ✅ 使用系统消息提供上下文
- ✅ 使用 Zod 架构设置参数
- ✅ 包含清晰的说明
测试:
- ✅ 先使用 Inspector UI 进行测试
- ✅ 部署前使用隧道与真实客户端进行测试
- ✅ 确认所有工具、资源和提示词都能按预期工作
部署:
- ✅ 先在本地和通过隧道进行测试
- ✅ 如果部署失败,运行
npx mcp-use login - ✅ 按语义化版本规范管理服务版本
- ✅ 记录不兼容变更
Widget 支持
自动注册 Widget
使用 mcp-apps 或 starter 模板时,resources/ 文件夹中的 Widget 会自动注册:
// resources/weather-display.tsx
import { useWidget, McpUseProvider, type WidgetMetadata } from 'mcp-use/react';
import { z } from 'zod';
const propSchema = z.object({
city: z.string(),
temperature: z.number()
});
// Required: Export widget metadata
export const widgetMetadata: WidgetMetadata = {
description: "Display weather information",
props: propSchema, // Use 'props', not 'schema'!
};
// Required: Export default component
export default function WeatherDisplay() {
const { props, isPending } = useWidget<z.infer<typeof propSchema>>();
// Always handle loading state
if (isPending) return <div>Loading...</div>;
return (
<McpUseProvider autoSize>
<div>
<h2>{props.city}</h2>
<p>{props.temperature}°C</p>
</div>
</McpUseProvider>
);
}
Widget 会自动成为:
- MCP 工具:
weather-display - MCP 资源:
ui://widget/weather-display.html
内容安全策略(CSP)
控制 Widget 可以访问哪些外部资源:
export const widgetMetadata: WidgetMetadata = {
description: "Weather widget",
props: z.object({ city: z.string() }),
metadata: {
csp: {
// APIs to call
connectDomains: ["https://api.weather.com"],
// Static assets to load
resourceDomains: ["https://cdn.weather.com"],
// Iframes to embed
frameDomains: ["https://embed.weather.com"],
// Script directives
scriptDirectives: ["'unsafe-inline'"],
},
},
};
也可以在服务级别设置:
server.uiResource({
type: "mcpApps",
name: "my-widget",
htmlTemplate: `...`,
metadata: {
csp: {
connectDomains: ["https://api.example.com"],
resourceDomains: ["https://cdn.example.com"],
},
},
});
双协议 Widget 支持
mcp-use 支持 MCP Apps 标准(SEP-1865),并自动提供双协议支持:
import { MCPServer } from 'mcp-use/server';
const server = new MCPServer({
name: 'my-server',
version: '1.0.0',
baseUrl: process.env.MCP_URL || 'http://localhost:3000', // Required for widgets
});
// Register a dual-protocol widget
server.uiResource({
type: "mcpApps", // Works with BOTH MCP Apps clients AND ChatGPT
name: "weather-display",
htmlTemplate: `<!DOCTYPE html>...`,
metadata: {
csp: { connectDomains: ["https://api.weather.com"] },
prefersBorder: true,
autoResize: true,
},
});
自动处理内容:
- MCP Apps 客户端(Claude、Goose)接收:
text/html;profile=mcp-app和_meta.ui.* - ChatGPT 接收:
text/html+skybridge和_meta.openai/* - 同一份 Widget 代码可在所有平台上运行!
自定义 OpenAI 元数据
需要 ChatGPT 专属功能?组合使用这两种元数据字段:
server.uiResource({
type: "mcpApps",
name: "my-widget",
htmlTemplate: `...`,
// Unified metadata (dual-protocol)
metadata: {
csp: { connectDomains: ["https://api.example.com"] },
prefersBorder: true,
},
// ChatGPT-specific overrides
appsSdkMetadata: {
"openai/widgetDescription": "ChatGPT-specific description",
"openai/customFeature": "some-value", // Any custom OpenAI metadata
},
});
项目结构
my-mcp-server/
├── resources/ # React widgets (apps-sdk)
│ └── widget.tsx
├── public/ # Static assets
├── index.ts # Server entry point
├── package.json
├── tsconfig.json
└── README.md
常见模式
带双协议 Widget 的工具:
import { MCPServer, widget, text } from 'mcp-use/server';
import { z } from 'zod';
const server = new MCPServer({
name: 'my-server',
version: '1.0.0',
baseUrl: process.env.MCP_URL || 'http://localhost:3000',
});
server.tool(
{
name: "show-data",
description: "Display data with visualization",
schema: z.object({
query: z.string()
}),
widget: {
name: "data-display", // Must exist in resources/
invoking: "Loading...",
invoked: "Data loaded"
}
},
async ({ query }) => {
const data = await fetchData(query);
return widget({
props: { data },
output: text(`Found ${data.length} results`)
});
}
);
资源模板(带参数):
server.resourceTemplate(
{
uriTemplate: "user://{userId}/profile",
name: "User Profile",
description: "Get user by ID",
mimeType: "application/json"
},
async ({ userId }) => {
const user = await fetchUser(userId);
return object(user);
}
);
错误处理:
server.tool(
{
name: "divide",
schema: z.object({
a: z.number(),
b: z.number()
})
},
async ({ a, b }) => {
if (b === 0) {
return text("Error: Cannot divide by zero");
}
return text(`Result: ${a / b}`);
}
);
详细示例
如需全面的示例和高级模式,请连接到 mcp-use MCP 服务,其中提供:
- 涵盖所有原语的完整示例资源
- 完整可运行的服务示例
- 详细文档
- 交互式 Widget 展示
了解更多
- 文档:https://docs.mcp-use.com
- MCP Apps 标准:https://docs.mcp-use.com/typescript/server/mcp-apps(双协议指南)
- 模板:https://docs.mcp-use.com/typescript/server/templates(模板对比)
- Widget 指南:https://docs.mcp-use.com/typescript/server/ui-widgets
- 示例:https://github.com/mcp-use/mcp-use/tree/main/examples
- 隧道指南:https://mcp-use.com/docs/tunneling
- Discord:https://mcp-use.com/discord
- GitHub:https://github.com/mcp-use/mcp-use
快速参考
命令:
npx create-mcp-use-app my-server- 初始化项目yarn dev- 开发模式yarn build- 构建生产版本yarn start- 运行生产服务器mcp-use start --tunnel- 通过隧道启动npx mcp-use login- 验证身份yarn deploy- 部署到云端
响应辅助函数:
text(str)、object(data)、markdown(str)、html(str)image(buf, mime)、audio(buf, mime)、binary(buf, mime)mix(...)- 组合多种内容类型widget({ props, output })- 返回包含数据的 widget
服务方法:
server.tool()- 定义可执行工具server.resource()- 定义静态/动态资源server.resourceTemplate()- 定义参数化资源server.prompt()- 定义提示词模板server.uiResource()- 定义 widget 资源server.listen()- 启动服务
Widget 元数据字段:
description- Widget 描述props- Widget 属性的 Zod 架构metadata- 统一配置(双协议)metadata.csp- 内容安全策略appsSdkMetadata- ChatGPT 专用覆盖项
可用模板:
starter- 功能齐全(工具、资源、提示词、widget)mcp-apps- 针对 ChatGPT 优化,附带产品示例blank- 最简基础模板