DEV Community

Cover image for I built a self-hosted AI workspace for macOS — meet Odysee
AlexDesign420
AlexDesign420

Posted on

I built a self-hosted AI workspace for macOS — meet Odysee

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.

What it does

  • 💬 Multi-Provider Chat — LM Studio, Ollama, DeepSeek, SiliconFlow, Anthropic, OpenAI
  • 🤖 AI Agents — Custom assistants with MCP tools, web browsing, shell access
  • 📄 Document RAG — PDFs, Office files, Markdown with full-text + vector search
  • 📧 Email Client — IMAP/SMTP with AI triage
  • 📅 Calendar — CalDAV sync (Nextcloud, Apple, Fastmail)
  • 🍳 Cookbook — Download and serve models via llama.cpp / vLLM
  • 🔬 Deep Research — Multi-step source synthesis
  • 🧠 Memory & Skills — Persistent vector memory, your agent learns over time

Tech Stack

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

How I turned it into a macOS app

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
Enter fullscreen mode Exit fullscreen mode

This creates two things:

1. dist/Odysseus.app — A macOS app bundle. The executable is a shell script that:

  • Starts the Python backend (uvicorn app:app)
  • Launches ChromaDB for vector search
  • Opens the UI in a chromeless window (via pywebview, or falls back to Chromium)
  • Cleans up all services when you close the window

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 app window wrapper

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.

Architecture

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
Enter fullscreen mode Exit fullscreen mode

The flask-style backend runs on localhost:7860. The frontend is vanilla JS with no build step — just open index.html and it works.

Quick Start

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

GitHub: AlexDesign420/Odysee-MacOS-App

Top comments (0)