Skip to content

This page describes the contracts that connect tools, policy, approval, hooks, and panels. The current versions are:

Contract Version Covers
Tool API raw.tool-api/2 Tool manifests, argument validation, effects, and conditional predicates.
Panel raw.panel/2 Live side panels and their blocks.
Hook raw.hook/2 Hook manifests, event payloads, and decisions.

A tool call has two separate kinds of data:

  • Arguments are the original input from the model, after validation. They are never rewritten. Hooks, approval, and the handler all see the same arguments.
  • Intended effects describe what a call would change, such as the files it would write or delete. They are computed before policy runs.

Intended effects are not results. A call that was approved and then failed has intended effects but no completed outcome. Effects are also not a security boundary, since the handler can still do anything its code permits.

For each tool call, Raw runs these steps in order. A failure at any step stops the call before the next step.

  1. Check that the tool is exposed, and that no unconditional deny rule applies.
  2. Validate the whole input against the JSON Schema and the tool’s validateArgs.
  3. Prepare intended effects, if the tool declares them, and validate the result.
  4. Evaluate conditional policy (tools.rules).
  5. Run PreToolUse hooks.
  6. Ask for approval when a rule requires it.
  7. Run the handler.

Effect descriptors must be synchronous and bounded. They may parse and normalize paths, but they must not read files, call a provider, run a shell, or change anything. A descriptor that returns a promise, or that throws, stops the call before the handler runs.

A tool manifest with api_version: 2 declares the following. Manifests reject unknown fields.

Field Required Description
api_version Yes 2.
id Yes Folder ID.
version Yes major.minor.patch.
name Yes Model-facing name.
description Yes What the tool does and what its result means.
input_schema Yes JSON Schema for the arguments.
entry Yes Module that exports handler and optionally validateArgs, describeEffects.
condition_sources No Sources a predicate may inspect: arguments and effects.
effects_schema No Object schema for the effects the tool declares. Required when the tool supports effects.
panels No Up to four panel declarations. See Panels.

Every conditional rule states its source explicitly. The source must be one of the tool’s declared condition_sources.

{ "source": "effects", "any": "files[*].path", "regex": "protected\\.txt$" }
Field Meaning
source arguments or effects.
any A dotted path with [*] for each array step. It must resolve to a string field in the source’s schema.
regex An RE2 pattern, unanchored.

A path that does not exist in the schema is a validation error. A field that is absent from a valid value does not match. Policies and hook subscriptions use the same predicate evaluator.

The write_file tool declares effects for both its operations form and its patch form.

Each effect is an object with an absolute, lexically normalized path and an operation:

Operation Produced by
write overwrite, append, replace_text, replace_lines, and patch add or update.
delete Patch delete.
rename_source Patch move, for the original path.
rename_destination Patch move, for the new path.

Paths are lexical. A symbolic link is not resolved. Every operation and patch target appears in the effects, so a rule on files[*].path covers both forms.

{ "source": "effects", "any": "files[*].path", "regex": "/protected/" }

When a rule requires approval, the approval callback receives one request object with these fields:

Field Description
identity The tool’s canonical identity.
name The model-facing name.
arguments The original arguments.
effects The intended effects, when the tool declares them.
toolCallId The call’s ID.
signal An abort signal.

The interface shows intended effects apart from the raw arguments. Approving a call does not change its arguments, and it does not turn intended effects into a completed outcome.

Hooks declare protocol_version: 2. For tool events, the payload contains:

Field Description
tool.arguments The original arguments.
tool.effects The intended effects, when the tool declares them.
tool.source "model" for a model call, or "user_action" for a panel action run from the dashboard. A missing value means "model".

Conditions on effects use the separately declared effects schema. See Hooks for the response protocol.

A panel is a live view that a tool keeps up to date. Panel state never goes to the model, except for one short confirmation line.

Declare panels in tool.json (panels), in the server’s config (for MCP), or by registration over ACP. Each declaration has these fields:

Field Description
id Panel ID, unique within the tool.
title Title shown to the user.
icon Optional. Unknown icons fall back to panel with a warning.
placement sidebar (default) or chat.
context Optional. summary panels also send a bounded reminder to the model after a compaction.
acp_plan Optional. Sends the panel’s checklist as an ACP plan.
actions Optional. Menu items on the panel.

A chat placement shows the panel inline in the conversation. A sidebar placement shows it in the side panel.

A tool updates a panel in one of two ways:

  • Return a result block of the form { "type": "panel", "panel": "<id>", "op": "replace" | "patch" | "close", ... } next to its normal content. Raw removes this block before hooks, caps, providers, and history see the result.
  • Call context.panels.update(panel, body) while the handler runs. The call resolves with the new revision. context.panels.get(panel) returns the last revision and document.

Panel updates are included with the tool result, including when the result is an error.

A panel document is made of blocks. The same block catalog is used in both placements.

Block Description
form A request for input, with text, single-select, or multi-select fields.
mermaid A diagram, with its source. If rendering is unavailable, the source is shown as text.

Form response actions submit or cancel a pending request. They never grant tool permission.

Limit Value
Declared panels per tool 4
Panels per session 16. A closed panel is evicted to make room.
Updates per panel per call 200
Document size 64 KiB

A panel action is a menu item that runs when the user selects it.

  • prompt actions draft a message for the user. They run in the browser or client.
  • tool actions run the declaring tool again through the normal tool path. Its allow, ask, and deny rules and its hooks apply. A click is never approval for an ask rule.

Panel errors use these codes: panel_invalid, panel_too_large, panel_undeclared, panel_not_owned, panel_unknown, panel_revision_conflict, panel_rate_limited, panel_limit, and panel_closed_context.

A rejected update in a result block never fails the tool. The model receives a line such as panel <id> update rejected: <code> <message>, and the history records the error.

A local tool can ask the user a question with context.interactions.request({ panel, document, timeout_ms? }). The request contains exactly one form block.

  • The default deadline is 30 minutes. A caller may set up to 24 hours.
  • A request has one of these states: pending, answered, cancelled, expired, or interrupted.
  • Cancelling the turn cancels the request. Reconnecting a browser leaves the wait in place.
  • An answer is validated against the form, and invalid answers are kept pending.
  • Answering a question never grants permission for a tool.

The ask_user tool uses this interface. A piped or non-interactive run returns interaction_unavailable immediately.

  • Tools covers manifests, selection, and rules from a user’s perspective.
  • Hooks covers the hook protocol and examples.
  • Architecture describes how the registry, policy, and sessions fit together.