Clarify spec and SDK: accept UIResourceMeta in both resources/list and resources/read (#410)
* Clarify spec and SDK: accept UIResourceMeta in both resources/list and resources/read The spec defines UIResource with _meta.ui, implicitly as an extension of the Resource type (resources/list), but examples and practice place _meta.ui on TextResourceContents (resources/read). The registerAppResource helper accepts _meta.ui in its config (which ends up in resources/list), but examples only return said _meta.ui from resources/read — and current hosts might be just ignoring it. This change: - Adds a 'Metadata Location' subsection to the draft spec explicitly stating that _meta.ui is valid on both the resource listing entry AND the content item, with content-item taking precedence. - Updates the spec example to show _meta on the resource declaration (resources/list). - Updates the CSP construction example to reference both locations. - Clarifies McpUiAppResourceConfig JSDoc: _meta here appears in resources/list and serves as a listing-level fallback for when content items omit _meta.ui. - Fixes the map-server example comment that incorrectly stated _meta must only be on the content item. * Add McpUiReadResourceResult type for UI metadata in resources/read * basic-host: support UIResourceMeta fallback from resources/list --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
2dd56c3dce
commit
bcfffb6585
1 changed files with 73 additions and 16 deletions
|
|
@ -260,6 +260,17 @@ The resource content is returned via `resources/read`:
|
|||
}
|
||||
```
|
||||
|
||||
#### Metadata Location
|
||||
|
||||
`UIResourceMeta` (CSP, permissions, domain, 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.
|
||||
|
||||
When `_meta.ui` is present on **both**, the content-item value takes precedence. Hosts MUST check both locations, preferring the content item and falling back to the listing entry.
|
||||
|
||||
> **Server guidance:** Prefer placing `_meta.ui` on the content item in `resources/read`, especially when metadata is dynamic or varies per-response. Use the listing-level `_meta.ui` (via `registerAppResource` config) when metadata is static and you want hosts to be able to review security configuration at connection time without fetching the resource.
|
||||
|
||||
#### Content Requirements:
|
||||
|
||||
- URI MUST start with `ui://` scheme
|
||||
|
|
@ -287,15 +298,24 @@ The resource content is returned via `resources/read`:
|
|||
Example:
|
||||
|
||||
```json
|
||||
// Resource declaration
|
||||
// Resource declaration (resources/list) — static defaults for host review
|
||||
{
|
||||
"uri": "ui://weather-server/dashboard-template",
|
||||
"name": "weather_dashboard",
|
||||
"description": "Interactive weather dashboard view",
|
||||
"mimeType": "text/html;profile=mcp-app"
|
||||
"mimeType": "text/html;profile=mcp-app",
|
||||
"_meta": {
|
||||
"ui": {
|
||||
"csp": {
|
||||
"connectDomains": ["https://api.openweathermap.org"],
|
||||
"resourceDomains": ["https://cdn.jsdelivr.net"]
|
||||
},
|
||||
"prefersBorder": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resource content with metadata
|
||||
// Resource content (resources/read) — takes precedence when present
|
||||
{
|
||||
"contents": [{
|
||||
"uri": "ui://weather-server/dashboard-template",
|
||||
|
|
@ -1725,8 +1745,10 @@ Hosts MUST enforce Content Security Policies based on resource metadata.
|
|||
**CSP Construction from Metadata:**
|
||||
|
||||
```typescript
|
||||
const csp = resource._meta?.ui?.csp; // `resource` is extracted from the `contents` of the `resources/read` result
|
||||
const permissions = resource._meta?.ui?.permissions;
|
||||
// Prefer content-level _meta.ui (resources/read), fall back to listing-level (resources/list)
|
||||
const uiMeta = resource._meta?.ui ?? listingResource._meta?.ui;
|
||||
const csp = uiMeta?.csp;
|
||||
const permissions = uiMeta?.permissions;
|
||||
|
||||
const cspValue = `
|
||||
default-src 'none';
|
||||
|
|
|
|||
Loading…
Reference in a new issue