Loading content…
Loading content…
Self-hostable personal assistant in Python with WebUI, chat channels, tools, memory, MCP and automations. Practical installation and operation guide.
Reviewed: 10/10/2026
Repository: https://github.com/HKUDS/nanobot
Primary documentation: installation, deployment, configuration, Telegram.
Compatibility: official documentation reviewed on 10/10/2026, with v0.3.5 as the published reference. Check
nanobot --version:mainmay describe later features. The server administration examples are deployment recommendations.
nanobot is a self-hostable Python-based assistant with web, terminal and messaging interfaces. It manages sessions, files, memory and automations through tools and plugins. It can be deployed as a private Telegram assistant with a remote model.
Documented capabilities: WebUI, terminal/TUI, conversations and workspaces, model presets and fallbacks, messaging channels, memory, skills, cron/automations, MCP, web search/fetch, file/shell tools, multiple instances, Docker/Compose deployment, integration via Python SDK and OpenAI-compatible API. Exact availability depends on the channel, installed extra, release and configuration.
Telegram / WebUI / CLI / otros canales
|
gateway de nanobot
|
sesión + workspace
|
contexto / memoria / skills
|
LLM (API o local)
|
herramientas / MCP / web / shell
|
respuesta al canal
~/.nanobot/config.json: configuration of models, tools, permissions, channels, WebUI and runtime.~/.nanobot/workspace/: memory, skills, automations and work artifacts.~/.nanobot/sessions/<workspace-id>/: session history separate from the workspace.nanobot webui, by default on http://127.0.0.1:8765 for local use.127.0.0.1:18790; API nanobot serve normally 8900. They should not be exposed as a matter of routine.| Version | Downloads (weekly) | Downloads (total) | Published |
|---|---|---|---|
0.1.0latest First published version. | 0 | 1 | October 14, 2026 |
Design security: a per-workspace restriction enforced by software does not replace kernel isolation. On Linux you can enable tools.exec.sandbox: "bwrap", and on macOS "seatbelt"; the documentation states that neither of these two backends isolates the network.
~/.nanobot and backups.bubblewrap for Linux sandbox outside the container.free -h, df -h, top/htop, response times, restarts, token usage and spend per provider. Set consumption limits at the API level.The documentation recommends an installer that chooses virtualenv, uv, pipx or your own environment:
# Revisar antes de ejecutar: script remoto del repositorio oficial
curl -fsSL https://raw.githubusercontent.com/HKUDS/nanobot/main/scripts/install.sh -o /tmp/nanobot-install.sh
less /tmp/nanobot-install.sh
sh /tmp/nanobot-install.sh
# Alternativa reproducible por gestor:
uv tool install nanobot-ai
# o pipx install nanobot-ai
nanobot --version
nanobot onboard --wizard
nanobot status
nanobot agent -m "Hello!"
If the executable is not in PATH, the installer indicates how to invoke it; documented options:
uv tool run --from nanobot-ai nanobot --version
pipx run --spec nanobot-ai nanobot --version
~/.nanobot/venv/bin/python -m nanobot --version
Do not use sudo pip install on the system Python. If the system flags externally-managed-environment, use uv tool, pipx or venv.### Python method with virtualenv (useful on VPS)
python3 --version # 3.11+
python3 -m venv ~/venvs/nanobot
source ~/venvs/nanobot/bin/activate
python -m pip install --upgrade pip
python -m pip install nanobot-ai
nanobot --version
nanobot onboard --wizard
nanobot status
nanobot agent -m "Hello!"
The agent -m test makes a real call to the model if configured; status validates the local state and does not necessarily call the API.
Scenario: Ubuntu/Debian, SSH access, separate service account and remote LLM provider. Review system changes before applying them.
# Accede con tu usuario administrativo por SSH.
sudo apt update && sudo apt upgrade -y
sudo apt install -y python3 python3-venv python3-pip git curl ca-certificates
# Firewall: NO ejecutes sin antes confirmar que SSH funciona
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status verbose
Check python3 --version. If it is lower than 3.11, install a compatible version from your distribution or a trusted version manager.
Create a separate account (example nanobot, without root login):
sudo adduser nanobot
sudo loginctl enable-linger nanobot
sudo -iu nanobot
Keep the account out of the sudo and docker groups, with access only to the service's data and credentials.
python3 --version
python3 -m venv ~/.venvs/nanobot
~/.venvs/nanobot/bin/python -m pip install --upgrade pip
~/.venvs/nanobot/bin/python -m pip install nanobot-ai
~/.venvs/nanobot/bin/nanobot --version
~/.venvs/nanobot/bin/nanobot onboard --wizard
Initialize ~/.nanobot/config.json, select provider/model and run a first test. If there is no browser on the VPS, use the onboard --wizard terminal wizard or edit JSON manually (section 7).
~/.venvs/nanobot/bin/nanobot gateway install-service --manager systemd --dry-run
~/.venvs/nanobot/bin/nanobot gateway install-service --manager systemd
systemctl --user status nanobot-gateway
journalctl --user -u nanobot-gateway -f
What it does: creates ~/.config/systemd/user/nanobot-gateway.service, reloads the systemd user, enables and restarts the service. It uses the Python of the installation from which you called the CLI. loginctl enable-linger nanobot allows the user unit to continue after closing SSH (requires administrative permissions).
Daily control:
systemctl --user restart nanobot-gateway
systemctl --user stop nanobot-gateway
systemctl --user start nanobot-gateway
journalctl --user -u nanobot-gateway --since "1 hour ago" --no-pager
Do not also enable nanobot gateway --background if the systemd service is already running it on the same instance: you could have two processes and conflicting ports/sessions.
On the VPS, the gateway/WebUI must listen only on loopback. To access it from your PC:
# EJECUTA EN TU ORDENADOR, NO EN LA VPS:
ssh -N -L 8765:127.0.0.1:8765 usuario@IP_O_HOST_DE_TU_VPS
Open http://127.0.0.1:8765 on your computer. Verify on the VPS which addresses are listening:
ss -lntp | grep -E '8765|18790|8900'
If it listens on 0.0.0.0:8765 or [::]:8765, review the configuration and firewall. For remote access, use the SSH tunnel, a private VPN or an authenticated proxy.
nanobot supports "${ENV_VAR}" in JSON fields. You can load keys through a systemd user unit:
mkdir -p ~/.config/nanobot
chmod 700 ~/.config/nanobot
install -m 600 /dev/null ~/.config/nanobot/secrets.env
nano ~/.config/nanobot/secrets.env
Configure the credentials in the private file:
PROVIDER_API_KEY=REEMPLAZAR
TELEGRAM_TOKEN=REEMPLAZAR
Edit the generated unit:
systemctl --user edit nanobot-gateway
Add:
[Service]
EnvironmentFile=%h/.config/nanobot/secrets.env
Then:
systemctl --user daemon-reload
systemctl --user restart nanobot-gateway
systemctl --user status nanobot-gateway
In the JSON, use "${PROVIDER_API_KEY}" and "${TELEGRAM_TOKEN}". EnvironmentFile configures the service, not the SSH terminal; for CLI tests, load the variables through a secret manager or a private shell file. Keep the values out of logs.## 6. VPS Deployment: route B — Docker Compose
The official documentation offers Dockerfile, docker-compose.yml and an override for bwrap. This route requires cloning the repo because Compose builds from that checkout. Recommendation: pin a reviewed tag/commit if you want reproducibility, and evaluate updates before using main.
# En VPS, con Docker Engine + Compose plugin ya instalados:
git clone https://github.com/HKUDS/nanobot.git
cd nanobot
git rev-parse --short HEAD # registra este hash
# Instala dependencias de Telegram dentro de la imagen:
NANOBOT_CHANNELS=telegram docker compose build
docker compose run --rm nanobot-cli onboard
# Edita ~/.nanobot/config.json del usuario que ejecuta compose:
chmod 700 ~/.nanobot
chmod 600 ~/.nanobot/config.json
nano ~/.nanobot/config.json
docker compose run --rm nanobot-cli agent -m "Hello!"
docker compose up -d nanobot-gateway
docker compose ps
docker compose logs -f nanobot-gateway
Persistence: the official Compose mounts the host's ~/.nanobot at /home/nanobot/.nanobot. The container runs the final process as an unprivileged user, UID 1000, and uses certain capabilities to adjust the ownership of the bind mount at startup. Check file permissions before restoring backups.
Port exposure: check docker compose config and the effective ports:. If a publication is on 0.0.0.0, change it to restrict it to 127.0.0.1 or remove it if you are only going to use Telegram long polling. Do not assume that Docker will respect all UFW rules like normal processes: check Docker rules, the provider's firewall and external tests.
If you need a Linux command sandbox inside the container:
# Sólo después de establecer tools.exec.sandbox=bwrap en config.json:
docker compose -f docker-compose.yml -f docker-compose.bwrap.yml up -d nanobot-gateway
The override enables namespaces and disables AppArmor/seccomp profiles. Evaluate that protection change before enabling it; it requires support for unprivileged user namespaces on the host.
Operational commands:
docker compose logs --tail=100 nanobot-gateway
docker compose restart nanobot-gateway
docker compose down # detiene, no debería borrar bind mount
Avoid mounting the Docker socket inside the agent; it would be a way to compromise the host. Do not run the container with --privileged for convenience.
Configure the model from WebUI → Settings → Models or nanobot onboard --wizard. For manual configuration, integrate this fragment into the existing JSON:
{
"providers": {
"custom": {
"apiKey": "${PROVIDER_API_KEY}",
"apiBase": "https://api.tu-proveedor-ejemplo.com/v1"
}
},
"modelPresets": {
"primary": {
"provider": "custom",
"model": "ID-REAL-DEL-MODELO"
}
},
"agents": {
"defaults": {
"modelPreset": "primary"
}
}
}
Adjust provider, endpoint, model and key as a set. Consult the documentation for presets, fallbacks and OpenAI-compatible providers.
Validation:
nanobot status
nanobot agent -m "Resume en una frase qué puedes hacer."
If you do not have the binary in PATH, use its absolute path, depending on the installation.
Telegram works over long polling by default, so for the pilot you normally do not need a public webhook or to open inbound ports.
In Telegram open @BotFather, create a bot with /newbot, copy the token to your secure manager.
In the same Python/venv as nanobot enable the extra/plugin:
nanobot plugins enable telegram
Use WebUI → Settings → Channels → Telegram, or manually add to ~/.nanobot/config.json:
{
"channels": {
"telegram": {
"enabled": true,
"token": "${TELEGRAM_TOKEN}"
}
}
}
Do not configure allowFrom: ["*"]. By omitting allowFrom, the channel enters pairing mode according to the official guide.
Restart the gateway and check nanobot channels status.
Send a DM to the bot from your account; when you receive a pairing code, approve it from an already trusted surface:
nanobot agent -m "/pairing approve ABCD-EFGH"
Repeat the message: it should respond normally. Never accept an approval order via chat from a user who is not yet authorized.
For groups: check who can mention the bot, how it handles attachments/links and whether it has execution permission. Restrict tool execution to authorized senders. If the token was leaked, revoke it in BotFather and update the service.## 9. Tools, MCP and automations
tools.exec): powerful, but high-risk. You can disable it completely with "tools": {"exec": {"enable": false}} merged into your configuration. It also supports timeout and sandbox.tools.mcpServers.<nombre> for stdio or HTTP/SSE servers, per the documentation. A third-party MCP is equivalent to installing software with permissions: review its author and scope.The following is a snippet to integrate, not a complete JSON:
{
"tools": {
"restrictToWorkspace": true,
"exec": {
"sandbox": "bwrap",
"timeout": 60
}
}
}
To install bubblewrap (host, without Docker):
sudo apt install bubblewrap
Warning: with Docker, enabling bwrap requires considering the override described above. If you have not yet reviewed those permissions, it is preferable to disable exec on the first deployment. The sandbox does not block network traffic nor guarantee immunity against vulnerabilities.
The official documentation shows the concept:
{
"tools": {
"mcpServers": {
"mi-servidor": {
"command": "npx",
"args": ["-y", "PAQUETE_MCP_REVISADO"],
"env": { "API_KEY": "${API_KEY_DEL_MCP}" }
}
}
}
}
Do not copy npx -y packages from the Internet without reviewing them on a critical VPS: pin the version, control dependencies and API permissions. For HTTP/SSE use an HTTPS endpoint, dedicated credentials and an egress policy.
From the WebUI you can create scheduled tasks and view results; the documentation devotes a section to cron, heartbeat and agent actions. For the first production rollout:
The workspace and the application's restrictions do not constitute a kernel boundary. bwrap and seatbelt do not isolate the network either. For independent user data, separate accounts, credentials and environments according to the level of trust.
Restrict egress to necessary services and block access to cloud metadata and internal networks. Keep tools.ssrfWhitelist empty except for justified exceptions. An agent with read access to secrets and network egress can exfiltrate them even inside a container.
Review skills and MCP scripts, and treat messages, documents and external pages as untrusted input. Retain logs and file changes with an appropriate retention policy.
nanobot --version
nanobot status
nanobot channels status
nanobot gateway status
nanobot gateway logs
# si usas systemd:
systemctl --user status nanobot-gateway
journalctl --user -u nanobot-gateway -n 100 --no-pager
# si usas Compose:
docker compose ps
docker compose logs --tail=100 nanobot-gateway
nanobot gateway status/logs correspond to the CLI's own background mode; with systemd or Compose it is advisable to use the real supervisor.
With the service stopped, save ~/.nanobot (includes config, sessions, workspace and, potentially, secrets). Conceptual example:
systemctl --user stop nanobot-gateway
umask 077
tar -czf "$HOME/nanobot-backup-$(date +%F).tar.gz" -C "$HOME" .nanobot
systemctl --user start nanobot-gateway
Encrypt the TAR before transferring it, restrict its permissions and test the restore in another environment. Back up ~/.config/nanobot/secrets.env separately: it is outside the ~/.nanobot folder.
# Si se instaló con uv:
uv tool upgrade nanobot-ai
# Si se instaló con pipx:
pipx upgrade nanobot-ai
# Si usa virtualenv:
~/.venvs/nanobot/bin/python -m pip install -U nanobot-ai
Then compare nanobot --version, reread the release notes, restart the service, test Telegram, pairing tests, sandbox and automations. For git/Compose, pin the commit, make a backup and rebuild with docker compose build and up -d after reviewing the changes. Do not perform unattended main updates in production.
| Symptom | What to check first |
|---|---|
nanobot: command not found | PATH, venv, uv/pipx runner, installation as the correct user |
status OK but not responding | provider credential, model ID, endpoint, outbound network, quotas |
| Telegram without messages | channels status, token, plugin in the same venv, gateway alive, connectivity |
| Code received but no access | approve pairing from CLI/authorized surface |
| WebUI inaccessible over SSH | service listening, ssh -L, local port occupied, loopback bind |
| Tools do not read files | selected workspace, Unix permissions, restrictToWorkspace, sandbox paths |
bwrap fails with Operation not permitted | user namespaces, host policy, seccomp/Compose override |
| automations do not run | persistent service, time zone, logs, cron, task permissions |
| rising consumption/tokens | accumulated sessions, concurrency, tool loops, chosen model |
Reviewed: 10/10/2026
Repository: https://github.com/HKUDS/nanobot
Primary documentation: installation, deployment, configuration, Telegram.
Compatibility: official documentation reviewed on 10/10/2026, with v0.3.5 as the published reference. Check
nanobot --version:mainmay describe later features. The server administration examples are deployment recommendations.
nanobot is a self-hostable Python-based assistant with web, terminal and messaging interfaces. It manages sessions, files, memory and automations through tools and plugins. It can be deployed as a private Telegram assistant with a remote model.
Documented capabilities: WebUI, terminal/TUI, conversations and workspaces, model presets and fallbacks, messaging channels, memory, skills, cron/automations, MCP, web search/fetch, file/shell tools, multiple instances, Docker/Compose deployment, integration via Python SDK and OpenAI-compatible API. Exact availability depends on the channel, installed extra, release and configuration.
Telegram / WebUI / CLI / otros canales
|
gateway de nanobot
|
sesión + workspace
|
contexto / memoria / skills
|
LLM (API o local)
|
herramientas / MCP / web / shell
|
respuesta al canal
~/.nanobot/config.json: configuration of models, tools, permissions, channels, WebUI and runtime.~/.nanobot/workspace/: memory, skills, automations and work artifacts.~/.nanobot/sessions/<workspace-id>/: session history separate from the workspace.nanobot webui, by default on http://127.0.0.1:8765 for local use.127.0.0.1:18790; API nanobot serve normally 8900. They should not be exposed as a matter of routine.Design security: a per-workspace restriction enforced by software does not replace kernel isolation. On Linux you can enable tools.exec.sandbox: "bwrap", and on macOS "seatbelt"; the documentation states that neither of these two backends isolates the network.
~/.nanobot and backups.bubblewrap for Linux sandbox outside the container.free -h, df -h, top/htop, response times, restarts, token usage and spend per provider. Set consumption limits at the API level.The documentation recommends an installer that chooses virtualenv, uv, pipx or your own environment:
# Revisar antes de ejecutar: script remoto del repositorio oficial
curl -fsSL https://raw.githubusercontent.com/HKUDS/nanobot/main/scripts/install.sh -o /tmp/nanobot-install.sh
less /tmp/nanobot-install.sh
sh /tmp/nanobot-install.sh
# Alternativa reproducible por gestor:
uv tool install nanobot-ai
# o pipx install nanobot-ai
nanobot --version
nanobot onboard --wizard
nanobot status
nanobot agent -m "Hello!"
If the executable is not in PATH, the installer indicates how to invoke it; documented options:
uv tool run --from nanobot-ai nanobot --version
pipx run --spec nanobot-ai nanobot --version
~/.nanobot/venv/bin/python -m nanobot --version
Do not use sudo pip install on the system Python. If the system flags externally-managed-environment, use uv tool, pipx or venv.### Python method with virtualenv (useful on VPS)
python3 --version # 3.11+
python3 -m venv ~/venvs/nanobot
source ~/venvs/nanobot/bin/activate
python -m pip install --upgrade pip
python -m pip install nanobot-ai
nanobot --version
nanobot onboard --wizard
nanobot status
nanobot agent -m "Hello!"
The agent -m test makes a real call to the model if configured; status validates the local state and does not necessarily call the API.
Scenario: Ubuntu/Debian, SSH access, separate service account and remote LLM provider. Review system changes before applying them.
# Accede con tu usuario administrativo por SSH.
sudo apt update && sudo apt upgrade -y
sudo apt install -y python3 python3-venv python3-pip git curl ca-certificates
# Firewall: NO ejecutes sin antes confirmar que SSH funciona
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status verbose
Check python3 --version. If it is lower than 3.11, install a compatible version from your distribution or a trusted version manager.
Create a separate account (example nanobot, without root login):
sudo adduser nanobot
sudo loginctl enable-linger nanobot
sudo -iu nanobot
Keep the account out of the sudo and docker groups, with access only to the service's data and credentials.
python3 --version
python3 -m venv ~/.venvs/nanobot
~/.venvs/nanobot/bin/python -m pip install --upgrade pip
~/.venvs/nanobot/bin/python -m pip install nanobot-ai
~/.venvs/nanobot/bin/nanobot --version
~/.venvs/nanobot/bin/nanobot onboard --wizard
Initialize ~/.nanobot/config.json, select provider/model and run a first test. If there is no browser on the VPS, use the onboard --wizard terminal wizard or edit JSON manually (section 7).
~/.venvs/nanobot/bin/nanobot gateway install-service --manager systemd --dry-run
~/.venvs/nanobot/bin/nanobot gateway install-service --manager systemd
systemctl --user status nanobot-gateway
journalctl --user -u nanobot-gateway -f
What it does: creates ~/.config/systemd/user/nanobot-gateway.service, reloads the systemd user, enables and restarts the service. It uses the Python of the installation from which you called the CLI. loginctl enable-linger nanobot allows the user unit to continue after closing SSH (requires administrative permissions).
Daily control:
systemctl --user restart nanobot-gateway
systemctl --user stop nanobot-gateway
systemctl --user start nanobot-gateway
journalctl --user -u nanobot-gateway --since "1 hour ago" --no-pager
Do not also enable nanobot gateway --background if the systemd service is already running it on the same instance: you could have two processes and conflicting ports/sessions.
On the VPS, the gateway/WebUI must listen only on loopback. To access it from your PC:
# EJECUTA EN TU ORDENADOR, NO EN LA VPS:
ssh -N -L 8765:127.0.0.1:8765 usuario@IP_O_HOST_DE_TU_VPS
Open http://127.0.0.1:8765 on your computer. Verify on the VPS which addresses are listening:
ss -lntp | grep -E '8765|18790|8900'
If it listens on 0.0.0.0:8765 or [::]:8765, review the configuration and firewall. For remote access, use the SSH tunnel, a private VPN or an authenticated proxy.
nanobot supports "${ENV_VAR}" in JSON fields. You can load keys through a systemd user unit:
mkdir -p ~/.config/nanobot
chmod 700 ~/.config/nanobot
install -m 600 /dev/null ~/.config/nanobot/secrets.env
nano ~/.config/nanobot/secrets.env
Configure the credentials in the private file:
PROVIDER_API_KEY=REEMPLAZAR
TELEGRAM_TOKEN=REEMPLAZAR
Edit the generated unit:
systemctl --user edit nanobot-gateway
Add:
[Service]
EnvironmentFile=%h/.config/nanobot/secrets.env
Then:
systemctl --user daemon-reload
systemctl --user restart nanobot-gateway
systemctl --user status nanobot-gateway
In the JSON, use "${PROVIDER_API_KEY}" and "${TELEGRAM_TOKEN}". EnvironmentFile configures the service, not the SSH terminal; for CLI tests, load the variables through a secret manager or a private shell file. Keep the values out of logs.## 6. VPS Deployment: route B — Docker Compose
The official documentation offers Dockerfile, docker-compose.yml and an override for bwrap. This route requires cloning the repo because Compose builds from that checkout. Recommendation: pin a reviewed tag/commit if you want reproducibility, and evaluate updates before using main.
# En VPS, con Docker Engine + Compose plugin ya instalados:
git clone https://github.com/HKUDS/nanobot.git
cd nanobot
git rev-parse --short HEAD # registra este hash
# Instala dependencias de Telegram dentro de la imagen:
NANOBOT_CHANNELS=telegram docker compose build
docker compose run --rm nanobot-cli onboard
# Edita ~/.nanobot/config.json del usuario que ejecuta compose:
chmod 700 ~/.nanobot
chmod 600 ~/.nanobot/config.json
nano ~/.nanobot/config.json
docker compose run --rm nanobot-cli agent -m "Hello!"
docker compose up -d nanobot-gateway
docker compose ps
docker compose logs -f nanobot-gateway
Persistence: the official Compose mounts the host's ~/.nanobot at /home/nanobot/.nanobot. The container runs the final process as an unprivileged user, UID 1000, and uses certain capabilities to adjust the ownership of the bind mount at startup. Check file permissions before restoring backups.
Port exposure: check docker compose config and the effective ports:. If a publication is on 0.0.0.0, change it to restrict it to 127.0.0.1 or remove it if you are only going to use Telegram long polling. Do not assume that Docker will respect all UFW rules like normal processes: check Docker rules, the provider's firewall and external tests.
If you need a Linux command sandbox inside the container:
# Sólo después de establecer tools.exec.sandbox=bwrap en config.json:
docker compose -f docker-compose.yml -f docker-compose.bwrap.yml up -d nanobot-gateway
The override enables namespaces and disables AppArmor/seccomp profiles. Evaluate that protection change before enabling it; it requires support for unprivileged user namespaces on the host.
Operational commands:
docker compose logs --tail=100 nanobot-gateway
docker compose restart nanobot-gateway
docker compose down # detiene, no debería borrar bind mount
Avoid mounting the Docker socket inside the agent; it would be a way to compromise the host. Do not run the container with --privileged for convenience.
Configure the model from WebUI → Settings → Models or nanobot onboard --wizard. For manual configuration, integrate this fragment into the existing JSON:
{
"providers": {
"custom": {
"apiKey": "${PROVIDER_API_KEY}",
"apiBase": "https://api.tu-proveedor-ejemplo.com/v1"
}
},
"modelPresets": {
"primary": {
"provider": "custom",
"model": "ID-REAL-DEL-MODELO"
}
},
"agents": {
"defaults": {
"modelPreset": "primary"
}
}
}
Adjust provider, endpoint, model and key as a set. Consult the documentation for presets, fallbacks and OpenAI-compatible providers.
Validation:
nanobot status
nanobot agent -m "Resume en una frase qué puedes hacer."
If you do not have the binary in PATH, use its absolute path, depending on the installation.
Telegram works over long polling by default, so for the pilot you normally do not need a public webhook or to open inbound ports.
In Telegram open @BotFather, create a bot with /newbot, copy the token to your secure manager.
In the same Python/venv as nanobot enable the extra/plugin:
nanobot plugins enable telegram
Use WebUI → Settings → Channels → Telegram, or manually add to ~/.nanobot/config.json:
{
"channels": {
"telegram": {
"enabled": true,
"token": "${TELEGRAM_TOKEN}"
}
}
}
Do not configure allowFrom: ["*"]. By omitting allowFrom, the channel enters pairing mode according to the official guide.
Restart the gateway and check nanobot channels status.
Send a DM to the bot from your account; when you receive a pairing code, approve it from an already trusted surface:
nanobot agent -m "/pairing approve ABCD-EFGH"
Repeat the message: it should respond normally. Never accept an approval order via chat from a user who is not yet authorized.
For groups: check who can mention the bot, how it handles attachments/links and whether it has execution permission. Restrict tool execution to authorized senders. If the token was leaked, revoke it in BotFather and update the service.## 9. Tools, MCP and automations
tools.exec): powerful, but high-risk. You can disable it completely with "tools": {"exec": {"enable": false}} merged into your configuration. It also supports timeout and sandbox.tools.mcpServers.<nombre> for stdio or HTTP/SSE servers, per the documentation. A third-party MCP is equivalent to installing software with permissions: review its author and scope.The following is a snippet to integrate, not a complete JSON:
{
"tools": {
"restrictToWorkspace": true,
"exec": {
"sandbox": "bwrap",
"timeout": 60
}
}
}
To install bubblewrap (host, without Docker):
sudo apt install bubblewrap
Warning: with Docker, enabling bwrap requires considering the override described above. If you have not yet reviewed those permissions, it is preferable to disable exec on the first deployment. The sandbox does not block network traffic nor guarantee immunity against vulnerabilities.
The official documentation shows the concept:
{
"tools": {
"mcpServers": {
"mi-servidor": {
"command": "npx",
"args": ["-y", "PAQUETE_MCP_REVISADO"],
"env": { "API_KEY": "${API_KEY_DEL_MCP}" }
}
}
}
}
Do not copy npx -y packages from the Internet without reviewing them on a critical VPS: pin the version, control dependencies and API permissions. For HTTP/SSE use an HTTPS endpoint, dedicated credentials and an egress policy.
From the WebUI you can create scheduled tasks and view results; the documentation devotes a section to cron, heartbeat and agent actions. For the first production rollout:
Documentation: https://github.com/HKUDS/nanobot/blob/main/docs/automations.md
The workspace and the application's restrictions do not constitute a kernel boundary. bwrap and seatbelt do not isolate the network either. For independent user data, separate accounts, credentials and environments according to the level of trust.
Restrict egress to necessary services and block access to cloud metadata and internal networks. Keep tools.ssrfWhitelist empty except for justified exceptions. An agent with read access to secrets and network egress can exfiltrate them even inside a container.
Review skills and MCP scripts, and treat messages, documents and external pages as untrusted input. Retain logs and file changes with an appropriate retention policy.
nanobot --version
nanobot status
nanobot channels status
nanobot gateway status
nanobot gateway logs
# si usas systemd:
systemctl --user status nanobot-gateway
journalctl --user -u nanobot-gateway -n 100 --no-pager
# si usas Compose:
docker compose ps
docker compose logs --tail=100 nanobot-gateway
nanobot gateway status/logs correspond to the CLI's own background mode; with systemd or Compose it is advisable to use the real supervisor.
With the service stopped, save ~/.nanobot (includes config, sessions, workspace and, potentially, secrets). Conceptual example:
systemctl --user stop nanobot-gateway
umask 077
tar -czf "$HOME/nanobot-backup-$(date +%F).tar.gz" -C "$HOME" .nanobot
systemctl --user start nanobot-gateway
Encrypt the TAR before transferring it, restrict its permissions and test the restore in another environment. Back up ~/.config/nanobot/secrets.env separately: it is outside the ~/.nanobot folder.
# Si se instaló con uv:
uv tool upgrade nanobot-ai
# Si se instaló con pipx:
pipx upgrade nanobot-ai
# Si usa virtualenv:
~/.venvs/nanobot/bin/python -m pip install -U nanobot-ai
Then compare nanobot --version, reread the release notes, restart the service, test Telegram, pairing tests, sandbox and automations. For git/Compose, pin the commit, make a backup and rebuild with docker compose build and up -d after reviewing the changes. Do not perform unattended main updates in production.
| Symptom | What to check first |
|---|---|
nanobot: command not found | PATH, venv, uv/pipx runner, installation as the correct user |
status OK but not responding | provider credential, model ID, endpoint, outbound network, quotas |
| Telegram without messages | channels status, token, plugin in the same venv, gateway alive, connectivity |
| Code received but no access | approve pairing from CLI/authorized surface |
| WebUI inaccessible over SSH | service listening, ssh -L, local port occupied, loopback bind |
| Tools do not read files | selected workspace, Unix permissions, restrictToWorkspace, sandbox paths |
bwrap fails with Operation not permitted | user namespaces, host policy, seccomp/Compose override |
| automations do not run | persistent service, time zone, logs, cron, task permissions |
| rising consumption/tokens | accumulated sessions, concurrency, tool loops, chosen model |