Docs
Start
Install, run setup, and what each file it writes is for.
Node 22.18 or newer. Node runs your TypeScript as it is, so there is no build
step. command not found: npx means Node is not installed: on a Mac, take the
installer from nodejs.org.
npm install @chloejs/core
npx chloe setupSetup asks two things, each with a default, so holding Enter works. --yes
takes every default. Running it again updates the model it chose in
chloe.config.ts, and leaves everything else alone. With no keyboard, which is
how a coding agent runs it, it takes the defaults.
It writes the files below, with a first agent, and installs typescript and
@types/node with the package manager your project already uses. If port 3067
is taken, most likely by another chloe, it puts this one on the next free port,
as serve: { port } in chloe.config.ts.
- Which model. A key first: a free one from OpenRouter, one from Anthropic
or OpenAI, or a gateway of your own. Under those, anything already set up on
this machine (the
claude,codex,agyandopencodecommands), with the models opencode and Antigravity say they run. Then it makes one real call to check the model answers and can call a tool, and asks again if it does not. See Models. - A git repository. In a folder that is not one, it makes one and commits what is there, under your git name, or "npx chloe setup" when git has none. Every change an agent makes to itself is a commit you can read and undo, and what you changed by hand in a file it changes is committed first, under your name. In a repository of your own setup commits nothing. It never installs git.
The first agent
Setup writes one, agents/assistant, with a purpose and nothing else. Run
npx chloe, open the link it prints, and tell it what you want done: it changes
itself to do it, its words, its jobs and its code, and each change is a commit
you can read and undo on the dashboard. See
What an agent may change about itself.
Or ask your coding agent, in the project's folder, for what you want done, like
"an agent that tells me every morning at 7 what is most urgent in my mail". It
reads these guides, which ship in the package for the version installed, and
makes the first agent into that one, or writes another and lists it in
chloe.config.ts.
There is no password to set. The dashboard opens with a link, and a password is for later, if you want one.
What it wrote
| File | What it is |
|---|---|
chloe.config.ts |
The list of agents, with the first one on it, and every setting. An agent not on it does not run. |
agents/assistant/ |
The first agent: agent.ts, which says what it is, and purpose.md, its words. Only a config setup writes gets one, because that config is what lists it. |
.env |
Every password, key and token, mode 600, never committed. |
tsconfig.json |
How your editor and tsc read the project's TypeScript. Node runs it as it is, so nothing is compiled. Setup also installs typescript and @types/node: chloe runs without them, but then an agent's change to its own code is not type checked before it goes live. |
It also adds "type": "module" to package.json, and node_modules, data
and .env to .gitignore.
// Every agent this copy runs, and how the runtime behaves. An agent is on this
// list or it does not exist.
//
// `settings` is every choice, as deep as it goes, and what it leaves out is the
// default. This file is in source control, so a key goes in .env beside it and
// is named here as `process.env.` and its name in .env. chloe reads no key it
// is not handed here.
import { defineConfig } from "@chloejs/core";
import shop from "./agent.ts";
export default defineConfig({
agents: [shop],
settings: {
// What an agent asks when its own agent.ts names none, and the gateway's key.
model: { defaultModel: "anthropic/claude-sonnet-5.5", key: process.env.CHLOE_MODEL_KEY },
// The shop's own channels: its Telegram bot and its WhatsApp number.
agents: {
shop: {
telegram: process.env.CHLOE_AGENTS_SHOP_TELEGRAM,
whatsapp: {
phone_number_id: process.env.CHLOE_AGENTS_SHOP_WHATSAPP_PHONE_NUMBER_ID,
token: process.env.CHLOE_AGENTS_SHOP_WHATSAPP_TOKEN,
app_secret: process.env.CHLOE_AGENTS_SHOP_WHATSAPP_APP_SECRET,
},
},
},
},
});A key reaches chloe only where the config names it, as process.env. and its
name in .env. chloe reads nothing else from the environment.
Run it
npx chloe # run everything: the dashboard, the cron lines, the channels
npx chloe link # a link that opens the dashboard signed in
npx chloe agent shop # talk to an agent
npx chloe agent shop stuck-orders # run one job now
npx chloe account # set a password, or a new one
npx chloe install # keep it running after you log out and after a rebootnpx chloe is one process on one port, and if it is down nothing runs. An edit
to an agent's files or to the config is live within a second, including a new
agent. An update to chloe itself needs a restart. npx chloe install makes it
a service: a systemd user unit on Linux, a launchd agent on a Mac.
npx chloe prints a link as it starts, http://127.0.0.1:3067/#in=.... Open it
in a browser on the same machine and you are in, with nothing to set: it signs
that browser in for a week, works once, and only within the hour.
npx chloe link prints another. On a server you reach over SSH, start it with
npx chloe --remote instead, and the link opens on your own computer: see
From another machine.
npx chloe install writes one service per machine, so on a machine already
running chloe it would move that service to this folder.
A small agent fits in one file: One file is a whole
project run with node.