Model or dataset
HKUDS/nanobot avatar
HKUDS/nanobot

HKUDS nanobot: what the wheels and the compose file actually decide

Lightweight, open-source AI agent for your tools, chats, and workflows.

48,618 stars8,591 forksPythonMIT

At a glance

What is it?
HKUDS nanobot is a self-hosted Python agent runtime, MIT licensed and classified as alpha, that runs as a WebUI, a native TUI, or a chat channel and exposes an OpenAI-compatible API. The interesting parts are the sharp edges: wheel coverage, a pip error on managed systems, a compose file that publishes one port on every interface, and channel dependencies that install while the container starts.
Who is it for?
nanobot fits a reader who wants one small Python agent runtime they can read, run from a WebUI or a chat app, and keep on their own machine, and who is comfortable with an alpha package, a Python 3.11 floor, and a ceiling on nearly every dependency. It does not fit a reader who needs a guaranteed terminal UI on an unusual platform, an offline container install, or chat channels that were not baked into the image.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Four wheel targets, and a source install that downloads a TUI archive

Platform wheels carry both the WebUI and the native terminal UI, and they exist for macOS 13+ on Apple Silicon and Intel, glibc 2.17+ Linux on ARM64 and x64, and Windows x64. The x64 runtime requires SSE4.2, so a server CPU older than that instruction set gets no wheel at all. A source-distribution install behaves differently: on first use it fetches a checksummed, version-matched TUI archive together with its licenses, notices, corresponding application source, source offer, and relinking instructions. That fallback is exactly where this project stops working for some readers. On any platform outside the wheel list, and on any host behind an air gap, an egress allowlist, or a proxy that blocks binary downloads, the archive fetch fails, the terminal UI never appears, and you are left with the WebUI and the CLI until the network path is fixed. Python 3.11 or newer is the floor for every path.

externally-managed-environment is the error you will meet first

On a PEP 668 managed macOS or Linux box, a naive install stops before nanobot ever runs. The named failure is externally-managed-environment, raised by pip when you reach for the plain command:

bash
python -m pip install nanobot-ai

Four documented ways around it exist: the one-command installer, `uv tool install nanobot-ai`, `pipx install nanobot-ai`, or installing inside a virtual environment. All four keep the package out of the system interpreter, and that is the whole point of the advice. What this project does not give you is one canonical command, so two readers can both be installing correctly and still end up with different interpreters, different PATH entries, and different places to look when the wrong version answers a call. The container route sidesteps the question entirely by building its own environment at /app/.venv instead of borrowing the host's Python.

install.sh picks the environment, then decides whether to open the WebUI

The one-command installer is a piped script, and it is worth reading before you run it:

bash
curl -fsSL https://raw.githubusercontent.com/HKUDS/nanobot/main/scripts/install.sh | sh

It installs or upgrades nanobot-ai from PyPI, and it refuses a system-wide pip install by selecting between an active virtual environment, uv, pipx, or a managed venv under ~/.nanobot/venv. On a fresh local desktop it then starts nanobot webui so you can configure the first provider and model in Settings, Models. Over SSH, headless, with an existing config, or on an older release, it keeps the terminal setup wizard instead, so the identical command behaves differently depending on the machine it lands on. It also prints the exact command it used, which is the line to copy when nanobot is not on your PATH. To see the plan without touching your environment, pass --dry-run:

bash
curl -fsSL https://raw.githubusercontent.com/HKUDS/nanobot/main/scripts/install.sh | sh -s -- --dry-run

Windows has its own one-liner in PowerShell, and scripts/install.sh and scripts/install.ps1 are readable in the repository if you would rather inspect than pipe.

Stable and source tracks update through different commands

The install table is split in two, and mixing the tracks is the quiet way to produce a bug report you cannot trust. The Stable track, installed by installer, uv, or pip, updates with the same package tool and runs one released Python, WebUI, and TUI version. The Current source track is an editable Git checkout, updates with `git pull --ff-only` plus an editable dependency sync, and runs Python, WebUI, and TUI straight from that checkout. Git and Bun are required only for the source path; every other path needs Python 3.11 or newer and nothing else. The failure mode is specific rather than general: a defect you reproduce on main may be version skew between a working tree and the published wheel rather than a fault in agent behavior, and nothing in the two tracks stops one checkout from reading the same ~/.nanobot state as a released install. Pin one track, write down the version, and diff dependencies before you file anything upstream.

The compose file drops all capabilities, adds three back, and publishes 8765 to everything

The bundled docker-compose.yml is stricter than a typical hobby stack. It sets cap_drop to ALL, adds back only CHOWN, SETGID, and SETUID so the entrypoint can fix bind-mount ownership and drop to the nanobot user, and sets no-new-privileges:true to stop a non-root process regaining capabilities through setuid binaries left in the image. It mounts ~/.nanobot onto /home/nanobot/.nanobot and caps the gateway at 1 CPU and 1G of memory, with reservations of 0.25 CPU and 256M. Three services run: nanobot-gateway on command gateway, nanobot-api on serve bound to 0.0.0.0 with a workspace at /home/nanobot/.nanobot/api-workspace, and nanobot-cli behind the cli profile running status. The gap to check before you deploy is port exposure. The gateway publishes 18790 on 127.0.0.1 and 8765 on every host interface, while the api container listens on 0.0.0.0 but is published only on 127.0.0.1. Nothing in the file keeps 8765 off the network, and there is no healthcheck, so restart: unless-stopped will happily restart a process that is already failing.

