NEW Browse AI tools across categories — updated daily. See what's new →

Mcp Builder

Build production-ready MCP servers with the mcp-use framework and automatic widget registration. Bootstrap with npx create-mcp-use-app and choose from three templates: starter (full-featured), mcp-...

Authormcp-use
Version1.0.0
LicenseMIT
Token count~4,137
UpdatedJun 5, 2026

Build production-ready MCP servers with the mcp-use framework and automatic widget registration. Bootstrap with npx create-mcp-use-app and choose from three templates: starter (full-featured), mcp-apps (ChatGPT-optimized), or blank (minimal) Define tools, resources, and prompts using Zod schemas with automatic validation and clear parameter descriptions Automatically register React widgets from the resources/ folder as MCP Tools and Resources with dual-protocol support for MCP Apps and...

Install

Quick install

via npx skills · works with 57+ agents
npx skills add https://github.com/mcp-use/skills/tree/HEAD/skills/mcp-builder
Or pick agent:
npx skills add mcp-use/skills --skill mcp-builder --agent claude-code
npx skills add mcp-use/skills --skill mcp-builder --agent cursor
npx skills add mcp-use/skills --skill mcp-builder --agent codex
npx skills add mcp-use/skills --skill mcp-builder --agent opencode
npx skills add mcp-use/skills --skill mcp-builder --agent github-copilot
npx skills add mcp-use/skills --skill mcp-builder --agent windsurf
More install options

Shorthand — useful for multi-skill repos:

npx skills add mcp-use/skills --skill mcp-builder

Manual — clone the repo and drop the folder into your agent's skills directory:

git clone https://github.com/mcp-use/skills.git
cp -r skills/skills/mcp-builder ~/.claude/skills/
How to use: Once installed, ask your agent to "use the mcp-builder skill" or describe what you want (e.g. "Build production-ready MCP servers with the mcp-use framework and automatic widg"). Requires Node.js 18+.

mcp-builder

Build production-ready MCP servers with the mcp-use framework and automatic widget registration. Bootstrap with npx create-mcp-use-app and choose from three templates: starter (full-featured), mcp-apps (ChatGPT-optimized), or blank (minimal) Define tools, resources, and prompts using Zod schemas with automatic validation and clear parameter descriptions Automatically register React widgets from the resources/ folder as MCP Tools and Resources with dual-protocol support for MCP Apps and...

mcp-builderby mcp-use

Build production-ready MCP servers with the mcp-use framework and automatic widget registration. Bootstrap with npx create-mcp-use-app and choose from three templates: starter (full-featured), mcp-apps (ChatGPT-optimized), or blank (minimal) Define tools, resources, and prompts using Zod schemas with automatic validation and clear parameter descriptions Automatically register React widgets from the resources/ folder as MCP Tools and Resources with dual-protocol support for MCP Apps and...

npx skills add https://github.com/mcp-use/skills --skill mcp-builderDownload ZIPGitHub

MCP Server Builder

Build production-ready MCP servers with the mcp-use framework. This Skill provides quick-start instructions and best practices for creating MCP servers.

Quick Start

Always bootstrap with npx create-mcp-use-app:

`npx create-mcp-use-app my-mcp-server
cd my-mcp-server
`

Choose template based on needs:

  • --template starter - Full-featured with all MCP primitives (tools, resources, prompts) + example widgets
  • --template mcp-apps - Optimized for ChatGPT widgets with product search example
  • --template blank - Minimal starting point for custom implementation
`# Example: MCP Apps template
npx create-mcp-use-app my-server --template mcp-apps
cd my-server
yarn install
`

Template Details:

  • starter: Best for learning - includes all MCP features plus widgets
  • mcp-apps: Best for ChatGPT apps - includes product carousel/accordion example
  • blank: Best for experts - minimal boilerplate

MCP Apps Structure

Automatic Widget Registration

The mcp-apps and starter templates automatically discover and register React widgets from the resources/ folder:

