SOPs declare what must happen; tool definitions declare what can be invoked. The two artifacts meet at the EXECUTION step: the step binds a tool by identity, and the engine validates every proposed call against the tool's own registered schemas. This document specifies the tool record — the third authoring artifact, after the SOP and alongside the Cedar policies.
The tool record
| Field | Type | Required | Semantics |
|---|---|---|---|
tool_id |
string | yes | Tool identity. Referenced by EXECUTION steps through the metadata binding, by policy rules, and by every tool_call event. |
description |
string | yes | Declared capability, consumed by the planner when proposing calls against the step contract. |
input_schema |
JSON Schema | yes | The parameters contract. The input gate validates every proposed call against this schema — deviation fails, no call is made. |
output_schema |
JSON Schema | yes | The returned-structure contract. The output gate validates before commit. |
endpoint |
object | yes | How the sandbox obtains and invokes the tool: source location and transport. |
auth |
object | yes | Credential requirements: which secrets the tool needs. Injected at runtime; never recorded. |
sandbox_profile |
object | yes | Execution constraints the orchestrator enforces: network egress scope, filesystem access. |
side_effect_class |
enum | yes | read-only, compensatable, or supersede — the inherent effect class. See below. |
Example
{
"tool_id": "web_search",
"description": "Retrieve search results for a query against the public web index.",
"input_schema": {
"type": "object",
"properties": {
"query": { "type": "string" },
"max_results": { "type": "integer", "minimum": 1, "maximum": 50 }
},
"required": ["query"]
},
"output_schema": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": {
"type": "object",
"properties": {
"url": { "type": "string" },
"title": { "type": "string" },
"snippet": { "type": "string" }
},
"required": ["url", "title"]
}
}
},
"required": ["results"]
},
"endpoint": { "…": "elided" },
"auth": { "…": "elided" },
"sandbox_profile": { "…": "elided" },
"side_effect_class": "read-only"
}Excerpt — retrieval tool record, web_search shape. Field structure is contractual; scalar values are placeholders pending the final excerpt pass.
Single source of truth
Both structural gates validate against the tool's registered schemas — not a parallel copy maintained in the SOP. The validated structure and the declared structure are the same document, which is the property that makes schema validation drift-proof:
| Gate | Validates against | Drift possibility |
|---|---|---|
| Input gate | The record's input_schema |
None — same artifact |
| Output gate | The record's output_schema |
None — same artifact |
A step cannot invoke an unregistered tool: the binding resolves against the registry, and an unresolvable binding fails at dispatch. Hallucinated tool calls die at this boundary or the input gate — never later.
Binding to steps
EXECUTION steps bind tools through metadata:
| Binding | Semantics |
|---|---|
tool_id |
The registered tool this step invokes |
| Call constraints | Optional step-side limits the planner respects when proposing parameters |
The planner proposes a call naming the bound tool and its parameters; the input gate checks the proposal against the registered input_schema; only then does the MCP sandbox provision.
Side-effect class
Declared on the tool record, inherited by the step through the binding, recorded on every execution. The class is an authoring declaration, not a runtime judgment — the property Saga compensations depends on.
| Class | Semantics | Compensation path |
|---|---|---|
read-only |
No external state mutated | Nothing to undo |
compensatable |
Writes that carry a declared inverse | The engine executes the inverse during rollback |
supersede |
Writes that are later versions of prior state | Rollback marks superseded rather than removing |
Policies may constrain by class — see the read-only policy example in the Policy Gateway.
Sandbox profile
| Property | Semantics |
|---|---|
| Network egress scope | The hosts the tool may reach from inside the container |
| Filesystem access | Nothing beyond the container's ephemeral workspace |
The profile is part of the record, so the constraint travels with the tool: a tool cannot execute outside its declared envelope, and the orchestrator enforces the envelope at provision time. The container lifecycle — provision, fetch, execute, destroy — is specified in security and isolation.
Registration acceptance criteria
| Rule | On violation |
|---|---|
input_schema and output_schema are well-formed JSON Schema |
Rejected at registration |
tool_id unique in the registry |
Rejected at registration |
endpoint resolvable |
Rejected at registration |
auth declares requirements — inline secrets are rejected structurally |
Rejected at registration |
side_effect_class declared |
Rejected at registration |
sandbox_profile within the deployment's allowed envelope |
Rejected at registration |
What the plane never does with a tool
| Never | Because |
|---|---|
| Execute an unregistered tool | Bindings resolve against the registry |
| Coerce a failed proposal into a call | Deviation is failure — schema validation |
| Reuse a container across calls | One container per execution — security |
| Record credential material | The redaction rule — ledger formats |
