Last updated: June 9, 2026
Local-first, until you connect a cloud model. FSR captured where the traffic actually went.
Tested on commit 573d431 (dev branch) · Scope: one-machine Docker test, source review, and packet capture. Not a long-term security audit.
Odysseus is a free, self-hosted AI workspace from the PewDiePie GitHub account. It runs as a Docker stack or a native macOS app, connects to local models through Ollama or to cloud providers such as OpenRouter, OpenAI, and Anthropic, and bundles chat, an agent with shell access, memory, document search, email, calendar, and image generation. The agent core is the open-source OpenCode project.
FSR verdict, in one sentence: Odysseus is worth testing if you are a technical user who can control the model path, tool permissions, and data directory; it is not a plug-and-play private ChatGPT replacement.
What FSR measured
| Test | Result |
|---|---|
| Local-model chat turn (Ollama) | No external network flow in the capture window |
| Cloud-model chat turn (OpenRouter) | One external flow; the only external TLS SNI was openrouter.ai |
| Default model on the first OpenRouter run | Auto-selected a tool-incompatible model; the agent returned a 404 |
What FSR did not prove: packet payload contents, long-term behavior, the native macOS install path, and whether every OpenRouter account hits the same 404. This is a single-machine test tied to one commit.
Odysseus is not private by default. It is private only along the paths you keep local.
Local model, cloud model, web search, remote SSH, and the agent’s tools do not share one boundary. You set privacy per path, not per product.
The receipt
The first failure came before the privacy test. FSR connected OpenRouter, left the model picker on its default, and sent one message. The agent answered with a 404:
OpenRouter returned 404 — check the base URL and model name. (No endpoints found that support tool use. Try disabling "bash". To learn more about provider routing, visit: https://openrouter.ai/docs/guides/routing/provider-selection)Run with that same default, Deep Research returned zero sources. Choosing a tool-capable model by hand fixed the next turn.
The setup fought back before that. Docker was not installed on the first attempt. Port 7000 answered with a 403 and a Server: AirTunes header, because macOS AirPlay Receiver had taken it; moving to port 7001 cleared it, after which the server answered with a 302 to /login. A temporary admin password printed to the setup log on first boot.
Those setup failures are the first buyer filter: this is a Docker system, not a consumer app. They are not the finding. The finding starts with the traffic capture.
- Briefing (June 2026)
- Review Tier and Scope
- TL;DR
- Keep It Local: Configure the Path, Not Just the Server
- At a Glance (labeled by evidence type)
- Local Path vs Cloud Path, and Alternatives
- Deep Dive: The Trust Boundary Moves With the Path
- Hardware: Free to Download Is Not Free to Run
- Use / Skip / Wait
- FAQ
- Methodology and Sources
- FSR Verdict
Briefing (June 2026)
What it is. A free, self-hosted AI workspace from the PewDiePie GitHub account, run as a Docker stack or a native macOS app. The agent core is the open-source OpenCode project. The Odysseus core is MIT licensed.
What FSR did. A focused hands-on test on one MacBook Pro (24GB, macOS Tahoe), on the dev branch at commit 573d43139914229f92e6c2f4951ec36cbdf77f55, with packet captures during local, cloud, and search turns, plus source inspection. This was not long-term operational use.
The finding that matters most. Privacy is path-dependent. In FSR’s capture, a local-model chat turn opened no external network flow. A cloud-model chat turn opened a flow whose only external SNI was openrouter.ai.
The bug most buyers will hit first. The source ships an empty default model. On provider setup, Odysseus auto-selects the first chat-capable model the provider returns. In FSR’s OpenRouter run that resolved to a content-safety classifier with no tool support, and the first agent message failed with a 404.
The useful part for buyers. The project’s own threat model is more candid than the marketing copy. It ships real defenses (role-based access, prompt-injection wrapping, security headers, TOTP two-factor authentication, reserved usernames, an admin-gated internal loopback) and states the two gaps a privacy buyer cares about: no filesystem sandbox and no network egress filtering, plus coarse token scopes.
One business diligence item. The core is MIT. An optional install path (INSTALL_OPTIONAL=true) pulls in PyMuPDF, which is AGPL-3.0. That is a deployment checkpoint for anyone building a service on top, not a violation.
Who it is for. Developers and home-lab users comfortable with Docker and local models. Not a turnkey private ChatGPT for non-technical buyers.
Review Tier and Scope
FSR ran Odysseus on one machine, inspected the source at a pinned commit, and captured network traffic during local, cloud, and search turns. This is a focused hands-on review, not long-term operational use.
FSR did not run Odysseus for 30 days, did not test on multiple machines or other operating systems, did not test the native macOS install path, did not inspect database contents, and did not verify payload-level data handling. The full testbed and the untested list are in the Methodology section. Security fixes for this project land on the default branch (dev) until formal releases, which is why FSR tested dev rather than a tagged release.
TL;DR
The buyer decision is simple, and it splits on one question: will you keep inference local?
- In FSR’s capture, a local-model chat turn opened no external network flow. A cloud-model chat turn opened one external flow; the only external SNI was
openrouter.ai. - On the Docker install, the agent shell does not get your host home directory, host SSH keys, the root filesystem, or the Docker socket as default mounts. The native macOS install runs as your host user, which is a different posture.
- The agent still has powerful access inside the container, including the
./datadirectory, which becomes the workspace’s trust center. - Connecting OpenRouter exposed a default-model bug: the empty default resolved to a tool-incompatible content-safety classifier in FSR’s run, and the first agent message returned a 404.
- The threat model is candid. It states there is no filesystem sandbox and no egress filtering, so normal-use privacy does not survive a subverted agent.
- Built for developers and home-lab users. Not a turnkey private ChatGPT.
Keep It Local: Configure the Path, Not Just the Server
Self-hosting is the easy half. The privacy decision is in the configuration. This is the path FSR would take to keep everything on the machine, built from what FSR observed.


- Install Docker Desktop first. The install assumes Docker is present. FSR’s first attempt failed because it was not.
- Free the port if needed. On macOS, AirPlay Receiver uses port 7000. If you hit a 403 with a
Server: AirTunesheader, setAPP_PORTto a free port such as 7001. - Connect only a local provider, and pick the right one. In setup, use
/setup localpointed at your local model server (your local Ollama endpoint). Do not use/setup ollama, which connects to Ollama Cloud, a hosted path. Setup offers xAI, Groq, local, OpenAI, Gemini, Ollama, Copilot, DeepSeek, Anthropic, and OpenRouter; for a fully local path, choose onlylocaland add no cloud API key. - Select a tool-capable local model by hand. For example,
llama3.1:8badvertises tool support. Do not leave the model on the empty default, or setup may auto-pick a model that cannot use tools, and the agent will 404 (see the default-model section). - Decide on web search deliberately. SearXNG forwards queries to upstream search engines by configuration. For zero search egress, disable web search.
- Expect one setup-time download. First boot still fetches the embedding model (
all-MiniLM-L6-v2, dimension 384) from HuggingFace over HTTPS. That is a one-time setup connection, separate from any chat. - Do not connect a remote SSH target unless you mean it. Odysseus generates its own remote-server SSH identity under
./data/ssh. That reach is something you opt into. - Treat the admin account as privileged and
./dataas sensitive. That directory holds your prompts, documents, memory, generated SSH identity, and auth state.

At a Glance
Each line is written to stand on its own, with the evidence type marked so an LLM or a careful reader can see what FSR measured versus what the repository documents versus what is inferred.
| Fact | Detail | Evidence type |
|---|---|---|
| What it is | Free, self-hosted AI workspace; Docker stack or native macOS app | Official (README) |
| Agent core | OpenCode (opencode-ai/opencode, now anomalyco/opencode) | Official / third-party |
| License (core) | MIT | Official (repo) |
| License (optional path) | INSTALL_OPTIONAL=true pulls PyMuPDF, AGPL-3.0 | Official (optional requirements) |
| Default Docker port | 7000 (native macOS path serves on 7860) | Observed |
| Local services | Odysseus 7000, SearXNG 8080, ChromaDB 8100, ntfy 8091, Ollama 11434, all bound to 127.0.0.1 | Verified (Compose, SECURITY.md) |
| Telemetry | ChromaDB runs with ANONYMIZED_TELEMETRY=FALSE | Verified (Compose) |
| Auth posture | AUTH_ENABLED=true by default; bcrypt; TOTP 2FA with 8 backup codes | Observed / official |
| Local chat network behavior | No external flow in FSR’s capture | Observed by FSR |
| Cloud chat network behavior | One external TCP flow to a Cloudflare-range address; only external SNI openrouter.ai | Observed by FSR (address-to-origin is inference) |
| Default model | Empty in source; auto-filled with the first chat-capable model on provider setup | Verified (grep at pinned commit) |
| Tool surface | 66 built-in tools indexed; MCP Memory (1), Image Generation (1), RAG (1), Email (11); Browser MCP off by default | Observed by FSR |
| Stars | Tens of thousands of GitHub stars; FSR’s snapshot was in the 50,000-60,000 range in early June 2026, and the count moves | Observed by FSR (June 2026) |
| Created | 2026-05-31 | Official |
| Releases / branch | Fixes land on dev until formal releases | Official (as of June 2026) |
Full Comparison
The real comparison is Odysseus against itself
Most reviews compare Odysseus to a rival. The more useful comparison is between its own two inference paths, because that is where privacy is decided.

| Dimension | Local path (Ollama) | Cloud path (e.g. OpenRouter) |
|---|---|---|
| Where inference runs | On your machine, via Ollama on 11434 | On the provider’s servers |
| External network flow in FSR’s capture | None observed (loopback only) | One external TCP flow; only external SNI was openrouter.ai |
| What leaves the machine during use | Nothing observed in the capture window | The model request is routed to the cloud provider |
| Speed in FSR’s single run | ~28.3 tok/s (llama3.1:8b, 163 tokens in 5.75s) | ~30.35 tok/s (gpt-4o-mini) |
| Observed cost of one short turn | Electricity plus hardware you already own | Displayed cost ~$0.0001 for one short gpt-4o-mini message (single run) |
| Tool support | Depends on the model; llama3.1:8b advertises tools | Depends on the model; the capability-unaware default can pick a tool-incompatible model and 404 |
| First-boot caveat | One-time HuggingFace embedding download still happens | Same one-time download |
Measurements are n=1 on one machine. FSR did not verify payload-level data handling. The Cloudflare-range address matched the openrouter.ai SNI in the same capture and is not confirmed as OpenRouter’s origin.
Alternatives, by decision axis (not by feature count)

A feature checklist is the wrong way to choose here. The decision is about trust boundary, team readiness, document handling, and maintenance load. The framing below is FSR’s read for buyer decisions; FSR did not benchmark these alternatives, so treat their maturity, RAG, and track-record positioning as orientation to confirm against each project’s own docs, not as tested findings.
| Tool | Pick it if you need | Reconsider if you need | Note |
|---|---|---|---|
| Odysseus | One bundled local control plane (agent, memory, email, calendar, deep research, model serving) | Mature team governance, audit logs, SSO | Distinct claim is integration breadth, not stability or RAG |
| Open WebUI | A more mature, multi-user chat UI | An all-in-one agent / email / calendar stack | Chat-UI focus, not an agent stack |
| AnythingLLM | Stronger document RAG | A broad agent control plane | Document-first, not a full agent suite |
| OpenClaw | A similar local-execution surface (closest comparison) | A more proven track record | Shown beside OpenCode on Ollama’s Launch page; track record unverified |
Deep Dive: The Trust Boundary Moves With the Path
The asymmetry that decides everything
“It runs on your machine, so it is private” is the claim this review takes apart, without turning into an attack on the product.
Here is the precise shape. FSR measured the normal-use floor: with a local model, a chat turn sent nothing externally. No external TCP destination, no external QUIC, no external TLS SNI, only loopback. That is real, and it is to the project’s credit.
The threat model states the ceiling, in writing. There is no filesystem sandbox for the shell path. There is no network egress filtering. So while normal local use stays local, nothing in the design stops a prompt-injected agent in a shell-enabled admin session from making outbound requests. The project files this under its own known gaps and points at a sandbox proposal (Issue #1058).
“Sends nothing in normal use” and “nothing prevents exfiltration if subverted” are both true at once. That layering is not a contradiction; it is the review. Privacy here is not a property of the container. It is a property of four things you connect: the model endpoint, the search provider, any remote SSH target, and which privileged tools the agent can run.
A trust-boundary map
| Path or component | Stays local? | Can leave the machine? | FSR tested? |
|---|---|---|---|
| Local model (Ollama) | Yes, in the capture | No external flow observed | Yes |
| Cloud model (OpenRouter, etc.) | No | Yes, the request goes to the provider | Yes |
| Web search (SearXNG) | The proxy is local | Yes, it forwards to upstream engines | Partially (no new flow in the window; not conclusive) |
| First-boot embedding download | No | Yes, HuggingFace over HTTPS, one time | Yes (observed) |
| Agent shell and file tools | Within the container on Docker | No egress filter, so a subverted agent could send out | Boundary inspected; exploitation not tested |
| Remote SSH target | Not applicable | Yes, if you connect one | No (untested) |
./data directory | Local | Only if something sends it | Inventoried; contents not inspected |
The Docker boundary is real, and narrower than non-technical readers may assume
Some launch coverage framed the agent as able to run code on the user’s PC and reach personal files. That is true for the native path. It is not true for the Docker path FSR tested, and the two are different security postures.
On the Docker path, the Compose file bind-mounts only these into the container: ./data to /app/data, ./logs to /app/logs, ./data/ssh to /app/.ssh, ./data/huggingface to /app/.cache/huggingface, and ./data/local to /app/.local. A targeted search of the Compose file for the Docker socket, the host HOME, /Users, and /home returns nothing. The default Compose file does not list mounts for your host home directory, your host SSH keys, the root filesystem, or the Docker socket.
That /app/.ssh path is not your personal SSH directory. It is a generated remote-server identity; the Compose comment tells you to add the shown public key to each remote server’s authorized_keys. Whether the agent can actually use that identity against a remote is something FSR did not test.
The boundary is a filesystem boundary, not a sandbox. Inside it, the agent’s shell still sees the full container filesystem, the container environment, the Docker network, and host.docker.internal (Compose adds a host-gateway entry so the container can reach host-local services such as Ollama on 11434). Filesystem isolation is not network isolation.
The native macOS path is different by design. ./start-macos.sh serves on 7860 and runs without a container, so on that path the shell runs as your host user with host filesystem access. The install method you pick is the boundary decision. FSR will not claim a Docker socket escape is impossible; the default Compose does not mount the socket, which is what FSR can show, not a proof of escape resistance.
The default-model 404, traced through the code

Asked to run bash a tool capable model lists Odysseuss data directory appdb authjson sessionsjson ssh personal docs and more On Docker this directory is the workspaces trust center separate from your host files
This is the part no coverage FSR saw has reached, and it is the part most buyers will hit first.
The source ships an empty default. src/settings.py:122 sets default_model to "", and line 127 sets default_model_fallbacks to []. The .env.example file has no chat-model default; it only carries commented embedding settings.
On provider setup, the app fills that blank in. routes/model_routes.py:1615 sets default_model = _first_chat_model(model_ids) or "", in other words the first chat-capable model the provider returns. “First chat model” resolves to the first non-embedding, non-text-to-speech model, falling back to models[0] (src/endpoint_resolver.py:31-35, with the same pattern in routes/research_routes.py:33-37 and line 597). The regression test tests/test_review_regressions.py:537 documents the behavior in one line: when the default is empty, the system picks the first visible model.
At runtime in FSR’s OpenRouter session, that resolved to nvidia/nemotron-3.5-content-safety:free, recorded at data/settings.json:48. This model is not hard-coded anywhere in the source; a grep finds the name only in a model catalog, a pricing table, and an icon map. The selection happened because the auto-picker took the first chat-capable model in the provider’s list, and that model was a content-safety classifier with no tool support.
The agent then asked to use a tool, and OpenRouter returned the 404 you saw in the opening. Deep Research, run with that same default, returned zero sources. Selecting a tool-capable model by hand fixed chat immediately.

So the accurate sentence is narrow: Odysseus did not ship that content-safety model as a hard-coded default. The bug is structural. An empty default plus capability-unaware first-model selection, run over a provider catalog that changes, can pick a model that looks chat-capable but cannot run the agent workflow. A new user may think they connected a provider correctly and still fail on the first useful turn. Because the catalog moves, FSR does not claim every OpenRouter account hits this same model; the pattern is the point, not the specific classifier.
Egress, at the flow level
FSR did not read packet contents. The method was a capture container sharing the target’s network namespace, with tshark filtering SYN-only on ip.dst and ipv6.dst plus udp.port==443 for QUIC. Capture sizes were 171, 158, and 180 packets for the local, cloud, and search turns. FSR did not verify payload-level data handling.
What that capture showed:
- Local model chat (Ollama via
host.docker.internal): no external TCP destination, no external QUIC, no external TLS SNI. Only loopback. No external flow. - Cloud model chat (OpenRouter): one external TCP flow to
104.18.2.115, no external QUIC, and the only external TLS SNI wasopenrouter.ai. The address is inside Cloudflare’s 104.18.0.0/15 range. FSR presents this as a Cloudflare-range address matching theopenrouter.aiSNI in the same capture, consistent with OpenRouter being fronted by Cloudflare, not as OpenRouter’s confirmed origin server. - Search (SearXNG): no new external flow during the window. That does not prove search stays local. Reuse and caching cannot be excluded, and SearXNG forwards to upstream engines by configuration. FSR will not claim SearXNG never egresses; the window simply did not show a new flow.
- First boot: the container fetched its embedding model (
all-MiniLM-L6-v2) fromhuggingface.coover HTTPS. That is a setup-time connection, separate from any chat.
The measurement and the threat model’s admission do not conflict. FSR measured the normal-use floor and found local chat stayed local. The project states there is no egress filtering to stop a subverted agent. Together they are the seam.
The security posture, defense by defense
A fair audit credits the defenses that are present. This project ships several, and the threat model is more candid than most commercial security pages.
| Defense | Source | What it means for buyers | Remaining gap |
|---|---|---|---|
| Role-based access (admin vs non-admin) | THREAT_MODEL + code (core/auth.py, src/tool_security.py) | Non-admins cannot run shell, file, email, or MCP tools | The admin session is powerful by design |
| Auth on by default, bcrypt, TOTP 2FA | SECURITY.md + code | Login required; two-factor available | None noted here |
| Prompt-injection wrapping | src/prompt_security.py | Untrusted content (web, emails, memories, tool output) is tagged as data | Not a guarantee against every injection |
| Security headers (CSP, X-Frame-Options, nosniff, no-referrer) | code | Standard web hardening present | style-src 'unsafe-inline' kept on purpose |
| Reserved usernames + admin-gated internal loopback | core/auth.py, core/middleware.py | A non-admin agent session cannot invoke admin tools | Relies on a magic-string check, a code-quality signal |
| No filesystem sandbox | THREAT_MODEL (own admission) | Agent shell runs as the app user | Issue #1058 (open) |
| No network egress filtering | THREAT_MODEL (own admission) | Normal-use privacy is not compromise resistance | No control to stop a subverted agent |
| Coarse token scopes | THREAT_MODEL | Companion and mobile tokens are chat or admin only | No per-capability granularity |
The internal-tool detail deserves precision, because it is a fragile pattern rather than an open hole. The require_admin check grants admin to any request whose user is internal-tool (core/middleware.py). The safety relies on a reserved-username guard: core/auth.py:RESERVED_USERNAMES blocks creation of internal-tool, api, demo, and system. The internal loopback token is secrets.token_hex(32) and is not persisted, and tool dispatch first checks owner_is_admin_or_single_user. The criticism is “magic-string design,” not “anyone can become admin.”
The patch-status ledger
FSR did not discover the issues below. Independent researchers reported them, and FSR is tracking their public status. Patch status moves, so reconfirm before any sensitive deployment.
| Issue / PR | What | Reported status |
|---|---|---|
| Issue #132 (independent researcher) | Broken access control plus SSRF / exfiltration risk | Reported, closed |
| PR #1039 | SSRF via the /api/v1/chat base_url parameter | Reported as addressed in the repo; FSR did not confirm the exact resolving PR |
| Issue #1058 | Shell / filesystem sandbox proposal | Open |
| RCE (independent researcher) | Demonstrated 1-click RCE chaining CSRF and command injection to add a backdoored admin account | Reported and demonstrated; hardening reported; a researcher write-up, not an FSR finding |
FSR is evaluating documented behavior, not labels applied to the codebase. he access-control report is public at GitHub issue #132 and the researcher’s blog; the RCE write-up is on X and a separate researcher’s site.
The licensing item: narrow, optional, still worth checking
The Odysseus core is MIT, which is permissive and low-friction. The catch is optional. Enabling the optional install path through the Docker build argument INSTALL_OPTIONAL=true pulls in PyMuPDF, which is AGPL-3.0. AGPL can create network-copyleft obligations when you redistribute the software or offer it to others over a network.
FSR is not calling this a violation, and it is not one on its face. It is a licensing diligence item: if you intend to build a product or internal platform on Odysseus, the AGPL dependency on that optional path is something to confirm and run past legal before you ship. This brief treats the dependency as documented in the project’s optional requirements; reconfirm which optional features pull PyMuPDF versus other extractors, and reconfirm the AGPL terms, against the current requirements at publish. PyMuPDF is dual-licensed (AGPL plus commercial), which is the structure that makes the check matter.
The data directory is the trust center
Even with the host boundary holding on Docker, the workspace’s own data directory is sensitive. An ls -la showed app.db (~548KB), auth.json (151B), ssh/, memory.json (2B), scheduled_emails.db (~90KB), personal_docs/, personal_uploads/, uploads/, generated_images/, tts_cache/, presets.json, rag/, memory_vectors/, deep_research/, fastembed_cache/, chroma/, huggingface/, local/, and mail-attachments/.
The Docker boundary protects your host home directory by default. It does not make ./data unimportant. That directory is where prompts, documents, memory, the generated SSH identity, and auth state live. If you would lock down a folder, lock down that one. A timing note: an early ls -la snapshot showed auth.json but not sessions.json; a later in-session listing (the bash output shown in this review) showed both sessions.json and settings.json present, consistent with the threat model’s seven-day session tokens being written to data/sessions.json on login. The directory fills out as you use it.
That local footprint is a pattern worth watching across agent tools. FSR found a close cousin in Grok Build CLI, xAI’s terminal agent, which stores its OAuth token and session under ~/.grok/: a single local directory holding your auth and session, with an agent operating over it, is the surface to lock down first.
The first run also seeded a task scheduler with email housekeeping jobs (summarize emails, draft replies, extract events, check urgency). That is convenient, and a reminder that this workspace is built to act, not only to answer.
Hardware: Free to Download Is Not Free to Run
These are the numbers FSR observed on one 24GB Mac, single run, so read them as a sample, not a benchmark.
- Container working set: about 1GB (shown as 1.07GB of a 7.57GB allocation in Docker Desktop).
- Docker Desktop VM reservation: about 7.5GB.
- Docker process host memory (Activity Monitor): about 7.26GB.
- Ollama model on disk: about 4.9GB to 5GB for
llama3.1:8b(Q4_K_M). - Local inference: about 28.3 tok/s (163 tokens in 5.75s).
- A cloud turn with
gpt-4o-mini: about 30.35 tok/s, displayed cost about $0.0001 for a short message.
Three numbers that are easy to confuse, kept separate on purpose: the container working set is not the Docker VM reservation; the Docker process memory is not the model weight size; and the Ollama model size is not the full cost of running local AI. The recurring cost is whatever local model your hardware can run well enough to replace cloud inference, plus the disk those models consume. The sticker and the real bill rarely match in AI tooling, in either direction. A $99 agent can become an $827 stack, which is what FSR found in the Ahrefs Agent A review; here the sticker is $0 and the bill is hardware. Downloaded models persist across container rebuilds in ./data/huggingface and ./data/local, and each can be tens of gigabytes, so a few of them fill a drive fast.
The buyer cost question is not the creator’s rig. Coverage describes PewDiePie’s demonstration setup as a high-end multi-GPU build, which is beside the point. The question is what runs acceptably on the machine you already own.
Use / Skip / Wait
Use it if you want one self-hosted workspace, you will run a tool-capable model (a local model such as llama3.1:8b, or a tool-supporting cloud model), you treat the admin account as privileged, and you are comfortable with Docker.
Skip it if you want turnkey privacy with zero configuration; you expect “local” to mean “no data leaves” while using cloud models; you need enterprise SSO, audit logging, or multi-tenant support; or your machine is weak and you would lean on cloud APIs, in which case the privacy premise is gone.
Wait if you intend to use it for sensitive or production data. Wait until the open sandbox gap (#1058) is closed and the access-control, SSRF, and RCE history is confirmed resolved, or until you can isolate it like an admin console and accept the current limits.
• Comfortable with Docker and willing to run a local model?
› No → Skip or wait.
› Yes → Will you keep inference local (no cloud key)?
• Yes → Use. Set a tool-capable local model explicitly; disable web search for zero search egress.
• No, you will use cloud models → Use, but drop the privacy premise. Treat it as a self-hosted front end to third-party models.
• Sensitive or production data? → Wait. Confirm #1058 and the access-control / SSRF / RCE history as resolved, or isolate and accept the risk.
FAQ
Is Odysseus private? Partly, and only along the paths you keep local. In FSR’s packet capture, a local-model chat turn (Ollama) opened no external network flow. A cloud-model chat turn (OpenRouter) routed the request to a third party. The project’s threat model also states there is no egress filtering, so a subverted agent could send data out. FSR did not verify payload-level data handling.
Does Odysseus send my prompts to OpenRouter, OpenAI, or Anthropic? Only if you connect those providers and select one of their models. In that path, the model request leaves your machine for the provider you chose; FSR observed a cloud-model turn opening one external flow with the SNI openrouter.ai. If you connect only a local provider through Ollama, FSR observed no external flow during a chat turn. Web search is a separate path that still reaches upstream engines.
Can the Odysseus agent reach my host files? On the Docker install FSR tested, no. The Compose file does not mount your host home directory, host ~/.ssh, the root filesystem, or the Docker socket. The agent shell still sees the full container filesystem, the Docker network, and host-exposed services. The ./data/ssh directory is a generated remote-server identity, not your host keys. The native macOS install is different: it runs as your host user with host filesystem access.
Is the Docker install safer than the native install? For the host-filesystem boundary, yes, in FSR’s reading. Docker keeps the agent inside a container that does not mount your host home, SSH keys, root filesystem, or Docker socket by default. The native macOS path runs outside that container, as your host user, on port 7860. If your priority is keeping the agent away from your personal files, the Docker path is the safer default. Neither path adds a shell sandbox or egress filtering.
Is Odysseus safe for business data? Not for sensitive production data yet, unless you isolate it like an admin console and accept the current limits. FSR will not label it safe or unsafe. The threat model documents real defenses (role-based access, two-factor authentication, prompt-injection wrapping) and admits real gaps (no filesystem sandbox, no egress filtering, coarse chat-or-admin token scopes). FSR found no official docs for enterprise SSO, audit logging, or multi-tenant use; researchers have reported access-control, SSRF, and RCE issues. Confirm patch status first.
What does the AGPL optional dependency mean? The Odysseus core is MIT licensed. Enabling the optional install path through the Docker build argument INSTALL_OPTIONAL=true pulls in PyMuPDF, which is AGPL-3.0. AGPL can create network-copyleft obligations if you redistribute the software or offer it as a service. This is a deployment diligence item for business use, not a violation. Confirm the dependency and seek legal review before commercial deployment.
What is the best alternative if I need team-ready local AI? Coverage describes Open WebUI as the more mature, multi-user option, and AnythingLLM as stronger for document RAG; OpenClaw is the closest comparison by local-execution surface. Odysseus leads on integration breadth, bundling agent, memory, email, calendar, deep research, and model serving in one local stack, not on stability or governance. For a team that needs audit logs and SSO, none of these is a drop-in enterprise answer yet. Verify positioning against each project’s docs.
What should I disable for a fully local path? Use /setup local pointed at your local model server (your local Ollama endpoint), not /setup ollama, which is Ollama Cloud, and add no cloud API key, so no model request leaves the machine. Set a tool-capable local model explicitly to avoid the empty-default 404. Disable web search, since SearXNG forwards to upstream engines and is the remaining egress path during normal use. Note that first boot still downloads the embedding model from HuggingFace once. Do not connect a remote SSH target unless you intend that reach.
Methodology and Sources
Testbed. One MacBook Pro, 24GB RAM, macOS Tahoe, Safari. Odysseus repo github.com/pewdiepie-archdaemon/odysseus, dev branch, commit 573d43139914229f92e6c2f4951ec36cbdf77f55. The docker-compose.yml was pinned by SHA-256 34087e0c82492e795fdb146ae38816c63183892227241d54a25f537f9f529650. Built image odysseus-odysseus:latest on base python:3.12-slim. Supporting images: chromadb/chroma:latest, binwiederhier/ntfy, and searxng/searxng:2026.5.31-7159b8aed (pinned, not :latest, because the :latest tag crashed on boot, issue #1414). Docker Desktop 4.76.0 (228118), Ollama 0.30.6, and llama3.1:8b (Q4_K_M, about 4.9GB, capabilities completion plus tools).
Network capture method. A capture container shared the target’s network namespace. tshark filtered SYN-only on ip.dst and ipv6.dst plus udp.port==443 for QUIC. Capture sizes were 171 packets (local), 158 (cloud), and 180 (search). FSR did not verify payload-level data handling.
Source verification. Code claims were checked by grep at the pinned commit and cited by file path and line. Security and threat-model claims were read from THREAT_MODEL.md and SECURITY.md on dev.
What was not tested.
- Payload contents of any request.
- Whether SearXNG egresses during normal use beyond the capture window; reuse and caching could not be excluded.
- The contents of
app.dbandscheduled_emails.db. - Whether the agent can use the generated SSH identity against a remote server.
- Whether every OpenRouter account hits the same 404; the catalog is volatile and the default selection is capability-unaware.
- Long-term behavior and live prompt-injection exploitation.
- Multiple machines, other operating systems, and the native macOS install path.
Source hierarchy. Highest weight: FSR’s hands-on observation and the project’s primary documents (repo, Compose file, THREAT_MODEL.md, SECURITY.md, source files by path and line). Third-party: researcher write-ups (one researcher’s RCE write-up on X and their site; another’s access-control report at issue #132 and their blog) and general security coverage. Star count, the demonstration-rig figures, the exact resolving PR for the SSRF fix, and some positioning claims are flagged for verification.
Validity window. This review is tied to one commit, one machine, and one capture method. Later branch changes to default-model selection, the Compose mounts, SECURITY.md, or THREAT_MODEL.md can invalidate specific findings. Where a finding could move, the article says so.
Masking. No password value, host machine name, OS username, API key, or personal tab content is reproduced. A temporary admin password prints to the setup log on first boot; FSR notes that it prints and does not show a value.
FSR Verdict (Tier B)
Odysseus is a real local-AI control plane for people who can operate it. The local path works and stayed local in FSR’s capture. The host-filesystem boundary on Docker is better than the early coverage suggested, and the threat model is more candid than most commercial security pages. Those things deserve credit.
The buyer risk is the gap between “self-hosted” and what it guarantees. Owning the software is not owning the outcome, the same split FSR found in the Base44 review: you own the code, not the runtime. The privacy guarantee only holds when you keep inference local, set a tool-capable model so the agent does not 404 on first run, understand that the agent’s reach is admin-like, treat ./data as sensitive, and accept that web search still touches upstream engines. Connect a cloud provider and the request leaves your machine; that is measured, not theoretical.
For a developer or home-lab user who wants one bundled stack and will run it deliberately, it earns a place to test. For anyone expecting a five-minute private ChatGPT, the answer is skip. For sensitive or production data, the answer is wait, until the sandbox gap and the reported vulnerabilities are confirmed resolved or the deployment is isolated and risk-accepted. The candid threat model is why FSR can recommend it to the first group with a straight face, and why FSR tells the others to hold.
This article is tied to commit 573d431 on the dev branch, tested June 9, 2026. The repository moves quickly; the Methodology section lists what could invalidate specific findings.