I've been running Odysseus as my daily-driver AI interface — local LLMs, document RAG, email triage, calendar sync. It's a web-based FastAPI app that works great in the browser, but I wanted a proper macOS app I could launch from my dock and distribute as a DMG.
So I built one. Here's what the app does and how I packaged it.
| Layer | Tool |
|---|---|
| Web framework | FastAPI (Python 3.11) |
| Frontend | Vanilla JS + CSS (PWA) |
| LLM providers | LM Studio, Ollama, DeepSeek, SiliconFlow, OpenAI, Anthropic |
| Vector store | ChromaDB + fastembed |
| Model serving | llama.cpp / vLLM |
| macOS app | Shell launcher + pywebview + DMG |
The base project already had a build-macos-app.sh
script, but I rewrote it to produce a proper .app
bundle and .dmg
that anyone can build:
./build-macos-app.sh
This creates two things:
1. dist/Odysseus.app — A macOS app bundle. The executable is a shell script that:
uvicorn app:app
)2. dist/Odysseus.dmg — A drag-to-Applications disk image for distribution.
The .app
is just a launcher — no embedded Python, no bundled binary. It drives the venv in the repo directory.
The key piece is scripts/app_window.py
, which uses pywebview to open the web UI in a native macOS window — no browser chrome, feels like a real app. If pywebview isn't available, it falls back to opening a chromeless Chromium window via --app=
.
Closing the window stops everything: the web server, ChromaDB, all child processes. The cleanup trap in the launcher script makes sure no stray Python processes are left behind.
Odysee/
├── app.py # FastAPI entry point
├── src/ # Core logic
│ ├── llm_core.py # Multi-provider LLM abstraction
│ ├── agent_loop.py # Agent execution loop
│ ├── chat_handler.py # Chat processing
│ ├── model_discovery.py # Auto-detect local models
│ └── mcp_manager.py # MCP server management
├── routes/ # API endpoints
├── services/ # Background services
├── static/ # Frontend (JS/CSS/HTML)
├── scripts/ # CLI tools + app_window.py
├── tests/ # ~350 tests
└── data/ # Created on first run
uvicorn app:app --host 127.0.0.1 --port 7860
The flask-style backend runs on localhost:7860. The frontend is vanilla JS with no build step — just open index.html
and it works.
git clone https://github.com/AlexDesign420/Odysee-MacOS-App.git
cd Odysee-MacOS-App
python3.11 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python setup.py
./venv/bin/uvicorn app:app --host 127.0.0.1 --port 7860
Open http://127.0.0.1:7860. First boot creates an admin account.
To build the macOS app:
./build-macos-app.sh
open dist/Odysseus.dmg
GitHub: AlexDesign420/Odysee-MacOS-App