Every command on this page targets a running agent installation, not the agent template. An installation is a workspace: one or more durable deep agents plus the durable workflows you ship alongside them. These verbs inspect and operate that running workspace — its agents, its workflows, the durable runs they produce, and the agent-local stores (database, storage, RAG, secrets, config, prompts) each agent reaches through the ambient stackbone client.

By default the CLI resolves the target to the local-dev installation linked to the current project (served by a running stackbone dev); pass --agent <installationId> on any verb to point at a different installation. The one exception is stackbone agents, which is how you discover the installation ids in the first place — it never takes --agent.

Conventions

These hold for every group below, so they are stated once here instead of on each verb.

  • Target resolution. A verb with no --agent runs against the local-dev installation linked to the current project, talking to it directly — so stackbone dev must be running. If it is not, the verb fails fast with the dev_not_running error (exit code 3) telling you to start it. Pass --agent <installationId> to target a cloud installation instead, which does not need stackbone dev. With no project and no --agent, the verb cannot guess a target and likewise fails with exit code 3 (no project). See Configuration → exit codes.
  • JSON output. Every verb accepts --json (or STACKBONE_JSON=1) and then emits a single { "schema_version": 1, ... } line on stdout. The per-verb payloads below show the inner fields. See Configuration → output contract.
  • Pagination. Every list-style verb takes --limit <n> and --cursor <opaque>, and its JSON payload carries items plus nextCursor / prevCursor (either may be null). Pass the previous page's nextCursor back as --cursor to walk forward. Some lists add domain-specific fields alongside items.
  • Destructive verbs need --yes. Any verb that mutates or deletes (retry, cancel, discard, purge, push, remove, rollback, approve, reject) refuses to run without --yes and exits 5 (permission denied) until you pass it. See Configuration → global flags.
  • Secrets are never revealed. Neither stackbone secrets nor stackbone openrouter ever prints a plaintext secret or key — reading a raw value is a human-only action in Studio behind a re-auth challenge.

stackbone agents

Discover the agent installations in your organization. Use the ids and slugs it lists as the --agent target for every other group. Read-only; takes no --agent.

Command Purpose
stackbone agents list List every agent installation in your organization (incl. local-dev).
stackbone agents get <slug> Read one installation by its slug (id, version, status, tunnel).

kind is cloud for a deployed installation or local for the local-dev install that exists while stackbone dev is running for this project.

JSON payload

// agents list
{ "schema_version": 1, "items": [
  { "id": "inst_123", "agentSlug": "hello-world", "status": "running", "kind": "cloud" }
] }

// agents get <slug>
{ "schema_version": 1, "agent": {
  "id": "inst_123", "agentSlug": "hello-world", "agentVersion": "1.2.0",
  "status": "running", "kind": "cloud", "templateName": "Hello World",
  "templateOwnerOrgSlug": "acme", "localTunnelUrl": null,
  "createdAt": "2026-05-01T10:00:00Z", "updatedAt": "2026-06-01T10:00:00Z" } }

Exit codes: 0 ok · 2 auth · 4 not found (unknown slug) · 1 generic. Full table: Configuration → exit codes.

stackbone workflows

Inspect the durable workflows the targeted installation's workspace exposes, and the input/output JSON Schema each one declares. Both verbs are read-only; no --yes gate.

A workflow declares its IO by exporting sibling inputSchema / outputSchema Zod objects next to the 'use workflow' function. workflows schema is how you read a workflow's per-call contract. When a workflow declares neither, the schema reads { input: null, output: null } and callers fall back to a raw JSON field.

Command Purpose
stackbone workflows list List the workflows the workspace exposes. Each row shows the workflow name and its trigger; marks one that declares an input/output schema ( if it does not).
stackbone workflows schema <name> Print one workflow's input/output JSON Schema. Falls back to a message when the workflow declares no schema.

JSON payload

