John Chaplin f1817fd560 Add macOS Apple Silicon Cookbook support
* Add Apple Silicon (Metal) GPU detection and unified-memory fit tuning

hardware.py detects Apple Silicon locally and over SSH, reporting
backend=metal, the chip name, and a RAM-scaled fraction of unified
memory as the usable GPU budget. fit.py gains an M1-M4 memory-bandwidth
table for realistic tok/s and drops vLLM-only formats (AWQ/GPTQ/FP8)
that can't be served on Metal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 32ac81dbc680361463a088dae867d555d5a79c3b)

* Generate macOS/Metal serve commands and surface the Metal GPU

cookbook_routes.py adds a macOS serve path (Ollama, Metal-aware
llama.cpp build using `sysctl hw.ncpu` instead of `nproc`, and a clear
error if vLLM is attempted). The frontend defaults Metal serving to
llama.cpp and offers llama.cpp/Ollama instead of vLLM/SGLang. The
odysseus-cookbook CLI's `gpus` command reports the Metal GPU via
sysctl/vm_stat.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 4ba01ce25d256ae032029898f361c824a34fcd4b)

* Add launchd LaunchAgent for macOS (systemd equivalent)

com.odysseus.ui.plist + install-service-macos.sh run Odysseus at login
and restart on crash, the macOS counterpart to odysseus-ui.service. The
installer auto-fills paths from the venv, so there's no hand-editing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 3d4b6b2c7b8b31af32201ed278115df9a559dea9)

* Document macOS install (brew, Ollama, AirPlay port, launchd)

README + setup.py cover the Homebrew / Apple Silicon path: brew install
python@3.11 tmux ollama, Metal serving via Ollama/llama.cpp, the launchd
service, and the macOS AirPlay Receiver conflict on ports 7000/5000.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 8dc9a3578a1726f070ed9f75c0958ae291a6d966)

* Add downloadable macOS launcher app builder

build-macos-app.sh generates dist/Odysseus.app and a drag-to-Applications
dist/Odysseus.dmg. The app starts the local server from this repo's venv and
opens the UI in a chrome-less app window (Chromium --app mode, falling back to
the default browser). It's a launcher wrapper — it drives the venv rather than
bundling Python — so the install path is baked in at build time.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 7927940c3810ee34640803b198d334a6ac93474d)

* Harden macOS Cookbook support: hide MLX, fix Metal build cache

Builds on the adopted PR #213 macOS/Metal work with two fixes and tests:

- fit.py: always drop MLX-quantized models. Odysseus only generates serve
  commands for llama.cpp/Ollama (Metal) and vLLM/SGLang (CUDA); MLX needs the
  mlx_lm runtime and the catalog's MLX repos ship no GGUF alternative, so they
  were surfaced on Apple Silicon but could never be served.
- cookbook_routes.py (macOS branch only): `rm -rf build` before configure so a
  poisoned CMakeCache from a prior failed CUDA attempt can't make every later
  build fail; explicit -DCMAKE_BUILD_TYPE=Release; a clear "brew install cmake"
  hint if cmake is missing. Linux/CUDA path unchanged.
- tests/test_hwfit_macos.py: MLX hidden on metal, MLX still hidden on CUDA
  (regression guard), Metal detection on Apple Silicon, and skipped on
  Linux/Intel (proves non-macOS detection is untouched).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Propagate unified_memory flag and document macOS GPU/Docker caveat

- hardware.py: detect_system now carries the unified_memory flag from GPU
  detection into the system dict (it was set by _detect_apple_silicon / AMD-APU
  detection but dropped during result assembly, so the API always reported
  null). Lets callers distinguish unified from discrete VRAM.
- README: prominent warning that Docker on Apple Silicon can't reach the Metal
  GPU (runs a Linux VM) — Cookbook must run natively for GPU serving; fix stale
  text that said Cookbook recommends MLX models (now hidden as unservable).
- test: detect_system propagates unified_memory.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Put Odysseus's venv bin on PATH for cookbook runners

