Skip to main content
Low-level utilities for building MCP UI resources, dual-protocol widget metadata, and SEO landing pages. Most servers register widgets declaratively with server.uiResource(...) (see UIResource), which calls these helpers internally. The functions and types here are the building blocks for that pipeline and are also exported for advanced use. A widget is shipped as a ui:// resource plus tool metadata. mcp-use supports two protocols from a single definition:
  • MCP Apps Extension (SEP-1865): mime type text/html;profile=mcp-app, metadata under _meta.ui.*, camelCase CSP keys. Used by Claude, Goose, and other MCP Apps clients.
  • ChatGPT Apps SDK: mime type text/html+skybridge, metadata under openai/* keys, snake_case CSP keys.
The adapters on this page transform one UnifiedWidgetMetadata definition into either format, so you write the configuration once.

Resource builders

These functions produce UIResourceContent objects ({ type: "resource", resource }) that you can return from a tool or resource handler. They are the lower-level primitives behind createUIResourceFromDefinition.

createUIResourceFromDefinition

Create a UIResourceContent from a high-level UIResourceDefinition. This is the main router: it inspects the discriminated type field and delegates to the appropriate builder.
Routes a definition to the correct resource creator based on its type ("externalUrl", "rawHtml", "remoteDom", "appsSdk", or "mcpApps"). The resource URI is derived from definition.name. For appsSdk and mcpApps types it is ui://widget/<name>.html; for the others it is ui://widget/<name>. When config.buildId is set, it is appended to the name (ui://widget/<name>-<buildId>...) for cache busting. The encoding defaults to "text" when definition.encoding is not set. For the externalUrl type, params are passed through buildWidgetUrl to build the iframe URL. Throws Error("Unknown UI resource type: ...") if the definition type is not one of the supported values (enforced by an exhaustiveness check). Parameters
UIResourceDefinition
required
UIResource definition (discriminated union on type)
Record<string, any>
required
Runtime parameters for the widget (used for the externalUrl type)
UrlConfig
required
URL configuration used when building widget URLs
Returns
Promise<UIResourceContent>
Signature

createMcpAppsResource

Create a UIResourceContent for the MCP Apps Extension (SEP-1865) using the text/html;profile=mcp-app mime type.
Builds a synchronous MCP Apps resource. The HTML template should contain the component code with embedded JS and CSS. The widget receives the tool output via the MCP protocol. Metadata is written under resource._meta.ui per SEP-1865. Only the fields you set are emitted: csp is included when it has at least one key, prefersBorder when it is not undefined, and domain when truthy. If no metadata fields apply, _meta is omitted entirely. Parameters
string
required
Resource URI (must start with ui://)
string
required
HTML template with embedded component code
{ description?: string; csp?: { connectDomains?: string[]; resourceDomains?: string[]; frameDomains?: string[]; baseUriDomains?: string[] }; prefersBorder?: boolean; domain?: string }
MCP Apps metadata (CSP, border preference, domain)
Returns
UIResourceContent
Signature

createExternalUrlResource

Create a UIResourceContent that loads an external URL in an iframe.
Wraps @mcp-ui/server’s createUIResource with content: { type: "externalUrl", iframeUrl }. Use this for widgets served from a separate origin (for example a Vite dev server or a deployed static site). Parameters
string
required
Resource URI (must start with ui://)
string
required
URL to load in the iframe
UIEncoding
default:"\"text\""
Encoding type ("text" or "blob")
AdaptersConfig
Adapter configuration (for example Apps SDK) passed through to @mcp-ui/server
AppsSdkMetadata
Additional metadata for the resource
Returns
Promise<UIResourceContent>
Signature

createRawHtmlResource

Create a UIResourceContent that renders raw HTML inline.
Wraps @mcp-ui/server’s createUIResource with content: { type: "rawHtml", htmlString }. The HTML is delivered inline rather than loaded from a URL. Parameters
string
required
Resource URI (must start with ui://)
string
required
HTML content to render
UIEncoding
default:"\"text\""
Encoding type ("text" or "blob")
AdaptersConfig
Adapter configuration (for example Apps SDK)
AppsSdkMetadata
Additional metadata for the resource
Returns
Promise<UIResourceContent>
Signature

createRemoteDomResource

Create a UIResourceContent for Remote DOM scripting.
Builds a Remote DOM resource with mime type application/vnd.mcp-ui.remote-dom+<framework>. Because remoteDom was removed from createUIResource in @mcp-ui/server v6, this constructs the resource object manually. When encoding is "blob", the script is base64-encoded into resource.blob; otherwise it is placed in resource.text.
The adapters and metadata parameters are accepted for signature parity but are not applied (they are prefixed with an underscore in the implementation). The MIME type is still rendered by @mcp-ui/client.
Parameters
string
required
Resource URI (must start with ui://)
string
required
JavaScript code for remote DOM manipulation
"react" | "webcomponents"
default:"\"react\""
Framework for remote DOM
UIEncoding
default:"\"text\""
Encoding type ("text" or "blob")
AdaptersConfig
Accepted for parity; not applied
AppsSdkMetadata
Accepted for parity; not applied
Returns
Promise<UIResourceContent>
Signature

buildWidgetUrl

Build the full URL for a locally served widget, including encoded props.
Constructs a URL of the form <baseUrl>:<port>/mcp-use/widgets/<slug>. The widget name is slugified for URL safety. When props is provided and non-empty, all props are serialized into a single props query parameter as JSON. When props is undefined or an empty object, no query parameter is added. Parameters
string
required
Widget identifier (slugified for the URL path)
Record<string, any> | undefined
required
Parameters passed as a single JSON-encoded props query param
UrlConfig
required
URL configuration (baseUrl, port, optional buildId)
Returns
string
Signature

UrlConfig

Configuration for building widget URLs, consumed by buildWidgetUrl and createUIResourceFromDefinition.
Properties
string
required
Base URL of the server (for example http://localhost)
number | string
required
Server port appended to the base URL
string
Optional build ID appended to widget URIs for cache busting
Signature

Protocol adapters

Adapters transform a single UnifiedWidgetMetadata definition into protocol-specific tool and resource metadata. Both implement ProtocolAdapter.

AppsSdkAdapter

Protocol adapter that emits ChatGPT Apps SDK metadata.
Transforms unified widget definitions into Apps SDK format: mime type text/html+skybridge, flat _meta keys prefixed with openai/, and snake_case CSP fields (connect_domains, resource_domains, and so on). buildToolMetadata always sets openai/outputTemplate to the resource URI and copies openai/toolInvocation/invoking, openai/toolInvocation/invoked, openai/widgetAccessible, and openai/resultCanProduceWidget from appsSdkMetadata when present. It falls back to metadata.invoking and metadata.invoked for the invocation status keys. buildResourceMetadata extends the base implementation by copying additional openai/* fields from appsSdkMetadata when they are not already set. Members
string
Readonly. Always "text/html+skybridge".
"apps-sdk"
Readonly protocol identifier.
Record<string, unknown>
Builds Apps SDK tool metadata for a definition and resource URI.
{ mimeType: string; _meta?: Record<string, unknown> }
Builds Apps SDK resource metadata (mime type plus _meta).
Signature

McpAppsAdapter

Protocol adapter that emits MCP Apps Extension (SEP-1865) metadata.
Transforms unified widget definitions into MCP Apps format: mime type text/html;profile=mcp-app (the value of RESOURCE_MIME_TYPE), metadata under the _meta.ui.* namespace, and camelCase CSP fields kept as-is. buildToolMetadata returns the new nested form { ui: { resourceUri } } and also includes the legacy flat key RESOURCE_URI_META_KEY pointing at the same URI for backward compatibility with older clients. Resource metadata is wrapped under _meta.ui. Members
string
Readonly. Equals RESOURCE_MIME_TYPE ("text/html;profile=mcp-app").
"mcp-apps"
Readonly protocol identifier.
Record<string, unknown>
Builds MCP Apps tool metadata (ui.resourceUri plus the legacy flat key).
{ mimeType: string; _meta?: Record<string, unknown> }
Builds MCP Apps resource metadata wrapped under _meta.ui.
Signature

ProtocolAdapter

The interface implemented by every protocol adapter (AppsSdkAdapter and McpAppsAdapter).
Defines how a unified widget definition is converted into protocol-specific tool and resource metadata. Properties
string
required
Readonly mime type for this protocol (text/html;profile=mcp-app for MCP Apps, text/html+skybridge for Apps SDK)
"mcp-apps" | "apps-sdk"
required
Readonly protocol identifier
Methods
Record<string, unknown>
required
Build protocol-specific tool metadata from a definition and resource URI
{ mimeType: string; _meta?: Record<string, unknown> }
required
Build protocol-specific resource metadata (includes mimeType and optional _meta)
Signature

CSPConfig

Unified Content Security Policy configuration. Adapters map these camelCase fields to MCP Apps (camelCase) or Apps SDK (snake_case) format.
Follows the SEP-1865 specification with support for arbitrary additional properties (the index signature allows fields not yet listed here, for future spec evolution). Properties
string[]
Domains allowed for fetch, XHR, and WebSocket connections
string[]
Domains allowed for images, scripts, stylesheets, and fonts
string[]
Allowed iframe origins
string[]
Allowed base URIs for the document (SEP-1865)
string[]
Domains for openExternal without a confirmation modal (ChatGPT only, not in SEP-1865)
string[]
CSP directive literals to include in script-src (for example 'unsafe-eval'). Use with caution, these weaken security.
string[]
CSP directive literals to include in style-src (for example 'unsafe-inline')
Signature

UnifiedWidgetMetadata

Protocol-agnostic widget metadata. Write it once, and adapters transform it into both MCP Apps and Apps SDK formats.
Follows SEP-1865 with support for arbitrary additional properties via an index signature. Some fields target a single protocol (noted below); the other protocol ignores them. Properties
string
Description of the widget
CSPConfig
Content Security Policy
boolean
Request a visible border around the widget
string
Dedicated domain for widget isolation
string
Human-readable summary for the AI model (ChatGPT only)
{ camera?; microphone?; geolocation?; clipboardWrite?; [key: string]: any }
Sandbox permissions requested by the UI (SEP-1865). Hosts MAY honor these via iframe allow attributes.
boolean
Enable automatic size change notifications (legacy MCP-UI, still supported)
string
Status text shown while the tool is running. Maps to openai/toolInvocation/invoking. Defaults to "Loading {name}...".
string
Status text shown after the tool completes. Maps to openai/toolInvocation/invoked. Defaults to "{name} ready".
Signature

RESOURCE_MIME_TYPE

The MCP Apps Extension mime type, re-exported from @modelcontextprotocol/ext-apps.
The mime type used for MCP Apps resources: "text/html;profile=mcp-app". It is the value returned by McpAppsAdapter’s mimeType property. Re-exported from @modelcontextprotocol/ext-apps/server for convenience. Signature

RESOURCE_URI_META_KEY

The legacy flat _meta key for an MCP Apps resource URI, re-exported from @modelcontextprotocol/ext-apps.
The flat _meta key under which the resource URI is duplicated for backward compatibility with older MCP Apps clients (McpAppsAdapter also emits the newer nested ui.resourceUri form). Re-exported from @modelcontextprotocol/ext-apps/server. Signature

Widget definition types

These types describe widgets at the discovery and manifest level.

WidgetManifest

Manifest describing a built widget on disk.
Describes a widget’s identity, props, preferred frame size, and built asset paths. The name must match the widget directory or file name. Properties
string
required
Unique widget identifier (must match directory or file name), for example "weather-display"
string
Human-readable title
string
Description of what the widget displays
string
Semantic version of the widget
WidgetProps
Widget props schema (type, required, default per prop)
[string, string]
Preferred frame size [width, height], for example ["800px", "600px"]
{ main?: string; scripts?: string[]; styles?: string[] }
Asset paths for the main entry, scripts, and styles
Signature

WidgetMetadata

Metadata exported from a React widget module (a resources/*.tsx file) for auto-discovery and auto-registration.
Declares a widget’s title, props schema, tool output, and dual-protocol metadata. Exported by widget developers as widgetMetadata. The auto-discovery pipeline reads it to register the widget and (when exposeAsTool is not false) an MCP tool.
This type is exported from mcp-use/react, not mcp-use/server. It is documented here because it configures the same dual-protocol widget pipeline.
Properties
string
Human-readable title for the widget
string
Description shown to the model and used for auto-registered tool descriptions
z.ZodTypeAny | InputDefinition[]
Zod schema (preferred) or InputDefinition array for widget props validation
z.ZodTypeAny | InputDefinition[]
Deprecated. Use props instead.
z.ZodTypeAny | InputDefinition[]
Deprecated. Use props instead.
((params: Record<string, any>) => CallToolResult | TypedCallToolResult<any>) | CallToolResult | TypedCallToolResult<any>
Function or static value producing the tool output (what the model sees). Defaults to a summary message.
boolean
default:"true"
Whether to auto-register this widget as an MCP tool. Set to false when paired with a custom server.tool().
ResourceAnnotations & Partial<ToolAnnotations>
Annotations applied to both the resource and the tool
Record<string, unknown>
Optional raw metadata for the widget
AppsSdkMetadata
Deprecated. Legacy ChatGPT-only metadata. Prefer metadata for dual-protocol support.
{ description?; csp?: CSPConfig; prefersBorder?; domain?; widgetDescription?; autoResize?; invoking?; invoked? }
Unified dual-protocol metadata. Write once; the server generates both Apps SDK and MCP Apps formats.
Signature

DiscoverWidgetsOptions

Options for discovering and registering widgets from a directory.
Controls where widgets are discovered, whether widgets without manifests are auto-registered, and an optional name filter. Properties
string
Path to the widgets directory. Defaults to dist/resources/mcp-use/widgets.
boolean
default:"false"
Automatically register widgets that do not have manifests
string | RegExp
Filter widgets by name pattern, for example "weather-*"
Signature

Landing page

MCPServer renders the v1 landing frontend at its exact basePath for GET and HEAD requests that explicitly accept text/html. It includes the animated mesh-gradient hero, endpoint copy control, hosted Manufact Inspector link, client installation tabs, and optional tools, prompts, and static resources registered before the server starts. Without OAuth, the page is public. With OAuth, it requires a bearer token by default. Set publicLandingPage: true to expose only the HTML page without a token; JSON, event-stream, wildcard probes, DELETE, and POST remain protected.

generateLandingPage

Generate the same v1-compatible HTML document outside MCPServer. The page includes SEO and JSON-LD metadata, connection instructions for common MCP clients, the hosted Manufact Inspector link, and optional icon and primitive lists. Its CSS and behavior are inline; the Outfit stylesheet and GitHub stars badge load from their original external URLs. Caller-provided values are escaped before entering HTML, including the JSON-LD script payload.
Parameters
LandingPageOptions
required
Server identity, endpoint URL, optional icon URL, and primitive lists.
Returns
string
Signature
LandingPageOptions requires name, version, and the absolute public MCP endpoint url. It also accepts title, description, iconUrl, tools, prompts, and resources.

LandingPageTool

A tool entry rendered in the landing page Primitives section.
Properties
string
required
Tool name
string
Optional human-readable title
string
Optional tool description
Signature

LandingPagePrompt

A prompt entry rendered in the landing page Primitives section.
Properties
string
required
Prompt name
string
Optional human-readable title
string
Optional prompt description
Signature

LandingPageResource

A resource entry rendered in the landing page Primitives section.
Properties
string
required
Resource URI
string
Optional resource name
string
Optional human-readable title
string
Optional resource description
Signature

Type generation

generateToolRegistryTypes

Generate TypeScript type definitions for the ToolRegistry from registered tools and write them to .mcp-use/tool-registry.d.ts.
Reads each registered tool’s Zod input and output schemas, converts them to TypeScript types, and emits a declare module "mcp-use/react" augmentation of the ToolRegistry interface. This powers type-safe tool calls in the useCallTool React hook. It is invoked automatically during development (on startup and on tool or widget changes) and by the mcp-use generate-types CLI command. Behavior and edge cases:
  • Production-safe: returns true immediately and writes nothing when process.env.NODE_ENV === "production".
  • Deterministic: tools are sorted alphabetically by name before generation.
  • Idempotent writes: the new content is compared against the existing file (ignoring the timestamp line); if unchanged, the file is not rewritten.
  • Defaults: a tool with no input schema is typed as null; a tool with no outputSchema is typed as Record<string, unknown>.
Parameters
Map<string, { config: ToolDefinition; handler: ToolCallback }>
required
The server’s registrations.tools map
string
default:"process.cwd()"
Project root directory where .mcp-use/ is written
Returns
Promise<boolean>
Signature