showcase/shell-docs/src/content/reference/channels/functions/defineChannelTool.mdx
defineChannelTool preserves a tool definition while inferring the handler
argument type from its Standard Schema.
function defineChannelTool<Schema extends ObjectSchema>(
tool: ChannelTool<Schema>,
): ChannelTool<Schema>;
interface ChannelTool<Schema extends ObjectSchema> {
name: string;
description: string;
parameters: Schema;
handler(
args: InferSchemaOutput<Schema>,
context: ChannelToolContext,
): unknown | Promise<unknown>;
}
import { defineChannelTool } from "@copilotkit/channels";
import { z } from "zod";
export const getIncident = defineChannelTool({
name: "get_incident",
description: "Read an incident by id.",
parameters: z.object({
incidentId: z.string(),
}),
async handler({ incidentId }) {
const incident = await incidents.get(incidentId);
return incident;
},
});
Register tools in createChannel({ tools }), add one with channel.tool(tool)
before startup, or pass turn-scoped tools to thread.runAgent({ tools }).
| Field | Type | Managed behavior |
|---|---|---|
thread | Thread | Current conversation handle. |
message | IncomingMessage | undefined | Reserved optional field; the current SDK tool runner leaves it undefined. Capture validated message data in the handler when the tool needs it. |
user | PlatformUser | undefined | Reserved optional field; the current SDK tool runner leaves it undefined. |
signal | AbortSignal | undefined | Reserved optional field; the current SDK tool runner leaves it undefined. |
platform | string | Managed tools currently report "intelligence"; branch on message.platform for Slack versus Teams. |
Return raw objects or arrays for data. The SDK JSON-serializes non-string results for the model. A tool that already posted UI should return a short natural-language confirmation so the model does not repeat the card.
See Tools and context for a complete managed example.