Skip to content

About

Claude code session orchestration from the browser

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

22 Commits

Folders and files

Repository files navigation

mission-control

A cockpit for your Claude Code sessions.
Launch several Claudes at once, watch them work in real time, and get pinged the moment one finishes or needs you — all from one localhost dashboard.

Python 3.12+  FastAPI + WebSockets  SQLite WAL  Loopback only  Frontend: vanilla JS

Launching a Claude Code session and watching it fix a failing test, while two more sessions run in the background and the 'awaiting' badge climbs

Launch a session, watch it work, and get pinged when it needs you — all on localhost.


If you've ever juggled three terminal tabs trying to remember which Claude was waiting on you, this is for you.

What it does

  • Launch sessions from a project picker — no typing absolute paths. Pick a folder, choose a model and permission mode, optionally seed it with a prompt or a saved task template, and go.
  • Watch them stream. Assistant text, tool calls, and results show up live as each session works.
  • Stay in the loop. When a session finishes its turn, gets blocked on a permission prompt, or errors out, you get a browser notification and the tab title updates with a count of how many need you. Routine streaming output stays quiet.
  • Answer permission prompts right from the dashboard — approve or deny without switching windows.
  • Run many at once. A sidebar gives you every session at a glance, each with a status dot and the project name front and center (not a cryptic UUID).
  • Pick up where you left off. Resume previous Claude Code conversations, import projects from your existing Claude history, and recover gracefully: sessions and transcripts are persisted, so a server restart doesn't lose your work.
  • Private by default. The server binds to 127.0.0.1 only, with a second layer of defense that rejects any non-loopback request. Nothing is exposed to your network.

Quickstart

You'll need Python 3.12+, uv, and the claude CLI on your PATH.

uv sync
uv run mission-control serve
# then open http://127.0.0.1:8765

That's it. Add a project from the picker, click + New session, and you're flying.

Configuration

All settings are environment variables — no config files to manage.

Variable Default What it does
MC_PORT 8765 Port to bind on.
MC_DB_PATH ~/.mission-control/state.db Where sessions, transcripts, projects, and templates are stored (SQLite). The parent directory is created on first run.
MC_CLAUDE_EXECUTABLE claude Override the claude binary. Shlex-split, so a multi-word command works — handy for pointing at the bundled fake Claude (see below).

How it works

mission-control is a single Python process:

  • FastAPI + WebSockets serve the HTTP/WS API and stream events to the browser.
  • Each session is a claude subprocess driven over stream-json, which gives clean, parseable signals for turn completion, tool calls, permission requests, and errors — the foundation for those "needs attention" notifications.
  • An SQLite store (WAL mode) keeps sessions, transcripts, projects, and templates so nothing is lost across restarts.
  • The frontend is vanilla JS served as static assets from the same process — no build step, no bundler.

Development

# Run the test suite
uv run pytest -q

# Lint (auto-fix, then verify clean)
uv run ruff check --fix .
uv run ruff check .

Editing the frontend

The web assets (mission_control/web/*.{html,js,css}) are bundled into the package at uv sync time, so uv run mission-control serve reads them from the installed package — not your source tree. While iterating on the UI, run the dev server with live reload instead:

uv run uvicorn mission_control.server:app --reload

If you'd rather use the regular serve command, re-bundle after each asset edit:

uv sync --reinstall-package mission-control

Try it without burning API tokens

A bundled fake Claude lets you drive the whole UI end-to-end without making real API calls. Point MC_CLAUDE_EXECUTABLE at it (replace <repo> with your absolute project path):

MC_CLAUDE_EXECUTABLE="python <repo>/tests/fakes/fake_claude.py --scenario assistant_then_result" \
  uv run mission-control serve

Then open http://127.0.0.1:8765 and:

  1. Add a project — click + New session → + Add project → navigate to a folder → Use this folder.
  2. Launch a few sessions — click + New session a few times. Watch each card appear with its own status dot, and the header badge / tab title update as sessions go idle.
  3. Get notified — the first click on the page asks for browser notification permission. Grant it, then watch a session finish.
  4. Answer a permission prompt — try the permission scenario.
  5. Terminate — use the per-card hover button or the detail-pane button; the card flips to terminated.
  6. Resume — relaunch against the same project and pick a past session from "Resume previous session."

Swap the scenario between restarts to exercise different behaviors:

Scenario What it emits
init_then_idle An init line, then idles.
assistant_then_result Assistant text, then a result.
permission A permission request the UI can resolve.
error_exit An error event, then a non-zero exit.

To confirm clean shutdown, run ps -ef | grep fake_claude after Ctrl-C'ing the server — you should see nothing left behind.

Status

Built and tested against its full spec: session launch, terminate, interact, attention notifications, the concurrent dashboard, localhost-only binding, and restart persistence all pass their scenario tests, with the linter clean and no orphaned subprocesses after shutdown.

License

Released under the MIT License.

About

Claude code session orchestration from the browser

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages