Skip to content

Commit 1ddd85b

Browse files
committed
Merge branch 'main' into fix/angular-preact-unify
2 parents 903aa82 + 2e8a176 commit 1ddd85b

File tree

8 files changed

+42
-213
lines changed

8 files changed

+42
-213
lines changed

.gitignore

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,5 @@ coverage/
2222
a2a_agents/python/a2ui_agent/src/a2ui/assets/**/*.json
2323
## new agent SDK path
2424
agent_sdks/python/src/a2ui/assets/**/*.json
25-
## Generated JS file from the strictly-typed `sandbox.ts`.
26-
samples/client/angular/projects/mcp_calculator/public/sandbox_iframe/sandbox.js
27-
*.tsbuildinfo
25+
## Generated files for sandbox frame.
26+
samples/client/angular/projects/mcp_calculator/public/sandbox_iframe/

samples/client/angular/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"build:renderer": "cd ../../../renderers && for dir in 'web_core' 'markdown/markdown-it'; do (cd \"$dir\" && npm install && npm run build); done",
1515
"serve:agent:restaurant": "cd ../../agent/adk/restaurant_finder && uv run .",
1616
"demo:restaurant": "npm run build:renderer && concurrently -k -n \"AGENT,WEB\" -c \"magenta,blue\" \"npm run serve:agent:restaurant\" \"npm start -- restaurant\"",
17-
"build:sandbox": "esbuild projects/mcp_calculator/public/sandbox_iframe/sandbox.ts --bundle --outfile=projects/mcp_calculator/public/sandbox_iframe/sandbox.js --format=esm --platform=browser"
17+
"build:sandbox": "esbuild ../shared/sandbox_iframe/sandbox.ts --bundle --outfile=projects/mcp_calculator/public/sandbox_iframe/sandbox.js --format=esm --platform=browser --alias:@modelcontextprotocol/ext-apps/app-bridge=./node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.js && cp ../shared/sandbox_iframe/sandbox.html projects/mcp_calculator/public/sandbox_iframe/sandbox.html"
1818
},
1919
"prettier": {
2020
"printWidth": 100,

samples/client/angular/projects/mcp_calculator/public/sandbox_iframe/README.md

Lines changed: 0 additions & 27 deletions
This file was deleted.

samples/client/angular/projects/mcp_calculator/public/sandbox_iframe/sandbox.html

Lines changed: 0 additions & 42 deletions
This file was deleted.

samples/client/angular/projects/mcp_calculator/public/sandbox_iframe/sandbox.ts

Lines changed: 0 additions & 128 deletions
This file was deleted.

samples/client/angular/projects/mcp_calculator/src/a2ui-catalog/mcp-app.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,16 @@ export class McpApp
143143

144144
window.addEventListener('message', this.messageHandler);
145145

146-
// Set src to trigger load AFTER listener is ready
147-
// TODO: Make the sandbox URL configurable. To ensure CORS encapsulation, the sandbox
148-
// should be served from a different origin than the host app.
149-
const sandboxUrl = 'sandbox_iframe/sandbox.html';
146+
147+
// Check for query param to opt-out of origin toggle (for testing)
148+
const urlParams = new URLSearchParams(window.location.search);
149+
const disableSecuritySelfTest = urlParams.get('disable_security_self_test') === 'true';
150+
151+
const currentOrigin = window.location.origin;
152+
let sandboxUrl = `${currentOrigin}/sandbox_iframe/sandbox.html`;
153+
if (disableSecuritySelfTest) {
154+
sandboxUrl += '?disable_security_self_test=true';
155+
}
150156
this.iframeSrc.set(
151157
this.sanitizer.bypassSecurityTrustResourceUrl(sandboxUrl),
152158
);

samples/client/shared/sandbox_iframe/README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ A2UI utilizes a **double-iframe isolation pattern** to run untrusted third-party
1515

1616
Testing for any changes in this directory requires bringing up the relevant clients and servers.
1717

18-
### Contact Multi-Surface Sample (Lit & ADK Agent)
18+
### 1. Contact Multi-Surface Sample (Lit & ADK Agent)
1919

2020
This test verifies the sandbox with a Lit-based client and an ADK-based A2A agent.
2121

@@ -26,3 +26,18 @@ This test verifies the sandbox with a Lit-based client and an ADK-based A2A agen
2626
- Path: `../../lit/contact/`
2727
- Command: `npm run dev` (requires building the Lit renderer first)
2828
- URL: `http://localhost:5173/`
29+
30+
### 2. MCP Apps (Calculator) (Angular)
31+
32+
This test verifies the sandbox with an Angular-based client, an MCP Proxy Agent, and a remote MCP Server.
33+
34+
- **MCP Server (Calculator)**:
35+
- Path: `../../../agent/mcp/mcp-apps-calculator/`
36+
- Command: `uv run .` (runs on port 8000)
37+
- **MCP Apps Proxy Agent**:
38+
- Path: `../../../agent/adk/mcp_app_proxy/`
39+
- Command: `uv run .` (requires `GEMINI_API_KEY` in `.env`)
40+
- **Angular Client App**:
41+
- Path: `../../angular/`
42+
- Command: `npm start -- mcp_calculator` (requires `npm run build:sandbox` and `npm install`)
43+
- URL: [`http://localhost:4200/?disable_security_self_test=true`](http://localhost:4200/?disable_security_self_test=true)

samples/client/shared/sandbox_iframe/sandbox.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,19 @@ if (!document.referrer.match(ALLOWED_REFERRER_PATTERN)) {
4343
const EXPECTED_HOST_ORIGIN = new URL(document.referrer).origin;
4444
const OWN_ORIGIN = new URL(window.location.href).origin;
4545

46-
// Security self-test: verify iframe isolation is working correctly.
47-
try {
48-
window.top!.alert("If you see this, the sandbox is not setup securely.");
49-
throw "FAIL";
50-
} catch (e) {
51-
if (e === "FAIL") {
52-
throw new Error("The sandbox is not setup securely.");
46+
// Check for query param to opt-out of security self-test (for testing)
47+
const urlParams = new URLSearchParams(window.location.search);
48+
const disableSelfTest = urlParams.get('disable_security_self_test') === 'true';
49+
50+
if (!disableSelfTest) {
51+
// Security self-test: verify iframe isolation is working correctly.
52+
try {
53+
window.top!.alert("If you see this, the sandbox is not setup securely.");
54+
throw "FAIL";
55+
} catch (e) {
56+
if (e === "FAIL") {
57+
throw new Error("The sandbox is not setup securely.");
58+
}
5359
}
5460
}
5561

0 commit comments

Comments
 (0)