Skip to content

ToolDefinition

A tool definition is a tool as data: what a model is told about a tool, in a form a catalog can store as JSON and a source can report before anything runs the tool. Effect AI’s Tool is the tool at runtime, with a handler. A definition keeps the tool’s parameters as the JSON Schema its source gave, since a tool that a source such as an MCP server lists has no Effect schema, and a JSON Schema is what an agent reads in any case.

Since v0.1.0

What a source says about a tool besides what it takes, under the names Effect AI gives its tool annotations. They are the source’s claims, hints and not guarantees, so a decision about what a tool may do must not rest on them alone. A hint left out means Effect AI’s default for it: the tool writes (readOnly false), may destroy (destructive true), is not safe to repeat (idempotent false), and reaches beyond the system it belongs to (openWorld true). Only a tool that is not read only can be destructive or idempotent.

Signature

declare const Annotations: Schema.Struct<{
readonly title: Schema.optionalKey<Schema.String>
readonly readOnly: Schema.optionalKey<Schema.Boolean>
readonly destructive: Schema.optionalKey<Schema.Boolean>
readonly idempotent: Schema.optionalKey<Schema.Boolean>
readonly openWorld: Schema.optionalKey<Schema.Boolean>
}>

Source

Since v0.1.0

Signature

export interface Annotations extends Schema.Schema.Type<typeof Annotations> {}

Source

Since v0.1.0

A tool as data: its name, what it does, its parameters as JSON Schema, and its source’s hints. A source reports these from discover, a catalog stores them as JSON, and ToolSource.toolkit and Assembly.toolkit build from them the tools a model calls.

Example (A catalog of a source’s tools, stored as JSON)

import { ToolDefinition, type ToolSource } from "@amends-dev/toolkit"
import { Effect, Schema } from "effect"
declare const github: ToolSource.ToolSource
declare const store: (catalog: string) => Effect.Effect<void>
const CatalogJson = Schema.fromJsonString(Schema.toCodecJson(Schema.Array(ToolDefinition.ToolDefinition)))
// Refreshing the catalog asks the source what it has now, and stores it for the turns to come.
const refresh = github.discover.pipe(Effect.flatMap(Schema.encodeEffect(CatalogJson)), Effect.flatMap(store))

Signature

declare const ToolDefinition: Schema.Struct<{
readonly name: Schema.NonEmptyString
readonly description: Schema.optionalKey<Schema.String>
readonly inputSchema: Schema.Codec<McpSchema.ToolJson, McpSchema.ToolJson, never, never>
readonly annotations: Schema.Struct<{
readonly title: Schema.optionalKey<Schema.String>
readonly readOnly: Schema.optionalKey<Schema.Boolean>
readonly destructive: Schema.optionalKey<Schema.Boolean>
readonly idempotent: Schema.optionalKey<Schema.Boolean>
readonly openWorld: Schema.optionalKey<Schema.Boolean>
}>
}>

Source

Since v0.1.0

Signature

export interface ToolDefinition extends Schema.Schema.Type<typeof ToolDefinition> {}

Source

Since v0.1.0