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.
- mcp_huddle-0.3.0/.gitignore +27 -0
- mcp_huddle-0.3.0/CHANGELOG.md +106 -0
- mcp_huddle-0.3.0/CLAUDE.md +52 -0
- mcp_huddle-0.3.0/CONTRIBUTING.md +67 -0
- mcp_huddle-0.3.0/LICENSE +21 -0
- mcp_huddle-0.3.0/PKG-INFO +292 -0
- mcp_huddle-0.3.0/README.md +264 -0
- mcp_huddle-0.3.0/docs/ONBOARDING.md +103 -0
- mcp_huddle-0.3.0/docs/TODO.md +34 -0
- mcp_huddle-0.3.0/docs/dashboard-de.png +0 -0
- mcp_huddle-0.3.0/docs/dashboard-es.png +0 -0
- mcp_huddle-0.3.0/docs/dashboard-ru.png +0 -0
- mcp_huddle-0.3.0/docs/dashboard-zh.png +0 -0
- mcp_huddle-0.3.0/docs/dashboard.png +0 -0
- mcp_huddle-0.3.0/examples/hooks/claude-check.sh +12 -0
- mcp_huddle-0.3.0/examples/hooks/gemini-check.sh +11 -0
- mcp_huddle-0.3.0/examples/hooks/session-end.sh +9 -0
- mcp_huddle-0.3.0/examples/registry.json +44 -0
- mcp_huddle-0.3.0/pyproject.toml +72 -0
- mcp_huddle-0.3.0/src/mcp_huddle/__init__.py +2 -0
- mcp_huddle-0.3.0/src/mcp_huddle/__main__.py +193 -0
- mcp_huddle-0.3.0/src/mcp_huddle/acp.py +57 -0
- mcp_huddle-0.3.0/src/mcp_huddle/bus.py +957 -0
- mcp_huddle-0.3.0/src/mcp_huddle/hooks/claude-check.sh +12 -0
- mcp_huddle-0.3.0/src/mcp_huddle/hooks/gemini-check.sh +11 -0
- mcp_huddle-0.3.0/src/mcp_huddle/hooks/session-end.sh +9 -0
- mcp_huddle-0.3.0/src/mcp_huddle/mimo_runner.py +180 -0
- mcp_huddle-0.3.0/src/mcp_huddle/openai_compatible_runner.py +219 -0
- mcp_huddle-0.3.0/src/mcp_huddle/py.typed +0 -0
- mcp_huddle-0.3.0/src/mcp_huddle/server.py +1529 -0
- mcp_huddle-0.3.0/src/mcp_huddle/spawn.py +947 -0
- mcp_huddle-0.3.0/src/mcp_huddle/static/dashboard.css +1512 -0
- mcp_huddle-0.3.0/src/mcp_huddle/static/dashboard.html +91 -0
- mcp_huddle-0.3.0/src/mcp_huddle/static/dashboard.js +1362 -0
- mcp_huddle-0.3.0/tests/test_bus_reliability.py +425 -0
- mcp_huddle-0.3.0/tests/test_mimo_runner.py +23 -0
- mcp_huddle-0.3.0/tests/test_openai_compatible_runner.py +55 -0
- mcp_huddle-0.3.0/tests/test_phase1_2.py +1131 -0
- mcp_huddle-0.3.0/tests/test_require_local.py +84 -0
- 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).
|
mcp_huddle-0.3.0/LICENSE
ADDED
|
@@ -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
|
+

|
|
34
|
+

|
|
35
|
+

|
|
36
|
+
|
|
37
|
+

|
|
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
|
+
|  |  |
|
|
270
|
+
|  |  |
|
|
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).
|