Native (non-Docker) installs run from a virtualenv whose bin holds the `hf` CLI
and `python3` the cookbook download/serve tmux scripts shell out to. Those
scripts start in a fresh login shell with the venv NOT activated, so on a native
macOS install `hf download` failed with "hf: command not found" — and the
`pip --user` self-heal missed because macOS has no bare `pip` command.

- cookbook_helpers.py: _local_tooling_path_export() — pure helper returning a
  PATH export for the running interpreter's bin dir (escaped for double quotes).
- cookbook_routes.py: download + serve runners prepend that dir on local runs
  (gated off SSH/Windows); swap the `pip` install fallbacks to `python3 -m pip`.
- tests: helper output for normal and spaced paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Document macOS llama.cpp serving prerequisites

Clarify the two serving paths on Apple Silicon: the recommended zero-build
route (brew install llama.cpp ships a Metal llama-server Cookbook finds on PATH),
and the from-source fallback, which requires cmake + Xcode Command Line Tools.
Without those the build is skipped and serving silently degrades to a slow CPU
build, so new users now know to install them (or use the prebuilt) up front.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Recommend only GGUF-servable models on Metal

Apple Silicon's only serving engines are llama.cpp and Ollama, both GGUF-only
(vLLM/SGLang are CUDA/ROCm and don't run on macOS). The catalog tags raw
safetensors repos with a default Q4_K_M quant, so the fit-ranking was
recommending ~397/501 models that have no GGUF and fail to serve on Metal with
"No GGUF found" (e.g. microsoft/Phi-mini-MoE-instruct).

Drop any model without a real GGUF (is_gguf/gguf_sources) on Apple Silicon —
subsumes the previous AWQ/GPTQ/FP8 special-case into one rule. On CUDA these
stay visible since vLLM serves safetensors directly. Metal recommendations go
501 -> 104, all actually servable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Remove macOS launchd LaunchAgent (cherry-picked extra)

Drop the launchd service from the PR #213 cherry-picks: the
install-service-macos.sh installer, the com.odysseus.ui.plist template, and the
README section documenting them. Tangential to the core Cookbook/Metal support
and not wanted. The build-macos-app.sh launcher is kept.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Add one-command macOS quick start (start-macos.sh)

Running Odysseus natively on a Mac previously meant ~7 manual terminal steps
(brew deps, venv, activate, pip, setup.py, uvicorn with the right port) — not
friendly for a generic macOS user, and the native run is required because Docker
on macOS can't reach the Metal GPU.

- start-macos.sh: installs Homebrew deps (python@3.11, tmux, prebuilt Metal
  llama.cpp), creates the venv, installs requirements, runs setup, and launches
  on a non-AirPlay port (7860). Idempotent; re-run to start again.
- README: the Apple Silicon section now leads with this one-command quick start
  and the clickable .app, with engine/port/manual details folded into a
  collapsible block. Added a pointer at the top of the manual-install section.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* macOS quick start: auto-open browser when ready

The "open this URL" line scrolled out of view as uvicorn kept logging after it,
so users missed it. Now start-macos.sh waits (in the background) until the
server accepts connections, prints a boxed "ready" banner at that point (i.e.
after the startup burst, not before), and opens the URL in the default browser
automatically. Skippable with ODYSSEUS_NO_OPEN=1 for headless/SSH use.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Don't assume/force a specific Python version on macOS

The README claimed "system Python is 3.9" — a machine-specific generalization
that's often wrong (macOS ships no recent Python by default; many users already
have 3.11+). Make it generic, and make start-macos.sh detect an existing
Python 3.11+ and use it, only installing python@3.11 when none is found instead
of forcing it on top of the user's Python.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Align start-macos.sh venv path with build-macos-app.sh

start-macos.sh created the environment in .venv/, but build-macos-app.sh and
the manual install steps use venv/ — so the clickable .app wouldn't reuse the
quick-start's environment and would rebuild a second one. Use venv/ everywhere.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* README: state clearly that MLX is unsupported on Apple Silicon

