vercel/ai · error · Error

No resources/read handler configured

Error message

No resources/read handler configured

What it means

The iframe app sent a `resources/read` request, but the host bridge was constructed without a `readResource` handler. The bridge has no host callback to service the request, so it fails with this error, which is delivered both to the host's `onError` callback and back to the iframe as a JSON-RPC error.

Source

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

        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');
        }
        return this.handlers.readResource(
          assertResourceReadParams(request.params),
        );

      case 'resources/list':
        if (this.handlers.listResources == null) {
          throw new Error('No resources/list handler configured');
        }
        return this.handlers.listResources(request.params);

      case 'ui/open-link':
        if (this.handlers.openLink == null) {
          throw new Error('No ui/open-link handler configured');
        }
        return this.handlers.openLink(assertOpenLinkParams(request.params));

      case 'ui/message':

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Add a `readResource` handler to the MCPAppBridge handlers if the app should read `ui://` resources.
  2. If resources should be unavailable, update the app to not call resources/read (the host capability `serverResources` is only advertised when the handler exists).
  3. Check for accidental handler omission when constructing the bridge (log `Object.keys(handlers)` at setup).
  4. Serve needed data through an allow-listed tool instead of resources if you do not want to expose resource reading.

Example fix

// before
handlers: { callTool: p => client.callTool(p) }
// after
handlers: {
  callTool: p => client.callTool(p),
  readResource: ({ uri }) => client.readResource({ uri }),
}
Defensive patterns

Strategy: validation

Validate before calling

// host-side, before constructing the bridge:
if (appReadsResources) {
  if (typeof handlers.readResource !== 'function') {
    throw new Error('MCPAppBridge requires a readResource handler when the app reads resources');
  }
}

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: `new MCPAppBridge({ handlers: {...} })` was called without `readResource`, and the app subsequently issued a `resources/read` request for a `ui://` resource.

Common situations: Host only wired tool support but the app also reads resources; intentionally read-only host setup while the embedded app still requests resources; handlers object partially copied from another bridge setup.

Related errors


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