Install from the source code
Run ChatPilot from its source code, on a server of your own or in Docker, and the everyday commands of such a copy.
Most people install the app: Install ChatPilot. This page is for developers and for a server of your own: ChatPilot from its source code, in Docker, or as a service on Debian or Ubuntu. These copies are set up and updated with commands.
You need uv (it installs ChatPilot's Python for you), ffmpeg for voice messages, libmagic for WhatsApp (Windows: included) and, for your Claude subscription, Claude Code.
On a Mac
Install Homebrew if you don't have it, then in Terminal:
brew install uv ffmpeg libmagic node
npm install -g @anthropic-ai/claude-code
claude
In Claude Code, type /login once and sign in with your Claude account, then quit it. Now get ChatPilot itself (replace the address with the one you were given):
git clone <the ChatPilot repository> chatpilot
cd chatpilot
uv sync
Go on with First start by command.
On Windows
The easy way: run the install script scripts\install-windows.ps1 from the repository in PowerShell:
powershell -ExecutionPolicy Bypass -File "$HOME\Downloads\install-windows.ps1"
It installs uv, Git and FFmpeg, puts ChatPilot in your user folder (chatpilot), asks for your Telegram user id, your name and the control bot's token, starts ChatPilot in the background and opens the panel. Running it again updates your copy and keeps your settings. Then choose your AI in the panel: Choose the AI.
By hand instead, in PowerShell:
winget install astral-sh.uv Gyan.FFmpeg Git.Git OpenJS.NodeJS
npm install -g @anthropic-ai/claude-code; claude
git clone <the ChatPilot repository> chatpilot; cd chatpilot; uv sync
(In Claude Code, /login once.) Then go on with First start by command.
On Linux
Ubuntu or Debian shown; other systems have the same packages under similar names:
sudo apt install ffmpeg libmagic1 git curl
curl -LsSf https://astral.sh/uv/install.sh | sh
npm install -g @anthropic-ai/claude-code && claude
git clone <the ChatPilot repository> chatpilot && cd chatpilot && uv sync
(In Claude Code, /login once.) Your logins go into the desktop keyring (GNOME Keyring or KWallet). On a server without one, ChatPilot keeps them in a file only your user can read.
A server that runs all the time
ChatPilot can also run on a server, in Docker (docker-compose.yml in the repository):
docker compose up -d
docker compose exec chatpilot chatpilot open
The first start needs no terminal steps: while the control bot isn't set up, ChatPilot shows a small setup page on the panel's address. Open the link the second command prints, paste the bot token from @BotFather and your Telegram user id, and ChatPilot starts. Sign in to the AI from the panel afterwards (Settings → AI → Sign in here).
The panel is then only on the server's own address 127.0.0.1:47821. Reach it from your computer through Tailscale or an SSH tunnel (ssh -L 47821:127.0.0.1:47821 yourserver, then open http://127.0.0.1:47821), or on your own domain over HTTPS: with docker-compose.https.yml next to it, Caddy gets the certificate for you (the steps are at the top of that file). Then the panel asks for your e-mail address, password and authenticator code; set them up once from the link chatpilot open prints. To update, run git pull && docker compose up -d --build in the repository; Settings → This app → Updates says when a new version is out.
Without Docker, on Debian or Ubuntu: sudo scripts/install-server.sh from the repository installs everything ChatPilot needs, runs it as its own chatpilot user, starts it at every boot and keeps your logins in an encrypted file (the key is in /etc/chatpilot/secrets.key; keep a copy). Then sudo chatpilot open prints the link. To update, run the script again with a newer copy. Installed by hand instead, as a service of your own user (below)? Run sudo loginctl enable-linger $USER so ChatPilot keeps running when you log out.
First start by command
On a computer with a terminal, store the control bot's token (it asks without showing what you type and keeps it in the secret store), then start ChatPilot as a background service and open the panel:
uv run chatpilot secret set control_bot_token
uv run chatpilot service install
uv run chatpilot open
The service starts again when you log in and restarts itself if it stops. Your Telegram user id is asked on the small setup page the panel shows the first time, as in the app; then the welcome's setup checklist follows. ChatPilot's own settings file is explained in The config file.
Everyday commands
In the repository folder (a copy from the installer has the same commands as chatpilot …, without uv run):
| Command | What it does |
|---|---|
uv run chatpilot open | opens the panel (it prints the link too) |
uv run chatpilot service status | says whether the background service runs |
uv run chatpilot service restart | restarts ChatPilot, e.g. after you changed config.yaml |
uv run chatpilot service logs -f | shows what ChatPilot is doing, or why it stopped |
uv run chatpilot service uninstall | stops the service, e.g. to run it in the foreground with uv run chatpilot -v run (only one ChatPilot may run at a time: otherwise it says chatpilot is already running) |
uv run chatpilot update | installs the newest version |
uv run chatpilot secret list | which secrets are stored (never their values); secret set <name> stores one, e.g. a new control_bot_token |
uv run chatpilot panel-login reset | removes the panel's password sign-in and signs everyone out (lost password or authenticator); then open the link from chatpilot open and set it up again |
uv run chatpilot licence show | the licence; also set (paste a key), check and remove |
uv run chatpilot mcp | lists each connected system and the tools the AI may use |
uv run chatpilot profiles | lists the system profiles and packs that were found |
Updates
A copy installed with git only moves forward to the newest version (uv run chatpilot update, or the Update now button). If it has changes or commits of your own, the Updates card says can't update itself and leaves it alone: update it yourself (git status, then git pull). After a git pull the button at the top says Restart. A git copy follows its own branch, so its card has no Versions choice.
In Docker, ChatPilot can't update itself: the image is what gets updated. The card shows the running version, the newest one and the command to run on the server (for an image built from the repository: git pull && docker compose up -d --build); Telegram tells you once per version and chatpilot update prints the same. There is no Update now button and no switch to install by themselves. Your settings and chats are kept in Docker's volumes and stay.
Backups by command
chatpilot backup now makes a backup (optionally into a folder you name).
chatpilot backup restore <file> restores a backup file (it ends in .tar.gz.enc) on a computer that already runs ChatPilot. It asks for the backup password, stops ChatPilot, puts back the databases, settings and logins, and starts it again. The databases that were there before are kept next to them (.before-restore).
Is the backup in the second place (a NAS folder, S3, WebDAV or Google Drive) and not on this computer? Run chatpilot backup restore --storage instead. On a computer that already had that storage chosen on the Backups card it looks there; on a new computer it asks where: the kind, the address or folder, and the keys. For Google Drive it prints Google's address instead: open it, sign in with the same Google account, then press Enter (with the browser on another computer, paste the address its tab ended on). It lists the backups there, newest first, fetches the one you pick into the backup folder and restores it as above. The keys you type are only used for this: the restore brings the storage and its keys back with your other settings, so the nightly copy goes on. To take a particular backup, add its name: chatpilot backup restore --storage chatpilot-20261024-0330.tar.gz.enc.
On a new computer it asks for the backup password you saved; a wrong one changes nothing.
chatpilot backup restore --live takes the live copy in that storage instead of a nightly backup: the state of a few seconds ago. It asks where the storage is on a new computer, as above. While the other ChatPilot is still sending to it, it stops and says where; switch that one off first, or add --force to carry on here anyway (the other one stops sending). After the restore, this computer sends the changes to the live copy. Link WhatsApp again on it, as after a move.
chatpilot backup move makes the backup for moving, as Make a backup for moving on the card does: Move ChatPilot to a server and back.
Checked against ChatPilot 0.1.0b1. Report a problem with this page