Nanobot is an open-source (MIT licence) ultra-lightweight framework for a personal AI agent, written in Python. You run it yourself on your own machine and can use it in the WebUI, in a terminal or in chat apps. The agent can work with tools (shell, files, web), and it has memory and scheduled tasks. The configuration, history and keys stay with you, not with someone else's service.
This guide shows how to deploy nanobot on a Linux server in Docker and control it through your own Telegram bot, from installation to the first reply. We use Claude through the Anthropic API as the model, but nanobot supports other providers too.
What you will need
- A Linux server (a small VPS is enough) with Docker and the
docker composeplugin - An API key from the model provider (Anthropic here)
- A Telegram account
In the commands below, replace the values in angle brackets with your own: <ANTHROPIC_API_KEY>, <BOT_TOKEN>, <TELEGRAM_USER_ID>. Never commit secrets to a repository.
1. Installation
git clone https://github.com/HKUDS/nanobot.git
cd nanobot
docker compose up -d nanobot-gateway
The first image build takes about 5 minutes. We start only the nanobot-gateway service; you don't need the nanobot-api container for this scenario.
If you run into Docker errors on a headless server:
# "unknown shorthand flag: 'd'" / permission denied on the compose plugin
chmod +x ~/.docker/cli-plugins/docker-compose
# the build fails on the credential helper (no secrets service)
echo '{}' > ~/.docker/config.json
If the build still fails on credentials after that, pull the base images by hand (the names are on the FROM lines in the Dockerfile):
docker pull node:24-bookworm-slim
docker pull ghcr.io/astral-sh/uv:python3.12-bookworm-slim
2. Onboarding: provider and model
The container runs as a user with UID 1000, so the configuration directory on the host must be owned by the same UID. The wizard is run with --user nanobot, otherwise it ends with a Permission denied error.
chown -R 1000:1000 ~/.nanobot/
docker compose exec --user nanobot nanobot-gateway nanobot onboard --wizard
In the wizard you enter the API key (<ANTHROPIC_API_KEY>) and the model, for example claude-sonnet-5. Create the key in the Anthropic Console inside a specific Workspace. A key at the level of the whole organization fails with an error that it is not bound to a workspace.
The configuration is in ~/.nanobot/config.json, and the agent's working files are in ~/.nanobot/workspace/.
3. Creating the bot in Telegram
- Open @BotFather in Telegram.
- Send the
/newbotcommand. - Enter a display name (anything) and a username, which must end with
bot, for examplemy_server_bot. - BotFather returns a token (
<BOT_TOKEN>). It is the password to the bot, so store it in a password manager. - Find your numeric Telegram ID (
<TELEGRAM_USER_ID>), for example by messaging @userinfobot.
Why Telegram and not WhatsApp: a Telegram bot has its own identity. The WhatsApp channel, on the other hand, connects as another device of your personal number and may offer a pairing code to anyone who writes to you. That is unsuitable for an agent with access to a server.
4. Connecting Telegram in nanobot
Enable the channel plugin:
docker compose exec --user nanobot nanobot-gateway nanobot plugins enable telegram
Add the channel section to ~/.nanobot/config.json:
{
"channels": {
"telegram": {
"enabled": true,
"token": "<BOT_TOKEN>",
"allowFrom": ["<TELEGRAM_USER_ID>"]
}
}
}
Mind the format: allowFrom is an array of strings, i.e. ["12345"]. Writing [12345] or "12345" does not pass validation and the channel won't start. Without allowFrom the channel runs in pairing-code mode, and the value ["*"] lets anyone in, so don't use it on a bot with access to a server.
After every config change, restart the gateway and watch the logs:
docker compose restart nanobot-gateway
docker compose logs -f nanobot-gateway
5. First test
Send your bot a message in Telegram, for example "How much free disk space is there?". If it replies, you are done. If it stays silent, the log will show a config validation or token error.
6. Security: rules for the agent
The most important safeguard is allowFrom with your ID. The second layer is the rules in ~/.nanobot/workspace/AGENTS.md, for example:
## Rules for server management
### Always allowed
- reading files, `docker ps`, `docker logs`, `df -h`, diagnostics
### Requires user confirmation
- restarting a container, `git commit` / `git push`, editing files
### Never without an explicit request (and even then, ask)
- `rm`, `docker rm`, `docker system prune`, database migrations
It is an instruction for the model, not a technical limit. The agent follows it for as long as it follows it.
7. Optional: managing the server and repositories
If you want the agent to see repositories and control Docker on the host, add this to docker-compose.yml (section x-common-config, volumes):
volumes:
- ~/.nanobot:/home/nanobot/.nanobot
- /var/www:/var/www
- /var/run/docker.sock:/var/run/docker.sock
The container also needs the docker binary itself. In the Dockerfile, add docker.io to apt-get install and put the user into the group matching the socket (find the GID with stat -c %g /var/run/docker.sock):
RUN groupadd -g 999 dockerhost || true && \
useradd -m -u 1000 -s /bin/bash -G dockerhost nanobot
A change to volumes only takes effect after docker compose down && docker compose up -d; a plain restart is not enough. After editing the Dockerfile, also run docker compose build.
Risk: access to the Docker socket is effectively root on the host. The agent can start a new container with any mount and read anything, including SSH keys. The rules from AGENTS.md do not stop that technically. For git push, therefore, use a dedicated deploy key with rights only to the repos you need, and consider a socket proxy that allows only selected commands.
Summary
You can set up nanobot on your own server in a few minutes, create a Telegram identity for it through BotFather, and allowFrom makes sure it listens only to you. The more permissions you give the agent, the more its rules matter, and so does where your keys end up. Start with read-only diagnostics and add permissions gradually.
Links: nanobot repository · configuration documentation · nanobot.wiki