Odysseus × crabbox × islo.dev

Run a self-hosted AI workspace on a throwaway cloud box in one command — and let its agent run code on throwaway boxes too. Same crabbox binary, same islo.dev fabric, both directions: sandbox the app, and sandbox the agent. No local install, nothing left behind.

● live · verified Jun 2026 PR #1 zozo123/odysseus upstream openclaw/crabbox islo.dev

What this is

Odysseus is a self-hosted, local-first AI workspace — chat, agents, deep research, a model cookbook, email, calendar, notes. Trying it normally means clone, venv, pip install, python setup.py, boot uvicorn — on your machine.

This fork adds one filecrabbox.sh — that does all of it on a remote islo.dev microVM instead, and throws the box away when you're done. crabbox is the ephemeral "warm a box, sync the diff, run the suite" path; the islo.dev CLI is the persistent "click the live app" path. App code is untouched.

# no local install — just an islo.dev key
git clone https://github.com/zozo123/odysseus.git && cd odysseus
export ISLO_API_KEY=$(cat islo.key)

./crabbox.sh serve   # boot Odysseus → public URL you can click
./crabbox.sh test    # warm a box, run the suite, tear down
./crabbox.sh shell   # interactive shell on the box

It runs both directions

The fork wires crabbox into Odysseus twice, in opposite directions — same binary, same islo.dev fabric:

outer · crabbox.sh you ──▶ crabbox ──▶ islo box runs Odysseus # sandbox the app inner · crabbox MCP Odysseus agent ──▶ crabbox ──▶ islo box runs the agent's code # sandbox the agent

The inner path is a built-in MCP server (mcp_servers/crabbox_server.py) that gives the agent one tool, crabbox_run: execute a command on a fresh throwaway box and get back stdout + exit code. So AI-generated code runs on a disposable microVM, never on the Odysseus host — which is exactly what islo.dev is for ("a secure sandbox for coding agents"). It degrades cleanly: no crabbox or key → the tool returns a hint instead of failing.

agent tool call: crabbox_run("echo agent-on-the-box && python -c 'print(2+2)' && uname -a")
leased isb_… slug=silver-crab provider=islo
agent-on-the-box
2+2= 4
Linux crabbox-islo-… 6.16.9+ x86_64 GNU/Linux
islo run summary  sync_skipped=true  command=1.795s  total=42.2s  exit=0
[crabbox: provider=islo image=python:3.12-slim exit=0]

Pipeline

your laptop islo.dev microVM (python:3.12-slim) ┌───────────────────┐ ┌──────────────────────────────────┐ ./crabbox.sh test ──warm──▶ lease isb_… (golden-barnacle) 808 files 32.7MiB ──sync──▶ rsync working tree → /workspace └───────────────────┘ apt deps · pip · python setup.py pytest ──▶ stream stdout + exit exit code ◀──────────────── release lease (or --keep) └──────────────────────────────────┘

Live run · Odysseus suite on islo.dev

Green slice
99 passed
0 failed · 4 skipped · 41.3s on the box
Cold start → results
~1m43s
warm + sync 15.1s + install + run
Real exit codes
exit 1
surfaced a real upstream test failure

1 · warm a box, sync the checkout

leased isb_crabbox-odysseus-e8dffb slug=golden-barnacle provider=islo
sync candidate: 808 files, 32.7 MiB  dirty_delta=5 files, 41.2 KiB
sync complete in 15.144s

2 · install + first-time setup (on the box)

▶ system deps      apt-get install git build-essential
▶ python deps      pip install -r requirements.txt
▶ first-time setup
  [ok] data/ · logs/ · chroma/ · rag/ · memory_vectors/
  [ok] .env created from .env.example
  [ok] Database initialized
  [ok] Initial admin user created (admin)  # temp password printed

3 · run the suite — clean green slice

ODYSSEUS_TESTS="tests -q -k 'recurrence or static_mime or ordinal or preview or …'" ./crabbox.sh test
.....sss........................................................s....... [ 69%]
...............................                                          [100%]
99 passed, 4 skipped, 1736 deselected in 3.70s
islo run summary  sync=15.1s  command=41.3s  total=1m42.1s  exit=0

4 · the harness reports real failures, too

A broader slice surfaced two genuine pre-existing upstream bugs — and crabbox.sh propagated the non-zero exit straight back to the laptop. The box isn't faking green:

FAILED tests/test_hwfit_quant_formats.py::…strict_not_lower_quant_fallback
        TypeError: 'NoneType' object is not subscriptable  # analyze_model() → None
FAILED tests/test_cookbook_helpers.py::test_pip_install_fallback_chain_propagates_failure_in_venv
2 failed, 104 passed, 4 skipped, 1729 deselected in 3.91s
islo run summary  sync=15.0s  command=42.8s  total=1m43.6s  exit=1
Honest scope. These are slices of Odysseus's 355-file suite chosen to run fast and dependency-light; ODYSSEUS_TESTS=tests runs the whole thing. The point here is the harness: warm → sync → install → run → real exit code, end-to-end, on a box that didn't exist two minutes ago. Both failures are upstream's, not the sandbox's.

One flag, many providers

crabbox is a control plane that fronts ~25 sandbox/VM backends. The same crabbox.sh runs Odysseus on any of them by swapping one flag — islo.dev is the live-verified default here.

providerkindflagverified
islomicroVM--provider islo
local-containerlocal Docker--provider local-container·
e2b / daytona / modalcloud sandbox--provider …·
aws / gcp / hetznerVM--provider …·

Why this matters

"Self-hosted" usually means "I'll try it this weekend." A throwaway box collapses that to one command: a reviewer, a CI job, or a curious stranger can stand the whole workspace up, click around a real running instance, and discard it — without trusting it near their own machine. Generate once, run anywhere, leave nothing behind.