Skip to content

Tool

The runtime object: manifest + local handler. Only exists in-process; handler is stripped when the tool is projected to a manifest for serialisation, MCP exposure, or discovery.

Type parameters are caller-asserted — the runtime validates against input / output JSON Schema, not the TS type — but let authors write typed handlers when they know the shape.

Type Parameter Default type
TInput unknown
TOutput unknown
Property Modifier Type Description Inherited from
codeArtifactRef? readonly CodeArtifactRef Signed pointer at the deploy-time OCI image + module path carrying the handler bytes. Absent for in-process manifests. ToolManifest.codeArtifactRef
description readonly string Human-readable one-liner describing what the tool does. Surfaced to the model as part of the tool definition (ModelToolDefinition.description) — the model uses it to decide when to call. Write it for the model: what the tool DOES, what it RETURNS, and when to prefer it over other tools. Skip implementation details. ToolManifest.description
effects? readonly readonly Effect[] Declared side-effects the tool causes — an EFFECT_KINDS kind (writes, network, external-side-effect, …), optionally with the resource it targets. Consumed by policy + audit machinery for effect-based gating (e.g. "block any tool with an external-side-effect in a dry-run"). Distinct from mutating — effects names WHICH effects; mutating is a coarser boolean. ToolManifest.effects
handler readonly (input, ctx) => Promise<TOutput> The runtime handler — the function invokeTool actually calls. Types are caller-asserted (matches the defineTool generics); the runtime validates against input / output JSON Schema at every invocation, not the TS type. -
id readonly ToolId Globally-unique tool identifier. Convention: <pack-id>.<tool-name> (kebab-case, dot-namespaced) — e.g. acme.verify-citation, demo.echo. The <pack-id> prefix scopes the tool to its pack; <tool-name> names the operation. Enforced as a ToolId brand; defineTool refuses ids that don't match the convention. ToolManifest.id
input readonly JsonSchema JSON Schema Draft 2020-12 for the tool's input. Handed to the model as the tool's parameter schema so it can generate valid calls. invokeTool validates every incoming input against this before invoking the handler — invalid input surfaces as a bad-input error, never reaches the handler. Zod authors: pass a Zod v4 schema to defineTool({input: zSchema}); the framework converts to JSON Schema at author time and preserves the Zod schema on tool.inputZod for TS-side inference. ToolManifest.input
inputZod? readonly ZodLikeSchema The original Zod schema, preserved when the tool was authored with a Zod v4 schema at the input slot. Present iff the author passed a Zod schema to defineTool; otherwise undefined. Wire form is always the converted JSON Schema on input — this field exists so TS callers can z.infer<typeof tool.inputZod> for static types. Explicitly `ZodLikeSchema undefined(not a bare optional marker): the more specificDefinedTool<TInSchema, TOutSchema>returned bydefineToolnarrows this to the exact Zod schema type when Zod is used, and toundefinedwhen JSON Schema is used. Consumers reading a heterogeneousAnyToolsee the union and narrow with!== undefined`.
limits? readonly RuntimeLimits Memory + CPU caps enforced by the sandbox at dispatch. ToolManifest.limits
mcpEndpoint? readonly string MCP server URL for transport: 'mcp' tools. Ignored when transport is native. See the Model Context Protocol spec for the expected endpoint shape. ToolManifest.mcpEndpoint
metadata? readonly Readonly<Record<string, unknown>> Free-form key/value metadata that rides along with the manifest. Not interpreted by the framework — passthrough for pack-authored annotations (e.g. {owner: 'team-legal', ticket: 'PROJ-123'}). Surfaced in GET /v1/tools/:id responses for tooling. ToolManifest.metadata
mutating? readonly boolean Semantic marker: true when this tool causes observable side effects (writes state, calls external APIs with mutations, sends messages, etc.). Read-only tools (queries, computations, retrievals) set false. Absent = defaults to true (safer — the framework's never_ask / ask_on_first_use / always_ask policy defaults hinge on this flag; mistakenly marking a mutating tool as read-only would bypass HITL, while the reverse only adds friction). Consumed by @kindgi/agents as the per-tool HITL default when an agent's conversationPolicy.hitl.tools sets neither an override nor a default for the tool — a read-only tool passes straight through, a mutating tool asks on first use. ToolManifest.mutating
needs? readonly readonly Need[] Named context slots the tool depends on (e.g. tenant, run, blob, memory:facts). Framework-level dependencies the tool expects the runtime to inject via ToolContext. Declarative: not checked when a flow is loaded. needsSpec is the typed, discriminated form (env / secrets / config / capabilities / bindings). ToolManifest.needs
needsSpec? readonly TypedNeeds Discriminated typed-dependency declarations (env / secrets / config / capabilities / bindings). See TypedNeeds for the shape. ToolManifest.needsSpec
network? readonly NetworkPolicy Network egress policy the sandbox honors. ToolManifest.network
output readonly JsonSchema JSON Schema Draft 2020-12 for the tool's output. invokeTool validates the handler's return value against this before surfacing it — a handler that returns off-schema fails with bad-output. Same Zod-conversion story as input. Prefer explicit schemas over type: 'object', additionalProperties: true — the model uses the output schema to interpret tool results downstream. ToolManifest.output
outputZod? readonly ZodLikeSchema Symmetric to inputZod for the output slot. -
sandbox? readonly SandboxMode Isolation posture — see SandboxMode. ToolManifest.sandbox
spec? readonly HttpToolSpec Declarative handler specification. When present, the runtime Tool.handler is synthesized from this spec — the manifest carries everything needed for a first-party framework synthesizer to build the fetch/query/dispatch call at register time. Author writes the spec; framework owns the correctness bits (timeouts, aborts, secret resolution, retries). Discriminated on spec.kind. The framework ships 'http' (see HttpToolSpec) as the first-party kind; other kinds plug in via registerToolSpecSynthesizer. spec and handler are MUTUALLY EXCLUSIVE at defineTool time — a tool is either declarative or imperative. Mixed usage fails to compile. The full JSON-serializable manifest (spec included) is what POST /v1/tools accepts — declarative tools can be registered from configuration without shipping code. ToolManifest.spec
transport? readonly "auto" | "native" | "mcp" How the tool is dispatched at invoke time. 'native' (default) uses the framework's in-process dispatch; 'mcp' routes through the Model Context Protocol endpoint declared at mcpEndpoint; 'auto' picks native if a handler exists, else mcp. Most pack-authored tools omit this and default to native. ToolManifest.transport
version readonly string Semver — REQUIRED. Every tool registered in a Kindgi deployment ships versioned; an agent's tools[].version is a semver range matched against these versions at dispatch time via semver.maxSatisfying. Enforced by defineTool(...) at the API boundary. ToolManifest.version