From zero to a running agent on your laptop. No cloud push, just the local emulator booting your agent(s) and durable workflows, reached 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, are persisted, and retry on failure.
You author both with the ambient stackbone client, run them locally with
stackbone dev, and ship them with stackbone publish. This page gets you
to a running agent on your machine.
Prerequisites
- Node.js. The CLI itself runs on Node ≥ 20.18 (Node 22 also works). The agent project you scaffold targets Node 24+ (the production runtime image is Node 24), 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, not optional. - A Stackbone account. Sign up at app.stackbone.ai. The CLI authenticates via the magic-link code flow.
OS support: the CLI runs on macOS, Linux and WSL2. Native Windows shells (PowerShell, CMD, Git Bash) are blocked at startup, 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 is published as @stackbone/cli (alpha dist-tag) 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 --helpYou can also pin the CLI per project, stackbone init adds @stackbone/cli
to the generated package.json so pnpm exec stackbone ... works inside the project.
2. Authenticate
stackbone loginThis opens the device-code flow (RFC 8628):
- A short verification code is printed to the terminal.
- Your browser opens to the verification URL.
- After confirming the magic link from your inbox the CLI stores a session
in
~/.stackbone/credentials.json(chmod 600).
Headless / CI? Pass --no-browser and follow the printed URL manually
(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-workspace
pnpm installThe [dir] positional is just the target subdirectory for the shell, it does
not double as an agent slug. Pass --name <ws> to set the workspace name.
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, publish 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.json,- an
.npmrc(a hoistednode_moduleslayout so the runtime resolves one copy of each shared dependency), .gitignoreand aREADME,- 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 ever writes new files, it never edits your existing TypeScript and
never edits stackbone.config.ts. It is fully offline: every piece you
add is a member of the workspace init already linked, not a separate
control-plane registration, so no login is required. 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 devYou don't run a dev script of your own, stackbone dev is the loop. It:
- Compiles and boots your agents in-process and your durable workflows,
with hot-reload on source edits. The workspace is discovered by
convention: every folder under
deep-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. - 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.
Once it's up, stackbone dev prints a stackbone studio box with the things
you'll actually 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 v3 · 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, the two 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, any non-empty bearer key is accepted. 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
A durable workflow is started, not chatted with. Kick one off 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 from the CLI with stackbone runs to inspect the run afterwards:
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).
Stuck? Re-run with
--jsonand readerror.code+error.suggestion, bumpSTACKBONE_LOG_LEVEL=debugto see the Pino logs on stderr, or runstackbone docs clifor the inline reference (no network).