// workflows list — one entry per workflow, each with its trigger and hasSchema flag
{ "schema_version": 1, "items": [
  { "name": "onboarding", "trigger": "POST /api/workflows/onboarding/start", "hasSchema": true },
  { "name": "reconcile",  "trigger": "POST /api/workflows/reconcile/start",  "hasSchema": false }
] }

// workflows schema <name> — each half is null when undeclared
{ "schema_version": 1, "schema": {
  "input":  { "type": "object", "properties": { "orderId": { "type": "string" } } },
  "output": { "type": "object", "properties": { "refunded": { "type": "boolean" } } } } }

The trigger is the HTTP entry point that starts a fresh durable run of the workflow (a POST /api/workflows/:name/start). The result is a durable run you inspect with stackbone runs.

The stackbone dev runtime serves the workflow routes for a local install. A cloud installation's workflow routes are the same model, served by the deployed runtime.

Exit codes: 0 ok · 4 not found (unknown workflow) · 1 generic.

stackbone runs

Inspect and control the durable execution runs of the targeted installation. A run is one durable invocation — a workflow run started from a trigger, or an agent chat turn — executed on the durable engine so it can pause and resume across processes. See Workflows → durable runs.

Command Purpose
stackbone runs list List recent runs. Filters: --status <running|done|failed|interrupted>, plus --limit/--cursor.
stackbone runs get <id> Inspect a single run (status, trigger, timing).
stackbone runs retry <id> Start a fresh durable run from a run's original input. Requires --yes.
stackbone runs cancel <id> Cancel a running run (marks it interrupted). Requires --yes.

A run's status is running, done, failed, or interrupted. interrupted covers both a run you cancelled and a durable run that is parked awaiting a human decision — a workflow that called requestApproval() and is waiting on the approvals inbox. retry does not resume a run in place; it starts a brand-new durable run from the original input, which is why it is destructive.

JSON payload

// runs list — paginated
{ "schema_version": 1,
  "items": [{ "id": "run_1", "status": "done", "trigger": "workflow", "createdAt": "2026-06-01T10:00:00Z" }],
  "nextCursor": "eyJ...", "prevCursor": null }

// runs retry <id> — the freshly-started run
{ "schema_version": 1, "run": { "id": "run_2", "status": "running" } }

A run's trigger tells you what produced it — e.g. workflow (a durable workflow run) or chat (an agent chat turn).

Exit codes: 0 ok · 4 not found (unknown run) · 5 permission (retry/cancel without --yes) · 1 generic (e.g. invalid --status).

stackbone hitl

Human-in-the-loop approvals for the targeted installation. This inbox is the return path for a parked durable run: when a workflow step calls requestApproval() (from @stackbone/sdk/workflow, see Workflows → human-in-the-loop), the run pauses and the pending approval surfaces here. Deciding it — approve or reject — resumes the parked run with your decision. An approval's run field links back to the run you can follow with stackbone runs get. --reason <text> is recorded as the decision comment. (Editing an approval payload is a Studio-only action.)

Command Purpose
stackbone hitl list List approvals. Filters: --status <pending|approved|rejected|timed_out|cancelled>, --limit/--cursor.
stackbone hitl get <id> Inspect one approval (topic, run, timeout, and its audit trail of past decisions).
stackbone hitl approve <id> Approve a pending approval (--reason), resuming the parked run. Requires --yes.
stackbone hitl reject <id> Reject a pending approval (--reason), resuming the parked run. Requires --yes.

An approval that no one decides before its timeout elapses ends as timed_out, and the workflow continues with the fallback decision the step declared.

JSON payload

// hitl list — paginated
{
  "schema_version": 1,
  "items": [
    { "id": "appr_1", "status": "pending", "topic": "refund", "createdAt": "2026-06-01T10:00:00Z" },
  ],
  "nextCursor": null,
  "prevCursor": null,
}

hitl get adds the run the approval belongs to and the parked run's timeout.

Exit codes: 0 ok · 4 not found (unknown approval) · 5 permission (approve/reject without --yes) · 1 generic.

