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 devboots Postgres + Redis + MinIO viadocker 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 --helpIf you prefer a global install:
pnpm add -g @stackbone/cli
stackbone --helpThe 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 loginThis 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-browserVerify with:
stackbone whoami
# user: jane@acme.com
# user id: ...
# organization: Acme (acme)
# endpoint: https://api.stackbone.ai3. 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-workspaceThe [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.tsfile), package.json,tsconfig.jsonandpnpm-workspace.yaml,- an
.npmrc(a hoistednode_moduleslayout so the runtime resolves one copy of each shared dependency), .gitignore, aREADME, andCLAUDE.md/AGENTS.mdfor 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-qualifierWith 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/--descriptionflag onstackbone init. Passing--starteror--templateprints a migration message and exits non-zero. Per-piece templates now live onstackbone add(the--templateflag below, for workflows).
The skills are sourced from
github.com/stackbone/stackbone-skillsand re-installed on everystackbone 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 togetheradd agent <name>(alias ofadd deep-agent) writesdeep-agents/<name>/index.ts. Agents carry no per-piece manifest: their runtime dependencies merge straight into the workspace rootpackage.json.add workflow <name>writesworkflows/<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 devstackbone 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
frpcrelay (*.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. SetSTACKBONE_FRPC_BINif you need to point at a system-installedfrpc. - Compiles and boots your agents in-process, and your durable workflows,
with hot-reload on source edits.
devdiscovers the workspace by convention: every folder underdeep-agents/with anindex.tsis an agent (the folder name is also themodela client selects to talk to it), and everyworkflows/<name>.workflow.tsis 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 gatewayFull 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
stackboneclient you use from inside a tool. - Workflows: durable workflows with
'use step'andrequestApproval()from@stackbone/sdk/workflowfor 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
--jsonand readerror.code+error.suggestion, bumpSTACKBONE_LOG_LEVEL=debugto see the Pino logs on stderr, or run read Troubleshooting. If you drive the CLI from a coding agent,stackbone docsprints how to connect that agent to these pages over MCP so it can look up the rest itself.