Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion specification/draft/apps.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,19 @@ interface UIResourceMeta {
* "www-example-com.oaiusercontent.com"
*/
domain?: string,
/**
* Public homepage URL for the app represented by this UI resource.
*
* This is distinct from `domain`, which configures the host-assigned sandbox
* origin. Hosts MAY expose this URL to help users learn more about or return
* to the app, but MUST treat it as an untrusted external link and apply their
* normal link validation, policy, and consent behavior. Its presence does not
* grant navigation permission or establish trust in the destination.
*
* @example
* "https://weather.example.com"
*/
homepage?: string,
/**
* Visual boundary preference
*
Expand Down Expand Up @@ -253,6 +266,7 @@ The resource content is returned via `resources/read`:
clipboardWrite?: {}; // Request clipboard write access
};
domain?: string;
homepage?: string;
prefersBorder?: boolean;
};
};
Expand All @@ -262,7 +276,7 @@ The resource content is returned via `resources/read`:

#### Metadata Location

`UIResourceMeta` (CSP, permissions, domain, prefersBorder) may be provided on either or both:
`UIResourceMeta` (CSP, permissions, domain, homepage, prefersBorder) may be provided on either or both:

- **`resources/list`:** On the resource entry's `_meta.ui` field. Useful as a static default that hosts can review at connection time.
- **`resources/read`:** On each content item's `_meta.ui` field. Useful for per-response overrides or dynamic metadata that is only known at read time.
Expand Down Expand Up @@ -311,6 +325,7 @@ Example:
"connectDomains": ["https://api.openweathermap.org"],
"resourceDomains": ["https://cdn.jsdelivr.net"]
},
"homepage": "https://weather.example.com",
"prefersBorder": true
}
}
Expand All @@ -328,6 +343,7 @@ Example:
"connectDomains": ["https://api.openweathermap.org"],
"resourceDomains": ["https://cdn.jsdelivr.net"]
},
"homepage": "https://weather.example.com",
"prefersBorder": true
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/generated/schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions src/generated/schema.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion src/server/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,9 @@ describe("registerAppResource", () => {
"ui://test/view.html",
{
description: "A test resource",
_meta: { ui: {} },
_meta: {
ui: { homepage: "https://example.com/apps/my-resource" },
},
},
callback,
);
Expand All @@ -240,6 +242,9 @@ describe("registerAppResource", () => {
expect(capturedUri).toBe("ui://test/view.html");
expect(capturedConfig?.mimeType).toBe(RESOURCE_MIME_TYPE);
expect(capturedConfig?.description).toBe("A test resource");
expect(capturedConfig?._meta).toEqual({
ui: { homepage: "https://example.com/apps/my-resource" },
});
});

it("should allow custom MIME type to override default", () => {
Expand Down
16 changes: 16 additions & 0 deletions src/spec.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,22 @@ export interface McpUiResourceMeta {
* ```
*/
domain?: string;
/**
* @description Public homepage URL for the app represented by this UI resource.
*
* This is distinct from `domain`, which configures the host-assigned sandbox
* origin. Hosts MAY expose this URL to
* help users learn more about or return to the app, but MUST treat it as an
* untrusted external link and apply their normal link validation, policy,
* and consent behavior. Its presence does not grant navigation permission
* or establish trust in the destination.
*
* @example
* ```ts
* "https://weather.example.com"
* ```
*/
homepage?: string;
/**
* @description Visual boundary preference - true if view prefers a visible border.
*
Expand Down