Single-file widget pattern:

`resources/
└── weather-display.tsx # Widget name becomes "weather-display"
`

Folder-based widget pattern:

`resources/
└── product-search/ # Widget name becomes "product-search"
├── widget.tsx # Entry point (required name!)
├── components/ # Sub-components
├── hooks/ # Custom hooks
├── types.ts
└── constants.ts
`

What happens automatically:

  • Server scans resources/ folder at startup
  • Finds .tsx files or widget.tsx in folders
  • Extracts widgetMetadata from each component
  • Registers as MCP Tool (e.g., weather-display)
  • Registers as MCP Resource (e.g., ui://widget/weather-display.html)
  • Builds widget bundles with Vite

No manual registration needed! Just export widgetMetadata and a default component.

Defining Tools

Tools are executable functions that AI models can call:

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

Key points:

  • Use Zod for schema validation
  • Add .describe() to all parameters
  • Return appropriate response types (text, object, widget)

Defining Resources

Resources expose data that clients can read:

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

Response helpers available:

  • text(string) - Plain text
  • object(data) - JSON objects
  • markdown(string) - Markdown content
  • html(string) - HTML content
  • image(buffer, mimeType) - Binary images
  • audio(buffer, mimeType) - Audio files
  • binary(buffer, mimeType) - Binary data
  • mix(...contents) - Combine multiple content types

Advanced response examples:

`// 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..."))
);
`

Defining Prompts

Prompts are reusable templates for AI interactions:

`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}.`
}
}
]
};
}
);
`

Testing Locally

Development mode (hot reload):

`yarn dev
`

Production mode:

`yarn build
yarn start
`

Inspector UI:
Access at http://localhost:3000/inspector to test tools, view resources, and try prompts.

Tunneling (test with ChatGPT before deploying):

Option 1 - Auto-tunnel:

`mcp-use start --port 3000 --tunnel
`

Option 2 - Separate tunnel:

`yarn start # Terminal 1
npx @mcp-use/tunnel 3000 # Terminal 2
`

You'll get a public URL like https://happy-cat.local.mcp-use.run/mcp

Tunnel details:

  • Expires after 24 hours
  • Closes after 1 hour of inactivity
  • Rate limit: 10 creations/hour, max 5 active per IP

Learn more: https://mcp-use.com/docs/tunneling

Deployment

Deploy to mcp-use Cloud (recommended):

`# Login first (if not already)
npx mcp-use login

# Deploy
yarn deploy
`

If authentication error:

`npx mcp-use login
yarn deploy
`

After deployment:

  • Public URL provided (e.g., https://your-server.mcp-use.com/mcp)
  • Auto-scaled and monitored
  • HTTPS enabled
  • Zero-downtime deployments

Best Practices

Tool Design:

  • ✅ One tool = one focused capability
  • ✅ Descriptive names and descriptions
  • ✅ Use .describe() on all Zod fields
  • ✅ Handle errors gracefully
  • ✅ Return helpful error messages

Resource Design:

  • ✅ Use clear URI schemes (config://, docs://, stats://)
  • ✅ Choose appropriate MIME types
  • ✅ Use response helpers for cleaner code
  • ✅ Make resources dynamic when needed

Prompt Design:

  • ✅ Keep prompts reusable
  • ✅ Use system messages for context
  • ✅ Parameterize with Zod schemas
  • ✅ Include clear instructions

Testing:

  • ✅ Test with Inspector UI first
  • ✅ Use tunneling to test with real clients before deploying
  • ✅ Verify all tools, resources, and prompts work as expected

Deployment:

  • ✅ Test locally and with tunneling first
  • ✅ Run npx mcp-use login if deploy fails
  • ✅ Version your server semantically
  • ✅ Document breaking changes

Widget Support

Automatic Widget Registration

When using the mcp-apps or starter template, widgets in the resources/ folder are automatically registered:

`// 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 automatically becomes available as:

  • MCP Tool: weather-display
  • MCP Resource: ui://widget/weather-display.html

