Quick start
Create an agent App, try it locally, then deploy it. Cantelop handles routing, Sandbox lifecycle, and persistent storage.
SDK 1.0 is the only supported SDK.
Prerequisites#
- Node.js 22 or newer and Bun 1.3.10 for native local development. Docker
mode (
cantelop dev --container) can be used instead of Bun. - Cantelop CLI 0.15.2 or newer. Check with
cantelop versionafter installing. - An API key for whichever agent SDK you pick below.
- A backend of your own to call the App from. Any Node.js server works; the steps below use a one-file script.
- Docker with
linux/amd64build support, when deploying or using local container mode. - A Cantelop account, when you're ready to deploy. Local development needs no login.
Run it locally#
-
Install the CLI#
The CLI creates local agent projects, runs them, and uploads builds when you deploy. Homebrew manages installation and removal. The alternative script downloads a release from Cantelop’s
stepandel/homebrew-tapGitHub repository, verifies its SHA-256 checksum, and installscantelopin~/.local/bin(replacing an existing copy there). Review the script before running it. The command below disables automatic shell-profile edits; add~/.local/binto your PATH yourself if needed.$ brew install stepandel/tap/cantelopHomebrew is recommended. The alternative installer supports macOS and Linux; see removal instructions to undo the installation.
-
Create a project#
In an empty directory, choose the agent SDK your Session runtime will use, then install the stable Cantelop SDK 1.0 package:
$ cantelop init -app hello -provider openai $ npm install @cantelop/sdk-app hellois the App name this project deploys to. It need not exist yet, andinitdoes not require a login. Four files are written, and none are overwritten:The manifest only names the definition module:
cantelop.json{ "schema_version": 3, "definition": "src/cantelop.ts" }Everything else about the App is declared in code. Starters generated by CLI 0.15.2 omit the inline message type
cantelop.app<{ prompt: string }>; add it before runningdevto avoid a declaration-generation error. Later CLI releases generate it. For the Claude starter:src/cantelop.tsimport { CantelopClient } from "@cantelop/sdk"; import { receive } from "./agent.js"; const cantelop = new CantelopClient(); export const agent = cantelop.app<{ prompt: string }>({ name: "hello", runtime: { receive }, environment: { ANTHROPIC_API_KEY: { secret: true, required: true }, }, });There is no HTTP API to write. Cantelop generates the App's Edge Worker, and your own backend reaches the App through this same
agentexport. -
Add your provider key#
cantelop devreads a.envbesidecantelop.jsonand passes the values your App declares to its Sessions:.envCODEX_API_KEY=sk-...The Pi starter declares no environment. Add the credential your provider needs to
environmentinsrc/cantelop.ts, for exampleANTHROPIC_API_KEY: { secret: true, required: true }.Keep
.envout of version control. Local development does not upload it;deploy --env-file .envexplicitly imports declared production values. Names beginning withCANTELOP_are reserved. -
Run it#
Terminal$ cantelop dev → Cantelop App running at http://127.0.0.1:8787 (native mode)devbuilds the App, records a local credential in the SDK'slocalprofile, and writes a compiled backend client to.cantelop/client/. That client keeps your App's exports but none of its Sandbox code, so a backend can import it without loading your agent SDK.Leave
devrunning and, in a second terminal, send the agent a message from a small backend script:try.mjsimport { agent } from "./.cantelop/client/client.mjs"; const session = agent.workspace({ slug: "ada" }).session(); const message = await session.dispatch({ prompt: "write hello.txt" }); console.log(session.id, message.id, message.state);Terminal$ CANTELOP_PROFILE=local node try.mjs → ses_... msg_... acceptedacceptedconfirms durable admission, not that the agent has finished. The first message provisions theadaWorkspace and starts a Sandbox. Once the agent completes the task, look forhello.txtunder.cantelop/dev/hello/workspaces/.Pass the printed Session ID as
session({ id })to continue the same Session, or read its output withsession.stream(). The integration credential authorizes every Workspace in the App, so it stays on your backend: authenticate your own users and choose their Workspace there.devrebuilds as you edit, and a failed build keeps the last good one serving. For Docker mode and its differences, see local development. To relay live agent output, see streaming output.
What you just ran#
- The App definition (
src/cantelop.ts) declares the App's name, runtime, environment, and optional webhooks withcantelop.app(...). - The Session runtime (
src/agent.ts) runs your agent inside an isolated Sandbox. See Session runtime. - The generated Edge Worker accepts your backend's commands at
/commands/{command}, one path per SDK call. You never write it; see ingress. - A Session keeps its identity when its Sandbox is released. A later message starts a fresh Sandbox; in-memory state must be restored by your agent.
- A Workspace holds persistent files shared by its Sessions. Select one per
user with
agent.workspace({ slug }). Add.cantelop/to your.gitignoreto exclude local data and the compiled client.
See architecture for the Agent model and runtime lifecycle.
Deploy it#
-
Sign the CLI in#
Terminal$ cantelop loginAuthorize the CLI in the browser tab it prints.
-
Deploy#
Terminal$ cantelop deploy --create-app --env-file .envdeploybuilds the generated Edge Worker and Session runtime image, creates thehelloApp if it does not exist, and imports the names your App declares inenvironmentfrom.env: secrets as secrets, the rest as variables. Undeclared entries are ignored. It then uploads both components and activates the release only when both succeed.The App name in
src/cantelop.tsalso names its public URL,https://hello.cantelop.dev. Choose your own available name ifhellois already taken. Later deploys need onlycantelop deploy; see environments for changing values without deploying.cantelop deploy --dry-runruns the same build with no login and no release.cantelop doctorchecks your toolchain, project, and required configuration once the App exists. -
Call it from your backend#
Deploying records the App's integration credential in the SDK's
defaultprofile, so the same script reaches the deployed App:Terminal$ CANTELOP_PROFILE=default node try.mjs → ses_... msg_... acceptedA backend hosted elsewhere cannot read that profile. Give it the credential through the host's secret store instead:
Terminal$ cantelop app credentialsIt prints
CANTELOP_APP_SLUGandCANTELOP_INTEGRATION_TOKENas dotenv. Keep the token on the backend, never in browser code.Deploy the backend and App from the same source; see deploy your backend with the App.
After deploying#
Open the console to inspect the App. See deployment for release behavior and the CLI reference for logs, Session inspection, credential rotation, and rollback.
You should see#
cantelop devrunning the App onhttp://127.0.0.1:8787.try.mjsprinting anacceptedmessage, andhello.txtin the local Workspace once the agent finishes.cantelop deployreporting bothapiandsession_runtimesucceeded.- Messages accepted by your deployed App with
CANTELOP_PROFILE=default.