fix(embed): make embed-mode framing opt-in

Embed-mode documents now keep the server's framing protection unless
GEV_EMBED_FRAME_ANCESTORS names the pages that may frame them (or * for any
page). The MCP Apps panel loads the app into its own page and needs no
framing. View answers are posted to the origin that sent the view rather
than to any origin.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Sameh KhamisandClaude Opus 5.5 committed 2026-10-02 19:47:37 -07:00
1 parent 3318390e3f
commit f7d3db5875
7 files changed
+74 -36

No files matched your search

+2 -1
View File
@@ -10,7 +10,8 @@ The panel runs the app's panel build (`npm run build:panel`, served at
`/panel/`) and loads it, with its data, through the MCP server, so it works
in Claude Desktop and in the Codex and ChatGPT desktop apps with a local
server and no HTTPS. `?embed=1` shows the app as the globe alone and takes
new views from the page that frames it. MCP leads with the tools that find
new views from the page that frames it; framing is off unless
`GEV_EMBED_FRAME_ANCESTORS` allows the framing page. MCP leads with the tools that find
what to show. See [tools and the MCP server](TOOLS.md).
## Tools and local MCP server — October 1, 2026
+8 -7
View File
@@ -164,14 +164,15 @@ The app applies it through its own actions (style, map, exactly the view's
layers, annotations, then the followed entity, retried until its layer has
it, or the camera when nothing is followed or the entity is not there yet,
since a camera flight would end the follow; then cockpit view when asked) and
answers `{ type: 'gev:view-applied', id, ok, steps }`. It
posts `{ type: 'gev:ready' }` once it can take views, and only its parent
page can send them. See `src/app/embed.js`.
answers `{ type: 'gev:view-applied', id, ok, steps }` to the origin that
sent the view. It posts `{ type: 'gev:ready' }` once it can take views, and
only its parent page can send them. See `src/app/embed.js`.
The development and preview servers let other pages frame embed-mode
documents only; every other document keeps `X-Frame-Options: DENY` and
`frame-ancestors 'none'`. `GEV_EMBED_FRAME_ANCESTORS` restricts which pages
may frame them (any by default).
No page may frame the app by default: every document keeps
`X-Frame-Options: DENY` and `frame-ancestors 'none'`. Setting
`GEV_EMBED_FRAME_ANCESTORS` lets the pages it names (CSP frame-ancestors
sources, or `*` for any page) frame embed-mode documents only. The MCP Apps
panel loads the app into its own page and needs no framing.
Answers that have something to show include `data.view`: the view that
shows them, with the matching layers on, an area framed from above, and a