Content Security Policy (CSP)

Control what external resources widgets can access:

`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'"],
},
},
};
`

Alternatively, set at server level:

`server.uiResource({
type: "mcpApps",
name: "my-widget",
htmlTemplate: `...`,
metadata: {
csp: {
connectDomains: ["https://api.example.com"],
resourceDomains: ["https://cdn.example.com"],
},
},
});
`

Dual-Protocol Widget Support

mcp-use supports the MCP Apps standard (SEP-1865) with automatic dual-protocol support:

`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,
},
});
`

What happens automatically:

MCP Apps clients (Claude, Goose) receive: text/html;profile=mcp-app with _meta.ui.

ChatGPT receives: text/html+skybridge with _meta.openai/

  • Same widget code works everywhere!

Custom OpenAI Metadata

Need ChatGPT-specific features? Combine both metadata fields:

`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
},
});
`

Project Structure

`my-mcp-server/
├── resources/ # React widgets (apps-sdk)
│ └── widget.tsx
├── public/ # Static assets
├── index.ts # Server entry point
├── package.json
├── tsconfig.json
└── README.md
`

Common Patterns

Tool with dual-protocol 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`)
});
}
);
`

Resource template (parameterized):

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

Error handling:

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

Detailed Examples

For comprehensive examples and advanced patterns, connect to the mcp-use MCP server which provides:

  • Complete example resources for all primitives
  • Full working server examples
  • Detailed documentation
  • Interactive widgets showcase

Learn More

  • Documentation: https://docs.mcp-use.com
  • MCP Apps Standard: https://docs.mcp-use.com/typescript/server/mcp-apps (dual-protocol guide)
  • Templates: https://docs.mcp-use.com/typescript/server/templates (template comparison)
  • Widget Guide: https://docs.mcp-use.com/typescript/server/ui-widgets
  • Examples: https://github.com/mcp-use/mcp-use/tree/main/examples
  • Tunneling Guide: https://mcp-use.com/docs/tunneling
  • Discord: https://mcp-use.com/discord
  • GitHub: https://github.com/mcp-use/mcp-use

Quick Reference

Commands:

  • npx create-mcp-use-app my-server - Bootstrap
  • yarn dev - Development mode
  • yarn build - Build for production
  • yarn start - Run production server
  • mcp-use start --tunnel - Start with tunnel
  • npx mcp-use login - Authenticate
  • yarn deploy - Deploy to cloud

Response helpers:

  • text(str), object(data), markdown(str), html(str)
  • image(buf, mime), audio(buf, mime), binary(buf, mime)
  • mix(...) - Combine multiple content types
  • widget({ props, output }) - Return widget with data

Server methods:

  • server.tool() - Define executable tool
  • server.resource() - Define static/dynamic resource
  • server.resourceTemplate() - Define parameterized resource
  • server.prompt() - Define prompt template
  • server.uiResource() - Define widget resource
  • server.listen() - Start server

Widget metadata fields:

  • description - Widget description
  • props - Zod schema for widget props
  • metadata - Unified config (dual-protocol)
  • metadata.csp - Content Security Policy
  • appsSdkMetadata - ChatGPT-specific overrides

Available templates:

  • starter - Full-featured (tools, resources, prompts, widgets)
  • mcp-apps - ChatGPT-optimized with product example
  • blank - Minimal boilerplate

More skills from mcp-use

