diff --git a/.github/workflows/community_code.yml b/.github/workflows/community_code.yml
index 0abdff1460..f49ae2feae 100644
--- a/.github/workflows/community_code.yml
+++ b/.github/workflows/community_code.yml
@@ -65,13 +65,13 @@ jobs:
- uses: astral-sh/setup-uv@v8.2.0
with:
enable-cache: true
- - name: uv sync each agent under agent/adk
+ - name: uv sync each agent under samples/community
# These samples are runnable apps, not publishable packages (several use a
# flat module layout with no wheel target), so --no-install-project verifies
# that their dependencies resolve and install without building each as a wheel.
run: |
set -euo pipefail
- find samples/community/agent/adk -name pyproject.toml -print0 |
+ find samples/community -name pyproject.toml -not -path "*/.venv/*" -not -path "*/node_modules/*" -print0 |
while IFS= read -r -d '' manifest; do
dir="$(dirname "$manifest")"
echo "::group::uv sync $dir"
diff --git a/.github/workflows/web_ci.yml b/.github/workflows/web_ci.yml
index c1c8019496..471ea2ab0b 100644
--- a/.github/workflows/web_ci.yml
+++ b/.github/workflows/web_ci.yml
@@ -45,7 +45,7 @@ permissions:
env:
RENDERERS_INC: "--include 'renderers/**'"
TOOLS_INC: "--include 'tools/**'"
- SAMPLES_INC: "--include 'samples/client/**' --include 'samples/mcp/**'"
+ SAMPLES_INC: "--include 'samples/client/**'"
jobs:
ci-renderers:
diff --git a/.gitignore b/.gitignore
index 08db06ecc3..1f1b0bff4b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,8 +33,8 @@ samples/client/angular/projects/mcp_calculator/public/mcp_apps_inner_iframe/
.yarn/cache
## Generated files for a2ui-in-mcpapps
-samples/mcp/a2ui-in-mcpapps/server/apps/dist
-samples/mcp/a2ui-in-mcpapps/server/apps/public
+samples/community/mcp/a2ui-in-mcpapps/server/apps/dist
+samples/community/mcp/a2ui-in-mcpapps/server/apps/public
# Vite cache
.vite/
diff --git a/package.json b/package.json
index e2c56f2d50..d21359090d 100644
--- a/package.json
+++ b/package.json
@@ -13,10 +13,6 @@
"samples/client/lit/*",
"samples/client/react/*",
"samples/personalized_learning",
- "samples/mcp/*",
- "samples/mcp/*/client",
- "samples/mcp/*/apps/src",
- "samples/mcp/a2ui-in-mcpapps/server/apps/*",
"specification/*/eval",
"specification/*/test",
"tools/*",
diff --git a/samples/community/README.md b/samples/community/README.md
index baacb1c330..853eede8a7 100644
--- a/samples/community/README.md
+++ b/samples/community/README.md
@@ -13,10 +13,3 @@ rather than on the monorepo workspace, and the folder carries its own
`orchestrator`) and Lit (`mcp-apps-in-a2ui-sample`, `personalized_learning`)
samples.
- **python** — `uv sync` for each agent under `agent/adk`.
-
-### Not built
-
-`client/angular/projects/mcp_calculator` is excluded from the build: it imports
-the renderer's internal v0.8 source (`Renderer` from `@a2ui/angular`'s
-`src/v0_8`), which the published package does not expose. Building it standalone
-would require vendoring the renderer source.
diff --git a/samples/community/client/angular/angular.json b/samples/community/client/angular/angular.json
index 66fcf246f7..8f17cba3b8 100644
--- a/samples/community/client/angular/angular.json
+++ b/samples/community/client/angular/angular.json
@@ -93,77 +93,6 @@
"defaultConfiguration": "development"
}
}
- },
- "mcp_calculator": {
- "projectType": "application",
- "schematics": {
- "@schematics/angular:component": {
- "style": "scss",
- "skipTests": true
- }
- },
- "root": "projects/mcp_calculator",
- "sourceRoot": "projects/mcp_calculator/src",
- "prefix": "app",
- "architect": {
- "build": {
- "builder": "@angular/build:application",
- "options": {
- "outputPath": "projects/mcp_calculator/dist",
- "browser": "projects/mcp_calculator/src/main.ts",
- "tsConfig": "projects/mcp_calculator/tsconfig.app.json",
- "preserveSymlinks": true,
- "inlineStyleLanguage": "scss",
- "assets": [
- {
- "glob": "**/*",
- "input": "projects/mcp_calculator/public"
- }
- ],
- "styles": ["projects/mcp_calculator/src/styles.scss"],
- "server": "projects/mcp_calculator/src/main.server.ts",
- "outputMode": "server",
- "ssr": {
- "entry": "projects/mcp_calculator/src/server.ts"
- }
- },
- "configurations": {
- "production": {
- "budgets": [
- {
- "type": "initial",
- "maximumWarning": "1.5MB",
- "maximumError": "2.5MB"
- },
- {
- "type": "anyComponentStyle",
- "maximumWarning": "4kB",
- "maximumError": "8kB"
- }
- ],
- "outputHashing": "all"
- },
- "development": {
- "optimization": false,
- "extractLicenses": false,
- "sourceMap": true
- }
- },
- "defaultConfiguration": "production"
- },
- "serve": {
- "builder": "@angular/build:dev-server",
- "configurations": {
- "production": {
- "buildTarget": "mcp_calculator:build:production"
- },
- "development": {
- "buildTarget": "mcp_calculator:build:development"
- }
- },
- "defaultConfiguration": "development"
- }
- }
}
},
"cli": {
diff --git a/samples/community/client/angular/projects/mcp_calculator/README.md b/samples/community/client/angular/projects/mcp_calculator/README.md
deleted file mode 100644
index b0a47f079f..0000000000
--- a/samples/community/client/angular/projects/mcp_calculator/README.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# MCP Calculator
-
-Sample application using the Chat-Canvas component with MCP Calculator Agent.
-
-## Prerequisites
-
-1. [nodejs](https://nodejs.org/en)
-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).)
-
-## Running
-
-1. Build the shared dependencies by running `yarn build` in the `renderers/web_core` directory
-2. Install local dependencies: `yarn install`
-3. Run the A2A server for all of the agents. ([Link to instructions](../../../../agent/adk/mcp_app_proxy/README.md))
-4. Build the `sandbox.js` for testing MCP Apps in A2UI demo
-
-- `yarn build:sandbox`
-
-5. Run the app:
-
-- `yarn start -- mcp_calculator`
-
-6. Open http://localhost:4200/
-
-## Usage
-
-Once the application is running, open `http://localhost:4200/` in your browser. You will see the MCP Calculator interface.
-
-### How to Use
-
-You can perform calculations using standard operations. When computing the expression, there are two different "equals" buttons:
-
-- **Local JavaScript Calculation (💻 =)**: Click this button to evaluate the expression immediately using standard JavaScript in the browser. The result will appear in the calculator display.
-- **MCP Agent Tool Call Calculation (🤖 =)**: Click this button to dispatch a tool call to the MCP server. The local display will reset, and the calculation will be handled by the agent asynchronously (the result will appear in the chat conversation).
-
-## Features
-
-- **Client-side Tool Dispatching**: The application supports tool call requests from the MCP client bridge. It maps tool arguments to A2UI Action context and dispatches them to the host agent.
diff --git a/samples/community/client/angular/projects/mcp_calculator/package.json b/samples/community/client/angular/projects/mcp_calculator/package.json
deleted file mode 100644
index acbefed27f..0000000000
--- a/samples/community/client/angular/projects/mcp_calculator/package.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "@a2ui/mcp_calculator",
- "version": "0.1.0",
- "private": true,
- "scripts": {
- "build": "echo \"mcp_calculator is excluded from the build: it imports the renderer's internal v0.8 source (projects/lib) which the published @a2ui/angular package does not expose.\"",
- "format": "prettier --write .",
- "format:check": "prettier --check .",
- "lint": "yarn --cwd ../.. lint",
- "test": "yarn --cwd ../.. test",
- "lint:fix": "yarn --cwd ../.. lint:fix"
- },
- "dependencies": {
- "@a2ui/angular": "^0.10.0",
- "@a2ui/web_core": "^0.10.0"
- }
-}
diff --git a/samples/community/client/angular/projects/mcp_calculator/public/gemini-color.svg b/samples/community/client/angular/projects/mcp_calculator/public/gemini-color.svg
deleted file mode 100644
index f1cf357573..0000000000
--- a/samples/community/client/angular/projects/mcp_calculator/public/gemini-color.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/catalog.ts b/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/catalog.ts
deleted file mode 100644
index f20087f161..0000000000
--- a/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/catalog.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2025 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import {Catalog} from '@a2ui/angular';
-import {inputBinding} from '@angular/core';
-
-export const DEMO_CATALOG = {
- McpApp: {
- type: () => import('./mcp-app').then(r => r.McpApp),
- bindings: ({properties}) => [
- inputBinding(
- 'content',
- () => ('content' in properties && properties['content']) || undefined,
- ),
- inputBinding('title', () => ('title' in properties && properties['title']) || undefined),
- ],
- },
- PongScoreBoard: {
- type: () => import('./pong-scoreboard').then(r => r.PongScoreBoard),
- bindings: ({properties}) => [
- inputBinding(
- 'playerScore',
- () => ('playerScore' in properties && properties['playerScore']) || undefined,
- ),
- inputBinding(
- 'cpuScore',
- () => ('cpuScore' in properties && properties['cpuScore']) || undefined,
- ),
- ],
- },
- PongLayout: {
- type: () => import('./pong-layout').then(r => r.PongLayout),
- bindings: ({properties}) => [
- inputBinding(
- 'mcpComponent',
- () => ('mcpComponent' in properties && properties['mcpComponent']) || undefined,
- ),
- inputBinding(
- 'scoreboardComponent',
- () =>
- ('scoreboardComponent' in properties && properties['scoreboardComponent']) || undefined,
- ),
- ],
- },
- Column: {
- type: () => import('@a2ui/angular').then(r => r.Column),
- bindings: ({properties}) => [
- inputBinding(
- 'alignment',
- () => ('alignment' in properties && properties['alignment']) || undefined,
- ),
- inputBinding(
- 'distribution',
- () => ('distribution' in properties && properties['distribution']) || undefined,
- ),
- inputBinding(
- 'children',
- () => ('children' in properties && properties['children']) || undefined,
- ),
- ],
- },
-} as Catalog;
diff --git a/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/mcp-app.ts b/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/mcp-app.ts
deleted file mode 100644
index 313ebc7cc9..0000000000
--- a/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/mcp-app.ts
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- Copyright 2025 Google LLC
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-import {DynamicComponent} from '@a2ui/angular';
-import * as Primitives from '@a2ui/web_core/types/primitives';
-import * as Types from '@a2ui/web_core/types/types';
-import {
- AppBridge,
- PostMessageTransport,
- SANDBOX_PROXY_READY_METHOD,
-} from '@modelcontextprotocol/ext-apps/app-bridge';
-import {
- ChangeDetectionStrategy,
- Component,
- computed,
- effect,
- ElementRef,
- inject,
- input,
- OnDestroy,
- OnInit,
- signal,
- viewChild,
-} from '@angular/core';
-import {DomSanitizer, SafeResourceUrl} from '@angular/platform-browser';
-
-@Component({
- selector: 'a2ui-mcp-app',
- standalone: true,
- imports: [],
- changeDetection: ChangeDetectionStrategy.OnPush,
- styles: `
- :host {
- display: flex;
- flex-direction: column;
- width: 100%;
- height: 500px;
- border: 1px solid var(--mat-sys-outline-variant);
- border-radius: 8px;
- overflow: hidden;
- position: relative;
- }
-
- iframe {
- flex: 1;
- width: 100%;
- height: 100%;
- border: none;
- background-color: white; /* Ensure content is readable */
- }
- `,
- template: `
- @if (resolvedContent()) {
-
- }
- `,
-})
-export class McpApp extends DynamicComponent implements OnDestroy, OnInit {
- private readonly sanitizer = inject(DomSanitizer);
-
- readonly content = input.required();
- protected readonly resolvedContent = computed(() => {
- let rawContent = super.resolvePrimitive(this.content() ?? null);
- if (rawContent && rawContent.startsWith('url_encoded:')) {
- rawContent = decodeURIComponent(rawContent.substring(12));
- }
- return rawContent;
- });
-
- private readonly contentUpdate = effect(() => {
- const rawContent = this.resolvedContent();
- const bridge = this.appBridge();
- if (bridge && rawContent) {
- bridge
- .sendSandboxResourceReady({
- html: rawContent,
- sandbox: 'allow-scripts',
- })
- .catch(err => console.error('Failed to update sandbox content:', err));
- }
- });
-
- readonly allowedTools = input([]);
- readonly title = input();
- protected readonly resolvedTitle = computed(() =>
- super.resolvePrimitive(this.title() ?? null),
- );
-
- protected readonly iframeSrc = signal(
- this.sanitizer.bypassSecurityTrustResourceUrl('about:blank'),
- );
-
- private iframe = viewChild.required>('iframe');
- private appBridge = signal(null);
- private messageHandler: ((event: MessageEvent) => void) | null = null;
-
- ngOnInit() {
- this.setupSandbox();
- }
-
- ngOnDestroy() {
- if (this.messageHandler) {
- window.removeEventListener('message', this.messageHandler);
- }
- const bridge = this.appBridge();
- if (bridge) {
- bridge.close().catch(e => console.error('Error closing AppBridge on destroy:', e));
- }
- }
-
- private setupSandbox() {
- if (this.messageHandler) {
- window.removeEventListener('message', this.messageHandler);
- }
-
- this.messageHandler = (event: MessageEvent) => {
- // Check if the message is from our iframe
- if (
- this.iframe().nativeElement &&
- event.source === this.iframe().nativeElement.contentWindow &&
- event.data?.method === SANDBOX_PROXY_READY_METHOD
- ) {
- // Init bridge
- this.initializeBridge();
- }
- };
-
- window.addEventListener('message', this.messageHandler);
-
- // Check for query param to opt-out of origin toggle (for testing)
- const urlParams = new URLSearchParams(window.location.search);
- const disableSecuritySelfTest = urlParams.get('disable_security_self_test') === 'true';
-
- const currentOrigin = window.location.origin;
- let sandboxUrl = `${currentOrigin}/mcp_apps_inner_iframe/sandbox.html`;
- if (disableSecuritySelfTest) {
- sandboxUrl += '?disable_security_self_test=true';
- }
- this.iframeSrc.set(this.sanitizer.bypassSecurityTrustResourceUrl(sandboxUrl));
- }
-
- private async initializeBridge() {
- if (!this.iframe().nativeElement.contentWindow) {
- return;
- }
-
- const iframe = this.iframe().nativeElement;
-
- // The app bridge is initialized without a direct connection to MCP server.
- // Communication with MCP server is expected to be handled by the sandbox iframe.
- const emptyMcpClient = null;
- const bridge = new AppBridge(
- emptyMcpClient,
- {name: 'MCP Calculator', version: '1.0.0'},
- {
- openLinks: {},
- logging: {},
- serverTools: {}, // Advertise support if we had a client
- },
- );
-
- bridge.onloggingmessage = params => {
- console.log(`[MCP App Log] ${params.level}:`, params.data);
- };
-
- bridge.oninitialized = () => {
- console.log('MCP App Initialized');
- };
-
- bridge.onsizechange = ({width, height}) => {
- // TODO: Implement dynamic resizing
- // Reference implementation in mcp-apps-custom-component.ts:
- // - Listen for size changes from the embedded app
- // - Update the iframe's width/height styles (with animation if desired)
- // - This prevents scrollbars and ensures the app fits its content
- //
- // Example logic:
- // if (height !== undefined) {
- // this.iframe().nativeElement.style.height = `${height}px`;
- // }
- console.log(`[MCP App] Resize requested: ${width}x${height}`);
- };
-
- bridge.oncalltool = async params => {
- console.log(`[MCP App] Tool call requested: ${params.name}`, params);
-
- if (!this.allowedTools().includes(params.name)) {
- console.warn(`[MCP App] Tool '${params.name}' not allowed.`);
- throw new Error(`Tool '${params.name}' not allowed`);
- }
-
- const args = params.arguments || {};
-
- // Map arguments to A2UI Action context
- const context: any[] = [];
- for (const [key, value] of Object.entries(args)) {
- if (typeof value === 'number') {
- context.push({key, value: {literalNumber: value}});
- } else if (typeof value === 'string') {
- context.push({key, value: {literalString: value}});
- } else if (typeof value === 'boolean') {
- context.push({key, value: {literalBoolean: value}});
- }
- }
-
- const action: Types.Action = {
- name: params.name,
- context: context.length > 0 ? context : undefined,
- };
-
- console.log('Sending action:', action);
-
- // Dispatch action asynchronously to the host/agent
- super.sendAction(action).catch(err => console.error('Failed to send action:', err));
-
- // Return empty result immediately (calculator UI can forget about it)
- return {content: []};
- };
-
- // Connect the bridge
- // We must pass the iframe's contentWindow as the target
- const transport = new PostMessageTransport(
- // The first argument is the target window to send messages TO (the iframe).
- // The second argument is the source window to validate messages FROM (also the iframe).
- iframe.contentWindow!,
- iframe.contentWindow!,
- );
- await bridge.connect(transport);
-
- // Clean up old bridge to prevent memory leaks and zombie event listeners.
- const oldBridge = this.appBridge();
- if (oldBridge) {
- oldBridge.close().catch(e => console.error('Error closing previous AppBridge:', e));
- }
- // Set the new bridge.
- this.appBridge.set(bridge);
- }
-}
diff --git a/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/pong-layout.ts b/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/pong-layout.ts
deleted file mode 100644
index 97a6b929ff..0000000000
--- a/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/pong-layout.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2026 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {DynamicComponent} from '../../../../projects/lib/src/public-api';
-import {Renderer} from '../../../../projects/lib/src/v0_8/rendering/renderer';
-import {Component, input} from '@angular/core';
-
-@Component({
- selector: 'a2ui-pong-layout',
- standalone: true,
- imports: [Renderer],
- template: `
-
-
-
-
-
-
-
-
- `,
-})
-export class PongLayout extends DynamicComponent {
- readonly mcpComponent = input(null);
- readonly scoreboardComponent = input(null);
-}
diff --git a/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/pong-scoreboard.ts b/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/pong-scoreboard.ts
deleted file mode 100644
index fe8a461a76..0000000000
--- a/samples/community/client/angular/projects/mcp_calculator/src/a2ui-catalog/pong-scoreboard.ts
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2026 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import {DynamicComponent} from '@a2ui/angular';
-import * as Primitives from '@a2ui/web_core/types/primitives';
-import * as Types from '@a2ui/web_core/types/types';
-import {ChangeDetectionStrategy, Component, computed, input} from '@angular/core';
-
-@Component({
- selector: 'a2ui-pong-scoreboard',
- standalone: true,
- imports: [],
- changeDetection: ChangeDetectionStrategy.OnPush,
- styles: `
- :host {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- gap: 1.5rem;
- padding: 1.5rem;
- color: #202124;
- background: #ffffff;
- height: 100%;
- width: 100%;
- position: relative;
- font-family: 'Google Sans', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
- box-sizing: border-box;
- }
- .a2ui-badge {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- gap: 4px;
- position: absolute;
- top: 1rem;
- left: 50%;
- transform: translateX(-50%);
- background: #e8eaed;
- color: #5f6368;
- font-size: 0.65rem;
- padding: 0.25rem 0.75rem;
- border-radius: 12px;
- text-transform: uppercase;
- letter-spacing: 0.5px;
- font-weight: 600;
- white-space: nowrap;
- border: 1px solid #dadce0;
- }
- .a2ui-icon {
- font-size: 0.8rem;
- color: #1a73e8;
- }
- .scores-wrapper {
- display: flex;
- flex-direction: column;
- gap: 1.5rem;
- width: 100%;
- margin-top: 1.5rem;
- }
- .score-card {
- display: flex;
- flex-direction: column;
- align-items: center;
- background: #f8f9fa;
- border-radius: 12px;
- padding: 1rem;
- border: 1px solid #e8eaed;
- transition: all 0.2s ease;
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
- width: 100%;
- box-sizing: border-box;
- }
- .score-card:hover {
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.08);
- transform: translateY(-2px);
- border-color: #d2e3fc;
- }
- .player-card {
- border-bottom: 3px solid #1a73e8;
- }
- .cpu-card {
- border-bottom: 3px solid #ea4335;
- }
- .score-label {
- font-size: 0.8rem;
- text-transform: uppercase;
- letter-spacing: 1px;
- color: #5f6368;
- margin-bottom: 0.5rem;
- font-weight: 600;
- }
- .score-value {
- font-size: 3.5rem;
- font-weight: 700;
- color: #202124;
- line-height: 1;
- }
- `,
- template: `
-
✦ A2UI Native
-
-
- Player
- {{ resolvedPlayerScore() }}
-
-
- CPU
- {{ resolvedCpuScore() }}
-
-
- `,
-})
-export class PongScoreBoard extends DynamicComponent {
- readonly playerScore = input();
- protected readonly resolvedPlayerScore = computed(
- () => super.resolvePrimitive(this.playerScore() ?? null) ?? 0,
- );
-
- readonly cpuScore = input();
- protected readonly resolvedCpuScore = computed(
- () => super.resolvePrimitive(this.cpuScore() ?? null) ?? 0,
- );
-}
diff --git a/samples/community/client/angular/projects/mcp_calculator/src/app/app.config.server.ts b/samples/community/client/angular/projects/mcp_calculator/src/app/app.config.server.ts
deleted file mode 100644
index b27c47b156..0000000000
--- a/samples/community/client/angular/projects/mcp_calculator/src/app/app.config.server.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2025 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import {ApplicationConfig, mergeApplicationConfig} from '@angular/core';
-import {provideServerRendering, withRoutes} from '@angular/ssr';
-import {appConfig} from './app.config';
-import {serverRoutes} from './app.routes.server';
-
-const serverConfig: ApplicationConfig = {
- providers: [provideServerRendering(withRoutes(serverRoutes))],
-};
-
-export const config = mergeApplicationConfig(appConfig, serverConfig);
diff --git a/samples/community/client/angular/projects/mcp_calculator/src/app/app.config.ts b/samples/community/client/angular/projects/mcp_calculator/src/app/app.config.ts
deleted file mode 100644
index 13e1ac7205..0000000000
--- a/samples/community/client/angular/projects/mcp_calculator/src/app/app.config.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2025 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import {
- configureChatCanvasFeatures,
- usingA2aService,
- usingA2uiRenderers,
- usingDefaultSanitizerMarkdownRenderer,
-} from '@a2a_chat_canvas/config';
-import {
- ApplicationConfig,
- provideBrowserGlobalErrorListeners,
- provideZonelessChangeDetection,
-} from '@angular/core';
-import {provideClientHydration, withEventReplay} from '@angular/platform-browser';
-import {DEMO_CATALOG} from '../a2ui-catalog/catalog';
-import {A2aServiceImpl} from '../services/a2a-service-impl';
-
-export const appConfig: ApplicationConfig = {
- providers: [
- provideBrowserGlobalErrorListeners(),
- provideZonelessChangeDetection(),
- provideClientHydration(withEventReplay()),
- configureChatCanvasFeatures(
- usingA2aService(A2aServiceImpl),
- usingA2uiRenderers(DEMO_CATALOG),
- usingDefaultSanitizerMarkdownRenderer(),
- ),
- ],
-};
diff --git a/samples/community/client/angular/projects/mcp_calculator/src/app/app.html b/samples/community/client/angular/projects/mcp_calculator/src/app/app.html
deleted file mode 100644
index 65fcee6008..0000000000
--- a/samples/community/client/angular/projects/mcp_calculator/src/app/app.html
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{ agentName() }}
-
-
-
-
-
I summon a calculator app served from an MCP server over A2UI.