The Tool endpoints expose the agent’s tool catalogue, surface a live session’s effective tool set, and let you execute a tool synchronously, asynchronously, or as a Server-Sent Events stream. Use these endpoints when you need to introspect what tools are available to an agent, inspect a single tool’s JSON-Schema input, or invoke a tool directly — either against an open session (with full gating against the session’s frozen scope) or sessionlessly (with the gateway creating an ephemeral session from per-request scope headers).
All endpoints in this group go through the container-scoped agent endpoint and must be reached through hoody-proxy.
Lists the agent’s built-in tool schemas (name, description, JSON-Schema input, read_only flag). Pagination: pass ?page=N&limit=M for a window; omit limit for the full set.
Returns the complete effective tool set for a live session — tools that are config-enabled and on PATH, gated by the session’s tool mode / agent allowlist / headless exclusions. Returns 404 when the session is not live.
Runs a tool through the single gated policy gate with no open session: the gateway creates an ephemeral local session from the scope headers (X-Hoody-Cwd / X-Hoody-Config-Dir) and runs the full permission checks. Sessionless runs are read-only by default — a non-read-only tool requires allow_mutations:true or confirm:true (else 400 tool_mutation_refused). A parked confirmation returns 409 tool_needs_confirmation with the echoed tool+params; re-issue with confirm:true.
The tool’s input parameters (its JSON-Schema body).
confirm
boolean
No
Re-issue a previously-parked confirmation. MUST be paired with confirm_token from the prior 409.
confirm_token
string
No
The single-use token returned in the 409 tool_needs_confirmation details.
allow_mutations
boolean
No
Sessionless only: opt a non-read-only tool into running under the full permission checks (else a sessionless mutating run is refused 400 tool_mutation_refused).
Caller-supplied confirmed/_-prefixed control keys are ignored — they are never trusted from the wire.
"text":"total 48\ndrwxr-xr-x 6 user user 4096 May 12 09:14 .\ndrwxr-xr-x 18 user user 4096 May 12 09:14 ..\n-rw-r--r-- 1 user user 2204 May 12 09:14 README.md\ndrwxr-xr-x 3 user user 4096 May 12 09:14 src\n"
}
]
}
{
"code":"tool_mutation_refused",
"message":"sessionless run refused for a non-read-only tool"
}
Error Code
Title
Description
Resolution
bad_request
Bad request
The request was malformed or carried invalid parameters.
Correct the request body or query parameters.
tool_mutation_refused
Tool mutation refused
A sessionless tool run resolved to a mutating tool with no confirmation posture. Sessionless runs are read-only by default.
Open a session and run the tool there, or supply allow_mutations:true / confirm:true on the sessionless run.
realm_scope_unsupported
Realm scope unsupported
A per-request realm header was supplied to an active-only RPC, which has no realm dimension to scope.
Omit the realm header on this route, or open a session to scope by realm.
{
"code":"forbidden",
"message":"request must arrive through the Hoody proxy"
}
Error Code
Title
Description
Resolution
forbidden
Forbidden (not via the Hoody proxy)
The request did not reach the service through the public endpoint.
Reach the agent through hoody-proxy, not by connecting to the container directly.
{
"code":"tool_not_found",
"message":"no tool with that name"
}
Error Code
Title
Description
Resolution
tool_not_found
Tool not found
No tool with the given name exists in the catalogue or in the session’s effective tool list.
List the catalogue (GET /tools) or the session’s tools (GET /sessions/{id}/tools) and use a valid name.
{
"code":"tool_needs_confirmation",
"message":"tool requires confirmation before execution"
}
Error Code
Title
Description
Resolution
tool_needs_confirmation
Tool needs confirmation
The tool was NOT executed: the permission checks requires confirmation first. The echoed tool+params let the caller re-issue the run with confirm:true.
Re-issue the run with confirm:true (or ?confirm=true), preserving the echoed params.
{
"code":"payload_too_large",
"message":"request body exceeds the configured size limit"
}
Error Code
Title
Description
Resolution
payload_too_large
Payload too large
The request body exceeds the configured size cap (MaxBodyBytes). The gateway rejects an oversized body at the edge before the handler reads it.
Reduce the request body below the configured limit (default 8 MiB); split a large payload into smaller requests.
{
"code":"rate_limited",
"message":"request rate limit exceeded"
}
Error Code
Title
Description
Resolution
rate_limited
Too many requests
The per-client request rate limit was exceeded; the gateway throttled the request before dispatch.
Honor the Retry-After header and retry; reduce the request rate.
{
"code":"internal_error",
"message":"internal server error"
}
Error Code
Title
Description
Resolution
internal_error
Internal error
An unexpected error occurred while handling the request.
Async form of runTool: returns {job_id} immediately and runs the gated tool in the background. Poll GET /jobs/{id} or GET /jobs/{id}/result for the result, a parked confirmation, or an execution error. A non-read-only sessionless run still requires an explicit posture.
Streaming form of runTool over Server-Sent Events: a start frame, then a result / needs_confirmation / error frame, then end. The work is a one-shot gated RPC, so there is no per-token stream — the SSE shape mirrors the kit streaming convention for symmetry with the session stream. A non-read-only sessionless run still requires an explicit posture.
Runs a tool through the gated policy gate on a live session, against the session’s frozen realm/container/cwd/tool-mode/dir-scope, with the full permission checks. It claims the session’s single serial turn slot so a direct tool run never races the turn loop (409 turn_in_flight if a turn is running; 409 gate_parked if a gate is parked). Because it occupies the turn slot it is also cancellable the same way a turn is: a concurrent POST /sessions/{id}/cancel (or a WS cancel frame, or session close) aborts the in-flight run. A parked confirmation returns 409 tool_needs_confirmation with the echoed params; re-issue with confirm:true. Returns 404 tool_not_found when the tool is not in the session’s effective tool list.
The tool’s input parameters (its JSON-Schema body).
confirm
boolean
No
Re-issue a previously-parked confirmation. MUST be paired with confirm_token from the prior 409.
confirm_token
string
No
The single-use token returned in the 409 tool_needs_confirmation details.
allow_mutations
boolean
No
Sessionless only: opt a non-read-only tool into running under the full permission checks (no effect on the in-session run, which inherits the session’s frozen scope).
Caller-supplied confirmed/_-prefixed control keys are ignored — they are never trusted from the wire.
The request was malformed or carried invalid parameters.
Correct the request body or query parameters.
realm_scope_unsupported
Realm scope unsupported
A per-request realm header was supplied to an active-only RPC, which has no realm dimension to scope.
Omit the realm header on this route, or open a session to scope by realm.
{
"code":"forbidden",
"message":"request must arrive through the Hoody proxy"
}
Error Code
Title
Description
Resolution
forbidden
Forbidden (not via the Hoody proxy)
The request did not reach the service through the public endpoint.
Reach the agent through hoody-proxy, not by connecting to the container directly.
{
"code":"tool_not_found",
"message":"no tool with that name"
}
Error Code
Title
Description
Resolution
not_found
Not found
The requested resource does not exist.
Verify the path and identifier.
tool_not_found
Tool not found
No tool with the given name exists in the catalogue or in the session’s effective tool list.
List the catalogue (GET /tools) or the session’s tools (GET /sessions/{id}/tools) and use a valid name.
{
"code":"turn_in_flight",
"message":"a turn is already running on this session"
}
Error Code
Title
Description
Resolution
tool_needs_confirmation
Tool needs confirmation
The tool was NOT executed: the permission checks requires confirmation first. The echoed tool+params let the caller re-issue the run with confirm:true.
Re-issue the run with confirm:true (or ?confirm=true), preserving the echoed params.
turn_in_flight
Turn in flight
A turn is already running on this session; the single serial turn slot is occupied, so a new turn/workflow run is refused.
Wait for the running turn to finish (observe agent_done on the session stream), then retry.
gate_parked
Gate parked
A confirm/question gate is parked on this session, so a new turn/workflow run is refused until it is answered. The parked gate is surfaced under details.pending_gate.
Answer the parked gate (/confirm or /answer) and retry; read it via GET /sessions/{id} or details.pending_gate.
{
"code":"payload_too_large",
"message":"request body exceeds the configured size limit"
}
Error Code
Title
Description
Resolution
payload_too_large
Payload too large
The request body exceeds the configured size cap (MaxBodyBytes). The gateway rejects an oversized body at the edge before the handler reads it.
Reduce the request body below the configured limit (default 8 MiB); split a large payload into smaller requests.
{
"code":"rate_limited",
"message":"request rate limit exceeded"
}
Error Code
Title
Description
Resolution
rate_limited
Too many requests
The per-client request rate limit was exceeded; the gateway throttled the request before dispatch.
Honor the Retry-After header and retry; reduce the request rate.
{
"code":"internal_error",
"message":"internal server error"
}
Error Code
Title
Description
Resolution
internal_error
Internal error
An unexpected error occurred while handling the request.