chatgpt-app-builderby mcp-useDEPRECATED: Use mcp-app-builder instead. Build ChatGPT apps with interactive widgets and zero-config React development. This skill is deprecated; migrate to mcp-app-builder for continued support and updates Enables collaborative UI between human users and LLM through shared interactive widgets Provides server handlers, React widget scaffolding, state management, and built-in hooks for tool calls and follow-up messages Covers display modes (inline, fullscreen, picture-in-picture), theming,...mcp-apps-builderby mcp-useMandatory reference guide for building production MCP servers with tools, resources, prompts, and widgets. Covers foundational concepts (Tool, Resource, Prompt, Widget primitives), server architecture, authentication patterns (OAuth, Supabase, custom), and deployment strategies Includes detailed guides for implementing tools, resources, prompts, response formatting, and widget-based UIs with state management and theming Documents common anti-patterns (missing validation, improper error...mcp-builderby mcp-useDEPRECATED: Build MCP servers with tools, resources, prompts, and interactive widgets using mcp-use. This skill is deprecated; use mcp-app-builder instead Supports defining tools, resources, prompts, and interactive React widgets within a single MCP server Includes response helpers for formatting outputs as text, markdown, HTML, images, objects, and custom widgets Provides server composition and proxying to aggregate multiple MCP servers into a unified interfacechatgpt-app-builderby mcp-useBuild ChatGPT apps with interactive widgets using mcp-use and OpenAI Apps SDK. Use when creating ChatGPT apps, building MCP servers with widgets, defining…

---

Source: https://github.com/mcp-use/skills/tree/HEAD/skills/mcp-builder
Author: mcp-use
Discovered via: mcpservers.org

SKILL.md source

---
name: mcp-builder
description: Build production-ready MCP servers with the mcp-use framework and automatic widget registration. Bootstrap with npx create-mcp-use-app and choose from three templates: starter (full-featured), mcp-...
---

# mcp-builder

Build production-ready MCP servers with the mcp-use framework and automatic widget registration. Bootstrap with npx create-mcp-use-app and choose from three templates: starter (full-featured), mcp-apps (ChatGPT-optimized), or blank (minimal) Define tools, resources, and prompts using Zod schemas with automatic validation and clear parameter descriptions Automatically register React widgets from the resources/ folder as MCP Tools and Resources with dual-protocol support for MCP Apps and...

# mcp-builderby mcp-use
Build production-ready MCP servers with the mcp-use framework and automatic widget registration. Bootstrap with npx create-mcp-use-app and choose from three templates: starter (full-featured), mcp-apps (ChatGPT-optimized), or blank (minimal) Define tools, resources, and prompts using Zod schemas with automatic validation and clear parameter descriptions Automatically register React widgets from the resources/ folder as MCP Tools and Resources with dual-protocol support for MCP Apps and...

`npx skills add https://github.com/mcp-use/skills --skill mcp-builder`Download ZIPGitHub

## MCP Server Builder

Build production-ready MCP servers with the mcp-use framework. This Skill provides quick-start instructions and best practices for creating MCP servers.

## Quick Start

Always bootstrap with `npx create-mcp-use-app`:

```
`npx create-mcp-use-app my-mcp-server
cd my-mcp-server
`
```

Choose template based on needs:

* `--template starter` - Full-featured with all MCP primitives (tools, resources, prompts) + example widgets

* `--template mcp-apps` - Optimized for ChatGPT widgets with product search example

* `--template blank` - Minimal starting point for custom implementation

```
`# Example: MCP Apps template
npx create-mcp-use-app my-server --template mcp-apps
cd my-server
yarn install
`
```

Template Details:

* starter: Best for learning - includes all MCP features plus widgets

* mcp-apps: Best for ChatGPT apps - includes product carousel/accordion example

* blank: Best for experts - minimal boilerplate

## MCP Apps Structure

### Automatic Widget Registration

The mcp-apps and starter templates automatically discover and register React widgets from the `resources/` folder:

Single-file widget pattern:

```
`resources/
└── weather-display.tsx # Widget name becomes "weather-display"
`
```

Folder-based widget pattern:

```
`resources/
└── product-search/ # Widget name becomes "product-search"
├── widget.tsx # Entry point (required name!)
├── components/ # Sub-components
├── hooks/ # Custom hooks
├── types.ts
└── constants.ts
`
```

What happens automatically:

* Server scans `resources/` folder at startup

* Finds `.tsx` files or `widget.tsx` in folders

* Extracts `widgetMetadata` from each component

* Registers as MCP Tool (e.g., `weather-display`)

* Registers as MCP Resource (e.g., `ui://widget/weather-display.html`)

* Builds widget bundles with Vite

No manual registration needed! Just export `widgetMetadata` and a default component.

## Defining Tools

Tools are executable functions that AI models can call:

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

Key points:

* Use Zod for schema validation

* Add `.describe()` to all parameters

* Return appropriate response types (text, object, widget)

## Defining Resources

Resources expose data that clients can read:

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

Response helpers available:

* `text(string)` - Plain text

* `object(data)` - JSON objects

* `markdown(string)` - Markdown content

* `html(string)` - HTML content

* `image(buffer, mimeType)` - Binary images

* `audio(buffer, mimeType)` - Audio files

* `binary(buffer, mimeType)` - Binary data

* `mix(...contents)` - Combine multiple content types

Advanced response examples:

```
`// 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..."))
);
`
```

