-
Notifications
You must be signed in to change notification settings - Fork 61
Description
Issue
Currently the spec requires you to place the CSP, permissions, etc information in two separate places:
- The resource metadata
_meta.ui?. - The contents of the resource.
Example: I have to add the _meta.ui info here:
registerAppResource(server,
resourceUri,
resourceUri,
{
mimeType: RESOURCE_MIME_TYPE,
_meta: {
ui: {
csp: {
connectDomains: ["https://xxx"],
resourceDomains: [
"https://xxx",
"https://fonts.googleapis.com",
"https://fonts.gstatic.com",
],
},
},
},
},
async (): Promise<ReadResourceResult> => {
const html = await fs.readFile(path.join(DIST_DIR, "cocktail-recipe-widget.html"), "utf-8");
return {
contents: [{ uri: resourceUri, mimeType: RESOURCE_MIME_TYPE, text: html }],
};
},
);
and here:
// resources/read response for UI resource
{
contents: [{
uri: string; // Matching UI resource URI
mimeType: "text/html;profile=mcp-app"; // MUST be "text/html;profile=mcp-app"
text?: string; // HTML content as string
blob?: string; // OR base64-encoded HTML
_meta?: {
ui?: {
csp?: {
connectDomains?: string[]; // Origins for network requests (fetch/XHR/WebSocket).
resourceDomains?: string[]; // Origins for static resources (scripts, images, styles, fonts).
frameDomains?: string[]; // Origins for nested iframes (frame-src directive).
baseUriDomains?: string[]; // Allowed base URIs for the document (base-uri directive).
};
permissions?: {
camera?: boolean; // Request camera access
microphone?: boolean; // Request microphone access
geolocation?: boolean; // Request geolocation access
clipboardWrite?: boolean; // Request clipboard write access
};
domain?: string;
prefersBorder?: boolean;
};
};
}];
}
Why it's a problem
There is redundancy in having to add the same exact information in two separate places. As a client implementor, I don't know which one to check. Do I check the resource meta? Do I check the resource result? I don't know.
As a server implementor, it was difficult for me to realize that I had to add it in two separate places. I was confused why my CSP wasn't getting used even though I put it in the resource meta, only to realize the client I'm using is checking it in the resource content.
Solution
Ideally, we have a single source of truth for where to put the meta. I think we should standardize it to be read in the resource read content. That's where most clients today have it implemented.