mcp-huddle 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. mcp_huddle-0.3.0/.gitignore +27 -0
  2. mcp_huddle-0.3.0/CHANGELOG.md +106 -0
  3. mcp_huddle-0.3.0/CLAUDE.md +52 -0
  4. mcp_huddle-0.3.0/CONTRIBUTING.md +67 -0
  5. mcp_huddle-0.3.0/LICENSE +21 -0
  6. mcp_huddle-0.3.0/PKG-INFO +292 -0
  7. mcp_huddle-0.3.0/README.md +264 -0
  8. mcp_huddle-0.3.0/docs/ONBOARDING.md +103 -0
  9. mcp_huddle-0.3.0/docs/TODO.md +34 -0
  10. mcp_huddle-0.3.0/docs/dashboard-de.png +0 -0
  11. mcp_huddle-0.3.0/docs/dashboard-es.png +0 -0
  12. mcp_huddle-0.3.0/docs/dashboard-ru.png +0 -0
  13. mcp_huddle-0.3.0/docs/dashboard-zh.png +0 -0
  14. mcp_huddle-0.3.0/docs/dashboard.png +0 -0
  15. mcp_huddle-0.3.0/examples/hooks/claude-check.sh +12 -0
  16. mcp_huddle-0.3.0/examples/hooks/gemini-check.sh +11 -0
  17. mcp_huddle-0.3.0/examples/hooks/session-end.sh +9 -0
  18. mcp_huddle-0.3.0/examples/registry.json +44 -0
  19. mcp_huddle-0.3.0/pyproject.toml +72 -0
  20. mcp_huddle-0.3.0/src/mcp_huddle/__init__.py +2 -0
  21. mcp_huddle-0.3.0/src/mcp_huddle/__main__.py +193 -0
  22. mcp_huddle-0.3.0/src/mcp_huddle/acp.py +57 -0
  23. mcp_huddle-0.3.0/src/mcp_huddle/bus.py +957 -0
  24. mcp_huddle-0.3.0/src/mcp_huddle/hooks/claude-check.sh +12 -0
  25. mcp_huddle-0.3.0/src/mcp_huddle/hooks/gemini-check.sh +11 -0
  26. mcp_huddle-0.3.0/src/mcp_huddle/hooks/session-end.sh +9 -0
  27. mcp_huddle-0.3.0/src/mcp_huddle/mimo_runner.py +180 -0
  28. mcp_huddle-0.3.0/src/mcp_huddle/openai_compatible_runner.py +219 -0
  29. mcp_huddle-0.3.0/src/mcp_huddle/py.typed +0 -0
  30. mcp_huddle-0.3.0/src/mcp_huddle/server.py +1529 -0
  31. mcp_huddle-0.3.0/src/mcp_huddle/spawn.py +947 -0
  32. mcp_huddle-0.3.0/src/mcp_huddle/static/dashboard.css +1512 -0
  33. mcp_huddle-0.3.0/src/mcp_huddle/static/dashboard.html +91 -0
  34. mcp_huddle-0.3.0/src/mcp_huddle/static/dashboard.js +1362 -0
  35. mcp_huddle-0.3.0/tests/test_bus_reliability.py +425 -0
  36. mcp_huddle-0.3.0/tests/test_mimo_runner.py +23 -0
  37. mcp_huddle-0.3.0/tests/test_openai_compatible_runner.py +55 -0
  38. mcp_huddle-0.3.0/tests/test_phase1_2.py +1131 -0
  39. mcp_huddle-0.3.0/tests/test_require_local.py +84 -0
  40. mcp_huddle-0.3.0/tests/test_smoke.py +88 -0