Odysseus has no mlx_lm runtime; it serves GGUF (llama.cpp/Ollama) and CUDA
(vLLM/SGLang) only. MLX-only models can't run on a Mac and are hidden from
Cookbook — make that explicit in both the quick start and the details.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* start-macos.sh: build the venv with an arm64 Python on Apple Silicon

A clean-room run surfaced this: with a universal2/x86 Python (e.g. the
python.org installer under /usr/local), the venv's compiled extensions install
as arm64 but get loaded as x86_64 when launched from the .app bundle, so it
crashes with "incompatible architecture (have arm64, need x86_64)". The terminal
run happened to work only because a universal binary defaults to arm64 there.

On Apple Silicon, look only under /opt/homebrew (arm64-only) for the build
Python, and install Homebrew's python@3.11 if none is present — so the venv is
arm64-only and launches correctly from both the terminal and the .app. Intel
and non-mac paths are unchanged. Verified end-to-end in a clean clone: .app now
boots on Metal with no arch error.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Address dev-exp review: macOS setup robustness + doc/UX fixes

From the voltagent dev-exp review of the branch:
- README: fix broken anchor links (the em-dash heading produced a slug the links
  didn't match); simplify the heading to a stable slug.
- cookbook_routes.py: add /opt/homebrew/bin and /usr/local/bin to the serve PATH
  so a brew-installed llama-server/ollama is found instead of falling back to a
  slow source build.
- start-macos.sh: guard against an empty Python path; fail fast with a clear
  message on port-in-use; ERR trap with a "safe to re-run" message; show pip
  progress (drop --quiet on the slow requirements install); stop the background
  browser-opener cleanly on exit/Ctrl+C (no orphaned poller).
- setup.py: bind hint to 127.0.0.1; suppress the manual run-hint when launched
  by start-macos.sh (ODYSSEUS_SKIP_RUN_HINT) so the URL isn't contradictory.
- build-macos-app.sh: the .app only opens the browser once the server is
  actually ready (not after the readiness timeout).
- cookbookServe.js: drop "Diffusers" from the Metal backend picker —
  diffusion_server.py is CUDA-only, so it was an unservable option on macOS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: yunggilja <yunggilja@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 14:59:19 +09:00
2026-06-01 13:21:57 +09:00
2026-05-31 23:58:26 +09:00
2026-05-31 23:58:26 +09:00
2026-06-01 14:55:33 +09:00
2026-05-31 23:58:26 +09:00
2026-05-31 23:58:26 +09:00
2026-06-01 10:57:31 +09:00
2026-05-31 23:58:26 +09:00
2026-05-31 23:58:26 +09:00
2026-05-31 23:58:26 +09:00
2026-05-31 23:58:26 +09:00
2026-05-31 23:58:26 +09:00
2026-05-31 23:58:26 +09:00
2026-05-31 23:58:26 +09:00
2026-05-31 23:58:26 +09:00
2026-05-31 23:58:26 +09:00
2026-05-31 23:58:26 +09:00

Odysseus

─────────────────────────────────────────────── ⊹ ࣪ ˖ ૮( ˶ᵔ ᵕ ᵔ˶ )っ Odysseus vers. 1.0 ───────────────────────────────────────────────

Odysseus

A self-hosted AI workspace -- meant to be the self-hosted version of the UI experience you get from ChatGPT and Claude. But with more jank and fun. Running on your own hardware, with your own data -- local-first, privacy-first, and no trojan.

Features

  • Chat -- chat with any local model or API; adding them is super simple.
     vLLM · llama.cpp · Ollama · OpenRouter · OpenAI
  • Agent -- hand it tools and let it run the whole task itself.
     built on opencode · MCP · web · files · shell · skills · memory
  • Cookbook -- Scans your hardware, recommends models, click to download and serve.. easy!
     built on llmfit · VRAM-aware · GGUF / FP8 / AWQ · fit scoring · vLLM / llama.cpp serving
  • Deep Research -- multi-step runs that gather, read, and synthesize sources into a nice visual report.
     adapted from Tongyi DeepResearch
  • Compare -- a fun tool to compare models side by side. Test completely blind, no bias!
     multi-model · blind test · synthesis
  • Documents -- YOU write the text, AI is there to assist, not the opposite.
     multi-tab editor · markdown · HTML · CSV · syntax highlighting · AI edits · suggestions
  • Memory / Skills -- Persistent memory and skills, your agent evolves over time as it better understands you and your tasks!
     ChromaDB · fastembed (ONNX) · vector + keyword retrieval · import/export
  • Email -- IMAP/SMTP inbox with AI triage built in: urgency reminders, auto-tag, auto-summary, auto-reply drafts, auto-spam.
     IMAP · SMTP · per-account routing · CalDAV-aware
  • Notes & Tasks -- Quick notes with reminders, a todo list, and scheduled tasks the agent can act on.
     note pings · checklist · cron-style tasks · ntfy / browser / email channels
  • Calendar -- Local-first calendar with CalDAV sync to Radicale / Nextcloud / Apple / Fastmail.
     CalDAV pull · .ics import/export · per-calendar colors · agent-aware
  • Works on mobile -- looks and runs great on your phone, not just desktop.
     responsive · installable (PWA) · touch gestures
  • Extras -- more to explore, happy if you give it a go!
     image editor · theme editor · file uploads (vision + PDF) · web search · presets · sessions · 2FA

Demo

A full, hover-to-play tour lives on the landing page (docs/index.html). A few looks:

Chat & Agents

Chat & Agents

Deep Research

Deep Research

Compare

Compare

Documents

Documents

Notes & Tasks

Notes & Tasks

Quick Start

Defaults work out of the box — clone, run, configure inside the app. Open the Settings panel after first login to point Odysseus at your LLM server, search provider, email account, etc. Only touch .env if you need to override deployment-level things like AUTH_ENABLED, DATABASE_URL, or pre-seed ODYSSEUS_ADMIN_PASSWORD (otherwise an initial password is generated and printed on first boot).

Contributing? See CONTRIBUTING.md for setup, testing, and pull request guidelines.

git clone https://github.com/pewdiepie-archdaemon/odysseus.git
cd odysseus
cp .env.example .env       # optional, but recommended for explicit defaults
docker compose up -d --build

Compose starts Odysseus, ChromaDB, SearXNG, and ntfy. First run does a full image build. Open http://localhost:7000 after the containers are healthy. If port 7000 is already taken, set APP_PORT=7001 (or another free port) in .env, recreate the container, and open http://localhost:7001.

On Apple Silicon, Docker can't use the Metal GPU (it runs a Linux VM), so Cookbook will serve models on the CPU only. For GPU-accelerated Cookbook, run the app natively — see Apple Silicon.

Cookbook remote servers use an Odysseus-owned SSH key from ./data/ssh inside Docker. In Cookbook -> Settings -> Servers, generate/copy the public key and add it to the remote server's ~/.ssh/authorized_keys. After generating the key, you can also install it from the host with:

ssh-copy-id -i data/ssh/id_ed25519.pub user@server

Cookbook local downloads are stored in ./data/huggingface, mounted as ~/.cache/huggingface inside the Odysseus container. Cookbook-installed serve engines and Python CLIs are stored in ./data/local, mounted as ~/.local, so vLLM/llama.cpp installs survive container recreation.

After downloading a model, open Cookbook -> Serve, pick the cached model, and launch it. When the server answers /v1/models, Odysseus adds it to the chat model picker automatically. For NVIDIA / AMD GPUs in Docker, install the host runtime (NVIDIA Container Toolkit or ROCm drivers) and enable the matching overlay via COMPOSE_FILE in .env:

# NVIDIA
COMPOSE_FILE=docker-compose.yml:docker/gpu.nvidia.yml
# AMD ROCm
COMPOSE_FILE=docker-compose.yml:docker/gpu.amd.yml

Verify with docker compose exec odysseus nvidia-smi -L (or rocm-smi).

The default Docker image is intentionally slim. For Python-based serve engines, use Cookbook -> Dependencies to install vLLM, SGLang, llama-cpp-python, or diffusers into the persisted ./data/local mount. Native CUDA builds inside the container also require CUDA toolkit binaries such as nvcc; if those are not installed in the container, use prebuilt Python wheels or serve from a remote GPU host that already has the toolkit.

Useful checks:

docker compose ps
docker compose logs --tail=120 odysseus
docker compose logs odysseus | grep -E 'ChromaDB|MemoryVectorStore|DEGRADED'
docker compose exec odysseus python -c "from services.hwfit.models import get_models; print(len(get_models()))"

Expected vector-memory startup lines in Docker:

ChromaDB connected: chromadb:8000
MemoryVectorStore initialized

The Cookbook model catalog check should print a non-zero count. If it prints 0, rebuild the Odysseus image with docker compose build --no-cache odysseus.

Option 2: Manual install — Linux / macOS

Requirements: Python 3.11+. Cookbook also requires tmux for background model downloads and serves.

On macOS (Apple Silicon)? Skip the manual steps below — run ./start-macos.sh for a one-command setup. See Apple Silicon.

Install system packages first:

# Debian/Ubuntu
sudo apt install tmux

# Arch
sudo pacman -S tmux

# Fedora
sudo dnf install tmux

# macOS (Homebrew). macOS ships no recent Python by default — install 3.11+
# (skip the python line if you already have Python 3.11 or newer):
brew install python@3.11 tmux

Then install Odysseus:

git clone https://github.com/pewdiepie-archdaemon/odysseus.git
cd odysseus
python3 -m venv venv          # on macOS use: python3.11 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python setup.py            # creates data dirs and prints an initial admin password
python -m uvicorn app:app --host 0.0.0.0 --port 7000

Apple Silicon (M-series)

On a Mac, run Odysseus natively (not in Docker) so Cookbook can use the Metal GPU. Cookbook serves models on whatever machine Odysseus runs on, and Docker on macOS is a Linux VM with no access to the GPU — in a container your Mac looks like a CPU-only Linux box.

Quick start — one command. From a fresh clone:

git clone https://github.com/pewdiepie-archdaemon/odysseus.git
cd odysseus
./start-macos.sh

That installs what's needed via Homebrew (Python 3.11+, tmux, and a prebuilt Metal llama-server), sets everything up, and launches Odysseus at http://127.0.0.1:7860. Log in with the admin password it prints, open Cookbook, and it detects your GPU (backend: metal) and recommends GGUF models that fit your Mac. (MLX models aren't supported on macOS and are hidden — see below.) Re-run ./start-macos.sh any time to start it again (use another port with ODYSSEUS_PORT=7900 ./start-macos.sh).

