Add CSP and CORS section to patterns docs
Adds a new section to the patterns guide explaining how to configure Content Security Policy and CORS for MCP Apps that make network requests: - CSP via `_meta.ui.csp` controls browser-side permissions (`connectDomains`, `resourceDomains`) - CORS via `_meta.ui.domain` provides a stable origin for API servers to allowlist Includes a type-checked example showing `computeAppDomainForClaude()` helper that hashes an MCP server URL to create a stable `*.claudemcpcontent.com` subdomain. Also adds `@see` links to `McpUiResourceMeta` and `McpUiResourceCsp` in `registerAppResource` JSDoc. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
5c4f4969b1
commit
13b6d06399
2 changed files with 162 additions and 0 deletions
|
|
@ -7,6 +7,7 @@
|
|||
* @module
|
||||
*/
|
||||
|
||||
import * as crypto from "node:crypto";
|
||||
import * as fs from "node:fs/promises";
|
||||
import type {
|
||||
McpServer,
|
||||
|
|
@ -198,6 +199,59 @@ function registerAppResource_withCsp(
|
|||
//#endregion registerAppResource_withCsp
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: registerAppResource with stable origin for external API CORS allowlists.
|
||||
*/
|
||||
function registerAppResource_withDomain(
|
||||
server: McpServer,
|
||||
dashboardHtml: string,
|
||||
) {
|
||||
//#region registerAppResource_withDomain
|
||||
// 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,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
//#endregion registerAppResource_withDomain
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Check for MCP Apps support in server initialization.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
import {
|
||||
RESOURCE_URI_META_KEY,
|
||||
RESOURCE_MIME_TYPE,
|
||||
McpUiResourceCsp,
|
||||
McpUiResourceMeta,
|
||||
McpUiToolMeta,
|
||||
McpUiClientCapabilities,
|
||||
|
|
@ -298,6 +299,54 @@ export function registerAppTool<
|
|||
* );
|
||||
* ```
|
||||
*
|
||||
* @example With stable origin for external API CORS allowlists
|
||||
* ```ts source="./index.examples.ts#registerAppResource_withDomain"
|
||||
* // 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,
|
||||
* },
|
||||
* },
|
||||
* },
|
||||
* ],
|
||||
* }),
|
||||
* );
|
||||
* ```
|
||||
*
|
||||
* @see {@link McpUiResourceMeta `McpUiResourceMeta`} for `_meta.ui` configuration options
|
||||
* @see {@link McpUiResourceCsp `McpUiResourceCsp`} for CSP domain allowlist configuration
|
||||
* @see {@link registerAppTool `registerAppTool`} to register tools that reference this resource
|
||||
*/
|
||||
export function registerAppResource(
|
||||
|
|
|
|||
Loading…
Reference in a new issue