-
Notifications
You must be signed in to change notification settings - Fork 32
spec: Add tool registration for Apps, to be called by Host (WebMCP-style!) #72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ochafik
wants to merge
12
commits into
main
Choose a base branch
from
feat/app-tool-registration
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,836
−7
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This PR adds comprehensive tool support for MCP Apps, enabling apps to register their own tools and handle tool calls from the host. ## Changes ### App (Guest UI) side: - Add `registerTool()` method for registering tools with input/output schemas - Add `oncalltool` setter for handling tool call requests from host - Add `onlisttools` setter for handling tool list requests from host - Add `sendToolListChanged()` for notifying host of tool updates - Registered tools support enable/disable/update/remove operations ### AppBridge (Host) side: - Add `sendCallTool()` method for calling tools on the app - Add `sendListTools()` method for listing available app tools - Fix: Use correct ListToolsResultSchema (was ListToolsRequestSchema) ### Tests: - Add comprehensive tests for tool registration lifecycle - Add tests for input/output schema validation - Add tests for bidirectional tool call communication - Add tests for tool list change notifications - All 27 tests passing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Implement automatic `oncalltool` and `onlisttools` handlers that are initialized when apps register tools. This removes the need for manual handler setup and ensures tools work seamlessly out of the box. - Add automatic `oncalltool` handler that routes calls to registered tools - Add automatic `onlisttools` handler that returns full Tool objects with JSON schemas - Convert Zod schemas to MCP-compliant JSON Schema using `zod-to-json-schema` - Add 27 comprehensive tests covering automatic handlers and tool lifecycle - Test coverage includes error handling, schema validation, and multi-app isolation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
| const tool2 = app.registerTool("tool2", {}, async (_args: any) => ({ | ||
| content: [], | ||
| })); | ||
| const tool3 = app.registerTool("tool3", {}, async (_args: any) => ({ |
| const appCapabilities = { tools: { listChanged: true } }; | ||
| app = new App(testAppInfo, appCapabilities, { autoResize: false }); | ||
|
|
||
| const tool1 = app.registerTool( |
- Always return inputSchema as object (never undefined) - Keep filter for enabled tools only in list - Update test to match behavior (only enabled tools in list) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR enables Apps to register their own tools that agents can call, making apps introspectable and accessible to the model without DOM parsing.
Apps expose semantic interfaces (state queries, operations) via standard MCP tools. The agent discovers capabilities via
tools/list, queries state, and drives interactions.This is a different model from other approaches where apps keep the model informed through side channels (e.g., OAI Apps SDK sending widget state changes to the model, MCP-UI adding tool call results to chat history). Instead, the agent actively queries app state and executes operations through tools.
Example:
Agent interaction:
Changes
App side (
app.ts)registerTool()- Register tools with Zod validationoncalltool/onlisttools- Handle tool requestssendToolListChanged()- Notify on tool updatesenable(),disable(),update(),remove()Host side (
app-bridge.ts)sendCallTool()- Call app toolssendListTools()- List app toolsListToolsResultSchemaCapabilities (
types.ts)tools: { listChanged?: boolean }serverTools: { listChanged?: boolean }(existing)Tests: ✓ 27 passing, 100% coverage
Design
Reuses standard MCP messages:
tools/call,tools/list,notifications/tools/list_changedSimilar to WebMCP but without turning the App (embedded page) into an MCP server - apps register tools within the App/Host architecture.
Lifecycle: App tools exist only while app loaded (ephemeral, sandboxed)
Separation: Server tools (persistent, trusted) vs App tools (ephemeral, sandboxed)
Breaking Changes
None. Purely additive.
Related
Implements the gist of #35 (WebMCP-style tool registration) while preserving the App/Host architecture.
🤖 Generated with Claude Code