Skip to content

feat: add MCP Apps (SEP-1865) support#1335

Draft
mattdholloway wants to merge 2 commits into
mainfrom
feat/mcp-apps-support
Draft

feat: add MCP Apps (SEP-1865) support#1335
mattdholloway wants to merge 2 commits into
mainfrom
feat/mcp-apps-support

Conversation

@mattdholloway
Copy link
Copy Markdown

Adds opt-in MCP Apps (SEP-1865) support to the SDK.

What

  • New enableMcpApps session capability (SessionConfig + ResumeSessionConfig). When true, the runtime advertises the extensions.io.modelcontextprotocol/ui extension to MCP servers and exposes the session.rpc.mcp.apps.{listTools,callTool,readResource,setHostContext,getHostContext} JSON-RPC methods. Defaults to false so hosts without an iframe renderer don't accidentally register UI-enabled tool variants they can't display.
  • Two new pure helpers in the Node SDK for hosts that render ui:// MCP App bundles in iframes:
    • buildMcpAppsCspHeader(csp) — builds the Content-Security-Policy header per SEP-1865 §UI Resource Format + §Security Implications. Emits the restrictive default (connect-src 'none') when _meta.ui.csp is absent, and the constructed default (connect-src 'self' + declared domains, etc.) when it is declared (even with empty arrays).
    • buildMcpAppsAllowAttribute(permissions) — maps _meta.ui.permissions to the iframe allow attribute (Permission Policy), including the hyphenated clipboard-write name.
  • Regenerated RPC/session-event types across Node, Python, Go, .NET, and Rust to pick up the new schema.

Tests

  • New 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 the allow attribute.
  • npm run build and the new test file pass locally.

Notes

  • Helpers are pure (no DOM, no fetch) so they're safe in Node, renderer, or service worker contexts.
  • Draft because I'd like a review on the spec-vs-implementation pinning before promoting.

@mattdholloway
Copy link
Copy Markdown
Author

@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>
@mattdholloway mattdholloway force-pushed the feat/mcp-apps-support branch from 5f12d41 to 0827b5a Compare May 19, 2026 16:51
@github-actions
Copy link
Copy Markdown
Contributor

Cross-SDK Consistency Review

Thanks 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: enableMcpApps capability in Python, Go, .NET, and Rust SDKs

The new enableMcpApps session option (which maps to the requestMcpApps wire flag) is only wired up in Node.js. The other four SDKs have no way to opt into MCP Apps support, meaning their sessions will never advertise extensions.io.modelcontextprotocol/ui to MCP servers.

The PR description mentions "Regenerated RPC/session-event types across Node, Python, Go, .NET, and Rust" but the diff only shows Node.js file changes. This appears to still be outstanding.

What needs to happen in each SDK:

  • Python (python/copilot/client.py): Add enable_mcp_apps: bool = False to create_session() and resume_session(), set payload["requestMcpApps"] = enable_mcp_apps alongside the other capability flags (~line 1497 and ~line 1883).

  • Go (go/types.go, go/client.go): Add EnableMcpApps bool to SessionConfig and ResumeSessionConfig (after OnExitPlanMode); set req.RequestMcpApps = Bool(true) in client.go when the flag is true (~lines 658–661 and 861–864).

  • .NET (dotnet/src/Types.cs, dotnet/src/Client.cs): Add public bool EnableMcpApps { get; set; } to both SessionConfig and ResumeSessionConfig; pass RequestMcpApps: config.EnableMcpApps ? true : null in both CreateSessionAsync and ResumeSessionAsync.

  • Rust (rust/src/types.rs): Add pub request_mcp_apps: Option<bool> to SessionConfig and ResumeSessionConfig (alongside request_exit_plan_mode), plus the corresponding with_request_mcp_apps builder method.

✅ Node.js-only helpers (buildMcpAppsCspHeader / buildMcpAppsAllowAttribute)

These helpers are specifically for iframe/browser rendering contexts. It's reasonable for them to live only in the Node.js SDK — no cross-language action needed here.


This review was generated by the SDK Consistency Review Agent.

Generated by SDK Consistency Review Agent for issue #1335 · ● 793.2K ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generated by SDK Consistency Review Agent for issue #1335 · ● 793.2K

Comment thread nodejs/src/types.ts
*
* @default false
*/
enableMcpApps?: boolean;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.pycreate_session() + resume_session() signatures enable_mcp_apps: bool = False parameter; payload["requestMcpApps"] = enable_mcp_apps
Go go/types.goSessionConfig + ResumeSessionConfig EnableMcpApps bool field; set req.RequestMcpApps = Bool(true) in client.go when the flag is set
.NET dotnet/src/Types.csSessionConfig + ResumeSessionConfig public bool EnableMcpApps { get; set; } property; pass RequestMcpApps: config.EnableMcpApps ? true : null in Client.cs
Rust rust/src/types.rsSessionConfig + ResumeSessionConfig pub request_mcp_apps: Option<bool> field + pub fn with_request_mcp_apps(mut self, enable: bool) -> Self builder

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant