vercel/ai · warning · Error

Invalid tools/call params

Error message

Invalid tools/call params

What it means

MCPAppBridge validates every app-initiated `tools/call` JSON-RPC request coming from the untrusted MCP App iframe. This error is thrown when the request params are not a JSON object or lack a string `name` field. The error surfaces via the host's `onError` handler and as a JSON-RPC -32603 error response to the iframe.

Source

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

function isNotification(
  message: MCPAppJsonRpcMessage,
): message is MCPAppJsonRpcNotification {
  return 'method' in message && !('id' in message);
}

/**
 * Normalizes unknown thrown values into an `Error`.
 */
function toError(error: unknown): Error {
  return error instanceof Error ? error : new Error(String(error));
}

/**
 * Validates the params for app-initiated `tools/call` requests.
 */
function assertToolCallParams(params: unknown): MCPAppToolCallParams {
  if (!isJSONObject(params) || typeof params.name !== 'string') {
    throw new Error('Invalid tools/call params');
  }

  return {
    name: params.name,
    arguments: isJSONObject(params.arguments) ? params.arguments : undefined,
  };
}

/**
 * Validates `resources/read` params and limits reads to `ui://` app resources.
 */
function assertResourceReadParams(params: unknown): { uri: string } {
  if (!isJSONObject(params) || typeof params.uri !== 'string') {
    throw new Error('Invalid resources/read params');
  }
  if (!params.uri.startsWith('ui://')) {
    throw new Error(
      `resources/read is limited to ui:// resources: ${params.uri}`,

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Fix the iframe app so `tools/call` params include a string `name` field: `{ name: 'toolName', arguments: {...} }`.
  2. Check `onError` logging on the host bridge to see the raw failing request and compare against the MCP Apps spec.
  3. If simulating the iframe, ensure the posted message is a JSON-RPC 2.0 request with a valid params object.
  4. Verify both host and app use a compatible MCP Apps protocol version.

Example fix

// before (app-side iframe request)
postMessage({ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { arguments: { q: 'x' } } })
// after
postMessage({ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { name: 'search', arguments: { q: 'x' } } })
Defensive patterns

Strategy: validation

Validate before calling

function isValidToolCallParams(params: unknown): boolean {
  return (
    typeof params === 'object' && params !== null && !Array.isArray(params) &&
    typeof (params as any).name === 'string'
  );
}
// app-side, before posting:
if (!isValidToolCallParams(params)) throw new Error('tools/call params need a string name');

Type guard

function isToolCallParams(v: unknown): v is { name: string; arguments?: Record<string, unknown> } {
  return typeof v === 'object' && v !== null && !Array.isArray(v) &&
    typeof (v as any).name === 'string' &&
    ((v as any).arguments === undefined || typeof (v as any).arguments === 'object');
}

Try / catch

try {
  await bridgeResult;
} catch (error) {
  if (error instanceof Error && error.message === 'Invalid tools/call params') {
    console.error('App sent malformed tools/call params; check iframe request shape');
  }
}

Prevention

When it happens

Trigger: The iframe posts a `tools/call` request whose params are missing, not a JSON object, or whose `params.name` is absent or not a string (e.g. params is null, an array, or `{ arguments: {...} }` without `name`).

Common situations: A buggy or malicious app iframe sends malformed requests; a hand-rolled iframe client deviates from the MCP Apps spec; protocol version mismatches where the app builds params differently; testing with synthetic window messages that omit `name`.

Related errors


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