Skip to main content
MCP Apps SDK
import { registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server";

Overview

registerAppResource is a convenience wrapper around the MCP SDK’s server.registerResource() that defaults the MIME type to RESOURCE_MIME_TYPE ("text/html;profile=mcp-app"). Use it to register the HTML resources that your tools reference via _meta.ui.resourceUri.

Signature

function registerAppResource(
  server: McpServer,
  name: string,
  uri: string,
  config: McpUiAppResourceConfig,
  readCallback: McpUiReadResourceCallback,
): RegisteredResource

Parameters

server
McpServer
required
The MCP server instance.
name
string
required
Human-readable resource name.
uri
string
required
Resource URI. Should match the _meta.ui.resourceUri in your tool config.
config
McpUiAppResourceConfig
required
Resource configuration extending MCP SDK’s ResourceMetadata.
description
string
Human-readable resource description.
mimeType
string
MIME type. Defaults to RESOURCE_MIME_TYPE if omitted.
_meta
object
Optional UI metadata for the resource listing (returned in resources/list). You can also set _meta.ui on individual contents[] items returned by the read callback — content-item values take precedence. See _meta Reference below for all fields.
readCallback
McpUiReadResourceCallback
required
Callback that returns the resource contents. The contents[] items can include _meta.ui for per-read security configuration.

Usage

Basic resource

registerAppResource(
  server,
  "Weather View",
  "ui://weather/view.html",
  {
    description: "Interactive weather display",
  },
  async () => ({
    contents: [
      {
        uri: "ui://weather/view.html",
        mimeType: RESOURCE_MIME_TYPE,
        text: await fs.readFile("dist/view.html", "utf-8"),
      },
    ],
  }),
);

With CSP configuration

Declare network domains your View needs in _meta.ui.csp on the contents[] items:
registerAppResource(
  server,
  "Music Player",
  "ui://music/player.html",
  {},
  async () => ({
    contents: [
      {
        uri: "ui://music/player.html",
        mimeType: RESOURCE_MIME_TYPE,
        text: musicPlayerHtml,
        _meta: {
          ui: {
            csp: {
              connectDomains: ["https://api.example.com"],
              resourceDomains: ["https://cdn.example.com"],
            },
          },
        },
      },
    ],
  }),
);

With permissions

Request browser capabilities like camera, microphone, geolocation, or clipboard access:
_meta: {
  ui: {
    permissions: {
      microphone: {},
      clipboardWrite: {},
    },
  },
}

With stable origin (domain)

Use _meta.ui.domain to give your View a stable sandbox origin for CORS allowlists. The value is a subdomain within the host’s domain space, not your own domain. See Resource _meta > domain for details.
_meta: {
  ui: {
    csp: { connectDomains: ["https://api.example.com"] },
    domain: computeDomainForClaude("https://example.com/mcp"),
  },
}

_meta Reference

See Resource _meta for the complete reference on CSP (connectDomains, resourceDomains, frameDomains, baseUriDomains), sandbox permissions (camera, microphone, geolocation, clipboardWrite), stable domain origins, prefersBorder, and listing-level vs content-item precedence.

Constants

ConstantValueDescription
RESOURCE_MIME_TYPE"text/html;profile=mcp-app"MIME type for MCP App UI resources
RESOURCE_URI_META_KEY"ui/resourceUri"Deprecated metadata key for tool-resource linkage
In the sunpeak framework, resources are co-located with tools and auto-discovered. See the Tool File Reference.