cd /news/ai-tools/i-built-a-self-hosted-ai-workspace-f… · home topics ai-tools article
[ARTICLE · art-22542] src=dev.to pub= topic=ai-tools verified=true sentiment=↑ positive

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

A developer built Odysee, a self-hosted AI workspace for macOS that packages a FastAPI-based local LLM interface into a native macOS app bundle and DMG. The app supports multiple LLM providers including LM Studio, Ollama, and OpenAI, along with document RAG, email triage, and calendar sync features. Odysee uses pywebview to display the web UI in a native macOS window and includes a cleanup mechanism that terminates all child processes when the window closes.

read2 min publishedJun 5, 2026

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

── more in #ai-tools 4 stories · sorted by recency
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/i-built-a-self-hoste…] indexed:0 read:2min 2026-06-05 ·