-
Notifications
You must be signed in to change notification settings - Fork 345
@mcp-ui/server createUIResource() does not output annotations in an MCP spec-compliant way #98
Description
Issue
createUIResource() does not output annotations at the right level in the embedded resource object according to the MCP specification.
import { createUIResource } from "@mcp-ui/server";
createUIResource({
uri: "ui://instance-1",
content: {
type: "externalUrl",
iframeUrl: "http://localhost:3000/",
},
encoding: "text",
resourceProps: {
annotations: {
audience: ["user"],
},
},
})
// The above code currently yields the following JSON:
// {
// "type": "resource",
// "resource": {
// "uri": "ui://instance-1",
// "mimeType": "text/uri-list",
// "text": "http://localhost:3000/",
// "annotations": {
// "audience": ["user"]
// },
// }
// }Why is this important?
Setting the audience to user should direct clients not to pass the resource along to the LLM. This helps create a cleaner chat experience, where the model won't summarize the URL or rawHTML. In the case of rawHTML, it serves as an additional layer of security by preventing prompt injection.
Expected
If an embedded resource has the annotations property, it should be set at the same level as the resource and type properties, according to https://modelcontextprotocol.io/specification/2025-06-18/schema#embeddedresource
interface EmbeddedResource {
_meta?: { [key: string]: unknown };
annotations?: Annotations;
resource: TextResourceContents | BlobResourceContents;
type: “resource”;
}{
"type": "resource",
"resource": {
"uri": "ui://instance-1",
"mimeType": "text/uri-list",
"text": "http://localhost:3000/",
},
"annotations": {
"audience": ["user"]
}
}Note
_meta is allowed to exist at any level in resource objects. Currently, createUIResource() adds _meta as a child property of the resource object. I think this is fine, but I'd be in favor of consistency if we want to lift _meta up to be alongside annotations.