workser CLI operates your app from the outside. @workser/app runs inside it, on every request.
Zero configuration
Workser provisions the project’s credentials into the app’s environment, so there is nothing to wire up and no key for anyone to paste:The default
workser export is lazy — it’s constructed on first property access, so importing the module can never throw. A missing WORKSER_PROJECT_ID surfaces at the call that needed it, naming the variable, instead of as an opaque module-load crash in a serverless cold start.fetch). Zero runtime dependencies.
What you get
These are the same records the Workser dashboard and your AI employees read and write. An app built on Workser isn’t integrating with a separate system — it’s reading its own business.
workser.business
Every resource has the same five methods:
orders, sales, fulfillments, pages, carts. For anything this version doesn’t name yet, use the escape hatch rather than hand-rolling a fetch:
removeis a real delete with no undo. For anything user-facing, prefer a status change viaupdate.listfilters are pass-through beyondlimit/offset— check what the resource actually supports rather than assuming a filter applied.
workser.db
Two ways in, and the choice matters:
workser_app_<projectId> role — never the owner — so it structurally cannot drop the database.
workser.storage
- Anything sizeable (presigned)
- Small files only (direct)
The client PUTs straight to storage, so a big file never occupies a request slot or a timeout budget.
workser.auth
Read-oriented on purpose:
Connected apps
The connection is owned by the project, not the app. An owner connects Gmail once and every app in the project can send mail — no OAuth flow to implement, no tokens to store, no refresh logic.connect(toolkit) returns a redirect_url the owner opens → read tools(slug) for the current argument schema → execute the authorized action.
safeRun checks connection readiness. It does not grant end-user permission or open a desktop approval prompt. Your server must authenticate the user, authorize the business operation and validate the arguments. App connections covers both development-time use by agents and runtime use by your app.
workser.agents
Use Agent Cloud to run an agent inside your product:
run() accepts work asynchronously; inspect the final status rather than treating acceptance as completion. See Agent Cloud for the full flow and usage boundary.
For product agents, pass referenceUserId so the session and audit record identify the app user the agent is serving. Use runAndWait() for a backend job that can hold a connection, listRuns() to query history and cancelRun() to stop active work. The event stream resumes from its last handled sequence when a retryable connection drops.
Workflows
401s from an app by design. Browse them in Workser Code or with workser workflow list.
Security posture
This SDK is used by AI agents, so anything it returns can end up in a model’s context window, a transcript, or a log. It’s built accordingly — and every one of these is covered by a test in the package.Refuses to hold a secret key in a browser
Refuses to hold a secret key in a browser
A Workser key grants access to a whole project, and bundlers inline
process.env. Constructing a client with a secret key in a browser or React Native throws BrowserSecretError.The fix is never an allowBrowser flag — it’s to call Workser from your own server and let the client talk to that.Refuses to send a key over plaintext
Refuses to send a key over plaintext
The base URL must be
https, or loopback for local development. Anything else is refused with code: 'config' rather than putting a key on the wire.Never logs or embeds a credential
Never logs or embeds a credential
Keys live only in the
Authorization header. Errors are redacted, and fields named like secrets are dropped entirely rather than masked.Parameterised SQL only
Parameterised SQL only
db.query(sql, params) binds server-side; there is no string-concatenation API to reach for, and building one on top defeats the point.Idempotency keys on writes
Idempotency keys on writes
The SDK retries automatically, so a create without a key can become two orders. Pass
{ idempotencyKey }.Errors
Every failure is aWorkserError with a stable code. Branch on the code, never on message text — messages change, codes don’t.
Also on the error:
status, request (method, path, status, requestId), details, retryable.
Escape hatches
Workser’s API moves faster than this package is republished, and being blocked on an npm release to reach an endpoint you already own would be a bad trade:Environment variables
All injected automatically in a Workser app:
Other client options:
timeoutMs (default 30s), maxRetries (default 2), headers (never put a credential here).
