Skip to content

MCP Apps: revisit CORS vs. tunneled HTTP side channels for direct-connect sessions #4408

Description

@schloerke

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Priority: LowLow-impact bug, docs polish, papercut, or unclear low-severity request.ai-triage:doneMarks an issue whose AI triage workflow is complete.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions