feat: add ui/download-file method for host-mediated file downloads

Add a new ui/download-file JSON-RPC request that allows MCP App views to
request file downloads through the host. Since MCP Apps run in sandboxed
iframes where direct downloads are blocked (allow-downloads not set),
this provides a host-mediated mechanism for file exports.

Spec changes (draft):
- Add ui/download-file request to Requests (View → Host) section
- Add downloadFile capability to HostCapabilities
- Document host behavior requirements (confirmation dialog, filename
  sanitization, base64 decoding, size limits)

SDK changes:
- Add McpUiDownloadFileRequest/Result interfaces to spec.types.ts
- Add downloadFile() method to App class
- Add ondownloadfile setter to AppBridge class
- Add DOWNLOAD_FILE_METHOD constant
- Generate Zod schemas

Example:
- Add download demo to integration-server (exports JSON with server time)
- Capability check: only shows download button when host advertises
  downloadFile capability

Based on developer feedback requesting file export capabilities for
visualization tools, document editors, and data analysis apps.
This commit is contained in:
Anton Pidkuiko MacBook 2026-02-19 21:25:48 +00:00
commit 494c73e7ca
No known key found for this signature in database

View file

@ -648,6 +648,8 @@ interface HostCapabilities {
experimental?: {};
/** Host supports opening external URLs. */
openLinks?: {};
/** Host supports file downloads via ui/download-file. */
downloadFile?: {};
/** Host can proxy tool calls to the MCP server. */
serverTools?: {
/** Host supports tools/list_changed notifications. */
@ -1013,6 +1015,49 @@ 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.
`ui/download-file` - Request host to download a file
```typescript
// Request
{
jsonrpc: "2.0",
id: 1,
method: "ui/download-file",
params: {
filename: string, // Suggested filename
content: string, // File content (text or base64-encoded)
mimeType: string, // MIME type (e.g. "image/svg+xml", "application/json")
encoding?: "utf-8" | "base64" // Content encoding, defaults to "utf-8"
}
}
// Success Response
{
jsonrpc: "2.0",
id: 1,
result: {} // Empty result on success
}
// Error Response (if denied or failed)
{
jsonrpc: "2.0",
id: 1,
error: {
code: -32000, // Implementation-defined error
message: "Download denied by user" | "Invalid content" | "Policy violation"
}
}
```
MCP Apps run in sandboxed iframes where direct file downloads are blocked (`allow-downloads` is not set). `ui/download-file` provides a host-mediated mechanism for apps to offer file exports — useful for visualization tools (SVG/PNG export), document editors, data analysis tools, and any app that produces downloadable artifacts.
Host behavior:
* Host SHOULD show a confirmation dialog before initiating the download.
* Host SHOULD use the `filename` as the suggested filename for the download.
* For `encoding: "base64"`, host MUST decode the content from base64 before creating the file.
* Host MAY reject the download based on security policy, file size limits, or user preferences.
* Host SHOULD sanitize the filename to prevent path traversal.
`ui/message` - Send message content to the host's chat interface
```typescript