Skip to content
Hoody.com

Inspect the agent’s tool catalogue, list the tool set available in a live session, and run tools sessionless or inside a live session through the same gated RPC the agent itself uses.

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.

NameInTypeRequiredDescription
pagequeryintegerNo1-based page number for pagination.
limitqueryintegerNoMaximum items per page (0 = no pagination).
X-Hoody-CwdheaderstringNoPer-request working-directory scope (the .hoody project layer / record cwd / tool+workflow cwd).
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override selecting which on-disk .hoody install a stateless read resolves against.
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
for await (const tool of client.agent.tools.listIterator()) {
console.log(tool.name, tool.read_only);
}

A page of tools plus pagination metadata. Each items[] element is the daemon’s row shape (name, description, JSON-Schema input, read_only). meta.total is the full count; meta.page and meta.limit are present only when limit>0.

Error CodeTitleDescriptionResolution

Lists the read-only subset of the catalogue (safe for planning / sessionless runs). Pagination honored.

NameInTypeRequiredDescription
pagequeryintegerNo1-based page number for pagination.
limitqueryintegerNoMaximum items per page (0 = no pagination).
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
for await (const tool of client.agent.tools.listReadOnlyIterator()) {
console.log(tool.name);
}

A page of read-only tool schemas plus pagination metadata. meta.total is the full count; meta.page and meta.limit are present only when limit>0.

Error CodeTitleDescriptionResolution

Returns the schema for a single built-in tool by name. Returns 404 tool_not_found for an unknown name.

NameInTypeRequiredDescription
namepathstringYesThe tool name.
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
const result = await client.agent.tools.get('read_file');
console.log(result.data.tool);

The schema is returned under tool (the gateway re-keys the daemon reply). input_schema is the JSON-Schema the run body must conform to.

Error CodeTitleDescriptionResolution

Returns the complete effective tool set for a live session: the built-in tools narrowed by the session’s tool mode, agent allowlist and headless exclusions, plus the MCP, skill and other tools the session’s configuration enables. Returns 404 when the session is not live.

NameInTypeRequiredDescription
idpathstringYesThe session id.
pagequeryintegerNo1-based page number for pagination.
limitqueryintegerNoMaximum items per page (0 = no pagination).
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex realm id. On a session route it names the realm the session is looked up in; a session in another realm, or in a realm this login does not serve, returns 404 not_found.
realmquerystringNoQuery alias of the X-Hoody-Realm header (read only when the header is absent).
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
for await (const tool of client.agent.sessions.listToolsIterator(sessionId)) {
console.log(tool.name);
}

A page of the session’s effective tools plus pagination metadata. meta.total is the full count; meta.page and meta.limit are present only when limit>0.

Error CodeTitleDescriptionResolution

Returns the MCP (mcp__*) tools available in a live session (drawn from the same effective tool set as the session’s tool listing). Returns 404 when the session is not live.

NameInTypeRequiredDescription
idpathstringYesThe session id.
pagequeryintegerNo1-based page number for pagination.
limitqueryintegerNoMaximum items per page (0 = no pagination).
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex realm id.
realmquerystringNoQuery alias of the X-Hoody-Realm header.
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
for await (const tool of client.agent.sessions.listMcpToolsIterator(sessionId)) {
console.log(tool.name);
}

A page of MCP tools plus pagination metadata. Each items[] element has the same tool-row shape as the session tool listing. meta.total is the full count.

Error CodeTitleDescriptionResolution

The three routes under POST /api/v1/agent/tools/{name}/... run a tool with no open session: an ephemeral local session is built from the scope headers and the tool goes through the same permission checks as the agent’s own tool calls. The work is not queued behind any open session; confirm and allow_mutations are wired straight onto the tool-run envelope.

Runs a tool synchronously and returns the result envelope. Caller-supplied control keys (confirmed, _-prefixed keys) are ignored; pass confirm, confirm_token, and allow_mutations only through the documented fields.

NameInTypeRequiredDescription
namepathstringYesThe tool name.
confirmquerybooleanNoQuery alias of the body confirm field (re-issue a previously-parked confirmation; pair with confirm_token).
confirm_tokenquerystringNoQuery alias of the body confirm_token field (the single-use token returned in the 409 tool_needs_confirmation details).
X-Hoody-Tool-ModeheaderstringNoSessionless tool-mode for the ephemeral session: standard (default) or orchestrator. Any other value is refused with 400 invalid_tool_mode.
X-Hoody-Dir-ScopeheaderstringNoSessionless directory-access scope: home (default) or full. Any other value is refused with 400 invalid_dir_scope.
X-Hoody-CwdheaderstringNoPer-request working-directory scope. Paths the tool touches resolve under this subtree.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex realm id.
realmquerystringNoQuery alias of the X-Hoody-Realm header.
NameTypeRequiredDescription
paramsobjectNoThe tool’s input parameters (its JSON-Schema body).
confirmbooleanNoRe-issue a previously-parked confirmation. Must be paired with confirm_token.
confirm_tokenstringNoThe single-use token returned in the prior 409 tool_needs_confirmation details, bound to the tool+params that parked.
allow_mutationsbooleanNoOpt a non-read-only tool into running with every permission check applied (else the run is refused with 400 tool_mutation_refused).
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
const result = await client.agent.tools.run('read_file', {
params: {
path: '/home/user/project/README.md',
reason: 'read the project overview before making changes',
},
});
console.log(result.data.status, result.data.output);

The tool result envelope. status is "ok" once the run completed; a tool that ran and failed is still "ok", so read is_error. error_code is present on a typed tool failure; hint and hint_cmd are present when the tool suggested a recovery; code and current_revision are present on a guarded write refused by an expected-revision check.

