> ## Documentation Index
> Fetch the complete documentation index at: https://sunpeak.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Apps registerAppResource - HTML Resources

> Register HTML resources for MCP App Views. Configure content security policies (CSP), iframe permissions, resource URIs, and domain settings.

<Badge color="green">MCP Apps SDK</Badge>

```ts theme={null}
import { registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server";
```

## Overview

`registerAppResource` is a convenience wrapper around the MCP SDK's [`server.registerResource()`](/docs/mcp-apps/mcp/resources) 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`](/docs/mcp-apps/server/register-app-tool).

## Signature

```ts theme={null}
function registerAppResource(
  server: McpServer,
  name: string,
  uri: string,
  config: McpUiAppResourceConfig,
  readCallback: McpUiReadResourceCallback,
): RegisteredResource
```

## Parameters

<ResponseField name="server" type="McpServer" required>
  The MCP server instance.
</ResponseField>

<ResponseField name="name" type="string" required>
  Human-readable resource name.
</ResponseField>

<ResponseField name="uri" type="string" required>
  Resource URI. Should match the `_meta.ui.resourceUri` in your tool config.
</ResponseField>

<ResponseField name="config" type="McpUiAppResourceConfig" required>
  Resource configuration extending MCP SDK's `ResourceMetadata`.

  <ResponseField name="description" type="string">
    Human-readable resource description.
  </ResponseField>

  <ResponseField name="mimeType" type="string">
    MIME type. Defaults to `RESOURCE_MIME_TYPE` if omitted.
  </ResponseField>

  <ResponseField name="_meta" type="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](#_meta-reference) below for all fields.
  </ResponseField>
</ResponseField>

<ResponseField name="readCallback" type="McpUiReadResourceCallback" required>
  Callback that returns the resource contents. The `contents[]` items can include `_meta.ui` for per-read security configuration.
</ResponseField>

## Usage

### Basic resource

```ts theme={null}
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:

```ts theme={null}
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:

```ts theme={null}
_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`](/docs/mcp-apps/server/resource-meta#domain--stable-sandbox-origin) for details.

```ts theme={null}
_meta: {
  ui: {
    csp: { connectDomains: ["https://api.example.com"] },
    domain: computeDomainForClaude("https://example.com/mcp"),
  },
}
```

## `_meta` Reference

See **[Resource `_meta`](/docs/mcp-apps/server/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

| Constant                | Value                         | Description                                       |
| ----------------------- | ----------------------------- | ------------------------------------------------- |
| `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 |

<Tip>
  In the [sunpeak framework](/docs/quickstart), resources are co-located with tools and auto-discovered. See the [Tool File Reference](/docs/app-framework/tools/tool-file).
</Tip>
