-
Notifications
You must be signed in to change notification settings - Fork 370
Add linkTrustedDomains view property #690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
8f02c23
a792b38
0d70095
864354c
689e769
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -225,6 +225,26 @@ interface UIResourceMeta { | |
| * - omitted: host decides border | ||
| */ | ||
| prefersBorder?: boolean, | ||
| /** | ||
| * Origins the view is expecting to open via `ui/open-link` | ||
| * | ||
| * Servers declare external destinations the view legitimately links to (for | ||
| * example its own marketing site). Hosts MAY use this list to skip the link | ||
| * confirmation prompt for matching destinations. | ||
| * | ||
| * - Each entry is an origin (scheme + host[:port]); a leading `*.` is a | ||
| * subdomain wildcard, matching the rules used for `csp` domain fields. | ||
| * - Empty or omitted = every `ui/open-link` is subject to the host's | ||
| * default policy (typically a confirmation prompt). | ||
| * | ||
| * This is a UX hint, NOT an authorization mechanism. Hosts retain full | ||
| * authority, MUST still apply their own allowlist/blocklist, and SHOULD NOT | ||
| * treat a declared origin as proof that a destination is safe. | ||
|
Comment on lines
+240
to
+242
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @domfarolino, you paid special attention in the corresponding issue on making sure hosts understand this feature is in no way a trust mechanism. Could you review this last part and confirm wether you deem this explanation sufficient to ensure nobody uses |
||
| * | ||
| * @example | ||
| * ["https://example.com", "https://*.example.com"] | ||
| */ | ||
| linkTrustedDomains?: string[], | ||
| } | ||
| ``` | ||
|
|
||
|
|
@@ -254,6 +274,7 @@ The resource content is returned via `resources/read`: | |
| }; | ||
| domain?: string; | ||
| prefersBorder?: boolean; | ||
| linkTrustedDomains?: string[]; // Origins ui/open-link may skip confirmation for. | ||
| }; | ||
| }; | ||
| }]; | ||
|
|
@@ -262,7 +283,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, prefersBorder, linkTrustedDomains) 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. | ||
|
|
@@ -1039,6 +1060,23 @@ MCP Apps introduces additional JSON-RPC methods for UI-specific functionality: | |
|
|
||
| Host SHOULD open the URL in the user's default browser or a new tab. | ||
|
|
||
| By default, hosts SHOULD guard `ui/open-link` against unexpected navigation — | ||
| for example by showing a confirmation prompt — since the URL originates from | ||
| sandboxed UI content. | ||
|
|
||
| **Trusted destinations (`linkTrustedDomains`).** A server MAY declare origins it | ||
| legitimately links to via the resource's `_meta.ui.linkTrustedDomains` (see | ||
| [UI Resource Format](#ui-resource-format)). For a `ui/open-link` whose URL | ||
| matches one of those origins, the host MAY **skip the confirmation prompt** and | ||
| open the link directly. | ||
|
|
||
| Matching uses the same origin rules as `csp` domain fields: an entry is an | ||
| origin (scheme + host[:port]) and a leading `*.` is a subdomain wildcard. | ||
|
|
||
| > **Security:** `linkTrustedDomains` is a UX hint, not an authorization | ||
| > mechanism. Because the value comes from the (untrusted) server, hosts MUST | ||
| > still enforce their own allowlist/blocklist and MAY confirm regardless. | ||
|
|
||
| `ui/download-file` - Request host to download a file | ||
|
|
||
| ```typescript | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.