[MCP-UI] Proxy and Better Message Handling#5487
Conversation
ui/desktop/src/main.ts
Outdated
|
|
||
| async function startMcpUIProxyServer(): Promise<number> { | ||
| return new Promise((resolve, reject) => { | ||
| const expressApp = express(); |
There was a problem hiding this comment.
nice - and this looks like it is already in the dependencies from electron?
There was a problem hiding this comment.
yeah! Express is already a dependency in the app.
https://github.com/block/goose/blob/feat/mcp-ui-improvements/ui/desktop/package.json#L70
There was a problem hiding this comment.
just a note regarding the deletions in this file: previously we were over-handling messages form the iframe, upgrading @mcp-ui/client and using a proxy takes most of this off our plate.
|
.bundle |
… checks. Update related comments and variable names for clarity.
…d origin checks. Update related comments and variable names for clarity." This reverts commit 0ce5a8a.
|
@aharvard looks good! Glad this also uses the SDK functionality instead of custom Goose code. |
|
Thanks for looking @liady!
^ yeah, you read my mind! |
idosal
left a comment
There was a problem hiding this comment.
Looks great @aharvard !
cc @evalstate - this should remove the limitations on the HF MCP-UI tools
There was a problem hiding this comment.
Pull Request Overview
This PR implements an MCP-UI proxy server to enable secure rendering of MCP UI resources in the Goose Desktop application. The proxy server allows controlled iframe embedding of external content while maintaining security through token-based authentication and origin validation.
Key changes:
- Added an HTTP server using Express to serve MCP-UI proxy HTML files with token-based security
- Integrated the
@mcp-ui/clientlibrary (updated to v5.14.1) for rendering MCP UI resources - Implemented security controls including random token generation, header injection, and origin validation
Reviewed Changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/desktop/static/mcp-ui-proxy.html | New proxy HTML page that handles iframe embedding for both raw HTML and external URLs with content security policy |
| ui/desktop/src/main.ts | Adds Express HTTP server for MCP-UI proxy with security middleware, port management, and Electron session configuration |
| ui/desktop/src/preload.ts | Exposes getMcpUIProxyUrl API to renderer process for fetching the proxy server URL |
| ui/desktop/src/components/MCPUIResourceRenderer.tsx | Refactors action handlers, removes custom type definitions in favor of imported types, and configures proxy URL support |
| ui/desktop/package.json | Updates @mcp-ui/client dependency from v5.13.0 to v5.14.1 |
| ui/desktop/package-lock.json | Updates lock file for @mcp-ui/client v5.14.1 |
| ui/desktop/forge.config.ts | Adds static directory to packaged resources |
Files not reviewed (1)
- ui/desktop/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.
Files not reviewed (1)
- ui/desktop/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Use lowercase 'x-mcp-ui-proxy-token' when injecting header to match Express's normalized header names for consistency and clarity.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.
Files not reviewed (1)
- ui/desktop/package-lock.json: Language not supported
Comments suppressed due to low confidence (1)
ui/desktop/src/components/MCPUIResourceRenderer.tsx:1
- Comment on line 332 contains a typo: 'MPC-UIs' should be 'MCP-UIs'.
import {
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
I chatted with @DOsinga about moving the server into the Rust backend, and @alexhancock will perform the maneuver. Thanks, guys! |
|
Thanks @alexhancock for moving the proxy server from Electron to the backend in #5749 @DOsinga and @michaelneale — can we get another look? If everything is in order, I'd like to merge! |
|
would that live mcp sampling test have anytihng to do with this - or just bad luck? |
* origin/main: (60 commits) chore: incorporate LF feedback (#5787) docs: quick launcher (#5779) Bump auto scroll threshold (#5738) fix: add one-time cleanup for linux hermit locking issues (#5742) Don't show update tray icon if GOOSE_VERSION is set (#5750) fix: get win node path from registry (#5731) Handle spaces in extension names also (#5770) Remove empty settings card for Scheduling Engine (#5771) fix windows cli build (#5768) fix: Implement a CredentialStore for auth (#5741) blog post: How to Successfully Migrate Your App with an AI Agent (#5762) Simplify finding `goosed` (#5739) More time for goosed (#5746) Match lower case (#5763) scan recipe for security when saving recipe (#5747) feat: trying grok for live test (#5732) Platform Extension MOIM (Minus One Info Message) (#5027) docs: remove hackathon banner (#5756) Fix: Recipes respect the quiet flag (#5743) docs: update cli commands (#5744) ...
dismissing stale review to unblock merge checks
FYI gpt-5-mini sampling test kept failing. I got it to pass on the second manual re-run. All checks passed. Ready to merge? |
|
Ran copilot security review and this came up as potentially important. Wondering if worth addressing @alexhancock or @DOsinga |
Co-authored-by: Andrew Harvard <aharvard@squareup.com>
…xt-test * 'main' of github.com:block/goose: chore: Add Adrian Cole to Maintainers (#5815) [MCP-UI] Proxy and Better Message Handling (#5487) Release 1.15.0 Document New Window menu in macOS dock (#5811) Catch cron errors (#5707) feat/fix Re-enabled WAL with commit transaction management (Linux Verification Requested) (#5793) chore: remove autopilot experimental feature (#5781) Read paths from an interactive & login shell (#5774) docs: acp clients (#5800)
* main: (33 commits) fix: support Gemini 3's thought signatures (#5806) chore: Add Adrian Cole to Maintainers (#5815) [MCP-UI] Proxy and Better Message Handling (#5487) Release 1.15.0 Document New Window menu in macOS dock (#5811) Catch cron errors (#5707) feat/fix Re-enabled WAL with commit transaction management (Linux Verification Requested) (#5793) chore: remove autopilot experimental feature (#5781) Read paths from an interactive & login shell (#5774) docs: acp clients (#5800) Provider error proxy for simulating various types of errors (#5091) chore: Add links to maintainer profiles (#5788) Quick fix for community all stars script (#5798) Document Mistral AI provider (#5799) docs: Add Community Stars recipe script and txt file (#5776) chore: incorporate LF feedback (#5787) docs: quick launcher (#5779) Bump auto scroll threshold (#5738) fix: add one-time cleanup for linux hermit locking issues (#5742) Don't show update tray icon if GOOSE_VERSION is set (#5750) ...
* main: (48 commits) [fix] generic check for gemini compat (#5842) Add scheduler to diagnostics (#5849) Cors and token (#5850) fix sessions coming back with empty messages (#5841) markdown export from URL (#5830) Next camp refactor live (#5706) Add out of context compaction test via error proxy (#5805) fix: Add backward compatibility for conversationCompacted message type (#5819) Add /agent/stop endpoint, make max active agents configurable (#5826) Handle 404s (#5791) Persist provider name and model config in the session (#5419) Comment out the flaky mcp callers (#5827) Slash commands (#5718) fix: remove setx calls to not permanently edit the windows shell PATH (#5821) fix: Parse maas models for gcp vertex provider (#5816) fix: support Gemini 3's thought signatures (#5806) chore: Add Adrian Cole to Maintainers (#5815) [MCP-UI] Proxy and Better Message Handling (#5487) Release 1.15.0 Document New Window menu in macOS dock (#5811) ...
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Alex Hancock <alexhancock@block.xyz> Co-authored-by: Zane <75694352+zanesq@users.noreply.github.com> Signed-off-by: Blair Allan <Blairallan@icloud.com>
Summary
This PR upgrades
@mcp-ui/clientto better handle messages from MCP-UI iframes and also decouples the MCP-UI iframe CSP from Goose's top-level CSP set for Electron.Our top-level CSP previously blocked external fonts, stylesheets, scripts, and media. We now use an MCP-UI Proxy with a permissive CSP inside a sandboxed iframe for security. This creates a parent-child iframe architecture in Goose.
Demo
Now, Goose can load external fonts inside MCP-UI iframes and MCP-UI resources can send
request-render-datato get thethemevalue from goose (as shown here in mcp-ui docs)goose-proxy-csp-fonts.mov
Now, Goose can load external video and audio media files (unmute video below for sound).
goose-proxy-csp-media.mov
Type of Change
Testing
Manual testing with aharavrd mcp as shown in videos above.
Related Issues
No issue or discussions to link.
Note
This work enables MCP-UI interoperability between Goose and ChatGPT by addressing two blockers:
Sandboxed iframe with permissive CSP - Implements ChatGPT's approach of using a 3rd party sandboxed origin with a lax CSP, enabling capabilities like remote script execution. This follows MCP-UI's documented pattern (used by Postman).
Render data support - Adds full render data implementation, which is currently missing in Goose.
This unblocks @idosal and @liady from targeting Goose for cross-platform MCP-UI development with the Apps SDK.