@@ -0,0 +1,27 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyo
5
+ *.pyd
6
+ .Python
7
+ *.egg-info/
8
+ dist/
9
+ build/
10
+ .venv/
11
+ venv/
12
+ *.egg
13
+
14
+ # macOS
15
+ .DS_Store
16
+
17
+ # Tests / coverage
18
+ .pytest_cache/
19
+ .coverage
20
+ htmlcov/
21
+
22
+ # Env
23
+ .env
24
+ *.env
25
+
26
+ # Logs (runtime / stray service logs — never belong in the repo)
27
+ *.log
@@ -0,0 +1,106 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.3.0] - 2026-06-19
11
+
12
+ ### Added
13
+
14
+ - **Read-only discussant agents by default** (`MCP_HUDDLE_READONLY`, default ON;
15
+ set `=0` for full-access workers). Spawned agents read files/web/docs/rules/
16
+ memory but cannot edit/write — they participate only via the huddle MCP tools.
17
+ Claude uses an allow/deny tool list; Codex uses `-s read-only` plus
18
+ auto-approved huddle MCP tools (verified: read-only sandbox + MCP works once
19
+ the MCP approval mode is `approve`).
20
+ - **Cloud-API agents**: `openai_compatible_runner --api-key-env` lets any
21
+ OpenAI-compatible cloud API (OpenAI/OpenRouter/vLLM/proxied Anthropic) join as
22
+ a read-only discussant via a registry entry — no CLI, no MCP on the agent side.
23
+ - **Paste-a-prompt onboarding** (`docs/ONBOARDING.md`): fill in which agents you
24
+ use (CLI or cloud API) and your AI agent installs huddle, registers the MCP
25
+ server, installs hooks, and writes `~/.mcp-huddle/registry.json`.
26
+ - `mcp-huddle --install-hooks [DIR]` copies the bundled Claude Code hooks and
27
+ prints the `settings.json` wiring.
28
+ - Optional on-disk registry `~/.mcp-huddle/registry.json` (merged with defaults;
29
+ precedence env > file > defaults) + a startup agent-discovery summary.
30
+ - Endpoint auth: `_require_local` enforces loopback on mutating HTTP endpoints +
31
+ SSE, with an optional `MCP_HUDDLE_TOKEN` bearer (no-op when unset).
32
+ - Dashboard: 3 skins (Glass/Web/Code), 5 terminal palettes, 10-language i18n
33
+ (incl. Arabic RTL), a single ⚙️ settings popover (theme × design × palette ×
34
+ language) with `?` help tooltips, an MCP-connection section, an env-vars/
35
+ spawn-rules reference, and a copyable agent-setup prompt.
36
+ - Room tree regrouped: project → date → organizer → numbered chats.
37
+ - Resizable + collapsible panels (collapse to a 48px rail with an expand
38
+ button), and a narrow-window overlay mode (chat full-width, side panels open
39
+ as opaque drawers over the chat via the ◧/◨ buttons).
40
+ - `CLAUDE.md` contributor/agent guide; README hero + theme/language gallery.
41
+ - PEP 561 `py.typed`; `--help` / `--version` CLI.
42
+
43
+ ### Changed
44
+
45
+ - `requires-python` raised to `>=3.11` (the code uses `typing.NotRequired`).
46
+ - Antigravity (`agy`) is now opt-in (`MCP_HUDDLE_ANTIGRAVITY_ENABLED=1`,
47
+ default OFF): it needs a prior interactive `agy` login (headless can't sign
48
+ in) and exposes no read-only flag. MiMo runs in a temp dir (never touches the
49
+ project), so it is effectively read-only with respect to your files.
50
+
51
+ ### Fixed
52
+
53
+ - Portability: removed macOS-only hardcoded paths (`mimo_runner` temp dir →
54
+ `tempfile`; agent binaries resolved via `shutil.which`).
55
+ - `server.py`: safe env-int parsing, `spawned_pids` merge under the meta lock,
56
+ `tempfile` brief (closes a `/tmp` TOCTOU), centralized Codex thread-resume.
57
+ - `bus.py`: corrupt-JSON resilience, `0700` data-dir perms, bounded message cache.
58
+ - MiMo runner validates output so a provider error (e.g. 403) is never posted as
59
+ a reply. Palette × light-theme clash fixed (palettes force dark structure).
60
+
61
+ ## [0.2.0] - 2026-06-18
62
+
63
+ ### Added
64
+
65
+ - Liquid Glass web dashboard with light/dark themes, agent avatars, kind badges,
66
+ and reply-to quotes.
67
+ - Configurable auto-spawn registry via `MCP_HUDDLE_SPAWN_REGISTRY` (JSON file);
68
+ see `examples/registry.json`.
69
+ - Codex wake-up loop: follow-up `kind=request` messages resume the same captured
70
+ Codex thread via `codex exec resume`.
71
+ - MiMo Code advisor slot (toggle with `MCP_HUDDLE_MIMO_ENABLED`).
72
+ - Watchdog that auto-closes rooms whose owner process died, plus retention sweep
73
+ for terminal rooms (`HUDDLE_RETENTION_DAYS` / `HUDDLE_RETENTION_SWEEP_SECS`).
74
+ - Rate-limit / usage-limit detection with cooldown and an in-room notice instead
75
+ of a silent agent death (`MCP_HUDDLE_RATE_LIMIT_COOLDOWN_SEC`).
76
+ - `CONTRIBUTING.md`, this `CHANGELOG.md`, and an expanded README (configuration
77
+ reference, security note, troubleshooting, and architecture overview).
78
+
79
+ ### Changed
80
+
81
+ - Default spawn registry is now Codex, Antigravity, MiMo, and Claude. Claude is
82
+ opt-in and OFF by default (`MCP_HUDDLE_CLAUDE_ENABLED=1` to enable) because
83
+ headless `claude -p` is metered.
84
+ - The HTTP dashboard binds to `127.0.0.1` only.
85
+ - Crash-safe lock release; malformed request bodies now return `400` instead of
86
+ `500`.
87
+
88
+ ### Removed
89
+
90
+ - Retired the local Qwen and DeepSeek advisor slots and the reverse-API
91
+ browser-session bridges they fronted.
92
+ - Retired the Gemini CLI slot; the Google-model advisor now runs exclusively on
93
+ Antigravity (`agy`).
94
+
95
+ ## [0.1.2]
96
+
97
+ ### Added
98
+
99
+ - Initial public-ish release: FastMCP server with persistent JSONL rooms,
100
+ 10 MCP tools, anti-loop guards, consensus (propose/vote), and stdio + HTTP
101
+ transports.
102
+
103
+ [Unreleased]: https://github.com/kolotovalexander/mcp-huddle/compare/v0.3.0...HEAD
104
+ [0.3.0]: https://github.com/kolotovalexander/mcp-huddle/compare/v0.2.0...v0.3.0
105
+ [0.2.0]: https://github.com/kolotovalexander/mcp-huddle/releases/tag/v0.2.0
106
+ [0.1.2]: https://github.com/kolotovalexander/mcp-huddle/releases/tag/v0.1.2
@@ -0,0 +1,52 @@
1
+ # CLAUDE.md — working on mcp-huddle
2
+
3
+ Guidance for AI agents (and humans) editing this repo. User-facing docs:
4
+ `README.md`; onboarding: `docs/ONBOARDING.md`; open work: `docs/TODO.md`.
5
+
6
+ ## What this is
7
+ A persistent multi-agent chat MCP server. AI agents join rooms and discuss;
8
+ a web dashboard lets humans watch/intervene. Two run modes (one binary):
9
+ `mcp-huddle` (stdio MCP) and `mcp-huddle --http` (HTTP MCP + dashboard on :8014).
10
+
11
+ ## Layout (deep modules, clear seams)
12
+ - `src/mcp_huddle/server.py` — MCP tools + HTTP/SSE routes + spawn/wake
13
+ orchestration. The public surface; keep tool/route signatures stable.
14
+ - `src/mcp_huddle/bus.py` — file-locked room/message/meta store with an
15
+ in-process message cache. **Concurrency-critical**: never change lock
16
+ ordering or acquire two locks at once; additions must stay defensive.
17
+ - `src/mcp_huddle/spawn.py` — agent registry + spawning. Agents are spawned
18
+ one-shot per turn (`cd <project> && <cli> …`), re-woken per addressed message;
19
+ Codex resumes its thread. `DEFAULT_REGISTRY`, read-only transform
20
+ (`_apply_readonly`, default ON), on-disk registry merge.
21
+ - `src/mcp_huddle/openai_compatible_runner.py` / `mimo_runner.py` — runners for
22
+ agents that don't speak MCP (cloud APIs / MiMo): read the room, call the
23
+ model, post via the bus. Both validate output before posting.
24
+ - `src/mcp_huddle/__main__.py` — CLI (argparse): `--http`, `--port`,
25
+ `--version`, `--install-hooks`.
26
+ - `src/mcp_huddle/static/{dashboard.html,css,js}` — the dashboard (vanilla JS,
27
+ no build step). Themes axis `data-theme`, skin axis `data-skin`, palette axis
28
+ `data-palette`, language `data-lang`; settings popover + i18n live in
29
+ `dashboard.js`.
30
+
31
+ ## Conventions
32
+ - Python 3.11+ stdlib only (no third-party in runtime code beyond `mcp` /
33
+ starlette / uvicorn). Keep it dependency-light.
34
+ - Agents are **read-only discussants by default** (`MCP_HUDDLE_READONLY`); they
35
+ read but never edit files and talk only via huddle MCP / the bus.
36
+ - New agent slots: prefer a `~/.mcp-huddle/registry.json` entry or the
37
+ `openai_compatible_runner` over hard-coding; cloud APIs use `--api-key-env`.
38
+ - Dashboard JS: no framework, no bundler — edit the files directly. UI strings
39
+ go through `t()` / `data-i18n`.
40
+
41
+ ## Verify before claiming done
42
+ ```bash
43
+ .venv/bin/pytest tests/ -q # full suite (currently 93 passing)
44
+ node --check src/mcp_huddle/static/dashboard.js # JS syntax
45
+ ```
46
+ For dashboard changes, the server serves files fresh (no-cache) — just reload
47
+ the browser. Python changes (server/spawn) require a server restart to go live.
48
+
49
+ ## Don't
50
+ - Don't break `bus.py` locking or `server.py` tool/route signatures.
51
+ - Don't add a build step or runtime dependencies to the dashboard.
52
+ - Don't enable agents that need interactive login (agy) by default.
@@ -0,0 +1,67 @@
1
+ # Contributing to mcp-huddle
2
+
3
+ Thanks for your interest in improving mcp-huddle! This is a small, focused
4
+ project — bug fixes, docs, and well-scoped features are all welcome.
5
+
6
+ ## Development setup
7
+
8
+ Requires Python 3.10+.
9
+
10
+ ```bash
11
+ git clone https://github.com/kolotovalexander/mcp-huddle
12
+ cd mcp-huddle
13
+ python -m venv .venv
14
+ source .venv/bin/activate
15
+ pip install -e ".[dev]"
16
+ ```
17
+
18
+ ## Running the server locally
19
+
20
+ ```bash
21
+ mcp-huddle --http # HTTP + dashboard on http://127.0.0.1:8014/dashboard
22
+ mcp-huddle # stdio transport (for MCP clients)
23
+ ```
24
+
25
+ Rooms are stored under `~/.mcp-huddle/` (override with `MCP_HUDDLE_HOME`). When
26
+ hacking, point `MCP_HUDDLE_HOME` at a throwaway directory so you don't touch your
27
+ real rooms:
28
+
29
+ ```bash
30
+ MCP_HUDDLE_HOME=$(mktemp -d) mcp-huddle --http
31
+ ```
32
+
33
+ ## Running tests
34
+
35
+ ```bash
36
+ .venv/bin/pytest tests/ -q
37
+ ```
38
+
39
+ Please add or update tests for any behavior change. Tests should be hermetic —
40
+ use the provided fixtures and an isolated `MCP_HUDDLE_HOME`; do not depend on
41
+ network access or on any agent CLI (`codex`, `agy`, `mimo`) being installed.
42
+
43
+ ## Pull request workflow
44
+
45
+ 1. Fork and create a topic branch off `main`.
46
+ 2. Keep changes focused; avoid unrelated refactors in the same PR.
47
+ 3. Make sure `pytest` passes and the dashboard still loads.
48
+ 4. Update `README.md` and `CHANGELOG.md` if you change user-facing behavior.
49
+ 5. Open a PR with a clear description of the problem and the fix.
50
+
51
+ ## Code style
52
+
53
+ - Standard library + the declared dependencies (`mcp`, `starlette`, `uvicorn`);
54
+ avoid adding new runtime dependencies without discussion.
55
+ - Match the existing style: typed function signatures, small functions, and
56
+ comments that explain *why* rather than *what*.
57
+ - Storage is the single source of truth — prefer file-backed state over
58
+ in-process global state so stdio clients and the dashboard stay consistent.
59
+
60
+ ## Reporting bugs
61
+
62
+ Open an issue at <https://github.com/kolotovalexander/mcp-huddle/issues> with
63
+ steps to reproduce, what you expected, and what happened (including relevant
64
+ stderr output).
65
+
66
+ By contributing, you agree that your contributions are licensed under the
67
+ project's [MIT License](LICENSE).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alexander Kolotov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,292 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcp-huddle
3
+ Version: 0.3.0
4
+ Summary: Persistent multi-agent chat MCP server with web dashboard. Rooms where AI agents huddle to discuss, critique, and decide.
5
+ Project-URL: Homepage, https://github.com/kolotovalexander/mcp-huddle
6
+ Project-URL: Issues, https://github.com/kolotovalexander/mcp-huddle/issues
7
+ Author: Alexander Kolotov
8
+ License: MIT
9
+ License-File: LICENSE
10
+ Keywords: ai,chat,claude,fastmcp,huddle,mcp,multi-agent
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Communications :: Chat
19
+ Classifier: Topic :: Software Development
20
+ Requires-Python: >=3.11
21
+ Requires-Dist: mcp>=1.27.0
22
+ Requires-Dist: starlette>=0.40.0
23
+ Requires-Dist: uvicorn>=0.32.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: httpx>=0.27; extra == 'dev'
26
+ Requires-Dist: pytest>=8.0; extra == 'dev'
27
+ Description-Content-Type: text/markdown
28
+
29
+ # mcp-huddle
30
+
31
+ > Persistent multi-agent chat MCP server. Rooms where AI agents (Claude, Codex, Antigravity, MiMo, ...) huddle to discuss, critique, and decide together — with a Liquid Glass web dashboard for humans to watch and intervene.
32
+
33
+ ![PyPI version](https://img.shields.io/pypi/v/mcp-huddle)
34
+ ![Python](https://img.shields.io/pypi/pyversions/mcp-huddle)
35
+ ![License](https://img.shields.io/pypi/l/mcp-huddle)
36
+
37
+ ![mcp-huddle dashboard — multi-agent discussion with selectable themes, palettes and 10-language UI](docs/dashboard.png)
38
+
39
+ ## Install
40
+
41
+ > **One-paste setup:** instead of wiring this up by hand, see
42
+ > [`docs/ONBOARDING.md`](docs/ONBOARDING.md) — fill in which agents you use
43
+ > (CLI or cloud API) and paste the prompt to your AI agent; it installs huddle,
44
+ > registers the MCP server, installs hooks, and writes your spawn registry.
45
+
46
+ ```bash
47
+ pip install mcp-huddle
48
+ ```
49
+
50
+ Or run it without installing, using [`uvx`](https://docs.astral.sh/uv/):
51
+
52
+ ```bash
53
+ uvx mcp-huddle --http # HTTP + dashboard
54
+ ```
55
+
56
+ This is version **0.3.0**. See [CHANGELOG.md](CHANGELOG.md) for release notes.
57
+
58
+ ## Two ways to run
59
+
60
+ `mcp-huddle` runs in **stdio mode by default** (the transport every MCP client expects), and in **HTTP + dashboard mode** when you pass `--http`. Both modes share the same JSONL storage at `~/.mcp-huddle/rooms/` via file locks, so a stdio-spawned client and the HTTP dashboard see the same rooms in real time.
61
+
62
+ ### 1) Stdio mode — for MCP clients (Claude Code, Codex, Antigravity, Claude Desktop)
63
+
64
+ Each client spawns its own `mcp-huddle` process and communicates via JSON-RPC over stdin/stdout. Use either the PyPI-installed `mcp-huddle` binary or `uvx mcp-huddle`.
65
+
66
+ **Claude Code** — edit `~/.claude/.mcp.json`:
67
+
68
+ ```json
69
+ {
70
+ "mcpServers": {
71
+ "huddle": {
72
+ "command": "uvx",
73
+ "args": ["mcp-huddle"]
74
+ }
75
+ }
76
+ }
77
+ ```
78
+
79
+ **Codex CLI** — add to `~/.codex/config.toml`:
80
+
81
+ ```toml
82
+ [mcp_servers.huddle]
83
+ command = "uvx"
84
+ args = ["mcp-huddle"]
85
+ ```
86
+
87
+ **Antigravity** (`agy`, Google-model slot — uses the `~/.gemini` config home) — add to `~/.gemini/config.json` `mcpServers`:
88
+
89
+ ```json
90
+ {
91
+ "huddle": {
92
+ "command": "uvx",
93
+ "args": ["mcp-huddle"]
94
+ }
95
+ }
96
+ ```
97
+
98
+ > Want the bleeding edge straight from GitHub instead of PyPI? Swap the args for
99
+ > `["--from", "git+https://github.com/kolotovalexander/mcp-huddle", "mcp-huddle"]`.
100
+
101
+ Restart the client. The 10 huddle tools become available.
102
+
103
+ > Tip: if your client doesn't see `uvx` because PATH is empty when it spawns the server, replace `"uvx"` with the absolute path (`which uvx` to find it — typically `/Users/you/.local/bin/uvx` on macOS).
104
+
105
+ ### 2) HTTP + dashboard mode — for humans
106
+
107
+ Run once in any terminal to watch rooms in the browser:
108
+
109
+ ```bash
110
+ mcp-huddle --http # or: uvx mcp-huddle --http
111
+ ```
112
+
113
+ Dashboard: <http://127.0.0.1:8014/dashboard>. The dashboard reads the same files the stdio clients write to — drop messages, close rooms, switch dark/light theme.
114
+
115
+ ## Features
116
+
117
+ - **10 MCP tools** for room creation, messaging, status, and consensus
118
+ - **JSONL storage** at `~/.mcp-huddle/rooms/` — grep-able, no DB
119
+ - **Anti-loop guards**: `kind` enum (`request`/`comment`/`ack`/`busy`/`result`/`final`/`system`/`close`), per-message dedup, server-side circuit breaker
120
+ - **Liquid Glass web dashboard** with two themes (dark/light), agent avatars, polished kind badges, reply-to quotes
121
+ - **Auto-spawn** enabled registry reviewers when a room is created (`auto_spawn=True`); default registry includes Codex, Antigravity, MiMo, and Claude (Claude is opt-in, OFF by default). Registry is configurable via `MCP_HUDDLE_SPAWN_REGISTRY`
122
+ - **Codex wake-up loop**: follow-up `kind=request` messages addressed to Codex (or `all`) resume the same captured Codex thread instead of starting from scratch
123
+ - **Watchdog** auto-closes rooms whose owner process died
124
+
125
+ ## Tools
126
+
127
+ These are the tools exposed over MCP (decorated with `@mcp.tool()` in
128
+ `src/mcp_huddle/server.py`):
129
+
130
+ | Tool | Purpose |
131
+ |------|---------|
132
+ | `room_create` | Create a new discussion room; returns `room_id`. Optionally auto-spawns enabled registry agents. |
133
+ | `room_invite` | Add an agent to an existing room. |
134
+ | `room_info` | Get room metadata: participants, status, cwd, etc. |
135
+ | `room_list` | List all rooms (open and closed). |
136
+ | `message_post` | Post a message to a room; returns `message_id`. Accepts `kind`, `to`, `reply_to`, `idempotency_key`. |
137
+ | `messages_read` | Read chat history as plain text; supports delta reads via `since_id`. |
138
+ | `room_summarize` | Get a token-efficient digest of messages since `since_id`. |
139
+ | `propose_resolution` | Propose a resolution to end discussion; returns `resolution_id`. |
140
+ | `resolution_vote` | Vote `ack` or `reject` on a resolution; all-ack makes the room `resolved`. |
141
+ | `notify_register` | Register a file path to receive notifications when a `kind=request` message arrives. |
142
+
143
+ Room lifecycle operations (request-close, close, delete, close-session) and
144
+ agent status are driven by the server internals and the dashboard HTTP API
145
+ rather than exposed as MCP tools.
146
+
147
+ ## Configuration
148
+
149
+ All configuration is via environment variables (defaults shown):
150
+
151
+ | Env var | Default | Purpose |
152
+ |---------|---------|---------|
153
+ | `PORT` | `8014` | HTTP port the server listens on (only used with `--http`). |
154
+ | `MCP_HUDDLE_HTTP` | (unset) | If set, run in HTTP + dashboard mode without passing `--http`. |
155
+ | `MCP_HUDDLE_HOME` | `~/.mcp-huddle` | Storage root. Rooms are stored in `$MCP_HUDDLE_HOME/rooms`. |
156
+ | `MCP_HUDDLE_SPAWN_REGISTRY` | (built-in: Codex + Antigravity + MiMo + Claude) | Path to a JSON file overriding the auto-spawn registry. See [`examples/registry.json`](examples/registry.json). |
157
+ | `MCP_HUDDLE_CLAUDE_ENABLED` | `0` | Set to `1` to auto-spawn an invited Claude (`claude -p`). OFF by default — `claude -p` is metered. |
158
+ | `MCP_HUDDLE_MIMO_ENABLED` | `1` | Set to `0` to disable the MiMo advisor slot. |
159
+ | `MCP_HUDDLE_PROBE_CACHE_TTL_SEC` | `300` | TTL (seconds) for the cached availability probe of registry agents. |
160
+ | `MCP_HUDDLE_RATE_LIMIT_COOLDOWN_SEC` | `900` | Cooldown after an agent hits a provider rate/usage limit before it is woken again. |
161
+ | `IDLE_TIMEOUT_SECS` | `600` | Idle window before an idle room with a dead owner is reaped. |
162
+ | `HUDDLE_RETENTION_DAYS` | `7` | Days a terminal (closed/resolved) room is retained before auto-deletion. |
163
+ | `HUDDLE_RETENTION_SWEEP_SECS` | `3600` | Interval between retention sweeps. |
164
+
165
+ ## Security
166
+
167
+ mcp-huddle is designed to run **locally, on a single trusted machine**:
168
+
169
+ - **The HTTP dashboard binds to `127.0.0.1` only** (hardcoded in
170
+ `src/mcp_huddle/__main__.py`). It is not exposed to your network, and there is
171
+ no authentication — anyone with access to localhost can read and post to
172
+ rooms. Do not put it behind a public reverse proxy without adding your own auth.
173
+ - **Auto-spawned agents are read-only discussants by default**
174
+ (`MCP_HUDDLE_READONLY`, default ON). They run as local CLI subprocesses (e.g.
175
+ `codex exec`, optionally `claude -p`) in the organizer's project directory and
176
+ may read files, search the web, and read your rules/memory/docs — but they
177
+ cannot edit or write files; they participate only via the huddle MCP tools
178
+ (`message_post` / `messages_read`). Under the hood: Claude gets an allow/deny
179
+ tool list (no `Edit`/`Write`/`Bash`); Codex runs `-s read-only` with the
180
+ huddle MCP tools auto-approved. Set `MCP_HUDDLE_READONLY=0` to spawn
181
+ full-access **worker** agents instead (they then inherit your shell
182
+ credentials and can act on your machine). Only enable registry agents you
183
+ trust, and review any `MCP_HUDDLE_SPAWN_REGISTRY` / `~/.mcp-huddle/registry.json`
184
+ override before use — its `cmd` entries are executed verbatim.
185
+ - **Antigravity (`agy`) is opt-in** (`MCP_HUDDLE_ANTIGRAVITY_ENABLED=1`): it
186
+ needs a prior interactive `agy` login and is not read-only-enforced. **MiMo**
187
+ runs in a throwaway temp dir, so it never touches your project files.
188
+ - **All data lives under `~/.mcp-huddle/`** (override with `MCP_HUDDLE_HOME`) as
189
+ plain JSONL/JSON files. Anything posted to a room is stored in clear text on
190
+ disk; do not paste secrets into rooms.
191
+
192
+ ## Troubleshooting
193
+
194
+ - **An agent never joins the room.** The registry only spawns agents whose CLI
195
+ is installed and on `PATH`. If `codex` / `agy` / `mimo` aren't found, that slot
196
+ is silently disabled. Confirm with `which codex agy mimo`. Claude is OFF by
197
+ default — set `MCP_HUDDLE_CLAUDE_ENABLED=1` to enable it. Daemon/launchd
198
+ environments often have a reduced `PATH`; the server falls back to common
199
+ absolute paths, but a custom install location may need a registry override.
200
+ - **`error: cannot bind 127.0.0.1:8014: Address already in use`.** Another
201
+ `mcp-huddle --http` (or some other service) already holds the port. Stop it, or
202
+ start on a different port: `PORT=8024 mcp-huddle --http`.
203
+ - **Client doesn't see `uvx`.** When an MCP client spawns the server with an
204
+ empty `PATH`, use the absolute path to `uvx` (`which uvx`).
205
+ - **Spawned Codex says "user cancelled MCP tool call".** Codex needs
206
+ `danger-full-access` to call MCP tools under `-a never`; the built-in registry
207
+ already sets this. A custom registry that pins a restricted sandbox will mute
208
+ Codex.
209
+
210
+ ## Architecture
211
+
212
+ ```
213
+ src/mcp_huddle/
214
+ __main__.py # CLI entrypoint: stdio (default) vs --http (uvicorn + dashboard)
215
+ server.py # FastMCP server: @mcp.tool() definitions, dashboard HTTP routes,
216
+ # watchdog, wake/spawn orchestration
217
+ bus.py # storage layer: JSONL rooms under ~/.mcp-huddle, file locks,
218
+ # dedup, resolutions, retention
219
+ spawn.py # SpawnSpec registry + agent process spawning / availability probes
220
+ mimo_runner.py # MiMo advisor runner (MCP-disabled `mimo run`)
221
+ openai_compatible_runner.py # generic OpenAI-compatible chat runner
222
+ acp.py # (planned) ACP daemon integration for persistent agent sessions
223
+ static/ # Liquid Glass dashboard assets (HTML/CSS/JS)
224
+ ```
225
+
226
+ Both run modes share the same on-disk store, so a stdio MCP client and the HTTP
227
+ dashboard always see the same rooms. Storage is the single source of truth —
228
+ there is no in-memory broker, no database, and no network message bus.
229
+
230
+ ## Agent loop discipline
231
+
232
+ Agents should treat the room as an append-only work queue, not a casual chat:
233
+
234
+ - Store the last message ID you processed and call `messages_read(room_id, since_id=last_seen_id)` on the next turn.
235
+ - Reply only to `kind=request` addressed to your agent name or `to=all`.
236
+ - Do not reply to `kind=request` with `reply_to` set; it is already somebody's answer, not a new task.
237
+ - Use `idempotency_key` when retrying `message_post` so network or process retries do not duplicate messages.
238
+ - Once a resolution is accepted, the room is read-only for normal discussion; only `system` and `close` messages are accepted.
239
+
240
+ ## Codex lifecycle
241
+
242
+ When a room auto-spawns Codex, huddle captures the `thread_id` from Codex JSONL
243
+ events and stores it in the room metadata. The first Codex process may exit
244
+ after its initial response. Later, when somebody posts a new `kind=request`
245
+ addressed to `Codex` or `all`, huddle resumes that same Codex thread with
246
+ `codex exec resume <thread_id>`, asks it to read the delta via
247
+ `messages_read(..., since_id=last_seen_id)`, and expects a single
248
+ `message_post(..., reply_to=<request_id>, idempotency_key=...)` response.
249
+
250
+ Requests with `reply_to` set are treated as answers and do not wake Codex.
251
+ Messages authored by Codex do not wake Codex again. This preserves one logical
252
+ Codex session per room without keeping a long-running Codex OS process alive.
253
+
254
+ Only Codex has UUID-based thread resume. The other registry agents
255
+ (Antigravity, MiMo) are one-shot/fresh-process per wake — each turn re-reads the
256
+ room transcript — until the ACP daemon integration in `src/mcp_huddle/acp.py` is
257
+ implemented.
258
+
259
+ ## Dashboard
260
+
261
+ Open <http://127.0.0.1:8014/dashboard>. The sidebar groups rooms **project → date → organizer → chats** (chats keep the agent-chosen name, numbered when there are several). Click a room to read the chat, send a `kind=system` message as Human (overrides anti-loop rules), or close it.
262
+
263
+ Everything is in the **⚙️ settings popover**: light/dark/auto **theme**, three **designs** (Glass / Web / Code), five terminal **palettes** (Dracula, Nord, Tokyo Night, Catppuccin, Gruvbox), and a **10-language UI** (en, ru, es, de, fr, pt, zh, ja, ar, hi) — plus copy-paste MCP-connection snippets and an env-var reference. Panels resize/collapse to a rail, and on a narrow window they become overlay drawers so the chat keeps full width.
264
+
265
+ ### Themes & languages
266
+
267
+ | | |
268
+ |---|---|
269
+ | ![Spanish UI](docs/dashboard-es.png) | ![Russian UI](docs/dashboard-ru.png) |
270
+ | ![Chinese UI](docs/dashboard-zh.png) | ![German UI](docs/dashboard-de.png) |
271
+
272
+ ## Publishing
273
+
274
+ Maintainer notes for cutting a release to PyPI:
275
+
276
+ 1. Bump the version in `pyproject.toml` and `src/mcp_huddle/__init__.py`.
277
+ 2. Add a [CHANGELOG.md](CHANGELOG.md) entry and tag the release.
278
+ 3. Build and upload:
279
+
280
+ ```bash
281
+ python -m build # builds sdist + wheel into dist/
282
+ python -m twine upload dist/* # requires a PyPI API token
283
+ ```
284
+
285
+ ## Contributing
286
+
287
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, tests, and the PR
288
+ workflow.
289
+
290
+ ## License
291
+
292
+ MIT — see [LICENSE](LICENSE).