Getting started

From zero to a running agent on your laptop. You push nothing to the cloud: the local emulator boots your agent(s) and durable workflows and serves them over an OpenAI/Anthropic-compatible chat endpoint.

A Stackbone project is two things working together:

  • Agents: conversational agents built on LangChain and served over the standard OpenAI Chat Completions and Anthropic Messages wire, so any compatible client can talk to them.
  • Durable workflows: code that survives restarts, sleeps, and human approvals, built on the Workflow SDK. Steps run once and retry on failure; the runtime persists each one.

You author both with the ambient stackbone client and run them locally with stackbone dev. To go live you deploy the agent's container image into your own cloud and register it, either with stackbone link or from the browser.

Prerequisites

  • Node.js: the CLI itself runs on Node ≥ 20.18 (Node 22 also works). The agent project you scaffold targets Node 24 or later, and so does the production runtime image, so use Node 24 for the full local loop.
  • Docker: stackbone dev boots Postgres + Redis + MinIO via docker compose. Redis backs the durable workflow runtime, so it is required.
  • A Stackbone account: sign up at app.stackbone.ai. The CLI authenticates with the device-code flow, which you approve in the browser.

OS support: the CLI runs on macOS, Linux, WSL2 and Git Bash. The CLI blocks native Windows shells (PowerShell and CMD) at startup because they lack the unix utilities the dev boot needs: use Git Bash, or install WSL2 (wsl --install -d Ubuntu) and run the CLI from inside the Ubuntu shell. Docker Desktop on Windows still works as long as it's reachable from WSL2.

1. Install

The CLI ships as @stackbone/cli and runs through pnpm dlx without installing anything globally:

pnpm dlx @stackbone/cli --help

If you prefer a global install:

pnpm add -g @stackbone/cli
stackbone --help

The generated project does not carry the CLI as a dependency, so pick one of the two forms above. If you want a project-local copy pinned in version control, add it yourself with pnpm add -D @stackbone/cli and run it as pnpm exec stackbone ....

2. Authenticate

stackbone login

This opens the device-code flow (RFC 8628):

  • The CLI prints a short verification code to the terminal, next to the URL that carries it.
  • Your browser opens on that URL.
  • Approve the request there, and the CLI stores a session in ~/.stackbone/credentials.json (chmod 600).

In a headless or CI environment, pass --no-browser and follow the printed URL yourself (also auto-detected when CI, SSH_CLIENT, or SSH_TTY is set):

stackbone login --no-browser

Verify with:

stackbone whoami
# user:      jane@acme.com
# user id:   ...
# organization: Acme (acme)
# endpoint:  https://api.stackbone.ai

3. Scaffold a workspace

A Stackbone project is a workspace, a folder that can hold many agents and durable workflows side by side. stackbone init emits that workspace shell:

stackbone init my-workspace
cd my-workspace

The [dir] positional is only the target subdirectory for the shell. It does not double as an agent slug. Pass --name <ws> to set the workspace name. init also installs the workspace dependencies (pnpm install, or npm install when pnpm is not on your PATH); pass --no-install to do that yourself.

stackbone init links the workspace to your organization: it registers the workspace's identity in the control plane and writes a .stackbone/project.json (so dev, link and the management commands know which org to talk to). Sign in with stackbone login first. Alongside the link it writes the workspace shell:

  • a deep-agents/ folder (one agent per subfolder),
  • a workflows/ folder (one durable workflow per *.workflow.ts file),
  • package.json, tsconfig.json and pnpm-workspace.yaml,
  • an .npmrc (a hoisted node_modules layout so the runtime resolves one copy of each shared dependency),
  • .gitignore, a README, and CLAUDE.md / AGENTS.md for coding agents,
  • the Stackbone agent skills (best-effort install).

Pick a first piece with --with

--with scaffolds one optional first piece on top of the shell:

--with What you get
empty shell only (the default)
agent one agent under deep-agents/<name>/
workflow one durable workflow at workflows/<name>.workflow.ts
workflow-agent an agent and a workflow already wired to call it

Every kind links the workspace, so all of them need you to be signed in (stackbone login) first: there is no offline init. The --with value only changes which first piece (if any) is scaffolded on top of the shell.

stackbone init my-workspace --with agent --name lead-qualifier

With a TTY and no --with, stackbone init shows an interactive picker for the first piece kind (empty / agent / workflow / workflow-agent).

There is no --starter / --template / --slug / --description flag on stackbone init. Passing --starter or --template prints a migration message and exits non-zero. Per-piece templates now live on stackbone add (the --template flag below, for workflows).

The skills are sourced from github.com/stackbone/stackbone-skills and re-installed on every stackbone init / link.

Add more pieces with stackbone add

Inside a workspace, grow the project one piece at a time. stackbone add only writes new files: it never edits your existing TypeScript and never edits stackbone.config.ts. It runs offline: every piece you add joins the workspace init already linked instead of registering with the control plane, so it needs no login. A name collision fails with a clear error; re-run with --force to overwrite.

stackbone add agent lead-qualifier          # → deep-agents/lead-qualifier/
stackbone add workflow qualify-lead         # → workflows/qualify-lead.workflow.ts
stackbone add workflow qualify-lead --calls lead-qualifier
stackbone add workflow-agent lead-qualifier # agent + workflow wired together
  • add agent <name> (alias of add deep-agent) writes deep-agents/<name>/index.ts. Agents carry no per-piece manifest: their runtime dependencies merge straight into the workspace root package.json.
  • add workflow <name> writes workflows/<name>.workflow.ts (durable workflows are dev-only today). Pass --calls <agent> to wire a step that delegates a turn to an agent, the workflow → agent hybrid.
  • add workflow-agent <name> is the composed template: it scaffolds an agent and a workflow already wired to call it.

4. Run the local emulator

stackbone dev

stackbone dev is the loop. The scaffold's dev script is a one-line alias for it (and build for stackbone build), so you never write a loop of your own. It:

  • Brings up a local Postgres + Redis + MinIO stack via docker compose.
  • Starts the local emulator (control-plane + Studio) at http://127.0.0.1:4242.
  • Opens a secure tunnel through Stackbone's frpc relay (*.tun.stackbone.ai) so the cloud-hosted Stackbone Studio (app.stackbone.ai/app) can reach the emulator without mixed-content issues. The tunnel is mandatory. Set STACKBONE_FRPC_BIN if you need to point at a system-installed frpc.
  • Compiles and boots your agents in-process, and your durable workflows, with hot-reload on source edits. dev discovers the workspace by convention: every folder under deep-agents/ with an index.ts is an agent (the folder name is also the model a client selects to talk to it), and every workflows/<name>.workflow.ts is a workflow (its name is the file basename, minus .workflow.ts). There is no per-agent process or port: agents run inside the one emulator server.

Your code starts last, once the environment can support it.

The first run stops for setup

Your agent names its model as a bare id ("openai/gpt-4o-mini"), which the deployment resolves through a model provider: any OpenAI-compatible endpoint you point it at. On a fresh machine there is none yet, so the first stackbone dev brings up the stack and then holds your workflows and agents back. It prints a link straight into Studio's guided setup.

Open the link, paste a base URL (and a key, if your provider needs one), and save. Your workspace starts in place, with nothing to restart and nothing to edit in your project.

If you already have a credential in your shell, export it and the first run never stops:

export MODEL_PROVIDER_BASE_URL=https://openrouter.ai/api/v1
export MODEL_PROVIDER_API_KEY=sk-...   # omit for a keyless local gateway

Full contract: The first run.

Once it's up, stackbone dev prints a stackbone studio box with the URLs you'll use:

╭─ stackbone studio ─────────────────────────────────────────────╮
│ ▸ Open Studio  https://app.stackbone.ai/app/<org>/installations/<id>?stackbone-dev=…
│                                                                 │
│   Tunnel      https://<id>.tun.stackbone.ai                     │
│   Local       http://127.0.0.1:4242                             │
│                                                                 │
│   Agent       my-first-agent                                    │
│   Protocol    v15  ·  N capabilities                            │
╰─────────────────────────────────────────────────────────────────╯
  • Open Studio: the deeplink; opening it lands you in the cloud Studio pointed at your local session.
  • Tunnel / Local: the public and loopback URLs of the emulator.
  • Agent: the linked workspace's name.
  • Protocol: the contract version and how many capabilities the runtime advertises.

5. Talk to the agent

Any client that speaks OpenAI Chat Completions or Anthropic Messages can talk to your agent. Both wires are on by default.

From Studio (easiest)

Open the Open Studio deeplink from the boot banner and chat with your agent in the Playground. Studio reaches the local emulator over the tunnel, so you get the same surface you'd get in the cloud.

From the command line

Pick the agent by name in the model field and send it a message:

curl -N -X POST http://127.0.0.1:4242/openai/v1/chat/completions \
  -H 'authorization: Bearer local-dev' \
  -H 'content-type: application/json' \
  -d '{"model":"my-first-agent","messages":[{"role":"user","content":"hi"}],"stream":true}'

That streams back chat.completion.chunk server-sent events, exactly like the OpenAI API. Locally, the emulator accepts any non-empty bearer key. See Agent protocol for the full request/response shapes (including the Anthropic Messages equivalent) and for the session headers: x-stackbone-session if you want the server to hold the conversation history for you, or x-stackbone-conversation if you keep replaying messages[] yourself but still want the turns grouped into one session.

Triggering a workflow

You start a durable workflow instead of chatting with it. Over HTTP:

curl -X POST http://127.0.0.1:4242/api/workflows/<name>/start \
  -H 'content-type: application/json' \
  -d '{ "orderId": "ord_123" }'
# → { "workflowName": "...", "runId": "...", "worldRunId": "...", "trigger": "..." }

…or start it by name from the CLI, which validates the input against the workflow's declared schema before it creates a run:

stackbone workflows list                                   # what this project exposes
stackbone workflows start <name> --input '{"orderId":"ord_123"}'

Either way you get back a run, which you then inspect:

stackbone runs list
stackbone runs get <runId>
stackbone logs tail --run <runId>

See Workflows for 'use workflow' / 'use step', sleeps, and human-in-the-loop approvals.

What's next

  • Agents: the agent model and the ambient stackbone client you use from inside a tool.
  • Workflows: durable workflows with 'use step' and requestApproval() from @stackbone/sdk/workflow for human approvals.
  • Stackbone Connect: call third-party APIs with broker-minted, install-scoped credentials via stackbone.connection(id).
  • Agent protocol: the full HTTP surface (chat completions, /api/workflows/*, /live, deep /health).
  • build and package: compile the workspace into a bundle, then write the deploy folder you run in your own cloud. Register the running box with link or from the browser.

When something fails: re-run with --json and read error.code + error.suggestion, bump STACKBONE_LOG_LEVEL=debug to see the Pino logs on stderr, or run read Troubleshooting. If you drive the CLI from a coding agent, stackbone docs prints how to connect that agent to these pages over MCP so it can look up the rest itself.

BUILT WITH ❤️ FROM CANADA AND SPAIN