feat: add MCP Apps (SEP-1865) support#1335
Conversation
|
@copilot resolve the merge conflicts in this pull request |
Adds opt-in 'enableMcpApps' session capability that advertises the
'extensions.io.modelcontextprotocol/ui' extension to MCP servers and
exposes 'session.rpc.mcp.apps.*' JSON-RPC methods.
Node SDK gains two pure helpers for hosts rendering 'ui://' MCP App
bundles in iframes:
- buildMcpAppsCspHeader — constructs the Content-Security-Policy header
per SEP-1865 §UI Resource Format + §Security Implications, including
the restrictive default ('connect-src none') when '_meta.ui.csp' is
absent and constructed defaults ('connect-src self', etc.) when it is
declared.
- buildMcpAppsAllowAttribute — maps '_meta.ui.permissions' to the iframe
'allow' attribute (Permission Policy).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
5f12d41 to
0827b5a
Compare
Cross-SDK Consistency ReviewThanks for adding MCP Apps (SEP-1865) support! The implementation in Node.js looks solid, but there is one consistency gap that needs to be addressed before merging. ❌ Missing:
|
There was a problem hiding this comment.
Generated by SDK Consistency Review Agent for issue #1335 · ● 793.2K
| * | ||
| * @default false | ||
| */ | ||
| enableMcpApps?: boolean; |
There was a problem hiding this comment.
Cross-SDK consistency gap: enableMcpApps is added here and to ResumeSessionConfig in Node.js, but the equivalent option is missing from the other four SDK implementations.
The requestMcpApps wire flag won't be sent by Python, Go, .NET, or Rust sessions, so hosts using those SDKs can't opt in to MCP Apps support. Suggested additions to bring the other SDKs into parity:
| SDK | Location | What to add |
|---|---|---|
| Python | python/copilot/client.py — create_session() + resume_session() signatures |
enable_mcp_apps: bool = False parameter; payload["requestMcpApps"] = enable_mcp_apps |
| Go | go/types.go — SessionConfig + ResumeSessionConfig |
EnableMcpApps bool field; set req.RequestMcpApps = Bool(true) in client.go when the flag is set |
| .NET | dotnet/src/Types.cs — SessionConfig + ResumeSessionConfig |
public bool EnableMcpApps { get; set; } property; pass RequestMcpApps: config.EnableMcpApps ? true : null in Client.cs |
| Rust | rust/src/types.rs — SessionConfig + ResumeSessionConfig |
pub request_mcp_apps: Option<bool> field + pub fn with_request_mcp_apps(mut self, enable: bool) -> Self builder |
Adds opt-in MCP Apps (SEP-1865) support to the SDK.
What
enableMcpAppssession capability (SessionConfig+ResumeSessionConfig). Whentrue, the runtime advertises theextensions.io.modelcontextprotocol/uiextension to MCP servers and exposes thesession.rpc.mcp.apps.{listTools,callTool,readResource,setHostContext,getHostContext}JSON-RPC methods. Defaults tofalseso hosts without an iframe renderer don't accidentally register UI-enabled tool variants they can't display.ui://MCP App bundles in iframes:buildMcpAppsCspHeader(csp)— builds theContent-Security-Policyheader per SEP-1865 §UI Resource Format + §Security Implications. Emits the restrictive default (connect-src 'none') when_meta.ui.cspis absent, and the constructed default (connect-src 'self'+ declared domains, etc.) when it is declared (even with empty arrays).buildMcpAppsAllowAttribute(permissions)— maps_meta.ui.permissionsto the iframeallowattribute (Permission Policy), including the hyphenatedclipboard-writename.Tests
nodejs/test/mcpAppsSandbox.test.ts(11 tests) pins both the restrictive default and the constructed default to the spec text, plus per-feature mapping for theallowattribute.npm run buildand the new test file pass locally.Notes