[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EWJ4WQFEDXAEJHTXNS47YN":3,"skill-same:01M6EWJ4WQFEDXAEJHTXNS47YN":159},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":47,"linkOnly":48,"markdownContent":49,"markdownBody":50,"frontMatter":51,"refName":52,"commitSha":53,"skillDirectory":54,"forksCount":55,"repositoryHtmlUrl":56,"repositoryHomepageUrl":57,"ownerHtmlUrl":58,"ownerBlogUrl":6,"ownerDescription":59,"updatedAt":60,"install":61,"resources":74},"01M6EWJ4WQFEDXAEJHTXNS47YN","mcp-apps-builder",null,"**MANDATORY for ALL MCP server work** - mcp-use framework best practices and patterns.\n\n**READ THIS FIRST** before any MCP server work, including:\n- Creating new MCP servers\n- Modifying existing MCP servers (adding\u002Fupdating tools, resources, prompts, widgets)\n- Debugging MCP server issues or errors\n- Reviewing MCP server code for quality, security, or performance\n- Answering questions about MCP development or mcp-use patterns\n- Making ANY changes to server.tool(), server.resource(), server.prompt(), or widgets\n\nThis skill contains critical architecture decisions, security patterns, and common pitfalls.\nAlways consult the relevant reference files BEFORE implementing MCP features.","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],"mcp apps builder","apps","builder","MCP","work","common pitfalls","relevant","resources","critical","widgets","files","common","consult","server","issues","code","debugging","architecture","mcp server","performance","2026-11-10 10:12:30",false,"---\nname: mcp-apps-builder\ndescription: |\n  **MANDATORY for ALL MCP server work** - mcp-use framework best practices and patterns.\n\n  **READ THIS FIRST** before any MCP server work, including:\n  - Creating new MCP servers\n  - Modifying existing MCP servers (adding\u002Fupdating tools, resources, prompts, widgets)\n  - Debugging MCP server issues or errors\n  - Reviewing MCP server code for quality, security, or performance\n  - Answering questions about MCP development or mcp-use patterns\n  - Making ANY changes to server.tool(), server.resource(), server.prompt(), or widgets\n\n  This skill contains critical architecture decisions, security patterns, and common pitfalls.\n  Always consult the relevant reference files BEFORE implementing MCP features.\n---\n\n# IMPORTANT: How to Use This Skill\n\nThis file provides a NAVIGATION GUIDE ONLY. Before implementing any MCP server features, you MUST:\n\n1. Read this overview to understand which reference files are relevant\n2. **ALWAYS read the specific reference file(s)** for the features you're implementing\n3. Apply the detailed patterns from those files to your implementation\n\n**Do NOT rely solely on the quick reference examples in this file** - they are minimal examples only. The reference files contain critical best practices, security considerations, and advanced patterns.\n\n---\n\n# MCP Server Best Practices\n\nComprehensive guide for building production-ready MCP servers with tools, resources, prompts, and widgets using mcp-use.\n\n## ⚠️ FIRST: New Project or Existing Project?\n\n**Before doing anything else, determine whether you are inside an existing mcp-use project.**\n\n**Detection:** Check the workspace for a `package.json` that lists `\"mcp-use\"` as a dependency, OR any `.ts` file that imports from `\"mcp-use\u002Fserver\"`.\n\n```\n├─ mcp-use project FOUND → Do NOT scaffold. You are already in a project.\n│  └─ Skip to \"Quick Navigation\" below to add features.\n│\n├─ NO mcp-use project (empty dir, unrelated project, or greenfield)\n│  └─ Scaffold first with npx create-mcp-use-app, then add features.\n│     See \"Scaffolding a New Project\" below.\n│\n└─ Inside an UNRELATED project (e.g. Next.js app) and user wants an MCP server\n   └─ Ask the user where to create it, then scaffold in that directory.\n      Do NOT scaffold inside an existing unrelated project root.\n```\n\n**NEVER manually create `MCPServer` boilerplate, `package.json`, or project structure by hand.** The CLI sets up TypeScript config, dev scripts, inspector integration, hot reload, and widget compilation that are difficult to replicate manually.\n\n---\n\n### Scaffolding a New Project\n\n```bash\nnpx create-mcp-use-app my-server\ncd my-server\nnpm run dev\n```\n\nFor full scaffolding details and CLI flags, see **[quickstart.md](references\u002Ffoundations\u002Fquickstart.md)**.\n\n---\n\n## Quick Navigation\n\n**Choose your path based on what you're building:**\n\n### ? Foundations\n**When:** ALWAYS read these first when starting MCP work in a new conversation. Reference later for architecture\u002Fconcept clarification.\n\n1. **[concepts.md](references\u002Ffoundations\u002Fconcepts.md)** - MCP primitives (Tool, Resource, Prompt, Widget) and when to use each\n2. **[architecture.md](references\u002Ffoundations\u002Farchitecture.md)** - Server structure (Hono-based), middleware system, server.use() vs server.app\n3. **[quickstart.md](references\u002Ffoundations\u002Fquickstart.md)** - Scaffolding, setup, and first tool example\n4. **[deployment.md](references\u002Ffoundations\u002Fdeployment.md)** - Deploying to Manufact Cloud, self-hosting, Docker, managing deployments\n\nLoad these before diving into tools\u002Fresources\u002Fwidgets sections.\n\n---\n\n### ? Adding Authentication?\n**When:** Protecting your server with OAuth (WorkOS, Supabase, or custom)\n\n- **[overview.md](references\u002Fauthentication\u002Foverview.md)**\n  - When: First time adding auth, understanding `ctx.auth`, or choosing a provider\n  - Covers: `oauth` config, user context shape, provider comparison, common mistakes\n\n- **[workos.md](references\u002Fauthentication\u002Fworkos.md)**\n  - When: Using WorkOS AuthKit for authentication\n  - Covers: Setup, env vars, DCR vs pre-registered, roles\u002Fpermissions, WorkOS API calls\n\n- **[supabase.md](references\u002Fauthentication\u002Fsupabase.md)**\n  - When: Using Supabase for authentication\n  - Covers: Setup, env vars, HS256 vs ES256, RLS-aware API calls\n\n- **[custom.md](references\u002Fauthentication\u002Fcustom.md)**\n  - When: Using any other identity provider (GitHub, Okta, Azure AD, Google, etc.)\n  - Covers: Custom verification, user info extraction, provider examples\n\n---\n\n### ? Building Server Backend (No UI)?\n**When:** Implementing MCP features (actions, data, templates). Read the specific file for the primitive you're building.\n\n- **[tools.md](references\u002Fserver\u002Ftools.md)**\n  - When: Creating backend actions the AI can call (send-email, fetch-data, create-user)\n  - Covers: Tool definition, schemas, annotations, context, error handling\n\n- **[resources.md](references\u002Fserver\u002Fresources.md)**\n  - When: Exposing read-only data clients can fetch (config, user profiles, documentation)\n  - Covers: Static resources, dynamic resources, parameterized resource templates, URI completion\n\n- **[prompts.md](references\u002Fserver\u002Fprompts.md)**\n  - When: Creating reusable message templates for AI interactions (code-review, summarize)\n  - Covers: Prompt definition, parameterization, argument completion, prompt best practices\n\n- **[response-helpers.md](references\u002Fserver\u002Fresponse-helpers.md)**\n  - When: Formatting responses from tools\u002Fresources (text, JSON, markdown, images, errors)\n  - Covers: `text()`, `object()`, `markdown()`, `image()`, `error()`, `mix()`\n\n---\n\n### ? Building Visual Widgets (Interactive UI)?\n**When:** Creating React-based visual interfaces for browsing, comparing, or selecting data\n\n- **[basics.md](references\u002Fwidgets\u002Fbasics.md)**\n  - When: Creating your first widget or adding UI to an existing tool\n  - Covers: Widget setup, `useWidget()` hook, `isPending` checks, props handling\n\n- **[state.md](references\u002Fwidgets\u002Fstate.md)**\n  - When: Managing UI state (selections, filters, tabs) within widgets\n  - Covers: `useState`, `setState`, state persistence, when to use tool vs widget state\n\n- **[interactivity.md](references\u002Fwidgets\u002Finteractivity.md)**\n  - When: Adding buttons, forms, or calling tools from within widgets\n  - Covers: `useCallTool()`, form handling, action buttons, optimistic updates\n\n- **[ui-guidelines.md](references\u002Fwidgets\u002Fui-guidelines.md)**\n  - When: Styling widgets to support themes, responsive layouts, or accessibility\n  - Covers: `useWidgetTheme()`, light\u002Fdark mode, `autoSize`, layout patterns, CSS best practices\n\n- **[advanced.md](references\u002Fwidgets\u002Fadvanced.md)**\n  - When: Building complex widgets with async data, error boundaries, or performance optimizations\n  - Covers: Loading states, error handling, memoization, code splitting\n\n---\n\n### ? Need Complete Examples?\n**When:** You want to see full implementations of common use cases\n\n- **[common-patterns.md](references\u002Fpatterns\u002Fcommon-patterns.md)**\n  - End-to-end examples: weather app, todo list, recipe browser\n  - Shows: Server code + widget code + best practices in context\n\n---\n\n## Decision Tree\n\n```\nWhat do you need?\n\n├─ New project from scratch\n│  └─> quickstart.md (scaffolding + setup)\n│\n├─ OAuth \u002F user authentication\n│  └─> authentication\u002Foverview.md → provider-specific guide\n│\n├─ Simple backend action (no UI)\n│  └─> Use Tool: server\u002Ftools.md\n│\n├─ Read-only data for clients\n│  └─> Use Resource: server\u002Fresources.md\n│\n├─ Reusable prompt template\n│  └─> Use Prompt: server\u002Fprompts.md\n│\n├─ Visual\u002Finteractive UI\n│  └─> Use Widget: widgets\u002Fbasics.md\n│\n└─ Deploy to production\n   └─> deployment.md (cloud deploy, self-hosting, Docker)\n```\n\n---\n\n## Core Principles\n\n1. **Tools for actions** - Backend operations with input\u002Foutput\n2. **Resources for data** - Read-only data clients can fetch\n3. **Prompts for templates** - Reusable message templates\n4. **Widgets for UI** - Visual interfaces when helpful\n5. **Mock data first** - Prototype quickly, connect APIs later\n\n---\n\n## ❌ Common Mistakes\n\nAvoid these anti-patterns found in production MCP servers:\n\n### Tool Definition\n- ❌ Returning raw objects instead of using response helpers\n  - ✅ Use `text()`, `object()`, `widget()`, `error()` helpers\n- ❌ Skipping Zod schema `.describe()` on every field\n  - ✅ Add descriptions to all schema fields for better AI understanding\n- ❌ No input validation or sanitization\n  - ✅ Validate inputs with Zod, sanitize user-provided data\n- ❌ Throwing errors instead of returning `error()` helper\n  - ✅ Use `error(\"message\")` for graceful error responses\n\n### Widget Development\n- ❌ Accessing `props` without checking `isPending`\n  - ✅ Always check `if (isPending) return \u003CLoading\u002F>`\n- ❌ Widget handles server state (filters, selections)\n  - ✅ Widgets manage their own UI state with `useState`\n- ❌ Missing `McpUseProvider` wrapper or `autoSize`\n  - ✅ Wrap root component: `\u003CMcpUseProvider autoSize>`\n- ❌ Inline styles without theme awareness\n  - ✅ Use `useWidgetTheme()` for light\u002Fdark mode support\n\n### Security & Production\n- ❌ Hardcoded API keys or secrets in code\n  - ✅ Use `process.env.API_KEY`, document in `.env.example`\n- ❌ No error handling in tool handlers\n  - ✅ Wrap in try\u002Fcatch, return `error()` on failure\n- ❌ Expensive operations without caching\n  - ✅ Cache API calls, computations with TTL\n- ❌ Missing CORS configuration\n  - ✅ Configure CORS for production deployments\n\n---\n\n## ? Golden Rules\n\n**Opinionated architectural guidelines:**\n\n### 1. One Tool = One Capability\nSplit broad actions into focused tools:\n- ❌ `manage-users` (too vague)\n- ✅ `create-user`, `delete-user`, `list-users`\n\n### 2. Return Complete Data Upfront\nTool calls are expensive. Avoid lazy-loading:\n- ❌ `list-products` + `get-product-details` (2 calls)\n- ✅ `list-products` returns full data including details\n\n### 3. Widgets Own Their State\nUI state lives in the widget, not in separate tools:\n- ❌ `select-item` tool, `set-filter` tool\n- ✅ Widget manages with `useState` or `setState`\n\n### 4. `exposeAsTool` Defaults to `false`\nWidgets are registered as resources only by default. Use a custom tool (recommended) or set `exposeAsTool: true` to expose a widget to the model:\n\n```typescript\n\u002F\u002F ✅ ALL 4 STEPS REQUIRED for proper type inference:\n\n\u002F\u002F Step 1: Define schema separately\nconst propsSchema = z.object({\n  title: z.string(),\n  items: z.array(z.string())\n});\n\n\u002F\u002F Step 2: Reference schema variable in metadata\nexport const widgetMetadata: WidgetMetadata = {\n  description: \"...\",\n  props: propsSchema,  \u002F\u002F ← NOT inline z.object()\n  exposeAsTool: false\n};\n\n\u002F\u002F Step 3: Infer Props type from schema variable\ntype Props = z.infer\u003Ctypeof propsSchema>;\n\n\u002F\u002F Step 4: Use typed Props with useWidget\nexport default function MyWidget() {\n  const { props, isPending } = useWidget\u003CProps>();  \u002F\u002F ← Add \u003CProps>\n  \u002F\u002F ...\n}\n```\n\n⚠️ **Common mistake:** Only doing steps 1-2 but skipping 3-4 (loses type safety)\n\n### 5. Validate at Boundaries Only\n- Trust internal code and framework guarantees\n- Validate user input, external API responses\n- Don't add error handling for scenarios that can't happen\n\n### 6. Prefer Widgets for Browsing\u002FComparing\nWhen in doubt, add a widget. Visual UI improves:\n- Browsing multiple items\n- Comparing data side-by-side\n- Interactive selection workflows\n\n---\n\n## Quick Reference\n\n### Minimal Server\n```typescript\nimport { MCPServer, text } from \"mcp-use\u002Fserver\";\nimport { z } from \"zod\";\n\nconst server = new MCPServer({\n  name: \"my-server\",\n  title: \"My Server\",\n  version: \"1.0.0\"\n});\n\nserver.tool(\n  {\n    name: \"greet\",\n    description: \"Greet a user\",\n    schema: z.object({ name: z.string().describe(\"User's name\") })\n  },\n  async ({ name }) => text(\"Hello \" + name + \"!\"),\n);\n\nserver.listen();\n```\n\n---\n\n## Response Helpers\n\n| Helper | Use When | Example |\n|--------|----------|---------|\n| `text()` | Simple string response | `text(\"Success!\")` |\n| `object()` | Structured data | `object({ status: \"ok\" })` |\n| `markdown()` | Formatted text | `markdown(\"# Title\\nContent\")` |\n| `widget()` | Visual UI | `widget({ props: {...}, output: text(...) })` |\n| `mix()` | Multiple contents | `mix(text(\"Hi\"), image(url))` |\n| `error()` | Error responses | `error(\"Failed to fetch data\")` |\n| `resource()` | Embed resource refs | `resource(\"docs:\u002F\u002Fguide\", \"text\u002Fmarkdown\")` |\n\n","# IMPORTANT: How to Use This Skill\n\nThis file provides a NAVIGATION GUIDE ONLY. Before implementing any MCP server features, you MUST:\n\n1. Read this overview to understand which reference files are relevant\n2. **ALWAYS read the specific reference file(s)** for the features you're implementing\n3. Apply the detailed patterns from those files to your implementation\n\n**Do NOT rely solely on the quick reference examples in this file** - they are minimal examples only. The reference files contain critical best practices, security considerations, and advanced patterns.\n\n---\n\n# MCP Server Best Practices\n\nComprehensive guide for building production-ready MCP servers with tools, resources, prompts, and widgets using mcp-use.\n\n## ⚠️ FIRST: New Project or Existing Project?\n\n**Before doing anything else, determine whether you are inside an existing mcp-use project.**\n\n**Detection:** Check the workspace for a `package.json` that lists `\"mcp-use\"` as a dependency, OR any `.ts` file that imports from `\"mcp-use\u002Fserver\"`.\n\n```\n├─ mcp-use project FOUND → Do NOT scaffold. You are already in a project.\n│  └─ Skip to \"Quick Navigation\" below to add features.\n│\n├─ NO mcp-use project (empty dir, unrelated project, or greenfield)\n│  └─ Scaffold first with npx create-mcp-use-app, then add features.\n│     See \"Scaffolding a New Project\" below.\n│\n└─ Inside an UNRELATED project (e.g. Next.js app) and user wants an MCP server\n   └─ Ask the user where to create it, then scaffold in that directory.\n      Do NOT scaffold inside an existing unrelated project root.\n```\n\n**NEVER manually create `MCPServer` boilerplate, `package.json`, or project structure by hand.** The CLI sets up TypeScript config, dev scripts, inspector integration, hot reload, and widget compilation that are difficult to replicate manually.\n\n---\n\n### Scaffolding a New Project\n\n```bash\nnpx create-mcp-use-app my-server\ncd my-server\nnpm run dev\n```\n\nFor full scaffolding details and CLI flags, see **[quickstart.md](references\u002Ffoundations\u002Fquickstart.md)**.\n\n---\n\n## Quick Navigation\n\n**Choose your path based on what you're building:**\n\n### ? Foundations\n**When:** ALWAYS read these first when starting MCP work in a new conversation. Reference later for architecture\u002Fconcept clarification.\n\n1. **[concepts.md](references\u002Ffoundations\u002Fconcepts.md)** - MCP primitives (Tool, Resource, Prompt, Widget) and when to use each\n2. **[architecture.md](references\u002Ffoundations\u002Farchitecture.md)** - Server structure (Hono-based), middleware system, server.use() vs server.app\n3. **[quickstart.md](references\u002Ffoundations\u002Fquickstart.md)** - Scaffolding, setup, and first tool example\n4. **[deployment.md](references\u002Ffoundations\u002Fdeployment.md)** - Deploying to Manufact Cloud, self-hosting, Docker, managing deployments\n\nLoad these before diving into tools\u002Fresources\u002Fwidgets sections.\n\n---\n\n### ? Adding Authentication?\n**When:** Protecting your server with OAuth (WorkOS, Supabase, or custom)\n\n- **[overview.md](references\u002Fauthentication\u002Foverview.md)**\n  - When: First time adding auth, understanding `ctx.auth`, or choosing a provider\n  - Covers: `oauth` config, user context shape, provider comparison, common mistakes\n\n- **[workos.md](references\u002Fauthentication\u002Fworkos.md)**\n  - When: Using WorkOS AuthKit for authentication\n  - Covers: Setup, env vars, DCR vs pre-registered, roles\u002Fpermissions, WorkOS API calls\n\n- **[supabase.md](references\u002Fauthentication\u002Fsupabase.md)**\n  - When: Using Supabase for authentication\n  - Covers: Setup, env vars, HS256 vs ES256, RLS-aware API calls\n\n- **[custom.md](references\u002Fauthentication\u002Fcustom.md)**\n  - When: Using any other identity provider (GitHub, Okta, Azure AD, Google, etc.)\n  - Covers: Custom verification, user info extraction, provider examples\n\n---\n\n### ? Building Server Backend (No UI)?\n**When:** Implementing MCP features (actions, data, templates). Read the specific file for the primitive you're building.\n\n- **[tools.md](references\u002Fserver\u002Ftools.md)**\n  - When: Creating backend actions the AI can call (send-email, fetch-data, create-user)\n  - Covers: Tool definition, schemas, annotations, context, error handling\n\n- **[resources.md](references\u002Fserver\u002Fresources.md)**\n  - When: Exposing read-only data clients can fetch (config, user profiles, documentation)\n  - Covers: Static resources, dynamic resources, parameterized resource templates, URI completion\n\n- **[prompts.md](references\u002Fserver\u002Fprompts.md)**\n  - When: Creating reusable message templates for AI interactions (code-review, summarize)\n  - Covers: Prompt definition, parameterization, argument completion, prompt best practices\n\n- **[response-helpers.md](references\u002Fserver\u002Fresponse-helpers.md)**\n  - When: Formatting responses from tools\u002Fresources (text, JSON, markdown, images, errors)\n  - Covers: `text()`, `object()`, `markdown()`, `image()`, `error()`, `mix()`\n\n---\n\n### ? Building Visual Widgets (Interactive UI)?\n**When:** Creating React-based visual interfaces for browsing, comparing, or selecting data\n\n- **[basics.md](references\u002Fwidgets\u002Fbasics.md)**\n  - When: Creating your first widget or adding UI to an existing tool\n  - Covers: Widget setup, `useWidget()` hook, `isPending` checks, props handling\n\n- **[state.md](references\u002Fwidgets\u002Fstate.md)**\n  - When: Managing UI state (selections, filters, tabs) within widgets\n  - Covers: `useState`, `setState`, state persistence, when to use tool vs widget state\n\n- **[interactivity.md](references\u002Fwidgets\u002Finteractivity.md)**\n  - When: Adding buttons, forms, or calling tools from within widgets\n  - Covers: `useCallTool()`, form handling, action buttons, optimistic updates\n\n- **[ui-guidelines.md](references\u002Fwidgets\u002Fui-guidelines.md)**\n  - When: Styling widgets to support themes, responsive layouts, or accessibility\n  - Covers: `useWidgetTheme()`, light\u002Fdark mode, `autoSize`, layout patterns, CSS best practices\n\n- **[advanced.md](references\u002Fwidgets\u002Fadvanced.md)**\n  - When: Building complex widgets with async data, error boundaries, or performance optimizations\n  - Covers: Loading states, error handling, memoization, code splitting\n\n---\n\n### ? Need Complete Examples?\n**When:** You want to see full implementations of common use cases\n\n- **[common-patterns.md](references\u002Fpatterns\u002Fcommon-patterns.md)**\n  - End-to-end examples: weather app, todo list, recipe browser\n  - Shows: Server code + widget code + best practices in context\n\n---\n\n## Decision Tree\n\n```\nWhat do you need?\n\n├─ New project from scratch\n│  └─> quickstart.md (scaffolding + setup)\n│\n├─ OAuth \u002F user authentication\n│  └─> authentication\u002Foverview.md → provider-specific guide\n│\n├─ Simple backend action (no UI)\n│  └─> Use Tool: server\u002Ftools.md\n│\n├─ Read-only data for clients\n│  └─> Use Resource: server\u002Fresources.md\n│\n├─ Reusable prompt template\n│  └─> Use Prompt: server\u002Fprompts.md\n│\n├─ Visual\u002Finteractive UI\n│  └─> Use Widget: widgets\u002Fbasics.md\n│\n└─ Deploy to production\n   └─> deployment.md (cloud deploy, self-hosting, Docker)\n```\n\n---\n\n## Core Principles\n\n1. **Tools for actions** - Backend operations with input\u002Foutput\n2. **Resources for data** - Read-only data clients can fetch\n3. **Prompts for templates** - Reusable message templates\n4. **Widgets for UI** - Visual interfaces when helpful\n5. **Mock data first** - Prototype quickly, connect APIs later\n\n---\n\n## ❌ Common Mistakes\n\nAvoid these anti-patterns found in production MCP servers:\n\n### Tool Definition\n- ❌ Returning raw objects instead of using response helpers\n  - ✅ Use `text()`, `object()`, `widget()`, `error()` helpers\n- ❌ Skipping Zod schema `.describe()` on every field\n  - ✅ Add descriptions to all schema fields for better AI understanding\n- ❌ No input validation or sanitization\n  - ✅ Validate inputs with Zod, sanitize user-provided data\n- ❌ Throwing errors instead of returning `error()` helper\n  - ✅ Use `error(\"message\")` for graceful error responses\n\n### Widget Development\n- ❌ Accessing `props` without checking `isPending`\n  - ✅ Always check `if (isPending) return \u003CLoading\u002F>`\n- ❌ Widget handles server state (filters, selections)\n  - ✅ Widgets manage their own UI state with `useState`\n- ❌ Missing `McpUseProvider` wrapper or `autoSize`\n  - ✅ Wrap root component: `\u003CMcpUseProvider autoSize>`\n- ❌ Inline styles without theme awareness\n  - ✅ Use `useWidgetTheme()` for light\u002Fdark mode support\n\n### Security & Production\n- ❌ Hardcoded API keys or secrets in code\n  - ✅ Use `process.env.API_KEY`, document in `.env.example`\n- ❌ No error handling in tool handlers\n  - ✅ Wrap in try\u002Fcatch, return `error()` on failure\n- ❌ Expensive operations without caching\n  - ✅ Cache API calls, computations with TTL\n- ❌ Missing CORS configuration\n  - ✅ Configure CORS for production deployments\n\n---\n\n## ? Golden Rules\n\n**Opinionated architectural guidelines:**\n\n### 1. One Tool = One Capability\nSplit broad actions into focused tools:\n- ❌ `manage-users` (too vague)\n- ✅ `create-user`, `delete-user`, `list-users`\n\n### 2. Return Complete Data Upfront\nTool calls are expensive. Avoid lazy-loading:\n- ❌ `list-products` + `get-product-details` (2 calls)\n- ✅ `list-products` returns full data including details\n\n### 3. Widgets Own Their State\nUI state lives in the widget, not in separate tools:\n- ❌ `select-item` tool, `set-filter` tool\n- ✅ Widget manages with `useState` or `setState`\n\n### 4. `exposeAsTool` Defaults to `false`\nWidgets are registered as resources only by default. Use a custom tool (recommended) or set `exposeAsTool: true` to expose a widget to the model:\n\n```typescript\n\u002F\u002F ✅ ALL 4 STEPS REQUIRED for proper type inference:\n\n\u002F\u002F Step 1: Define schema separately\nconst propsSchema = z.object({\n  title: z.string(),\n  items: z.array(z.string())\n});\n\n\u002F\u002F Step 2: Reference schema variable in metadata\nexport const widgetMetadata: WidgetMetadata = {\n  description: \"...\",\n  props: propsSchema,  \u002F\u002F ← NOT inline z.object()\n  exposeAsTool: false\n};\n\n\u002F\u002F Step 3: Infer Props type from schema variable\ntype Props = z.infer\u003Ctypeof propsSchema>;\n\n\u002F\u002F Step 4: Use typed Props with useWidget\nexport default function MyWidget() {\n  const { props, isPending } = useWidget\u003CProps>();  \u002F\u002F ← Add \u003CProps>\n  \u002F\u002F ...\n}\n```\n\n⚠️ **Common mistake:** Only doing steps 1-2 but skipping 3-4 (loses type safety)\n\n### 5. Validate at Boundaries Only\n- Trust internal code and framework guarantees\n- Validate user input, external API responses\n- Don't add error handling for scenarios that can't happen\n\n### 6. Prefer Widgets for Browsing\u002FComparing\nWhen in doubt, add a widget. Visual UI improves:\n- Browsing multiple items\n- Comparing data side-by-side\n- Interactive selection workflows\n\n---\n\n## Quick Reference\n\n### Minimal Server\n```typescript\nimport { MCPServer, text } from \"mcp-use\u002Fserver\";\nimport { z } from \"zod\";\n\nconst server = new MCPServer({\n  name: \"my-server\",\n  title: \"My Server\",\n  version: \"1.0.0\"\n});\n\nserver.tool(\n  {\n    name: \"greet\",\n    description: \"Greet a user\",\n    schema: z.object({ name: z.string().describe(\"User's name\") })\n  },\n  async ({ name }) => text(\"Hello \" + name + \"!\"),\n);\n\nserver.listen();\n```\n\n---\n\n## Response Helpers\n\n| Helper | Use When | Example |\n|--------|----------|---------|\n| `text()` | Simple string response | `text(\"Success!\")` |\n| `object()` | Structured data | `object({ status: \"ok\" })` |\n| `markdown()` | Formatted text | `markdown(\"# Title\\nContent\")` |\n| `widget()` | Visual UI | `widget({ props: {...}, output: text(...) })` |\n| `mix()` | Multiple contents | `mix(text(\"Hi\"), image(url))` |\n| `error()` | Error responses | `error(\"Failed to fetch data\")` |\n| `resource()` | Embed resource refs | `resource(\"docs:\u002F\u002Fguide\", \"text\u002Fmarkdown\")` |\n\n",{"name":5,"description":7},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":62,"prompt":72,"zipAvailable":73},[63,66,69],{"tool":64,"command":65},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill mcp-apps-builder",{"tool":67,"command":68},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill mcp-apps-builder",{"tool":70,"command":71},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill mcp-apps-builder","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002FSKILL.md",true,[75,81,87,91,95,99,103,107,111,115,119,123,127,131,135,139,143,147,151,155],{"path":76,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":79,"sourceHtmlUrl":80},"LICENSE.txt","LICENSE","许可证",9164,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002FLICENSE.txt",{"path":82,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":85,"sourceHtmlUrl":86},"references\u002Fauthentication\u002Fcustom.md","REFERENCE","参考文档",6557,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Fauthentication\u002Fcustom.md",{"path":88,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":89,"sourceHtmlUrl":90},"references\u002Fauthentication\u002Foverview.md",6594,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Fauthentication\u002Foverview.md",{"path":92,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":93,"sourceHtmlUrl":94},"references\u002Fauthentication\u002Fsupabase.md",5149,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Fauthentication\u002Fsupabase.md",{"path":96,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":97,"sourceHtmlUrl":98},"references\u002Fauthentication\u002Fworkos.md",6232,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Fauthentication\u002Fworkos.md",{"path":100,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":101,"sourceHtmlUrl":102},"references\u002Ffoundations\u002Farchitecture.md",6745,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Ffoundations\u002Farchitecture.md",{"path":104,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":105,"sourceHtmlUrl":106},"references\u002Ffoundations\u002Fconcepts.md",3395,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Ffoundations\u002Fconcepts.md",{"path":108,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":109,"sourceHtmlUrl":110},"references\u002Ffoundations\u002Fdeployment.md",2695,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Ffoundations\u002Fdeployment.md",{"path":112,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":113,"sourceHtmlUrl":114},"references\u002Ffoundations\u002Fquickstart.md",6155,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Ffoundations\u002Fquickstart.md",{"path":116,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":117,"sourceHtmlUrl":118},"references\u002Fpatterns\u002Fcommon-patterns.md",21203,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Fpatterns\u002Fcommon-patterns.md",{"path":120,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":121,"sourceHtmlUrl":122},"references\u002Fserver\u002Fprompts.md",16730,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Fserver\u002Fprompts.md",{"path":124,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":125,"sourceHtmlUrl":126},"references\u002Fserver\u002Fresources.md",11592,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Fserver\u002Fresources.md",{"path":128,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":129,"sourceHtmlUrl":130},"references\u002Fserver\u002Fresponse-helpers.md",12685,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Fserver\u002Fresponse-helpers.md",{"path":132,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":133,"sourceHtmlUrl":134},"references\u002Fserver\u002Ftools.md",10437,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Fserver\u002Ftools.md",{"path":136,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":137,"sourceHtmlUrl":138},"references\u002Fwidgets\u002Fadvanced.md",19955,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Fwidgets\u002Fadvanced.md",{"path":140,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":141,"sourceHtmlUrl":142},"references\u002Fwidgets\u002Fbasics.md",18605,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Fwidgets\u002Fbasics.md",{"path":144,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":145,"sourceHtmlUrl":146},"references\u002Fwidgets\u002Finteractivity.md",22793,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Fwidgets\u002Finteractivity.md",{"path":148,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":149,"sourceHtmlUrl":150},"references\u002Fwidgets\u002Fstate.md",15923,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Fwidgets\u002Fstate.md",{"path":152,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":153,"sourceHtmlUrl":154},"references\u002Fwidgets\u002Fui-guidelines.md",15818,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Freferences\u002Fwidgets\u002Fui-guidelines.md",{"path":156,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":157,"sourceHtmlUrl":158},"skill-report.json",14271,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fmcp-use\u002Fmcp-apps-builder\u002Fskill-report.json",[160,170,179,187,193,200],{"skillNo":161,"name":162,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":163,"categories":164,"keywords":166,"publishedAt":47},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[165],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[167,168,169],"model","model hierarchy","model hierarchy skill",{"skillNo":171,"name":172,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":173,"categories":174,"keywords":176,"publishedAt":47},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[175],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[30,177,178],"zoom","zoom mcp",{"skillNo":180,"name":181,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":182,"categories":183,"keywords":184,"publishedAt":47},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[185,186,28,177],"sdk","zoom apps sdk",{"skillNo":188,"name":189,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":190,"categories":191,"keywords":192,"publishedAt":47},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[189],{"skillNo":194,"name":195,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":196,"categories":197,"keywords":199,"publishedAt":47},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[198],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[195],{"skillNo":201,"name":202,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":203,"categories":204,"keywords":205,"publishedAt":47},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[202]]