vercel/ai · error · Error

No tools/call handler configured

Error message

No tools/call handler configured

What it means

The iframe app sent a `tools/call` request, but the host bridge was constructed without a `callTool` handler in its `handlers` object. The bridge refuses to proxy the request since there is no host callback to execute it. This is a host configuration error surfaced as a JSON-RPC error to the iframe and to `onError`.

Source

Thrown at packages/react/src/mcp-apps/bridge.ts:358

  ): Promise<unknown> {
    switch (request.method) {
      case 'ui/initialize':
        return {
          protocolVersion: MCP_APP_PROTOCOL_VERSION,
          hostCapabilities: {
            ...(this.handlers.callTool != null ? { serverTools: {} } : {}),
            ...(this.handlers.readResource != null
              ? { serverResources: {} }
              : {}),
            ...(this.handlers.onLog != null ? { logging: {} } : {}),
          },
          hostInfo: this.hostInfo,
          hostContext: this.hostContext,
        };

      case 'tools/call': {
        if (this.handlers.callTool == null) {
          throw new Error('No tools/call handler configured');
        }
        const params = assertToolCallParams(request.params);
        // Deny-by-default: the (untrusted) MCP App may only invoke tools the
        // host has explicitly allow-listed. Omitting `allowedTools` exposes no
        // tools, rather than forwarding every requested tool to `callTool`.
        if (
          this.handlers.allowedTools == null ||
          !this.handlers.allowedTools.includes(params.name)
        ) {
          throw new Error(`Tool is not app-visible: ${params.name}`);
        }
        return this.handlers.callTool(params);
      }

      case 'resources/read':
        if (this.handlers.readResource == null) {
          throw new Error('No resources/read handler configured');
        }

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Add a `callTool` handler (and `allowedTools` allow-list) when constructing MCPAppBridge if the app should invoke tools.
  2. If tools should remain unavailable, configure the app to not call tools — the host will never accept them.
  3. Verify handlers were not spread/overridden after bridge construction.
  4. Check `ui/initialize`'s reported capabilities: serverTools is only advertised when `callTool` exists.

Example fix

// before
const bridge = new MCPAppBridge({ targetWindow, handlers: { onError: console.error } })
// after
const bridge = new MCPAppBridge({
  targetWindow,
  handlers: {
    allowedTools: ['search'],
    callTool: params => client.callTool(params),
    onError: console.error,
  },
})
Defensive patterns

Strategy: validation

Validate before calling

// host-side, at construction time:
const bridge = new MCPAppBridge({
  targetWindow,
  handlers: {
    ...(appNeedsTools
      ? { allowedTools: ['search'], callTool: p => client.callTool(p) }
      : {}),
    onError: e => console.error('MCP App bridge error:', e),
  },
});
if (appNeedsTools) console.assert('callTool' in bridgeHandlers, 'callTool handler required');

Type guard

function hasCallToolHandler(h: unknown): h is { callTool: (p: any) => unknown } {
  return typeof h === 'object' && h !== null && 'callTool' in h &&
    typeof (h as any).callTool === 'function';
}

Try / catch

try {
  await appRequest;
} catch (error) {
  if (error instanceof Error && error.message === 'No tools/call handler configured') {
    console.error('Bridge was built without a callTool handler; add one or stop the app from calling tools');
  }
}

Prevention

When it happens

Trigger: `new MCPAppBridge({ handlers: { ... } })` was called without `callTool`, then the app called `tools/call` (the app may attempt this because `ui/initialize` reports serverTools capability based on handler presence).

Common situations: Host intentionally disabled tool access but the app still calls tools; copy-pasted bridge setup omitted `callTool`; conditional handler wiring where the flag was false at mount time.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/3a9252ef74f0c3ca. Report an issue: GitHub.