Prefer a clickable app? After your first ./start-macos.sh, build a launcher Odysseus.app (+ a drag-to-Applications .dmg) that starts the server and opens the UI in its own window:

./build-macos-app.sh          # → dist/Odysseus.app and dist/Odysseus.dmg
What start-macos.sh does, serving engines, and manual steps

start-macos.sh is just the manual steps wrapped up: Homebrew deps → a Python venvpip install -r requirements.txtpython setup.pyuvicorn on a non-AirPlay port. Run them by hand if you prefer (the Linux steps above, but use python3.11 -m venv and --port 7860).

Serving engines on Metal — Cookbook only recommends models it can serve here:

  • llama.cppbrew install llama.cpp (done by start-macos.sh) provides a prebuilt Metal llama-server, no compile. Without it, Cookbook builds it from source on first serve, which needs cmake + Xcode Command Line Tools (brew install cmake && xcode-select --install).
  • Ollamabrew install ollama is another simple Metal-accelerated option.
  • vLLM/SGLang are CUDA/ROCm-only and do not run on macOS.

MLX models are not supported on Apple Silicon. Odysseus serves models via llama.cpp/Ollama (GGUF) and vLLM/SGLang (CUDA) — it has no MLX (mlx_lm) runtime. So MLX-only models can't be served on a Mac and are deliberately hidden from Cookbook's recommendations there; pick a GGUF build instead.

Port 7000 & AirPlay — macOS AirPlay Receiver holds ports 7000/5000, so start-macos.sh defaults to 7860. To use 7000, turn AirPlay Receiver off in System Settings → General → AirDrop & Handoff.

Build prerequisites baked in — the .app wraps this repo's venv (it doesn't bundle Python), so the path is fixed at build time — rebuild if you move the repo.

Option 3: Manual install — Windows (PowerShell)

Windows support is not actively tested. Use it with caution; Docker on Linux or a Linux/macOS manual install is the safer path for now.

git clone https://github.com/pewdiepie-archdaemon/odysseus.git
cd odysseus
python -m venv venv
venv\Scripts\Activate.ps1
pip install -r requirements.txt
python setup.py
python -m uvicorn app:app --host 0.0.0.0 --port 7000

Open http://localhost:7000, log in with the generated admin password, and configure everything else inside Settings.

Security Notes

Odysseus is a self-hosted workspace with powerful local tools: shell access, file uploads, model downloads, web research, email/calendar integrations, and API tokens. Treat it like an admin console.

  • Keep AUTH_ENABLED=true for any network-accessible deployment.
  • Do not expose it directly to the public internet without HTTPS and a trusted reverse proxy.
  • Keep data/, .env, logs, databases, and uploaded/generated media out of Git. They are ignored by default.
  • Review data/auth.json after first boot: disable open signup unless you intentionally want it, make only your own account admin, and keep demo/test accounts non-admin.
  • Non-admin users do not get shell/Python/file read/write by default, and admin-only routes/tools such as MCP management, API tokens, webhooks, model/cookbook serving, backup/vault, and app settings are admin-gated. Other features are controlled by per-user privileges, so review each user's privileges before exposing a deployment.
  • Rotate any API keys or tokens that were ever pasted into a shared chat, demo, screenshot, or log.
  • If you enable API tokens or webhooks, create separate tokens per integration and delete unused ones.
  • Prefer binding manual development runs to 127.0.0.1; bind to 0.0.0.0 only when you intentionally want LAN/reverse-proxy access.
  • Before publishing a fork, run git status --short and confirm no private files from .env, data/, logs/, uploads, backups, or local databases are staged.

