REF · STACKBONE / WIKI · v0.9.4 stackbone

@stackbone/sdk integration

How the CLI installs, links and runs the @stackbone/sdk inside generated agent projects.

The SDK every published agent depends on. The CLI wires its env vars automatically — once you createClient() inside your agent, the emulator (and later production) injects every credential it needs.

Canonical reference: libs/sdk/README.md — the SDK's own README documents every module with code samples and error codes. This page only covers the CLI ↔ SDK seam.

What the SDK exposes

The SDK is monolithic and ships six wrapper modules + five control-plane façades. Add it once and reach every platform primitive through the same client:

import { createClient } from '@stackbone/sdk';

const stackbone = createClient(); // zero args in production
Module Wraps Status
client.database Postgres via Neon Data API + Drizzle ✅ shipped
client.storage S3 / R2 / MinIO via @aws-sdk/client-s3 ✅ shipped
client.ai OpenAI SDK pointed at OpenRouter ✅ shipped
client.rag LlamaParse + chunker + embeddings + pgvector + tsvector ✅ shipped
client.approval HITL inbox + HMAC-signed decision callbacks ✅ shipped
client.secrets Workspace-encrypted secrets ✅ shipped
client.config Typed dynamic configuration ✅ shipped
client.queues QStash publisher + Hono receiver 🚧 coming
client.events Workspace event bus 🚧 coming
client.connections OAuth integrations (Notion, GDrive, Slack…) 🚧 coming
client.memory Long-term mem0-backed memory 🚧 coming
client.observability OpenTelemetry traces + logs 🚧 coming

The coming modules are part of the public surface today but every method returns not_implemented. See libs/sdk/README.md → Coming Soon.

How the CLI connects to the SDK

stackbone dev injects the env vars createClient() reads, so a freshly scaffolded agent works zero-config locally:

SDK config field Env var Provided by stackbone dev
(reads env only) STACKBONE_POSTGRES_URL ✅ (local Postgres)
databaseUrl DATABASE_URL ✅ (local Postgres)
agentJwt STACKBONE_AGENT_JWT TODO
agentId STACKBONE_AGENT_ID
stackboneApiUrl STACKBONE_API_URL ✅ (emulator URL)
s3.endpoint S3_ENDPOINT ✅ (MinIO :9004)
s3.bucket S3_BUCKET ✅ (stackbone-dev)
s3.accessKeyId AWS_ACCESS_KEY_ID
s3.secretAccessKey AWS_SECRET_ACCESS_KEY
openrouterKey OPENROUTER_API_KEY bring your own
openrouterBaseUrl OPENROUTER_BASE_URL optional
qstashToken QSTASH_TOKEN TODO (Epic V1)
llamaParseApiKey LLAMA_PARSE_API_KEY optional
mem0ApiKey MEM0_API_KEY optional
approvalSigningKey STACKBONE_APPROVAL_SIGNING_KEY TODO

When a credential is missing, the relevant module returns the canonical *_missing error code (openrouter_key_missing, database_url_missing, …) and data is null — see libs/sdk/README.md → Result Envelope.

Production: zero args

Inside a Stackbone-hosted container the platform pre-populates every env var listed above. Production agent code is just:

const stackbone = createClient();

Local development: bring your OpenRouter key

stackbone dev doesn't manage LLM credits — that's your account, not the platform's. Export the key in your shell (or use a .env.local your template loads):

export OPENROUTER_API_KEY=sk-or-...
stackbone dev

The same applies to LlamaParse and mem0 if you opt in.

Escape hatch

The SDK is a fachada, not a moat. The platform also injects the upstream env vars so you can drop down to the underlying SDK whenever the wrapper doesn't expose what you need:

// instead of client.database.from('...').select(...)
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL!);
const rows = await sql`SELECT * FROM leads`;

This is the structural difference from @vercel/kv: Stackbone wrappers coexist with the upstream SDK, they don't replace it. The rationale lives in ADR 2026-04-24-sdk-monolitico-agente.

Where to go next