Skip to content

[MCP] Add the McpApp universal component and mcpCatalog to @a2ui/catalog-mcp - #2799

Draft
josemontespg wants to merge 1 commit into
catalogs-mcp-configfrom
catalogs-mcp-app-component
Draft

josemontespg wants to merge 1 commit into
catalogs-mcp-configfrom
catalogs-mcp-app-component

Conversation

@josemontespg

@josemontespg josemontespg commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Adds the McpApp universal component (A2uiMcpApp) and mcpCatalog to @a2ui/catalog-mcp, on top of the host configuration from the parent PRs and the shared double-iframe sandbox from #3056.

A host registers mcpCatalog (the component plus callMcpTool) with its MessageProcessor and calls configureMcpCatalog once. Without a configured client, McpApp dispatches allowed tools/call requests as A2UI actions.

Changes

  • src/components/mcp_app.ts: the McpApp element on SandboxedFrameElement, with the MCP Apps sandbox handshake, allowedFunctions/allowedTools, data model binding and frame sizing; callMcpTool is resolved from the component's catalog first, then the surface's.
  • src/components/mcp_app_bridge.ts: McpAppBridge on @modelcontextprotocol/ext-apps/app-bridge: ui/open-link, ui/message, ui/request-display-mode, ui/update-model-context, tool input and result notifications, tool execution through callMcpTool, enriched McpUiHostContext.
  • src/components/payload_validation.ts: JSON Schema validation of function call arguments against allowedFunctions.
  • src/catalog.ts, src/index.ts: mcpCatalog = new Catalog(MCP_CATALOG_ID, '1.0', [A2uiMcpApp], [CallMcpToolImplementation]); the entry point exports mcpCatalog and A2uiMcpApp.
  • src/testing/frame_test_support.ts, tests/fixtures/apps/test_app.ts, tests/mcp_app_scenarios.test.ts: Karma scenarios against a real App SDK guest, including tool execution through a configured client.
  • README.md, CHANGELOG.md: the McpApp section.

Verification

  • yarn workspace @a2ui/catalog-mcp test: 82 Node tests, 211 Karma tests.
  • ./scripts/fix_format.sh --check, python3 scripts/fix_licenses.py --check.

Related to #3157

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the sandboxed McpApp component to the A2UI MCP catalog, enabling secure rendering of MCP Apps inside an iframe with JSON-RPC communication, data model synchronization, and tool/function execution. It also restructures the package entry points to support DOM-free environments and adds comprehensive tests. The review feedback highlights three key improvement opportunities: using a single-pass regex replacement when unescaping JSON Pointer sequences to prevent order-of-operations bugs, wrapping decodeURIComponent in a try-catch block to handle malformed encoding errors gracefully, and deferring action dispatching to safely catch synchronous errors.

Comment thread typescript/catalogs/mcp/src/components/mcp_app_bridge.ts
Comment thread typescript/catalogs/mcp/src/components/mcp_app.ts
Comment thread typescript/catalogs/mcp/src/components/mcp_app_bridge.ts Outdated
@josemontespg
josemontespg force-pushed the catalogs-mcp-app-component branch from f562b15 to 63a21f5 Compare September 25, 2026 17:40
@josemontespg
josemontespg added this pull request to stack #2804 September 25, 2026 18:11
@josemontespg
josemontespg force-pushed the catalogs-mcp-app-component branch from 63a21f5 to ed54574 Compare September 25, 2026 18:37
@josemontespg
josemontespg force-pushed the catalogs-mcp-app-component branch from ed54574 to 5692925 Compare September 25, 2026 20:21
@josemontespg
josemontespg force-pushed the catalogs-mcp-app-component branch from 5692925 to e9da27f Compare October 1, 2026 20:11
@josemontespg
josemontespg removed this pull request from stack #2804 October 1, 2026 20:12
@josemontespg
josemontespg added this pull request to stack #2940 October 1, 2026 20:12
@josemontespg
josemontespg force-pushed the catalogs-mcp-app-component branch from e9da27f to 6155ab4 Compare October 1, 2026 20:43
@josemontespg
josemontespg force-pushed the catalogs-mcp-app-component branch from 6155ab4 to 7d1a93d Compare October 1, 2026 21:42
@josemontespg
josemontespg removed this pull request from stack #2940 October 1, 2026 21:56
@josemontespg
josemontespg changed the base branch from catalogs-iframe-components to catalogs-mcp-app-schema October 1, 2026 21:56
@josemontespg
josemontespg force-pushed the catalogs-mcp-app-component branch from 7d1a93d to 7a053a3 Compare October 1, 2026 21:56
@josemontespg
josemontespg added this pull request to stack #2946 October 1, 2026 21:56
@josemontespg
josemontespg force-pushed the catalogs-mcp-app-component branch from 7a053a3 to bed2438 Compare October 1, 2026 22:14
josemontespg added a commit that referenced this pull request Oct 1, 2026
### Summary

`ResolveA2uiProp` turns every prop whose type matches `ActionLike` into a `() => Promise<void>` thunk. Since #2859 added `V1Action` to `ActionLike`, whose function-call variant infers as the weak type `{functionCall?: any}`, every object type matches it, so props declared as `z.record(z.unknown())` (or any `Record<string, ...>`) now resolve to an action thunk instead of their data type. The runtime binder is unaffected (it reads the zod schema), so this is a type-only regression, but it breaks `tsc` for catalogs that read such props, for example the iframe and MCP catalogs in #2797 and #2799.

Object types with a string index signature now resolve as data, as before #2859. Props shaped like an action (`{event: ...}`, `{functionCall: ...}`, `V1Action`) still resolve to the thunk.

### Changes

* `typescript/web_core/src/resolution/generic-binder.ts`: add `HasStringIndex<T>` and check it inside the `ActionLike` branch of `ResolveA2uiProp` before producing the thunk type.
* `typescript/web_core/CHANGELOG.md`: Unreleased entry.

### Verification

* `yarn --cwd typescript/web_core test` (842 tests) and `./scripts/fix_format.sh --check` pass locally.
* The iframe and MCP catalog packages of the stack above typecheck again with this change.
@josemontespg
josemontespg force-pushed the catalogs-mcp-app-component branch from bed2438 to fafc22c Compare October 1, 2026 22:41
@josemontespg josemontespg changed the title feat(catalogs): add the McpApp universal component to @a2ui/catalog-mcp feat(catalogs): add the v1.0 MCP catalog and the McpApp universal component to @a2ui/catalog-mcp Oct 2, 2026
@josemontespg
josemontespg added this pull request to stack #3011 October 5, 2026 20:45
@josemontespg
josemontespg removed this pull request from stack #3011 October 7, 2026 23:18
@josemontespg
josemontespg changed the base branch from catalogs-mcp-app-schema to main October 7, 2026 23:18
@josemontespg
josemontespg force-pushed the catalogs-mcp-app-component branch from 3f9c7e7 to 62ca645 Compare October 7, 2026 23:19
@josemontespg
josemontespg changed the base branch from main to catalogs-mcp-app-schema October 7, 2026 23:19
@josemontespg
josemontespg added this pull request to stack #3055 October 7, 2026 23:19
@josemontespg
josemontespg removed this pull request from stack #3055 October 7, 2026 23:32
@josemontespg
josemontespg changed the base branch from catalogs-mcp-app-schema to catalogs-shared-sandbox October 7, 2026 23:33
@josemontespg
josemontespg force-pushed the catalogs-mcp-app-component branch from 62ca645 to 938293d Compare October 7, 2026 23:33
@josemontespg josemontespg changed the title feat(catalogs): add the v1.0 MCP catalog and the McpApp universal component to @a2ui/catalog-mcp [MCP] feat(catalogs): add the v1.0 MCP catalog and the McpApp universal component to @a2ui/catalog-mcp Oct 7, 2026
@josemontespg
josemontespg added this pull request to stack #3057 October 7, 2026 23:34
@josemontespg josemontespg changed the title [MCP] feat(catalogs): add the v1.0 MCP catalog and the McpApp universal component to @a2ui/catalog-mcp [MCP] Add the v1.0 MCP catalog and the McpApp universal component to @a2ui/catalog-mcp Oct 8, 2026
@josemontespg
josemontespg force-pushed the catalogs-mcp-app-component branch 2 times, most recently from 0ee35a4 to f47d2e6 Compare October 8, 2026 21:34
Comment thread typescript/catalogs/mcp/src/v1_0/components/index.ts Outdated
Comment thread typescript/catalogs/mcp/src/functions/callMcpTool.ts Outdated
Comment thread typescript/catalogs/mcp/src/v1_0/components/payload_validation.ts Outdated
Comment thread typescript/catalogs/mcp/tsconfig.test.json
Comment thread typescript/catalogs/mcp/karma.conf.cjs Outdated
@josemontespg
josemontespg force-pushed the catalogs-mcp-app-component branch 2 times, most recently from 0157eac to 7ca0b1f Compare October 9, 2026 18:18
@josemontespg
josemontespg removed this pull request from stack #3057 October 9, 2026 18:19
Comment thread typescript/catalogs/mcp/src/v1_0/components/index.ts Outdated
Comment thread typescript/catalogs/mcp/src/v1_0/functions.ts Outdated
Comment thread typescript/catalogs/mcp/CHANGELOG.md
Comment thread typescript/catalogs/mcp/src/index.ts Outdated
Comment thread typescript/catalogs/mcp/src/index.ts
Comment thread typescript/catalogs/mcp/src/catalog.ts Outdated
Comment thread samples/community/mcp/a2ui-over-mcp-filesystem/client/app.ts
…og to @a2ui/catalog-mcp

Add mcpCatalog, the v1 MCP catalog with the McpApp universal component
(A2uiMcpApp) and callMcpTool, backed by the shared double-iframe sandbox
runtime from typescript/catalogs/shared/sandbox/. McpAppBridge implements the
MCP Apps host side on @modelcontextprotocol/ext-apps/app-bridge (ui/open-link,
ui/message, ui/request-display-mode, ui/update-model-context, tool input and
result notifications, tool execution through callMcpTool, host context), and
payload validation checks function call arguments against allowedFunctions.
Without a configured client, McpApp dispatches allowed tools/call requests as
A2UI actions.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant