feat: add ui/download-file method for host-mediated file downloads#475
Open
feat: add ui/download-file method for host-mediated file downloads#475
Conversation
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.
Collaborator
Author
Contributor
|
cc/ @connor4312 @nickcoai for input too :-) |
|
This is kind of neat
|
Replace custom {filename, content, mimeType, encoding} params with
standard MCP resource types: EmbeddedResource for inline content and
ResourceLink for host-resolved references.
New params shape:
params: { contents: (EmbeddedResource | ResourceLink)[] }
This reuses existing MCP primitives instead of inventing new ones,
and enables hosts to show resource 'bubbles' or resolve ResourceLink
URIs via resources/read on the MCP server.
Collaborator
Author
|
thank you @connor4312 |
connor4312
reviewed
Feb 20, 2026
| * For `EmbeddedResource` with `blob`, host MUST decode the content from base64 before creating the file. | ||
| * For `ResourceLink`, host MAY fetch the resource on behalf of the app or open the URI directly. | ||
| * Host MAY reject the download based on security policy, file size limits, or user preferences. | ||
| * Host SHOULD sanitize filenames to prevent path traversal. |
There was a problem hiding this comment.
I think this is no longer relevant in the resources world
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Add a new
ui/download-fileJSON-RPC request that allows MCP App views to request file downloads through the host.Why
MCP Apps run in sandboxed iframes where direct file downloads are blocked (
allow-downloadsis not set). Based on developer feedback, many apps need file export capabilities — visualization tools (SVG/PNG export), document editors, data analysis tools, and any app producing downloadable artifacts.ui/download-fileprovides a host-mediated mechanism for this, consistent with the existingui/open-linkpattern.Design: MCP Resource Types
Following feedback to reuse existing MCP primitives, the params use standard MCP resource types instead of custom fields:
EmbeddedResource— Inline content viaresource.text(UTF-8) orresource.blob(base64). The host creates a blob and triggers the download directly.ResourceLink— A reference URI the host resolves viaresources/readon the MCP server. This avoids passing large content through postMessage and lets hosts show resource "bubbles" or use native download mechanisms.This approach:
EmbeddedResource,ResourceLink) instead of inventing new content formatsResourceLinkfor cases where the host can fetch directly, avoiding unnecessary data transfer through the iframeChanges
Spec (
specification/draft/apps.mdx)ui/download-filerequest to "Requests (View → Host)" section with examples for bothEmbeddedResourceandResourceLinkdownloadFilecapability toHostCapabilitiesresources/readSDK
spec.types.ts:McpUiDownloadFileRequestuses(EmbeddedResource | ResourceLink)[],McpUiDownloadFileResult,downloadFileinMcpUiHostCapabilities,DOWNLOAD_FILE_METHODconstantapp.ts:App.downloadFile()method with JSDoc examples for embedded text, embedded blob, and resource linkapp-bridge.ts:AppBridge.ondownloadfilesetter with JSDoc example showing both resource typestypes.ts: Re-exports,AppRequest/AppResultunion additionsgenerate-schemas.ts: AddedEmbeddedResourceSchema,ResourceLinkSchemato external type listgenerated/: Auto-generated Zod schemas using SDK schema importsExample
integration-server: Two side-by-side demo buttons:EmbeddedResource(text content)ResourceLink(host resolves viaresources/read)integration-server/server.ts: Registers a sample downloadable resource atresource:///sample-report.txtProtocol
App SDK Usage
Security
ui/open-link)allow-downloadson iframe — download is always host-mediatedResourceLink, host resolves via MCPresources/read(no direct HTTP fetch from iframe)