Error CodeTitleDescriptionResolution

Async form of /run: 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.

NameInTypeRequiredDescription
namepathstringYesThe tool name.
confirmquerybooleanNoQuery alias of the body confirm field.
confirm_tokenquerystringNoQuery alias of the body confirm_token field.
X-Hoody-Tool-ModeheaderstringNoSessionless tool-mode for the ephemeral session (standard or orchestrator).
X-Hoody-Dir-ScopeheaderstringNoSessionless directory-access scope (home or full).
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local).
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex realm id.
realmquerystringNoQuery alias of the X-Hoody-Realm header.
NameTypeRequiredDescription
paramsobjectNoThe tool’s input parameters.
confirmbooleanNoRe-issue a previously-parked confirmation (paired with confirm_token).
confirm_tokenstringNoSingle-use token from the prior 409 tool_needs_confirmation details.
allow_mutationsbooleanNoOpt a non-read-only tool into running with every permission check applied.
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
const started = await client.agent.tools.start('read_file', {
params: {
path: '/home/user/project/README.md',
reason: 'read the project overview before making changes',
},
});
const jobId = started.data.job_id;
if (!jobId) throw new Error('The tool run did not start');
const result = await client.agent.jobs.getResult(jobId);

The gateway-minted job id. Poll GET /jobs/{id} or GET /jobs/{id}/result for the tool result, a parked confirmation (re-issue /runAsync with confirm:true plus the confirm_token), or an execution error.

Error CodeTitleDescriptionResolution

Streaming form of /run 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.

NameInTypeRequiredDescription
namepathstringYesThe tool name.
confirmquerybooleanNoQuery alias of the body confirm field.
confirm_tokenquerystringNoQuery alias of the body confirm_token field.
X-Hoody-Tool-ModeheaderstringNoSessionless tool-mode for the ephemeral session (standard or orchestrator).
X-Hoody-Dir-ScopeheaderstringNoSessionless directory-access scope (home or full).
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local).
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex realm id.
realmquerystringNoQuery alias of the X-Hoody-Realm header.
NameTypeRequiredDescription
paramsobjectNoThe tool’s input parameters.
confirmbooleanNoRe-issue a previously-parked confirmation (paired with confirm_token).
confirm_tokenstringNoSingle-use token from the prior 409 tool_needs_confirmation details.
allow_mutationsbooleanNoOpt a non-read-only tool into running with every permission check applied.
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
const stream = await client.agent.tools.run(
'read_file',
{
params: {
path: '/home/user/project/README.md',
reason: 'read the project overview before making changes',
},
},
{ stream: true },
);
for await (const frame of stream) {
console.log(frame.event, frame.data);
}

SSE stream of the tool run: an opening start frame, a result / needs_confirmation / error frame, then a closing end frame.

Error CodeTitleDescriptionResolution

POST /api/v1/agent/sessions/{id}/tools/{name}/run

Section titled “POST /api/v1/agent/sessions/{id}/tools/{name}/run”

Runs a tool on a live session through the same permission checks as the agent’s own tool calls: caller-supplied control keys are ignored, and the tool runs in the session’s own scope (its realm, container, cwd, tool mode and dir scope) with every check applied. 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. A tool-call rule is checked here too: a limit the call breaks returns 200 is_error; a check_in it falls under, or a rules check that could not complete, returns 409 tool_needs_confirmation with details.gate_cause: "rules" and details.reason naming the rule. Returns 404 tool_not_found when the tool is not in the session’s effective tool list.

Some tools need the session’s model loop or a human and cannot be run directly: spawn_agent, run_workflow, review_with_panel, and ask_question_to_user are refused with 422 tool_not_directly_runnable and nothing runs; ask the agent for them in a turn instead.

On a session whose approval policy is "always", a tool that is itself a nested executor (spawn_agent, run_workflow, review_with_panel, tool_orchestrator, run_codex, …) returns 409 approval_policy_unsatisfiable instead; every other side-effecting tool parks for confirmation as usual, and the confirmation must carry the approver lease (X-Hoody-Approver-Lease) when one was minted.

NameInTypeRequiredDescription
idpathstringYesThe session id.
namepathstringYesThe tool name.
confirmquerybooleanNoQuery alias of the body confirm field (re-issue a previously-parked confirmation; pair with confirm_token).
confirm_tokenquerystringNoQuery alias of the body confirm_token field.
X-Hoody-Approver-LeaseheaderstringNoThe approver-lease capability returned by POST /sessions/{id}/approver-lease. Required on every confirmation on an "always" session whose lease was minted.
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex realm id.
realmquerystringNoQuery alias of the X-Hoody-Realm header.
NameTypeRequiredDescription
paramsobjectNoThe tool’s input parameters (its JSON-Schema body).
confirmbooleanNoRe-issue a previously-parked confirmation. Must be paired with confirm_token.
confirm_tokenstringNoSingle-use token from the prior 409 tool_needs_confirmation details.
allow_mutationsbooleanNoOpt a non-read-only tool into running with every permission check applied on a sessionless run.
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
const result = await client.agent.sessions.runTool(sessionId, 'bash', {
params: {
command: 'git status',
reason: 'check the working tree before committing',
},
});
console.log(result.data.status, result.data.output);

The tool result envelope. status is "ok" once the run completed; a tool that ran and failed is still "ok", so read is_error. error_code is present on a typed tool failure; hint and hint_cmd are present when the tool suggested a recovery; code and current_revision are present on a guarded write refused by an expected-revision check.

Error CodeTitleDescriptionResolution