stackbone logs

Live-tail the targeted installation's logs over a server-sent stream.

Command Purpose
stackbone logs tail Stream log lines. Server-side filters: --run <id>, --level <info|warn|error…>, --q <text>, --trace-id <id>. Client-side: --since, --until, --limit, --follow.

--level, --q and --trace-id are applied by the server. --since and --until (a duration like 15m/2h or an ISO timestamp) and --limit (default 100) are applied locally as lines arrive — this stream has no server-side time range or pagination. Without --follow the tail stops once --limit lines have printed; with --follow it streams until you hit Ctrl-C.

When a durable run or one of its steps fails, the runtime logs it at error with the real error message and stack, so stackbone logs tail --level error surfaces every crash. Scope the tail to a single run with --run <id> to read just that run's lifecycle — the same id you see in stackbone runs list. Caller mistakes log at warn: triggering a workflow with input that fails its declared schema is logged as workflow_input_invalid, so a bad payload is visible in the stream rather than silently dropped.

JSON payload — one envelope per line (not a paged list):

{ "schema_version": 1, "time": 1717236000000, "line": "agent booted", "level": "info" }

Exit codes: 0 ok (including a clean Ctrl-C stop) · 3 no project · 1 generic (e.g. invalid --limit/--since).

stackbone db

Database operations for the targeted installation. The migrate group runs the same migration engine stackbone dev uses on boot, against your local dev database; the read-only Explorer verbs (query, schemas, table) talk to the targeted installation over the control plane.

  • The migrate verbs read the connection string from STACKBONE_POSTGRES_URL when it is set. If it is not, migrate up and migrate status automatically discover it from a running stackbone dev session for this project, so you do not have to export the variable in a separate shell. With neither the variable set nor a live dev session the command exits 3 (no project). They resolve the schema + migrations directory from agent.yaml (database.schema, default src/schema.ts; database.migrations, default .stackbone/migrations).
  • The Explorer verbs accept --agent like the rest of this page.
Command Purpose
stackbone db migrate up Apply every pending migration (advisory-locked, atomic per file). Supports --target <tag>.
stackbone db migrate create <name> Generate a new SQL migration by diffing src/schema.ts against the journal.
stackbone db migrate status Classify each migration as applied, pending or drifted (informational).
stackbone db query [sql] Run one read-only SELECT against the installation. SQL from the positional, --file <path> or stdin.
stackbone db schemas List the schemas and tables visible to the installation, with row estimates.
stackbone db table <schema> <table> Browse rows of one table with cursor pagination (--limit, --cursor, --order asc|desc).

The migration verbs' flags and JSON payloads are documented in full at Commands → Database operations. The Explorer verbs return:

// db query / db table
{
  "schema_version": 1,
  "columns": [{ "name": "id" }, { "name": "email" }],
  "rows": [{ "id": 1, "email": "a@b.com" }],
  "truncated": false,
  "duration_ms": 12,
}

The control plane enforces "a single SELECT" on db query; anything else is rejected server-side. Results are capped (truncated at 1000 rows for query; cursor-paged for table).

Exit codes: 0 ok · 3 no project (missing agent.yaml, or no database connection — STACKBONE_POSTGRES_URL unset and no running stackbone dev session to discover it from) · 1 generic (migration failure, invalid migration name, bad identifier, non-SELECT SQL).

stackbone storage

Operate the S3-style object store bound to the targeted installation. --bucket <name> is required on every object verb (an install can expose more than one bucket).

Command Purpose
stackbone storage buckets List the buckets the installation exposes.
stackbone storage list List objects in --bucket, optionally under --prefix. Supports --limit/--cursor.
stackbone storage get <key> Download an object to stdout (or --out <path>) via a short-lived presigned URL.
stackbone storage put <key> Upload a local --file <path> under the key.
stackbone storage presign <key> Print a short-lived presigned download URL for the object.
stackbone storage remove <key> Delete an object. Requires --yes.

