Skip to content

Commit 03cc5f9

Browse files
committed
refactor: Add a new Angular sample project for an MCP calculator with A2A integration.
1 parent c709920 commit 03cc5f9

30 files changed

Lines changed: 962 additions & 45 deletions

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +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/orchestrator/public/sandbox_iframe/sandbox.js
25+
## Generated JS file from the strictly-typed `sandbox.ts`.
26+
samples/client/angular/projects/mcp_calculator/public/sandbox_iframe/sandbox.js

samples/agent/adk/orchestrator/README.md

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,17 @@ Subagents are configured using RemoteA2aAgent which translates ADK events to A2A
4242
uv run . --port=10005
4343
```
4444

45-
Optionally, run the MCP Server and MCP App Proxy Agent to MCP Apps in A2UI demo:
46-
47-
```bash
48-
cd samples/agent/mcp/calculator
49-
uv run . --port=8000
50-
```
51-
52-
```bash
53-
cd samples/agent/adk/mcp_app_proxy
54-
uv run . --port=10006
55-
```
56-
5745
3. Run the orchestrator agent:
5846

5947
```bash
6048
cd samples/agent/adk/orchestrator
61-
uv run . --port=10002 --subagent_urls=http://localhost:10003 --subagent_urls=http://localhost:10004 --subagent_urls=http://localhost:10005 --subagent_urls=http://localhost:10006
49+
uv run . --port=10002 --subagent_urls=http://localhost:10003 --subagent_urls=http://localhost:10004 --subagent_urls=http://localhost:10005
6250
```
6351

6452
4. Try commands that work with any agent:
6553
a. "Who is Alex Jordan?" (routed to contact lookup agent)
6654
b. "Show me chinese food restaurants in NYC" (routed to restaurant finder agent)
6755
c. "Show my sales data for Q4" (routed to rizzcharts)
68-
d. "Open calculator" (routed to mcp app proxy)
6956

7057
## Disclaimer
7158

@@ -75,4 +62,4 @@ All operational data received from an external agent—including its AgentCard,
7562

7663
Similarly, any UI definition or data stream received must be treated as untrusted. Malicious agents could attempt to spoof legitimate interfaces to deceive users (phishing), inject malicious scripts via property values (XSS), or generate excessive layout complexity to degrade client performance (DoS). If your application supports optional embedded content (such as iframes or web views), additional care must be taken to prevent exposure to malicious external sites.
7764

78-
Developer Responsibility: Failure to properly validate data and strictly sandbox rendered content can introduce severe vulnerabilities. Developers are responsible for implementing appropriate security measures—such as input sanitization, Content Security Policies (CSP), strict isolation for optional embedded content, and secure credential handling—to protect their systems and users.
65+
Developer Responsibility: Failure to properly validate data and strictly sandbox rendered content can introduce severe vulnerabilities. Developers are responsible for implementing appropriate security measures—such as input sanitization, Content Security Policies (CSP), strict isolation for optional embedded content, and secure credential handling—to protect their systems and users.

samples/client/angular/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Here are the instructions if you want to do each step manually.
3737
* `npm start -- contact`
3838
* `npm start -- rizzcharts`
3939
* `npm start -- orchestrator`
40+
* `npm run build:sandbox && npm start -- mcp_calculator`
4041
* `npm start -- gallery` (Client-only, no server required)
4142
5. Open http://localhost:4200/
4243

samples/client/angular/angular.json

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,116 @@
495495
}
496496
}
497497
}
498+
},
499+
"mcp_calculator": {
500+
"projectType": "application",
501+
"schematics": {
502+
"@schematics/angular:component": {
503+
"style": "scss",
504+
"skipTests": true
505+
},
506+
"@schematics/angular:class": {
507+
"skipTests": true
508+
},
509+
"@schematics/angular:directive": {
510+
"skipTests": true
511+
},
512+
"@schematics/angular:guard": {
513+
"skipTests": true
514+
},
515+
"@schematics/angular:interceptor": {
516+
"skipTests": true
517+
},
518+
"@schematics/angular:pipe": {
519+
"skipTests": true
520+
},
521+
"@schematics/angular:resolver": {
522+
"skipTests": true
523+
},
524+
"@schematics/angular:service": {
525+
"skipTests": true
526+
}
527+
},
528+
"root": "projects/mcp_calculator",
529+
"sourceRoot": "projects/mcp_calculator/src",
530+
"prefix": "app",
531+
"architect": {
532+
"build": {
533+
"builder": "@angular/build:application",
534+
"options": {
535+
"browser": "projects/mcp_calculator/src/main.ts",
536+
"tsConfig": "projects/mcp_calculator/tsconfig.app.json",
537+
"preserveSymlinks": true,
538+
"inlineStyleLanguage": "scss",
539+
"assets": [
540+
{
541+
"glob": "**/*",
542+
"input": "projects/mcp_calculator/public"
543+
}
544+
],
545+
"styles": [
546+
"projects/mcp_calculator/src/styles.scss"
547+
],
548+
"server": "projects/mcp_calculator/src/main.server.ts",
549+
"outputMode": "server",
550+
"ssr": {
551+
"entry": "projects/mcp_calculator/src/server.ts"
552+
}
553+
},
554+
"configurations": {
555+
"production": {
556+
"budgets": [
557+
{
558+
"type": "initial",
559+
"maximumWarning": "500KB",
560+
"maximumError": "1MB"
561+
},
562+
{
563+
"type": "anyComponentStyle",
564+
"maximumWarning": "4kB",
565+
"maximumError": "8kB"
566+
}
567+
],
568+
"outputHashing": "all"
569+
},
570+
"development": {
571+
"optimization": false,
572+
"extractLicenses": false,
573+
"sourceMap": true
574+
}
575+
},
576+
"defaultConfiguration": "production"
577+
},
578+
"serve": {
579+
"builder": "@angular/build:dev-server",
580+
"configurations": {
581+
"production": {
582+
"buildTarget": "mcp_calculator:build:production"
583+
},
584+
"development": {
585+
"buildTarget": "mcp_calculator:build:development"
586+
}
587+
},
588+
"defaultConfiguration": "development"
589+
},
590+
"test": {
591+
"builder": "@angular/build:karma",
592+
"options": {
593+
"codeCoverage": true,
594+
"tsConfig": "projects/mcp_calculator/tsconfig.spec.json",
595+
"inlineStyleLanguage": "scss",
596+
"assets": [
597+
{
598+
"glob": "**/*",
599+
"input": "projects/mcp_calculator/public"
600+
}
601+
],
602+
"styles": [
603+
"projects/mcp_calculator/src/styles.scss"
604+
]
605+
}
606+
}
607+
}
498608
}
499609
},
500610
"cli": {

samples/client/angular/package.json

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +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-
"serve:agent:contact": "cd ../../agent/adk/contact_lookup && uv run .",
18-
"demo:contact": "npm run build:renderer && concurrently -k -n \"AGENT,WEB\" -c \"magenta,blue\" \"npm run serve:agent:contact\" \"npm start -- contact\"",
19-
"serve:agent:rizzcharts": "cd ../../agent/adk/rizzcharts && uv run .",
20-
"demo:rizzcharts": "npm run build:renderer && concurrently -k -n \"AGENT,WEB\" -c \"magenta,blue\" \"npm run serve:agent:rizzcharts\" \"npm start -- rizzcharts\"",
21-
"build:sandbox": "esbuild projects/orchestrator/public/sandbox_iframe/sandbox.ts --bundle --outfile=projects/orchestrator/public/sandbox_iframe/sandbox.js --format=esm --platform=browser"
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"
2218
},
2319
"prettier": {
2420
"printWidth": 100,
@@ -93,4 +89,4 @@
9389
"../../../renderers/web_core",
9490
"../../../renderers/markdown/markdown-it"
9591
]
96-
}
92+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# MCP Calculator
2+
3+
Sample application using the Chat-Canvas component with MCP Calculator Agent.
4+
5+
## Prerequisites
6+
7+
1. [nodejs](https://nodejs.org/en)
8+
2. An endpoint hosting the MCP Calculator A2AService. ([Review the instructions on how to run MCP Calculator A2AService](../../../../agent/adk/mcp_app_proxy/README.md).)
9+
10+
## Running
11+
12+
1. Build the shared dependencies by running `npm run build` in the `renderers/web_core` directory
13+
2. Install the dependencies: `npm i`
14+
3. Run the A2A server for all of the agents. ([Link to instructions](../../../../agent/adk/mcp_app_proxy/README.md))
15+
4. Build the `sandbox.js` for testing MCP Apps in A2UI demo
16+
17+
- `npm run build:sandbox`
18+
19+
5. Run the app:
20+
21+
- `npm start -- mcp_calculator`
22+
23+
6. Open http://localhost:4200/
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Loading

samples/client/angular/projects/orchestrator/public/sandbox_iframe/README.md renamed to samples/client/angular/projects/mcp_calculator/public/sandbox_iframe/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This directory contains the `sandbox.html` and its associated resources.
66

77
`sandbox.html` is designed to be loaded into an `<iframe>` to provide a secure,
88
isolated environment for running MCP (Model Context Protocol) applications. It
9-
acts as a bridge between the host application (Orchestrator) and the untrusted
9+
acts as a bridge between the host application (MCP Calculator) and the untrusted
1010
or external MCP apps, managing communication via `postMessage`.
1111

1212
## Development

samples/client/angular/projects/orchestrator/public/sandbox_iframe/sandbox.html renamed to samples/client/angular/projects/mcp_calculator/public/sandbox_iframe/sandbox.html

File renamed without changes.

0 commit comments

Comments
 (0)