Get started

From nothing to your first todo in a few minutes

Telos runs as one container plus Postgres. Nothing to clone and nothing to build: save a compose file, make two secrets, start it. After step 4 you have the whole todo app. Steps 5 and 6 are extras you can skip.

Save the compose file

Make an empty directory and save this in it as docker-compose.yml:

name: telos

services:
  telos:
    image: vantreeseba/telos:latest
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET:?generate one with `openssl rand -hex 32`}
      DATABASE_URL: postgres://telos:${POSTGRES_PASSWORD:?set a database password}@postgres:5432/telos
      # The address you actually reach Telos at. Sign-in links are built from it.
      APP_URL: ${APP_URL:-http://localhost:3001}
      # How sign-in links are emailed. See "Sign in" below.
      SMTP_URL: ${SMTP_URL:-}
      SECURE_LOCAL_NET: ${SECURE_LOCAL_NET:-false}
      NODE_ENV: production
    ports:
      - "${PORT:-3001}:3001"

  postgres:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: telos
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set a database password}
      POSTGRES_DB: telos
    volumes:
      - telos_pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U telos -d telos"]
      interval: 5s
      timeout: 5s
      retries: 10

volumes:
  telos_pgdata:

Make the secrets and start it

It refuses to start without both, so generate them into .env beside the compose file:

printf 'BETTER_AUTH_SECRET=%s\nPOSTGRES_PASSWORD=%s\n' \
  "$(openssl rand -hex 32)" "$(openssl rand -hex 24)" > .env

docker compose up -d

Migrations run at boot, so there is no setup step. Keep that .env: BETTER_AUTH_SECRET signs sessions and POSTGRES_PASSWORD is the database's own.

Upgrading is docker compose pull && docker compose up -d. Your data lives in the telos_pgdata volume, which survives docker compose down.

Sign in

Telos has no passwords. Give it one way to sign people in, in .env, then docker compose up -d again:

  • Email: SMTP_URL=smtp://user:pass@mail.example.com:587, and links are emailed.
  • An OpenID Connect provider such as heautou: nothing to set. The login page of a new instance has a Set up sign-in tab to paste its setup URL into.
  • Just this machine: SECURE_LOCAL_NET=true, and typing an address signs you in. Never on a reachable instance.

Open http://localhost:3001 and sign in. The first account to sign in is the admin.

Make a project and add todos

New project in the sidebar, then type a todo in a sentence and press Enter. Tick it off when it is done. From there:

  • Set what a todo waits on, and it shows as blocked, with its blockers named, until they are done.
  • Give todos labels and due dates. A late one is flagged, and the project can sort by due date.
  • Press n to add, / to filter, and Ctrl K to search every project.
That is the app. If a list of todos is all you want, you can stop here. The rest of this page is extras.

The board optional

The same todos as lanes you name yourself, one of which means done. Switch to Board on the project. Dragging a card into the done lane ticks it off, and ticking it moves the card.

Put an agent on a lane optional

AI is off at every level until you turn it on.

Switch it on

  1. Instance: as the admin, Settings → AI → "AI on this instance".
  2. Account: Settings → AI. Settings gains the Agents and MCP servers tabs.
  3. Project: its AI switch, and under it auto-run if you want agents to start on todos by themselves.

Make an agent

Settings → Agents → Start from one of the three starters: a Planner that splits work into todos, a Worker that does it and a Reviewer that rules PASS or FAIL. Type the endpoint's base URL (any OpenAI-compatible one, a local Ollama included) and pick a model from the list it returns.

Give it a lane

On the board, open the lane's menu → Agent…, and set where a passing run and a failing run send the todo. With auto-run off, press Run now on a card to work it once.

The app keeps a setup checklist on the home page until every step for a first run is taken, and each row links to where it is fixed.

Connect your own client optional

With AI on, make an API key in Settings and point any MCP client, Claude Code for one, at /mcp on your instance. Each key has a switch per tool, all on until you turn one off.

# Claude Code, for example
claude mcp add --transport http telos http://localhost:3001/mcp \
  --header "x-api-key: <your API key>"

Before you put it on a domain

Registration is open: any address that completes a sign-in gets an account. Put Telos behind a reverse proxy with TLS, and read Before you expose it first.