What is a Tool?
A Tool document declares the contract for one callable capability: argument and result schemas, mutability class, and optional default policies. It does not declare where the tool runs or which credentials it uses—that lives in your worker processes and runtime installation config. At run time, workers connect to the runtime over the Work gRPC stream and register handlers for each tool@version binding.
Conformant runtimes use the pull model: instead of the manifest listing a URL to call, the code that implements a tool (a worker) connects to the runtime and announces "I can handle this tool." The runtime then hands authorized calls to whoever registered. Because nothing in the manifest hard-codes an address, tool identity is attested at execution (verified live when the call happens) rather than trusted from a URL written months ago.
Concept examples
Contract only (in the manifest — no URL, no API key):
kind: Tool
metadata:
name: get-forecast
namespace: weather
spec:
description: Return the forecast for a city.
input_schema:
inline:
type: object
properties:
city: { type: string }Pull model (worker registers; runtime dispatches when the model calls the tool):
Worker → register("weather.get-forecast@1.0.0")
Model → tool_call(name: get_forecast, args: { city: "Oslo" })
Runtime → invoke registered worker → tool_result → modelSide-effect class (what recovery is allowed after a crash):
side_effect_class: read_only # safe to retry
side_effect_class: non_idempotent_write # never silently run twiceMinimal example
apiVersion: phrony.com/v1
kind: Tool
metadata:
name: send-alert
namespace: weather
version: 1.0.0
governance:
risk_tier: high
classifications:
- weather.high-impact-external
labels:
owning-team: weather-platform
spec:
description: Send a public weather alert for a region.
side_effect_class: non_idempotent_write
input_schema:
ref: schemas/alert-input
output_schema:
inline:
type: object
properties:
alert_id: { type: string }
status: { type: string, enum: [sent, rejected] }
required: [alert_id, status]
additionalProperties: false
default_policies:
- weather.high-severity-alert-boundary
available_when:
- agent.capability: weather-alertsPlace Tool documents under tools/ in the Agent bundle, or reference them from a governed catalog at publish time. See Conventions and Tool bindings.
Bundle file
weather-assistant/
agent.yaml
tools/
send-alert.yaml # kind: Tool
schemas/
alert-input.jsonThe publish pipeline resolves input_schema.ref and output_schema.ref the same way as Agent output.schema.ref: bundle-relative paths with the schema search order in Conventions.
Field reference
Top-level
| Field | Type | Required | Description |
|---|---|---|---|
apiVersion | string | Yes | Must be phrony.com/v1 |
kind | string | Yes | Must be Tool |
metadata | object | Yes | Identity, governance, labels |
spec | object | Yes | Contract fields |
metadata
Tool supports the same metadata tiers as Agent. Only metadata.governance.authority_boundaries are enforced (compiled to policies at publish); other governance fields are descriptive and recorded in evidence. See Conventions.
| Field | On Tool | Notes |
|---|---|---|
name, namespace, version | Required | Semver in version; catalog logical id is namespace.name |
governance | Optional | Subset commonly used: risk_tier, classifications |
labels, annotations | Optional | Descriptive only |
spec
| Field | Type | Required | Description |
|---|---|---|---|
description | string | No | Human- and model-facing summary |
side_effect_class | string | No | Mutability for dispatch and recovery (see below) |
input_schema | object | No | JSON Schema for arguments ( ref or inline; mutually exclusive) |
output_schema | object | No | JSON Schema for tool results |
default_policies | string[] | No | Logical refs to Policy documents |
available_when | string[] | No | Declarative availability predicates (enforced when evaluated) |
strict | boolean | No | When true, arguments must validate strictly against input_schema |
on_failure | string | No | Tool-level failure handling hint for the runtime |
terminal | boolean | No | When true, a successful call may end the agent loop |
input_schema and output_schema
Exactly one of ref (+ optional version) or inline per schema object.
input_schema:
ref: schemas/alert-input
version: 2Bindings use input_schema (same shape as on Tool documents).
side_effect_class
The side-effect class answers one question: if we're not sure whether this call actually ran, is it safe to run it again? That matters after a crash or timeout. Reading data is safe to retry; charging a credit card is not. Declaring this lets the runtime recover safely instead of guessing. ("Idempotent" just means running it twice has the same effect as running it once.)
| Value | Meaning |
|---|---|
read_only | No durable side effects; safe to redispatch after indeterminate failure |
idempotent_write | Writes safely retried with the same call_id |
non_idempotent_write | At-most-once unless the handler proves idempotency |
irreversible_action | Cannot be safely repeated; indeterminate outcomes require human review |
Bindings may narrow side_effect_class but must not widen it relative to the Tool document at deploy.
Deliberately absent from Tool
The portable Tool kind does not include:
- Endpoints, URLs, or connection strings
- Credentials or secret references
executehooks or other SDK closures- Implementation hashes or worker binary ids
Those stay in application code and installation configuration.
Catalog identity and versioning
Tools are referenced from an Agent binding by logical ref:
ref: weather.send-alert@^1.0namespace.namematchesmetadata.namespaceandmetadata.name.@versionis a semver constraint; publish pins one concrete contract version in the resolved snapshot.- Deploy may narrow schemas or policies but never widen beyond the pinned Tool version.
Policy resolution
Policies attached to a tool call come from, in merge order ( deny wins / most restrictive ):
- Tool
default_policies - Agent binding
policies - Agent-wide policies
- Policies compiled from
metadata.governance.authority_boundarieson Agent or Tool
See Policy and Tool bindings.
Up next