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.
Extends
Section titled “Extends”Type Parameters
Section titled “Type Parameters”| Type Parameter | Default type |
|---|---|
TInput |
unknown |
TOutput |
unknown |
Properties
Section titled “Properties”| 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 |