Skip to content
WebMCP Agents
Esc
↑↓navigate↵open⌘Jpreview
On this page

chatRequestSchema

The zod schema for the POST body of /api/chat, and the LIMITS it enforces.

The zod schema for the POST body of /api/chat, and the LIMITS it enforces. Counts, sizes and names are capped so a page, or anyone calling the endpoint, cannot send an unbounded prompt. createChatHandler already applies it; use it when you write your own handler or test a client.

Import

import { chatRequestSchema, LIMITS } from "@webmcp-agents/chat/server";
import type { ChatRequest } from "@webmcp-agents/chat/server";

LIMITS is exported from @webmcp-agents/chat/server (and used by the client internally); the main entry does not export it.

Example

A handler of your own that validates the body first and answers with the first issues.

import { chatRequestSchema, LIMITS } from "@webmcp-agents/chat/server";

// A handler of your own: validate the POST body first.
export async function POST(req: Request): Promise<Response> {
  const parsed = chatRequestSchema.safeParse(await req.json());

  if (!parsed.success) {
    return Response.json(
      {
        error: "bad_request",
        issues: parsed.error.issues.slice(0, 10),
      },
      { status: 400 },
    );
  }

  const { messages, tools, agent } = parsed.data;
  console.log(
    `${messages.length}/${LIMITS.messages} messages,`,
    `${tools.length}/${LIMITS.tools} tools, agent: ${agent ?? "none"}`,
  );
  return Response.json({ ok: true });
}

Options

chatRequestSchema.safeParse(body) takes the parsed JSON body. Its fields (ChatRequest):

Name Type Default Description
messages AgentMessage[] required The conversation, 1 to 160. Each has an id of 1 to 64 characters, a role of "user" or "assistant" and at most 40 parts.
tools { name, description, inputSchema }[] required The page’s tools: at most 48, with unique names.
page { url?: string } not set Where the conversation happens. url is at most 2000 characters; only a same-origin path reaches the model.
agent string not set The agent’s id, matching /^[a-zA-Z0-9_.-]{1,64}$/, looked up in the handler’s registry. An id only: instructions in the body are unknown keys and are stripped.

Rules per field

Field Rule
text part text is at most 8000 characters.
reasoning part text is at most 32 000 characters; providerMetadata at most 32 000 characters as JSON.
tool part id is 1 to 128 characters; name matches the tool name rule; state is one of the ToolCallStates; output.content has at most 20 items; error and prompt are at most 8000 characters; providerMetadata at most 32 000 characters as JSON. A nested agent run is not accepted (the cloud adapter strips it).
tool name /^[a-zA-Z0-9_.-]{1,128}$/
tool description At most 1024 characters.
tool inputSchema An object, at most 8192 characters as JSON.

LIMITS

Key Value Meaning
bodyBytes 1 048 576 Request body, counted while streaming.
messages 160 Messages per request. The cloud adapter trims the oldest past this.
parts 40 Parts per message.
text 8000 Characters per text, error or prompt.
reasoning 32 000 Characters of reasoning text (and its metadata).
tools 48 Tools per request.
description 1024 Characters per tool description.
schemaBytes 8192 Characters per input schema, as JSON.

Returns

chatRequestSchema.safeParse(body) gives { success: true, data: ChatRequest } or { success: false, error } with the zod issues. ChatRequest is z.infer<typeof chatRequestSchema>.

Notes

  • The body size is checked before parsing, by the handler (413), not by the schema.
  • A tool output keeps content and isError only: other keys of a result do not reach the server.
  • Only a same-origin path from page.url reaches the model, and only for a same-origin browser request.

See also

Was this page helpful?