Chloe

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 setup

Setup 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.

  1. 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, agy and opencode commands), 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.
  2. 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 reboot

npx 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.