Skip to content

Tool Args Schema

argsSchema describes the arguments an agent should send to a tool. Pedelec uses a JSON-compatible subset designed for common frontend tool inputs.

It is not the complete JSON Schema specification.

The root must always be an object:

import type { ToolArgsSchema } from "@kaoruisaac/pedelec";
const schema = {
type: "object",
properties: {
query: { type: "string" },
},
required: ["query"],
} satisfies ToolArgsSchema;

A no-argument tool still uses an object:

const emptySchema = {
type: "object",
properties: {},
required: [],
} satisfies ToolArgsSchema;

Schema nodes can include:

{
description?: string;
default?: JsonValue;
examples?: JsonValue[];
}

default and examples guide the agent. The SDK does not automatically insert a missing default into received args.

{
type: "string",
description: "Output language.",
default: "en",
examples: ["en", "zh-TW"]
}

Your handler must still decide what to do when an optional property is missing.

{
type: "string",
enum?: string[],
minLength?: number,
maxLength?: number,
pattern?: string
}

Example:

role: {
type: "string",
enum: ["viewer", "editor"],
description: "Role to assign."
}

pattern is a string representation of a regular-expression pattern. Keep patterns simple and portable.

{
type: "number" | "integer",
enum?: number[],
minimum?: number,
maximum?: number
}

Use integer for counts and pixel dimensions when fractions are not meaningful.

delta: {
type: "integer",
minimum: -10,
maximum: 10
}
{
type: "boolean",
enum?: boolean[]
}

Usually enum is unnecessary for booleans, but it is part of the type.

{
type: "array",
items: ToolArgsSchemaNode,
minItems?: number,
maxItems?: number,
uniqueItems?: boolean
}

Example:

ids: {
type: "array",
items: { type: "string", minLength: 1 },
minItems: 1,
maxItems: 50,
uniqueItems: true
}

Use sensible bounds. An agent-generated array should not be able to request an unbounded bulk operation.

{
type: "object",
properties?: Record<string, ToolArgsSchemaNode>,
required?: string[]
}

Example:

position: {
type: "object",
properties: {
x: { type: "number" },
y: { type: "number" }
},
required: ["x", "y"]
}

Only put property names in required that are actually defined and required by your handler.

{
oneOf: ToolArgsSchemaNode[]
}

Example:

target: {
oneOf: [
{
type: "object",
properties: { id: { type: "string" } },
required: ["id"]
},
{
type: "object",
properties: { index: { type: "integer", minimum: 0 } },
required: ["index"]
}
]
}

Prefer clearly distinguishable alternatives. Ambiguous branches make agent output and application validation harder.

$ref and $defs are not supported. Reuse TypeScript constants:

import type { ToolArgsSchemaNode } from "@kaoruisaac/pedelec";
const pointSchema = {
type: "object",
properties: {
x: { type: "number" },
y: { type: "number" },
},
required: ["x", "y"],
} satisfies ToolArgsSchemaNode;
const moveShapeSchema = {
type: "object",
properties: {
shapeId: { type: "string", minLength: 1 },
destination: pointSchema,
},
required: ["shapeId", "destination"],
} satisfies ToolArgsSchema;

The documented first schema version does not support fields such as:

  • $defs and $ref;
  • additionalProperties;
  • format;
  • exclusiveMinimum and exclusiveMaximum;
  • multipleOf;
  • full JSON Schema conditionals and composition keywords beyond the supported oneOf shape; and
  • arbitrary custom keywords.

Do not copy a large OpenAPI or JSON Schema document into argsSchema and assume it will work.

The SDK clones the schema through JSON serialization before sending it to Core. Therefore the schema cannot contain:

  • functions;
  • symbols;
  • BigInt;
  • cyclic references; or
  • values with meaningful behavior that is lost in JSON.

A serialization failure rejects session creation with INVALID_INPUT.

The schema helps the provider and Core understand the expected shape. It does not replace application-level validation.

session.onTool("update_counter", (raw) => {
const args = raw as { delta?: unknown };
if (!Number.isInteger(args.delta) || Math.abs(args.delta as number) > 100) {
return {
error: {
code: "INVALID_DELTA",
message: "delta must be an integer between -100 and 100.",
},
};
}
return updateCounter(args.delta as number);
});

Validate authorization, current application state, resource existence, and any rules that cannot be expressed in the schema.

  • Prefer a few explicit properties over one generic object.
  • Use enums when the domain is small and stable.
  • Add descriptions to non-obvious fields.
  • Add bounds to arrays and numeric operations.
  • Make destructive intent explicit.
  • Avoid optional fields that radically change behavior without a clear discriminator.
  • Keep tool inputs small enough to inspect and log safely.

Continue with Registering tool handlers.