JSON payload

// storage list — paginated, plus folder prefixes
{ "schema_version": 1,
  "items": [{ "key": "uploads/foo.txt", "size": 1024, "last_modified": "2026-06-01T10:00:00Z" }],
  "common_prefixes": ["uploads/"], "nextCursor": null, "prevCursor": null }

// storage presign <key>
{ "schema_version": 1, "url": "https://…", "expires_at": "2026-06-01T10:05:00Z" }

The reserved rag/ key prefix is managed by stackbone rag — the backend rejects put/remove under it.

Exit codes: 0 ok · 4 not found (unknown bucket/key) · 5 permission (remove without --yes) · 1 generic (missing --bucket/--file).

stackbone rag

Operate the managed retrieval index bound to the targeted installation. The document, query and job verbs require --collection <name>.

Command Purpose
stackbone rag collections list List collections with per-collection document and chunk counts.
stackbone rag collections create <name> Create an empty collection.
stackbone rag collections remove <name> Delete a collection and every document under it. Requires --yes.
stackbone rag list List documents in --collection. Supports --limit/--cursor.
stackbone rag get <docId> Download a document original to stdout (or --out <path>).
stackbone rag ingest <path> Upload a local .txt/.md/.pdf (≤ 25 MiB) into --collection, staging an async job.
stackbone rag query <text> Run a similarity query over --collection. Supports --topk, --model.
stackbone rag remove <docId> Delete a document (cascades to its chunks). Requires --yes.
stackbone rag jobs List async ingest jobs, optionally filtered by --collection.
stackbone rag retry <jobId> Re-enqueue a failed ingest job. Requires --yes.
stackbone rag cancel <jobId> Cancel a non-terminal ingest job. Requires --yes.

JSON payload

// rag ingest
{ "schema_version": 1, "job_id": "job_1", "status": "queued" }

// rag query
{ "schema_version": 1,
  "items": [{ "id": "doc_1", "chunk_idx": 0, "score": 0.83, "content": "…" }],
  "dimensions": 1536, "embedded_with": "text-embedding-3-small" }

rag query <text> embeds the query text server-side with your organization key and runs the similarity search against --collection, returning the ranked chunks. The response reports the vector dimensions and the model it embedded with (embedded_with).

Exit codes: 0 ok · 4 not found (unknown collection/doc/job) · 5 permission (destructive verb without --yes) · 1 generic (missing --collection, unsupported file type).

stackbone secrets

Manage environment-scoped secrets bound to the targeted installation. There is deliberately no reveal verb — the CLI never prints a plaintext value. set is idempotent on the name (create and rotate are the same call).

Command Purpose
stackbone secrets list List secret names (values always masked) and their last-rotated time.
stackbone secrets set <name> Create or rotate a secret. Value from --value <v> or stdin; --description.
stackbone secrets remove <name> Delete a secret. Requires --yes.

JSON payload

// secrets list — value_preview is a mask, never the plaintext
{
  "schema_version": 1,
  "items": [
    {
      "name": "OPENAI_API_KEY",
      "value_preview": "••••",
      "last_rotated_at": "2026-06-01T10:00:00Z",
    },
  ],
}

Exit codes: 0 ok · 4 not found (unknown secret) · 5 permission (remove without --yes) · 1 generic (empty value).

stackbone config

Manage the agent's AGENT_CONFIG document on the targeted installation. The control plane models config as one versioned JSON document, not a bag of keys: every write appends a new version, the highest is active, and a rollback copies a prior version forward.

Command Purpose
stackbone config get Print the active config document (value, version, author).
stackbone config set Persist a new version. Reads a JSON object from --file <path> or stdin.
stackbone config versions List recent versions (newest first, up to 100).
stackbone config rollback --version <n> Roll the active config back to a prior version. Requires --yes.

JSON payload