Putting it behind HTTPS

Odysseus serves plain HTTP on its port. That's fine for localhost and trusted LAN/VPN use, but browsers will warn ("Password fields present on an insecure page") and the login + API tokens travel in cleartext. For anything reachable outside your machine — including a Tailscale IP shared with other devices — put a TLS-terminating reverse proxy in front.

Shortest path with Caddy (auto-renews Let's Encrypt certs):

odysseus.example.com {
  reverse_proxy localhost:7000
}

For a LAN-only Tailscale deployment, Caddy + tailscale-cert or the built-in MagicDNS HTTPS feature both work. nginx/Traefik configs are similar — proxy localhost:7000, terminate TLS at the proxy. Once that's in place, the browser warning goes away and your login is encrypted.

Contributing

Help is welcome. The best entry points are fresh-install testing, provider setup bugs, mobile/editor polish, docs, and small focused refactors. See ROADMAP.md for the current help-wanted list.

Configuration

Most setup is done inside the app with /setup or Settings. Use .env for deployment-level defaults and secrets you want present before first boot. Key settings:

Variable Default Description
LLM_HOST localhost Your LLM server (e.g. llm-host.local:8000)
LLM_HOSTS -- Comma-separated list for model discovery
OPENAI_API_KEY -- Optional OpenAI key. Prefer adding providers in the app unless pre-seeding.
SEARXNG_INSTANCE http://localhost:8080 SearXNG URL. Docker overrides this to http://searxng:8080.
SEARXNG_SECRET generated on first Docker boot Optional SearXNG cookie/CSRF secret. Leave blank unless you need to pin it.
AUTH_ENABLED true Enable/disable login
LOCALHOST_BYPASS false Development-only auth bypass for loopback requests. Keep false for shared/network deployments.
DATABASE_URL sqlite:///./data/app.db Database connection string
CHROMADB_HOST localhost ChromaDB host for vector memory. Docker overrides this to chromadb.
CHROMADB_PORT 8100 ChromaDB port for manual host runs. Docker overrides this to 8000.
EMBEDDING_URL -- OpenAI-compatible embeddings endpoint

Bundled services

Docker Compose includes these by default. The bundled service ports bind to 127.0.0.1 unless you opt in to a different bind address in .env, so they are reachable from the host machine but not from your LAN or the public internet by default:

  • ChromaDB → vector store for semantic memory. In Docker, Odysseus connects to chromadb:8000; from the host it is exposed as ${CHROMADB_BIND:-127.0.0.1}:8100.
  • SearXNG → meta search for web search. In Docker, Odysseus connects to searxng:8080; from the host it is exposed as 127.0.0.1:8080.
  • ntfy → local notification service, exposed as ${NTFY_BIND:-127.0.0.1}:8091.

Phone push notifications via ntfy: A phone cannot subscribe to 127.0.0.1 on your server. To expose ntfy safely without opening it on every interface:

  • Tailscale (recommended) — set NTFY_BIND=<tailscale-host-ip> and NTFY_BASE_URL=http://<tailscale-host-ip>:8091 in .env, recreate ntfy, then point the ntfy Android/iOS app at http://<tailscale-host-ip>:8091/<your-topic>.
  • Enable ntfy auth and bind to LAN — add NTFY_AUTH_FILE + NTFY_AUTH_DEFAULT_ACCESS=deny-all to the ntfy service, create a user with docker compose exec ntfy ntfy user add ..., then set NTFY_BIND to your LAN IP. See the ntfy docs.

Optional external services

Built-in MCP servers (optional setup)

Odysseus auto-registers a few built-in MCP servers at startup. The npx-based ones (currently the browser server, @playwright/mcp) only start when their npm package is already in the local npx cache. If a package isn't cached, that server is skipped with a startup log message explaining what to do, so a fresh install does not block on a multi-minute npm download or hang if Playwright system deps are missing.

To enable the browser MCP (page navigation, screenshots, vision), run once:

npx -y @playwright/mcp@latest --version

That installs @playwright/mcp plus Playwright (~300MB total). Restart Odysseus and the server will register at startup.

Ollama with Docker

If Odysseus is running in Docker and Ollama is running on the host, add the endpoint in Settings as:

http://host.docker.internal:11434/v1

The default Compose file already maps host.docker.internal on Linux. Ollama also needs to listen outside its own loopback interface:

OLLAMA_HOST=0.0.0.0:11434 ollama serve

For a systemd Ollama install, set that in the Ollama service override. If Odysseus can see Ollama but requests hang or fail, check that your host firewall allows Docker bridge traffic to port 11434.

First-token latency is usually Ollama/model/hardware, not Odysseus. To compare, test Ollama directly:

curl http://127.0.0.1:11434/v1/models

Architecture

app.py                   # FastAPI entry point
core/      auth, database, middleware, constants
src/       llm_core, agent_loop, agent_tools, chat_processor, search/
routes/    chat, session, document, memory, model … endpoints
services/  docs, memory, search, hwfit (Cookbook) …
static/    index.html + app.js + style.css + js/ (modular front-end)
docs/      landing page (index.html) + preview clips

Data

All user data lives in data/ (gitignored): app.db (sessions, messages, documents), memory.json, presets.json, uploads/, personal_docs/, chroma/, settings.json.

Star History

Star History Chart

License

MIT -- see LICENSE and ACKNOWLEDGMENTS.md.

                                  |
                                 |||
                                |||||
                  |    |    |   |||||||
                 )_)  )_)  )_)   ~|~
                )___))___))___)\  |
               )____)____)_____)\\|
             _____|____|____|_____\\\__
             \                       /
       ~^~^~~^~^~~^~^~~^~^~~^~^~~^~^~~^~^~~^~^~
               ~^~  all aboard!  ~^~
       ~^~^~~^~^~~^~^~~^~^~~^~^~~^~^~~^~^~~^~^~
Description
No description provided
Readme MIT 28 MiB
Languages
Python 44.7%
JavaScript 43.6%
CSS 9.3%
HTML 1.8%
Shell 0.5%