## Defining Prompts

Prompts are reusable templates for AI interactions:

```
`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}.`
}
}
]
};
}
);
`
```

## Testing Locally

Development mode (hot reload):

```
`yarn dev
`
```

Production mode:

```
`yarn build
yarn start
`
```

Inspector UI:
Access at `http://localhost:3000/inspector` to test tools, view resources, and try prompts.

Tunneling (test with ChatGPT before deploying):

Option 1 - Auto-tunnel:

```
`mcp-use start --port 3000 --tunnel
`
```

Option 2 - Separate tunnel:

```
`yarn start # Terminal 1
npx @mcp-use/tunnel 3000 # Terminal 2
`
```

You'll get a public URL like `https://happy-cat.local.mcp-use.run/mcp`

Tunnel details:

* Expires after 24 hours

* Closes after 1 hour of inactivity

* Rate limit: 10 creations/hour, max 5 active per IP

Learn more: https://mcp-use.com/docs/tunneling

## Deployment

Deploy to mcp-use Cloud (recommended):

```
`# Login first (if not already)
npx mcp-use login

# Deploy
yarn deploy
`
```

If authentication error:

```
`npx mcp-use login
yarn deploy
`
```

After deployment:

* Public URL provided (e.g., `https://your-server.mcp-use.com/mcp`)

* Auto-scaled and monitored

* HTTPS enabled

* Zero-downtime deployments

## Best Practices

Tool Design:

* ✅ One tool = one focused capability

* ✅ Descriptive names and descriptions

* ✅ Use `.describe()` on all Zod fields

* ✅ Handle errors gracefully

* ✅ Return helpful error messages

Resource Design:

* ✅ Use clear URI schemes (config://, docs://, stats://)

* ✅ Choose appropriate MIME types

* ✅ Use response helpers for cleaner code

* ✅ Make resources dynamic when needed

Prompt Design:

* ✅ Keep prompts reusable

* ✅ Use system messages for context

* ✅ Parameterize with Zod schemas

* ✅ Include clear instructions

Testing:

* ✅ Test with Inspector UI first

* ✅ Use tunneling to test with real clients before deploying

* ✅ Verify all tools, resources, and prompts work as expected

Deployment:

* ✅ Test locally and with tunneling first

* ✅ Run `npx mcp-use login` if deploy fails

* ✅ Version your server semantically

* ✅ Document breaking changes

## Widget Support

### Automatic Widget Registration

When using the `mcp-apps` or `starter` template, widgets in the `resources/` folder are automatically registered:

```
`// 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 automatically becomes available as:

* MCP Tool: `weather-display`

* MCP Resource: `ui://widget/weather-display.html`

### Content Security Policy (CSP)

Control what external resources widgets can access:

```
`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'"],
},
},
};
`
```

Alternatively, set at server level:

```
`server.uiResource({
type: "mcpApps",
name: "my-widget",
htmlTemplate: `...`,
metadata: {
csp: {
connectDomains: ["https://api.example.com"],
resourceDomains: ["https://cdn.example.com"],
},
},
});
`
```

## Dual-Protocol Widget Support

mcp-use supports the MCP Apps standard (SEP-1865) with automatic dual-protocol support:

```
`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,
},
});
`
```

What happens automatically:

* MCP Apps clients (Claude, Goose) receive: `text/html;profile=mcp-app` with `_meta.ui.*`

* ChatGPT receives: `text/html+skybridge` with `_meta.openai/*`

* Same widget code works everywhere!

### Custom OpenAI Metadata

Need ChatGPT-specific features? Combine both metadata fields:

```
`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
},
});
`
```

## Project Structure

```
`my-mcp-server/
├── resources/ # React widgets (apps-sdk)
│ └── widget.tsx
├── public/ # Static assets
├── index.ts # Server entry point
├── package.json
├── tsconfig.json
└── README.md
`
```

## Common Patterns

Tool with dual-protocol 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`)
});
}
);
`
```

Resource template (parameterized):

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

Error handling:

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

## Detailed Examples

For comprehensive examples and advanced patterns, connect to the mcp-use MCP server which provides:

* Complete example resources for all primitives

* Full working server examples

* Detailed documentation

* Interactive widgets showcase

## Learn More

* Documentation: https://docs.mcp-use.com

* MCP Apps Standard: https://docs.mcp-use.com/typescript/server/mcp-apps (dual-protocol guide)

* Templates: https://docs.mcp-use.com/typescript/server/templates (template comparison)

* Widget Guide: https://docs.mcp-use.com/typescript/server/ui-widgets

* Examples: https://github.com/mcp-use/mcp-use/tree/main/examples

* Tunneling Guide: https://mcp-use.com/docs/tunneling

* Discord: https://mcp-use.com/discord

* GitHub: https://github.com/mcp-use/mcp-use

## Quick Reference

Commands:

* `npx create-mcp-use-app my-server` - Bootstrap

* `yarn dev` - Development mode

* `yarn build` - Build for production

* `yarn start` - Run production server

* `mcp-use start --tunnel` - Start with tunnel

* `npx mcp-use login` - Authenticate

* `yarn deploy` - Deploy to cloud

Response helpers:

* `text(str)`, `object(data)`, `markdown(str)`, `html(str)`

* `image(buf, mime)`, `audio(buf, mime)`, `binary(buf, mime)`

* `mix(...)` - Combine multiple content types

* `widget({ props, output })` - Return widget with data

Server methods:

* `server.tool()` - Define executable tool

* `server.resource()` - Define static/dynamic resource

* `server.resourceTemplate()` - Define parameterized resource

* `server.prompt()` - Define prompt template

* `server.uiResource()` - Define widget resource

* `server.listen()` - Start server

Widget metadata fields:

* `description` - Widget description

* `props` - Zod schema for widget props

* `metadata` - Unified config (dual-protocol)

* `metadata.csp` - Content Security Policy

* `appsSdkMetadata` - ChatGPT-specific overrides

Available templates:

* `starter` - Full-featured (tools, resources, prompts, widgets)

* `mcp-apps` - ChatGPT-optimized with product example

* `blank` - Minimal boilerplate

## More skills from mcp-use
chatgpt-app-builderby mcp-useDEPRECATED: Use mcp-app-builder instead. Build ChatGPT apps with interactive widgets and zero-config React development. This skill is deprecated; migrate to mcp-app-builder for continued support and updates Enables collaborative UI between human users and LLM through shared interactive widgets Provides server handlers, React widget scaffolding, state management, and built-in hooks for tool calls and follow-up messages Covers display modes (inline, fullscreen, picture-in-picture), theming,...mcp-apps-builderby mcp-useMandatory reference guide for building production MCP servers with tools, resources, prompts, and widgets. Covers foundational concepts (Tool, Resource, Prompt, Widget primitives), server architecture, authentication patterns (OAuth, Supabase, custom), and deployment strategies Includes detailed guides for implementing tools, resources, prompts, response formatting, and widget-based UIs with state management and theming Documents common anti-patterns (missing validation, improper error...mcp-builderby mcp-useDEPRECATED: Build MCP servers with tools, resources, prompts, and interactive widgets using mcp-use. This skill is deprecated; use mcp-app-builder instead Supports defining tools, resources, prompts, and interactive React widgets within a single MCP server Includes response helpers for formatting outputs as text, markdown, HTML, images, objects, and custom widgets Provides server composition and proxying to aggregate multiple MCP servers into a unified interfacechatgpt-app-builderby mcp-useBuild ChatGPT apps with interactive widgets using mcp-use and OpenAI Apps SDK. Use when creating ChatGPT apps, building MCP servers with widgets, defining…

---

**Source**: https://github.com/mcp-use/skills/tree/HEAD/skills/mcp-builder
**Author**: mcp-use
**Discovered via**: mcpservers.org

Related skills 6

running-claude-code-via-litellm-copilot

★ Featured

Use when routing Claude Code through a local LiteLLM proxy to GitHub Copilot, reducing direct Anthropic spend, configuring ANTHROPIC_BASE_URL or ANTHROPIC_MODEL overrides, or troubleshooting Copilot proxy setup failures such as model-not-found, no localhost traffic, or GitHub 401/403 auth errors.

xixu-me 155k
AI & ML

skills-cli

★ Featured

Use when users ask to discover, install, list, check, update, remove, back up, restore, sync, or initialize Agent Skills, mention `bunx skills`, `npx skills`, `skills.sh`, or `skills-lock.json`, ask "find a skill for X", or want help extending agent capabilities with installable skills.

xixu-me 155k
AI & ML

repo-intake-and-plan

★ Featured

Narrow RigorPilot helper for README-first deep learning repo reproduction. Use when the task is specifically to scan a repository, read the README and common project files, extract documented commands, classify inference, evaluation, and training candidates, and return the smallest trustworthy reproduction plan to the main orchestrator. Do not use for environment setup, asset download, command execution, final reporting, paper lookup, or end-to-end orchestration.

lllllllama 127k
AI & ML

image-to-video

★ Featured

Animate any still image on RunComfy — this skill is a smart router that matches the user's intent to the right i2v model in the RunComfy catalog. Picks HappyHorse 1.0 I2V (Arena #1, native audio, identity preservation) for general animations, Wan 2.7 with `audio_url` for custom-voiceover lip-sync, or Seedance 2.0 Pro for multi-modal animation from image + reference video + reference audio. Bundles each model's documented prompting patterns so the caller gets sharper output without burning ite...

agentspace-so 121k
AI & ML

video-edit

★ Featured

Edit existing video on RunComfy — this skill is a smart router that matches the user's intent to the right edit model in the RunComfy catalog. Picks Wan 2.7 Edit-Video (general restyle / background swap / packaging swap, identity + motion preservation), Kling 2.6 Pro Motion Control (transfer precise motion from a reference video to a target character), or Lucy Edit Restyle (lightweight identity-stable restyle / outfit swap). Bundles each model's documented prompting patterns so the skill gets...

agentspace-so 121k
AI & ML

nano-banana-2

★ Featured

Generate images with Google Nano Banana 2 (Gemini-family flash-tier text-to-image) on RunComfy — bundled with the model's documented prompting patterns so the skill gets sharper output than naive prompting against the same model. Documents Nano Banana 2's strengths (rapid iteration, in-image typography rendering, predictable framing, optional web-grounded context), the resolution-tier pricing, the safety-tolerance dial, and when to route to Nano Banana Pro / GPT Image 2 / Flux 2 / Seedream in...

agentspace-so 121k
AI & ML