// config get
{ "schema_version": 1, "version": 4, "value": { "feature": { "newFlow": true } },
  "updatedAt": "2026-06-01T10:00:00Z", "updatedBy": "a@b.com" }

// config set
{ "schema_version": 1, "unchanged": false, "config": { "version": 5 } }

The config value must be a JSON object (never a primitive or array) — anything else fails before the network call.

Exit codes: 0 ok · 4 not found (unknown version) · 5 permission (rollback without --yes) · 1 generic (input not a JSON object).

stackbone prompts

Manage the versioned, named-by-key prompt catalog on the targeted installation. Each key holds an append-only chain of versions: the highest is the live head, writes never edit history (update appends a version when content changes; rollback copies an older version forward to a new head).

Command Purpose
stackbone prompts list List every prompt at its current version.
stackbone prompts get <key> Print a prompt (current version, or a pinned --version <n>).
stackbone prompts create <key> Register a prompt at version 1. Content via --template, --file or stdin; --name required.
stackbone prompts update <key> Append a version and/or patch the head (--template/--file, --name, --description, --metadata).
stackbone prompts remove <key> Soft-delete a prompt. Requires --yes.
stackbone prompts versions <key> List a prompt's version history (newest first, up to 200).
stackbone prompts rollback <key> --version <n> Promote a prior version to the live head. Requires --yes.
stackbone prompts preview <key> Server-side compile the prompt against a --vars <file.json>; reports a missing {{var}} cleanly.

JSON payload

// prompts list
{ "schema_version": 1, "items": [{ "key": "welcome_email", "currentVersion": 3, "name": "Welcome email" }] }

// prompts preview — ok:false is a clean 200 (a missing variable), not an error
{ "schema_version": 1, "ok": true, "version": 3, "output": "Hi Ada" }

--template and --file are mutually exclusive. On update, at least one field is required.

Exit codes: 0 ok · 4 not found (unknown key/version) · 5 permission (remove/rollback without --yes) · 1 generic (missing --name/content, bad --metadata JSON).

stackbone contract

Inspect the Stackbone Agent Protocol contract the targeted installation advertises, and validate the local project against it. All verbs are read-only.

Command Purpose
stackbone contract show Print the full contract (version, build, runtime URL, capabilities).
stackbone contract capabilities List the capabilities the installation reports (e.g. queues.jobs, storage.s3).
stackbone contract validate Validate the local agent.yaml against the target's contract (or the local emulator contract when no installation is linked). Run before a publish.

capabilities is derived from the same handshake show reads — there is no separate endpoint. validate fails (exit 1) when the contract version is unsupported or a declared capability is not advertised; the publish it precedes ships a workspace bundle (the workspace's agents and workflows).

For a per-call input/output contract, workflows declare their own schema — use stackbone workflows schema <name>.

JSON payload

// contract validate
{
  "schema_version": 1,
  "ok": true,
  "violations": [],
  "deviations": [],
  "contractVersion": 1,
  "source": "install",
}

Exit codes: 0 ok · 3 no project (validate with no agent.yaml) · 1 generic (validation failed, contract incompatible).

stackbone openrouter

Inspect the OpenRouter wiring of the targeted installation. Both verbs are read-only and the secret key value is never returned.

Command Purpose
stackbone openrouter get Read the install's key info: mode (managed sub-key vs your own env key), public id, monthly spend cap, status.
stackbone openrouter models List the OpenRouter model catalogue with per-million-token input/output pricing.

JSON payload

// openrouter get — no bearer value, ever
{
  "schema_version": 1,
  "key": {
    "configured": true,
    "mode": "managed",
    "base_url": "https://openrouter.ai/api/v1",
    "public_id": "or-pub-…",
    "status": "active",
    "spend_limit_usd": 50,
  },
}

Exit codes: 0 ok · 2 auth · 1 generic.

The platform for agent developers.Build, ship and observe agentsthat survive prod.

© 2026 · STACKBONEBUILT WITH ❤️ FROM CANADA AND SPAIN