--- license: mit tags: - hermes - ai-agent - ollama - docker - auto-discovery - local-ai - mcp - portable - self-hosted - tabbyapi - vllm library_name: docker --- # 🏕️ Basecamp — The First Portable AI Agent Container with Network Auto-Discovery **v2.0** — the reliability release (current): - **Global scan dedup** — every service appears once with its container-name URL (no more gateway/loopback duplicates across discovery, config, tavern, and the wiring audit). - **LobeChat discovery fixed** — the starter pack's LobeChat was silently invisible (probe-key mismatch); now discovered and listed like everything else. - **MongoDB discovered** — raw wire-protocol probe (OP_MSG isMaster) so the starter pack's mongo shows up too. - **Verified live** — 16/16 services on the reference stack, one entry each. **v1.0.6** — the adaptive release: - **Adaptive discovery** — boot ALWAYS rescans (stale config can't freeze it), subnet sweep finds services when no docker socket is mounted, `BASECAMP_EXTRA_HOSTS` reaches cross-host/remote machines, network name is irrelevant. - **Any mess, any fix** — all 44 fix recipes inline in the agent's skill (not just discovered services); `tavern status` lists EVERY service with link:port; the SOUL answers service questions from tavern status. - **Auto-wire** — a webui-only network gets basecamp's bundled Ollama wired as the engine automatically, the user is told exactly what happened, and given cloud options (Nous portal ~$20/mo, Ollama.com, OpenRouter). **v1.0.5** — the self-healing release: - **The Fixer's toolbox** — basecamp now ships with every CLI it needs to EXECUTE fixes: postgres/mongosh/sqlite/redis clients, docker CLI + compose, yq, and full network diagnostics. It doesn't just describe the fix — it can run it (when the docker socket is mounted). - **`tavern self-check`** — verifies every discovered service against its recipe and reports ✅/⚠️/❌ (self-heal #1). "The fixer approves." - **`tavern update-check`** — polls Docker Hub/GHCR for newer image tags and reports what moved (self-heal #2). - **Self-check exit codes** — `tavern self-check` exits 1 when any service is failing, so scripts and CI can gate on it (self-heal #3 groundwork; a cloud CI run is planned once the repo is public). - **Coding starter pack** — 10 services incl. postgres/pgvector memory + mongo, with all verified pitfalls baked into the recipes (tabby pin, flowise pin, librechat mongo requirement, GHCR locations). **v1.0.4** — the fixer release. Basecamp Hermes now carries a soul: - **The Fixer** — Basecamp Hermes has a purpose: making stacks talk to themselves. The SOUL.md gives it identity and a Fixer's Creed (name the setting, give the one line, verify it) so it answers connection problems with conviction, not guesses. - **Fix recipes baked in** — 39 per-service wiring recipes (config location, exact keys, one-line fix, verification) ship inside the container. The stack skill embeds recipes inline for everything discovered, plus a full `references/wiring-recipes.md` for the rest. - **Skill always at hand** — SOUL.md + `-s basecamp-stack` preload on every hermes launch mean the agent has the stack knowledge without having to remember to look for it. **v1.0.3** — the identity + reliability release: - **Indigo identity** — Basecamp runs its own indigo skin ("Welcome to Basecamp Hermes!") so you can tell it apart from a host install at a glance; model readout shows `basecamp/` (created via `ollama cp` alias on the discovered engine). - **Boot race fixed** — the bundled-model pull now starts AFTER discovery, so the network scan never competes with a multi-GB download. Cold boots consistently discover the whole stack (7/7 on the reference stack). - **Smarter auto-select** — an external Ollama (your stack) is preferred over the bundled fallback; alias creation is verified before use, and stale `basecamp/` aliases are excluded from model lists. - **Separate commands** — host `hermes` = your install; `basecamp` = the container edition. No more ambiguity about which agent you're in. - **`tavern wire` wiring wizard** — every boot runs a stack wiring audit (✅ wired / ⚠️ needs attention / ❌ broken) with the exact one-line fix for anything mis-wired. Ask the container's Hermes "why won't my stack talk to each other?" — it has the ground truth via the injected `basecamp-stack` skill. - **Expanded discovery** — 30+ service probes: KoboldCpp, LM Studio, SGLang, llamafile, exo, TGI, Aphrodite, LibreChat, LobeChat, AnythingLLM, Dify, Flowise, n8n, Langflow, RAGFlow, Qdrant, Milvus, Chroma, Weaviate, ComfyUI, A1111, InvokeAI, Whisper, Piper, OpenRouter, KoboldAI Horde. **v1.0.2** — the stack-gauntlet release (tested against a live 6-service AI stack): - **TabbyAPI + SillyTavern now discovered** — auth-gated services (401/403) are fingerprinted and listed as `[needs auth]` so the connect screen can prompt for keys (previously invisible) - **Fixed hermes v0.20 wiring** — named custom provider (`providers.basecamp`) with inline API key, sidestepping the #28660 security gate that blocks env keys for LAN endpoints; reasoning-effort turned off (local engines reject thinking params with HTTP 400); stale context probes cleared - **Ollama preferred for auto-select** — hermes hard-requires ≥64K context, so headless mode picks an Ollama endpoint; OpenAI-compatible engines (TabbyAPI, vLLM) are still listed for interactive choice - **SearXNG probed via its fast static page** — no more slow search-query probe losing the boot race **v1.0.1** — rebuilt on the official Hermes installer (the old `pip3 install hermes-cli` stub is gone), leaked-key fallback removed from `tavern.sh`, and the git history scrubbed of both. Build from source below. One image. One command. It finds your AI stack and just works. Basecamp bundles **Hermes Agent** (the full agent — tools, skills, memory, gateway) **+ Ollama** (a brain it always has in its backpack), then does something nobody else's container does: **it sniffs your network on first boot** and auto-discovers your entire local AI stack — Ollama, TabbyAPI, vLLM, LiteLLM, LocalAI, llama.cpp, SearXNG, MCPO, Open WebUI, SillyTavern — and connects Hermes to the best brain it finds. No hardcoded URLs. No config files to hand-edit. Just `docker run`. ## Self-healing (the fixer maintains itself) Basecamp ships three self-healing layers so its wiring knowledge stays true even as the ecosystem moves: 1. **`tavern self-check`** — runs every discovered service against its recipe's verification step and reports ✅/⚠️/❌. Catches stale recipes and broken services before a user hits them. "The fixer approves." 2. **`tavern update-check`** — polls Docker Hub / GHCR for the newest published tag of every discovered service and reports what moved, so you can pull the newer image before an old one rots. 3. **Self-check exits 1 on failure** (`.github/workflows/recipe-verify.yml` is ready to use) — `tavern self-check` returns a non-zero exit when any service is RED, so a scheduled CI job can boot the full coding starter pack, run self-check, and fail loudly when a recipe has gone stale (an image moved, a flag changed, a service renamed). The workflow is shipped in the repo; wiring it to a public GitHub repo is a planned step. ## The Coding Starter Pack (10 best-of-breed AI coding tools) Basecamp ships a companion compose file that stands up a complete AI coding environment — every tool in its own container, all on the same Docker network, all wired to your stack's Ollama + TabbyAPI, all able to call each other by container name. ```bash cd basecamp docker compose -f docker-compose.starter.yml up -d basecamp rediscover # basecamp finds the whole pack basecamp wire # wiring audit ``` | # | Service | What it is | Port | |---|---------|-----------|------| | 1 | **code-server** | VS Code in the browser (the IDE) | 8443 | | 2 | **qdrant** | Vector DB — code RAG backbone | 6333 | | 3 | **chroma** | Lightweight vector DB (alternative) | 8005 | | 4 | **n8n** | Workflow automation | 5678 | | 5 | **lobe-chat** | AI chat UI (wired to stack Ollama) | 3210 | | 6 | **anythingllm** | RAG workspace (docs + codebase Q&A) | 3001 | | 7 | **librechat** | Multi-model chat UI (needs mongo — included) | 3080 | | 8 | **meilisearch** | Full-text search (code/docs search) | 7700 | | 9 | **postgres** | Postgres + pgvector — Hermes long-term memory | 5432 | | 10 | **mongo** | MongoDB — LibreChat's database | 27017 | **Removed (verified broken, 2026-08-09):** `tabby` (its bundled llama-server dlopens libcuda.so.1 even with `--device cpu` — crash-loops in CPU-only containers; needs GPU access) and `flowise` (upstream dependency bug — `@langchain/core` export error crashes boot on `latest` and 3.1.4). Both have full "do not use" recipes in basecamp so the agent warns before anyone ships them again. The IDE comes pre-loaded with **Continue.dev** (AI assistant). Point Continue's model at `http://ollama:11434/v1` (or `http://tabbyapi:5000/v1`) — your stack's models power the whole pack. (Inline code completion via the Tabby extension is available but needs a completion server; tabby's own image is currently broken in CPU-only containers — see the recipe.) Default credentials are in the compose file — change them before exposing anything publicly. ## Why this is different | Everyone else | Basecamp | |----------------------------------------------------|--------------------------------------------| | Manual compose file, hand-wired URLs | Auto-discovers your stack on first boot | | One hardcoded provider | Picks the best brain it finds, falls back to its own Ollama | | Agent config touches your host install | Container-only, env-scoped, cannot clobber a host Hermes | | Separate agent + separate model server | One image, both inside, batteries included | ## Safety model (read this first) Basecamp is **container-only** and is designed so it can never damage a Hermes install on the host that runs it: - **No writes into any Hermes home it doesn't own.** Hermes runtime config (provider URL, key, model) is passed as **environment variables**, sourced from `basecamp.env` (chmod 600) at `exec` time. Basecamp never overwrites `config.yaml` or `.env` files — not in the container, and certainly not on the host. - **State lives in named volumes only.** `basecamp-hermes` → `/root/.hermes` and `basecamp-ollama` → `/root/.ollama` inside the container. Nothing on the host is modified by running basecamp. - **No secrets in the image.** API keys are collected at the connect screen, saved chmod 600 inside the volume, and injected into the dynamically generated `tavern` CLI. The static fallback `tavern.sh` ships with empty key placeholders. - **Hermes is installed with the official installer**, never `pip install hermes-cli` (that PyPI package is an unrelated stub, not Hermes Agent). ## Quick start ```bash # Option A: pull the prebuilt image (Docker Hub) docker pull jpanasuk/basecamp:2.0 # Option B: build from source docker build -t local/basecamp:latest . # Run against your AI docker network (named volumes keep state across runs) docker run -it --rm \ --name basecamp \ --network your-ai-network \ --gpus all \ -p 11436:11434 \ -v basecamp-ollama:/root/.ollama \ -v basecamp-hermes:/root/.hermes \ jpanasuk/basecamp:2.0 ``` Or use the convenience launcher (auto-detects network + GPU, TTY-safe): ```bash ./basecamp.sh ``` First run shows the connect screen: pick your inference engine, enter API keys when prompted. Later runs skip it — config is saved in the volume. ## What it discovers | Service | What Basecamp does with it | |----------------|-----------------------------------------------------| | Ollama | Primary/secondary brain, lists available models | | TabbyAPI / vLLM / LiteLLM / LocalAI / llama.cpp | Primary inference engine (OpenAI-compatible) | | SearXNG | Wires search into the agent + tavern CLI | | MCPO | Exposes MCP tools to the agent | | Open WebUI / SillyTavern | Detects your chat UIs, reports them | ## Inside the container | Command | What it does | |----------------------|------------------------------------------------| | `tavern status` | Show connected services | | `tavern chat "hi"` | Chat with your primary inference (streaming) | | `tavern models` | List available models | | `tavern search "q"` | Search via discovered SearXNG | | `tavern mcp` | List/call discovered MCP tools | | `tavern rediscover` | Re-scan for services | | `hermes` | The Hermes Agent CLI, pointed at your stack | | `ollama` | Manage basecamp's bundled Ollama | ## Layout ``` basecamp/ ├── Dockerfile # ubuntu:22.04 + Ollama + Hermes (official installer) ├── discover.py # network scan, connect screen, tavern generator ├── tavern.sh # static fallback CLI (no secrets) ├── tavern_mcp.py # MCP server: status/self-check/wire/rediscover/models/chat ├── recipes.py # per-service fix recipes (the fixer's knowledge base) ├── entrypoint.sh # boot: discover -> wire -> env-scoped hermes config ├── basecamp.sh # host-side launcher (docker only — never touches host config) ├── docker-compose.starter.yml # 10-service coding starter pack ├── SOUL.md # Basecamp Hermes identity + Fixer's Creed ├── dockroot/ # standalone "virtual docker root" MCP image └── supervisord.conf # Ollama only (hermes is exec'd, not supervised) ``` ## Credits Basecamp is a **packaging of [Hermes Agent](https://hermes-agent.nousresearch.com)** by [Nous Research](https://nousresearch.com) — all agent intelligence, tools, skills, and the gateway are theirs. Basecamp's only contribution is the box: the Docker packaging, the network auto-discovery, the safe env-scoped wiring, and the `tavern` toolkit. Full credit and gratitude to the Hermes team for building the agent that makes this project worth shipping. ## Development notes - Test discovery locally without touching anything: `BASECAMP_CONFIG=/tmp/bc.json BASECAMP_DISCOVERY=/tmp/bc-disc.json BASECAMP_ENV_FILE=/tmp/bc.env python3 discover.py serve` - `discover.py` is container-only by design. It writes only to paths given by `BASECAMP_CONFIG` / `BASECAMP_DISCOVERY` / `BASECAMP_ENV_FILE` (defaults are under `/root/.hermes` / `/opt/basecamp` inside the container). - If a secret ever leaks into this repo: rotate it, then scrub git history before publishing.