From cd6bfb9efba32df2850d55c89caea72a631aa726 Mon Sep 17 00:00:00 2001 From: ancientcomputing Date: Mon, 12 Oct 2026 20:09:51 -0700 Subject: [PATCH 1/2] sdk-guide: MCP Apps sandbox, layer by layer (CSP intersection, content rules, sandboxed iframe, pinned navigation) --- docs/sdk-guide.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/docs/sdk-guide.md b/docs/sdk-guide.md index 13f2cab..c87c466 100644 --- a/docs/sdk-guide.md +++ b/docs/sdk-guide.md @@ -706,6 +706,36 @@ policy allows them. Shared context reaches the model with the next `respond` / ` turn — a turn run on `languageModelSession` doesn't send it ([Running a turn](#running-a-turn-and-when-to-use-languagemodelsession)). `ConfirmingToolAuthorizer` remembers the user's answer per view and tool, so a polling view asks once (destructive calls ask each time). +**The sandbox, layer by layer.** A view is HTML and script from someone else's server, so +`MCPAppViewController` contains it in layers, each of which holds even if the one above it failed: + +1. **CSP, declared ∩ allowed.** A server's `_meta.ui.csp` is a request, not a grant: the CSP + actually served on the view's document is each declared origin list intersected with your + `MCPAppsSandboxPolicy` (`allowedConnectOrigins`, `allowedResourceOrigins`, + `allowedFrameOrigins`), so a server update can never widen what your app lets a view reach. + With the default `.closed` policy that is `default-src 'none'`, `connect-src 'none'`, + `frame-src 'none'`, plus `base-uri`, `form-action` and `object-src 'none'`; inline script and + style run, nothing loads from the network. Server-supplied origins are validated strictly + (`https://` / `wss://`, a DNS host, optional port) before they go into the header, and + `baseUriDomains` is never granted. Read `controller.effectiveCSP` for what a view really got. +2. **A network block under the CSP.** A `WKContentRuleList` on the whole web view blocks every + http(s), ws(s) and ftp load outside the effective origins — so even a mis-served CSP lets + nothing out. +3. **A sandboxed iframe.** The view runs in an `