Commit graph ext-apps/src/app-bridge.test.ts
Author SHA1 Message Date
Matthew Wang
d27acc42b1 Add and helper functions 2026-01-16 21:20:10 -08:00
Ido Salomon
b273279849
feat: add ui/update-model-context (#125)
---------

Co-authored-by: Olivier Chafik <ochafik@anthropic.com>
2026-01-12 15:21:45 +00:00
martinalong
dc226be962
Remove viewport 2025-12-31 21:36:29 -08:00
martinalong
82e64d56bb
Separate viewport and containerDimensions 2025-12-26 14:15:54 -08:00
martinalong
87f6f3f27e
Update documentation and revert type change 2025-12-26 14:15:53 -08:00
martinalong
93b9da9e7a
Updating viewport type and documentation 2025-12-26 14:15:53 -08:00
Olivier Chafik
2dd223b611
refactor: rename request methods to remove send prefix (#161)
* refactor: rename request methods to remove send prefix

Following the MCP TS SDK convention where request methods don't have
the "send" prefix (reserved for notifications):

- App.sendMessage() → App.message()
- App.sendOpenLink() → App.openLink()
- AppBridge.sendResourceTeardown() → AppBridge.resourceTeardown()

The old method names are kept as deprecated aliases for backwards
compatibility.

Updated all examples to use the new method names.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test: add tests for deprecated method aliases

- Update existing tests to use new method names (message, openLink)
- Add tests verifying deprecated aliases are same reference as new methods
- Add tests verifying deprecated aliases still work functionally

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: rename message→sendMessage, resourceTeardown→teardownResource

- App.message() → App.sendMessage() (with deprecated message alias)
- AppBridge.resourceTeardown() → AppBridge.teardownResource() (with deprecated aliases)

This better follows the pattern where methods that send data have 'send' or action verb prefix.

* fix: update examples to use sendMessage instead of message

* fix: update basic-host to use teardownResource

* fix: update threejs-server to use sendMessage

* refactor: remove deprecated app.message alias

The app.message alias was removed since sendMessage is the correct name.
sendResourceTeardown already exists in AppBridge.

* refactor: remove resourceTeardown alias, keep only sendResourceTeardown

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-16 22:07:06 +00:00
Anton Pidkuiko
37aab03de0
docs: add tool visibility and restructure _meta.ui (#131)
* docs: add tool visibility and restructure _meta.ui

- Restructure tool metadata: `_meta["ui/resourceUri"]` → `_meta.ui.resourceUri`
- Add `visibility` array field: ["model"], ["apps"], or ["model", "apps"]
- Default ["model"] preserves standard MCP behavior
- ["apps"] enables widget-only tools hidden from agent
- Add McpUiToolMeta interface for type safety
- Add Design Decision #4 explaining approach vs OpenAI's two-field model

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* address PR review comments

- Change default visibility to ["model", "apps"]
- Add deprecation notice for flat ui/resourceUri format
- Add McpUiToolMeta and McpUiToolVisibility to spec.types.ts
- Improve tools/list and tools/call behavior wording

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: regenerate schemas for McpUiToolMeta types

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: tool visibility and nested _meta.ui format

- Rename visibility "apps" → "app" in McpUiToolVisibility type
- Add _meta.ui.resourceUri nested format (deprecate flat format)
- Add getToolUiResourceUri() utility with backward compatibility
- Add visibility demo to system-monitor-server:
  - get-system-stats: visibility ["model"] with resourceUri
  - refresh-stats: visibility ["app"] (app-only polling)
- Update all example servers to use new _meta.ui format
- Add 11 unit tests for getToolUiResourceUri()

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: regenerate schemas with updated dependencies

* feat: export McpUiToolMeta type and add type annotations

- Export McpUiToolMeta and McpUiToolVisibility types from types.ts
- Export corresponding Zod schemas (McpUiToolMetaSchema, McpUiToolVisibilitySchema)
- Add `as McpUiToolMeta` type annotations to all example servers
- Update docs/quickstart.md with proper typing

Ensures type safety for `_meta.ui` tool metadata across the codebase.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add server helpers and optional connect() transport

Add `src/server/` with convenience functions for registering MCP App tools
and resources:

- `registerAppTool(server, name, config, handler)`
- `registerAppResource(server, name, uri, config, callback)`

The `transport` parameter in `App.connect()` is now optional, defaulting to
`PostMessageTransport(window.parent)`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Update src/server/index.ts

Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>

* feat: update McpUiAppToolConfig to support both _meta.ui and flat formats

* refactor: simplify server helper imports

* docs: add deprecation notice and improve resourceUri documentation

* feat: add backward compat normalization in registerAppTool

- If _meta.ui.resourceUri is set, also set legacy flat key
- If legacy flat key is set, also set _meta.ui.resourceUri
- Preserves existing visibility when merging
- Does not overwrite if both formats already set

* refactor: avoid mutating config arg in registerAppTool

* style: format with prettier

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Olivier Chafik <ochafik@anthropic.com>
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
2025-12-16 21:47:40 +00:00
Olivier Chafik
54344552b7
api: optional Client in AppBridge (allow custom forwarding), better protocol types (AppRequest, AppNotification, AppResult) (#146)
* Add setter-based handlers for MCP request/notification forwarding

- Add oncalltool, onlistresources, onlistresourcetemplates, onreadresource, onlistprompts setters for Guest UI → Host requests
- Add sendToolListChanged, sendResourceListChanged, sendPromptListChanged methods for Host → Guest UI notifications
- Refactor connect() to use new setters with inlined callbacks
- Update documentation to clarify optional client parameter behavior
- Remove unused forwardRequest/forwardNotification helper methods
- Add comprehensive tests for AppBridge without MCP client (manual handlers)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Potential fix for pull request finding 'Unused variable, import, function or class'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>

* fix: move prettier to dependencies for git-based installs

* fix: add explicit prettierrc to prevent inheriting parent configs during git-based installs

* Apply suggestions from code review

Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>

* refactor(tests): factor out test values and add missing assertions

Address PR review feedback:
- Factor out test value objects (toolCall, resultContent, etc.) for clearer tests
- Add missing assertions on receivedRequests[0] for list handlers
- Improve test readability by defining expected values at the top of each test

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: improve TypeDoc formatting and use `as const` for notification methods

- Use proper TypeDoc syntax with `@param callback.params` and `@param callback.extra`
- Add {@link ResultType} references for return types
- Replace `as Notification` with `as const` on method literals where possible
  (sendResourceListChanged, sendPromptListChanged)
- Simplify sendHostContextChange cast syntax

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(types): use explicit type unions for AppBridge protocol types

- Add AppBridgeRequest, AppBridgeNotification, AppBridgeResult type unions
  that explicitly list all valid types for the protocol
- Replace generic SDK Request/Notification/Result with our specific types
- Remove all type casts by using `as const` on method literals
- Add index signature to McpUiHostContext for forward compatibility

This improves type safety and documents exactly what the AppBridge supports.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: move AppRequest/AppNotification/AppResult to types.ts

Move protocol type unions from app-bridge.ts to types.ts where they
belong with other type definitions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: regenerate schemas with clean npm install

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
2025-12-13 21:07:13 +00:00
Olivier Chafik
0408a6e9c7
release: 0.1.1 (prettier fix to unlock release) (#138)
* fix: prettify generated files on the fly

- Add prettier --write to generate:schemas script to format generated
  files immediately after generation
- Remove redundant prettier:fix from CI schema verification step
  (now that generation includes formatting)

This fixes the release CI failure where generated files weren't
formatted. Previously, PR CI masked this by running prettier:fix
before the final prettier check, while release CI ran the check
directly on freshly-generated (unformatted) files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* format

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-12 00:44:04 +01:00
Olivier Chafik
eaea3f9e07
feat: store and expose hostContext in App class (#139)
* feat: store and expose hostContext in App class

Fixes #129 - The App class now stores the initial hostContext received
during initialization and exposes it via getHostContext().

Changes:
- Add _hostContext private property to App class
- Store result.hostContext in connect() method
- Add getHostContext() getter method (parallel to getHostCapabilities())
- Update onhostcontextchanged setter to merge partial updates into
  stored context
- Add default notification handler to update context even when
  user hasn't set onhostcontextchanged

This enables apps to:
- Access toolInfo immediately after connection (only in initial context)
- Render with correct theme/locale without waiting for first notification
- Synchronously access viewport, timezone, and other initial state

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: use sendHostContextChange for partial update accumulation test

Address PR review feedback: The test was using setHostContext with full
context spreads which didn't clearly demonstrate partial update
accumulation. Now uses sendHostContextChange directly to send truly
partial updates (only theme, then only viewport), making it clear
the App correctly merges multiple partial notifications.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-12 00:39:58 +01:00
Olivier Chafik
70b393a7e6
feat: implement ui/notifications/tool-cancelled + add missing App.onteardown (#120)
* feat: implement ui/notifications/tool-cancelled throughout SDK

Wire the tool-cancelled notification that hosts MUST send when tool
execution is cancelled (user action, timeout, classifier intervention, etc.):

- Add McpUiToolCancelledNotification type in spec.types.ts
- Generate Zod schema via ts-to-zod
- Add AppBridge.sendToolCancelled() method for hosts
- Add App.ontoolcancelled setter for guest UIs
- Export type and schema from types.ts
- Add tests for notification with/without reason

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: add App.onteardown handler for graceful shutdown

Wire the guest UI side of ui/resource-teardown request:

- Add onteardown setter in App class for guest UIs to handle teardown
- Allow ui/resource-teardown in assertRequestHandlerCapability
- Import McpUiResourceTeardownRequest/Result types
- Add tests for sync and async cleanup handlers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(example): wire tool-cancelled and teardown in basic-host

Update basic-host example to properly use the new notifications:

- Send sendToolCancelled when tool call promise rejects
- Send sendResourceTeardown when React component unmounts
- Store appBridge ref for cleanup access

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(example): implement graceful teardown per spec recommendation

Address review feedback: the host now waits for guest's teardown
response before unmounting, following the spec: "Host SHOULD wait
for a response before tearing down the resource (to prevent data loss)."

Changes:
- Add close button to tool call panels
- Two-phase unmount: isDestroying state dims panel and disables events
- sendResourceTeardown() completes before component removal
- Non-app tool results close immediately

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(examples): add onteardown handlers to demo apps

Demonstrate graceful shutdown with simulated 500ms cleanup work.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-11 20:31:17 +01:00
Liad Yosef
ba1a27e465
fix: change size-changed to be in correct tense (#83)
* fix: change size-changed to be in correct tense

* sdk changes
2025-12-08 12:14:56 +01:00
Olivier Chafik
cf4492df89
Add App <-> AppBridge tests, setHostContext & sendToolInputPartial (#55)
* Add App <-> AppBridge integration tests

- Add minimalistic tests validating communication between App (guest) and AppBridge (host)
- Test initialization handshake flow
- Test Host -> App notifications (toolInput, toolInputPartial, toolResult, hostContext)
- Test App -> Host notifications (sizeChange, log)
- Test App -> Host requests (sendMessage, sendOpenLink)
- Test ping functionality
- Add setHostContext and sendToolInputPartial to AppBridge
- Add test script to package.json

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: add JSDoc for setHostContext and sendToolInputPartial

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: add @types/bun for test type checking

- Add @types/bun devDependency for bun:test types
- Fix mock client request return type

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 22:18:31 +00:00