The MCP server instance
Human-readable resource name
Resource URI (should match the _meta.ui field in tool config)
Resource configuration
Callback that returns the resource contents
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"),
},
],
}),
);
registerAppResource(
server,
"Music Player",
"ui://music/player.html",
{
description: "Audio player with external soundfonts",
},
async () => ({
contents: [
{
uri: "ui://music/player.html",
mimeType: RESOURCE_MIME_TYPE,
text: musicPlayerHtml,
_meta: {
ui: {
csp: {
resourceDomains: ["https://cdn.example.com"], // For scripts/styles/images
connectDomains: ["https://api.example.com"], // For fetch/WebSocket
},
},
},
},
],
}),
);
// Computes a stable origin from an MCP server URL for hosting in Claude.
function computeAppDomainForClaude(mcpServerUrl: string): string {
const hash = crypto
.createHash("sha256")
.update(mcpServerUrl)
.digest("hex")
.slice(0, 32);
return `${hash}.claudemcpcontent.com`;
}
const APP_DOMAIN = computeAppDomainForClaude("https://example.com/mcp");
registerAppResource(
server,
"Company Dashboard",
"ui://dashboard/view.html",
{
description: "Internal dashboard with company data",
},
async () => ({
contents: [
{
uri: "ui://dashboard/view.html",
mimeType: RESOURCE_MIME_TYPE,
text: dashboardHtml,
_meta: {
ui: {
// CSP: tell browser the app is allowed to make requests
csp: {
connectDomains: ["https://api.example.com"],
},
// CORS: give app a stable origin for the API server to allowlist
//
// (Public APIs that use `Access-Control-Allow-Origin: *` or API
// key auth don't need this.)
domain: APP_DOMAIN,
},
},
},
],
}),
);
McpUiResourceMeta for _meta.ui configuration optionsMcpUiResourceCsp for CSP domain allowlist configurationregisterAppTool to register tools that reference this resource
Register an app resource with the MCP server.
This is a convenience wrapper around
server.registerResourcethat:RESOURCE_MIME_TYPE("text/html;profile=mcp-app")