Node 24 builds the WebUI, Python 3.12 runs it, and channels install at startup

The Dockerfile is two stages. A node:24-bookworm-slim builder runs npm ci in webui/, copies in packages/client-events, and emits the bundle into nanobot/web/dist. The runtime is ghcr.io/astral-sh/uv:python3.12-bookworm-slim with ca-certificates, git, bubblewrap, openssh-client, and libmagic1 installed, and it creates its own interpreter with uv venv --seed at /app/.venv. Every Python install step passes NANOBOT_SKIP_WEBUI_BUILD=1 so the prebuilt bundle is not rebuilt inside the image, and an optional NANOBOT_EXTRAS build arg selects extras at build time. Channel dependencies are the soft spot. They are preinstalled from their manifests for a comma-separated list driven by NANOBOT_CHANNELS, which defaults to whatsapp, and any channel that was not baked into the image installs its own manifest-declared dependencies the first time it starts. That needs a writable environment and outbound package access, so a locked-down or offline container can bring up its gateway and then fail on the one channel you actually wanted.

files, shell, web fetch, and cron share one surface above Dream memory

The tool list is the security story: files, shell, web search, web fetch, MCP, cron, image generation, and subagents, all reachable from the same agent that keeps session history and long-term memory through Dream and can run long-horizon goals. On a desktop install started with nanobot webui, that agent holds your user permissions, your home directory, and your shell, and the capability dropping shown in docker-compose.yml belongs to the container path rather than the local one. Two limits follow. First, a fetched page or an MCP server is untrusted input arriving in the same context as your instructions, and the model is what decides whether that becomes a shell command. Second, scheduled automations through cron outlive the conversation that created them, so a bad tool call can repeat on a timer long after the chat is gone. Treat every connected channel as remote code execution, and remember that the compose file mounts your real ~/.nanobot into the container.

Most dependencies carry a ceiling, and websockets 16 exists for Feishu

pyproject.toml for version 0.3.5 brackets nearly every direct dependency between a floor and a ceiling: typer below 1.0.0, anthropic below 1.0.0, pydantic below 3.0.0, httpx below 1.0.0, mcp from 1.26.0, openai at 2.8.0 or newer, croniter below 7.0.0, and setproctitle only where sys_platform is not win32. One range is shaped by something outside this repository: websockets is held between 15.0 and 17.0 because Feishu's lark-oapi requires websockets below 16 while the core supports both 15 and 16. The package carries the Development Status :: 3 - Alpha classifier and only Python 3.11 and 3.12 appear in its classifiers. In practice this means a ceiling can move under you between nanobot patch releases, and an alpha tag on a project whose most recent release is v0.3.5 dated 2026-09-15 is a reason to read docs/configuration.md before you build scheduled work on top of it.

Editorial conclusion

nanobot fits a reader who wants one small Python agent runtime they can read, run from a WebUI or a chat app, and keep on their own machine, and who is comfortable with an alpha package, a Python 3.11 floor, and a ceiling on nearly every dependency. It does not fit a reader who needs a guaranteed terminal UI on an unusual platform, an offline container install, or chat channels that were not baked into the image. Before you build on it, check three things: whether port 8765 is reachable from your network, whether pip hands you externally-managed-environment, and which channel dependencies your container will try to install at startup. Pin one install track, record the version, and read the configuration notes before you wire scheduled automations to it.

Frequently asked questions

what is nanobot ai

It is a self-hosted personal AI agent framework written in Python, published on PyPI as nanobot-ai under the MIT license, and it runs in a WebUI, terminal, or chat apps. It combines tools, long-term memory through Dream, MCP integrations, model routing, multi-agent delegation, scheduled automation, and an OpenAI-compatible API in a small core. Because the same name is also used for medical nanobot research and unrelated consumer products, confirm you are on the PyPI project nanobot-ai and the docs at nanobot.wiki.

how to install nanobot

The one-command path pipes scripts/install.sh into sh, which installs or upgrades nanobot-ai from PyPI and avoids a system-wide pip install by using an active virtual environment, uv, pipx, or a managed venv under ~/.nanobot/venv. `uv tool install nanobot-ai` and `python -m pip install nanobot-ai` are the other documented paths, and Python 3.11 or newer is the prerequisite.

how to install nanobot on windows

PowerShell has its own one-liner, irm https://raw.githubusercontent.com/HKUDS/nanobot/main/scripts/install.ps1 | iex, and the same --dry-run flag is available for previewing. Supported platform wheels include Windows x64, and the native TUI ships inside those wheels. Git and Bun are only required for a source install.

how to setup nanobot

On a fresh local desktop the installer starts nanobot webui so you can configure the first provider and model in Settings, Models. Over SSH, headless, with an existing config, or on an older release, it keeps the terminal setup wizard instead, and it prints the exact command it used in case nanobot is not on your PATH.

how to use nanobot

It runs in a browser WebUI or the terminal and connects to Telegram, Discord, Slack, WeChat, Email, Mattermost, Linear, and other channels. Tools include files, shell, web search, web fetch, MCP, cron, image generation, and subagents, and it also exposes a Python SDK and an OpenAI-compatible API for integrations.

how to use nanobot with ollama

The project describes its model layer as OpenAI-compatible APIs, local LLMs, image generation, search, and fallbacks, and its documentation lives at nanobot.wiki. The README does not name Ollama specifically and does not give a local model command, so the configuration reference is where you would confirm that path.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/hkuds-nanobot.svg)](https://hysenlabs.com/projects/hkuds-nanobot)