You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
MCP Apps: revisit CORS vs. tunneled HTTP side channels for direct-connect sessions #4408
Tracking a deliberately-deferred design decision from the MCP Apps work (#4407).
Context
When a Shiny app is served as an MCP App, HTTP side channels (file upload/download, server-side selectize/DataTables, dynamically inserted dependencies) need to reach the app from the sandboxed iframe. Two transports exist:
Tunnel — requests go through the app-only _shiny_http tool (postMessage → tools/call), same channel as the websocket tunnel.
Direct-connect — where the host honors the declared CSP, the iframe opens a real WebSocket straight to the app for reactivity.
Today, even in direct-connect mode the HTTP side channels stay tunneled (_shiny_http accepts calls without a connectionId), and no CORS headers are added to the app.
The trade-off (why it's deferred)
Adding permissive CORS to the app so the iframe could make direct cross-origin XHRs would mean any website could read a localhost/deployed Shiny app's responses. That's an unacceptable default, so we kept side channels tunneled. The cost is extra round-trips for side-channel traffic in direct mode (reactivity itself is still native-speed over the direct WebSocket).
What to revisit
Is there a safe, scoped CORS story (e.g. echoing only the host's sandbox origin, credentialed vs. not, per-deployment opt-in) that would let direct-mode side channels go direct without opening the app to arbitrary origins?
Or is tunneled-side-channels the right permanent design, in which case close this and document the rationale?
References: mcp/QUESTIONS.md §3 and mcp/architecture.md ("Security decisions") on the branch.
Experimental feature; not blocking the initial merge.
Activity