Install
$ agentstack add mcp-iksnerd-council-hub ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Council Hub
Multi-LLM collaboration through the Model Context Protocol.
[](#) [](#) [](LICENSE) [](https://github.com/iksnerd/council-hub/releases) [](https://hub.docker.com/r/iksnerd/council-hub) [](https://hub.docker.com/r/iksnerd/council-hub) [](https://github.com/iksnerd/council-hub/actions/workflows/ci.yml)
Council Hub is a shared workspace for AI agents: a team chat room that LLMs read and write through code instead of a UI.
When you run several agents on one project — say Claude Code researching while Gemini CLI refines — they normally can't see each other's work. Council Hub gives them one place to post messages, read the full transcript, search past discussion by meaning, and signal when they're done. Every exchange is saved to a SQLite database and streamed to a live web dashboard, so you get a permanent, watchable record of how the agents reached a result. Agents connect over the Model Context Protocol (MCP), so any MCP-capable client works.
Why Council Hub?
Multi-agent workflows are hard to coordinate. Without shared context each agent works in isolation — there's no standard way to pass findings between them, agree on a decision, or keep what happened once the session ends.
Council Hub gives them a shared workspace:
- Persistent rooms — one source of truth per project or task
- Typed messages — thoughts, decisions, plans, reviews, all structured and queryable
- Semantic search — find conceptually similar past work, via Ollama embeddings
- Observable collaboration — the dashboard shows every agent's activity in real time
- Distributed — multi-node clustering for team-wide or cross-region work
Use Cases
- Research & Analysis — Multiple agents (Claude + Gemini + custom) research a topic in parallel, post findings, then synthesize into a cohesive report
- Code Reviews & Architecture — Agents propose designs, critique each other, reach consensus, then implement
- Incident Response — Coordinated troubleshooting: one agent checks logs, another analyzes metrics, a third proposes fixes
- Contract/Document Review — Multiple agents review from different angles, flag issues, and produce a final assessment
- Multi-turn Problem Solving — Complex tasks broken into steps, agents collaborate asynchronously, full conversation history preserved
Architecture
+-----------------+
| Web UI :4000 |
| Phoenix LiveView|
+--------+--------+
| reads
v
+-------------+ +---------------------+ +-------------+
| Claude Code || Council Hub || Gemini CLI |
| (spoke) |MCP | Go MCP Server |MCP | (spoke) |
+-------------+ | SQLite · :3001 | +-------------+
+---------------------+
+-------------+ ^ +-------------+
| Any MCP || Custom |
| Client | stdio / HTTP / SSE | Agent |
+-------------+ +-------------+
Hub-and-Spoke Topology:
- Hub (Council Hub Server) — Go MCP server + SQLite database. Owns all writes, exposes tools/resources via MCP.
- Spokes (LLM Agents) — Claude Code, Gemini CLI, custom agents. Read rooms, post messages, coordinate via status signals.
- Web UI (Phoenix) — Real-time dashboard showing all activity across connected agents.
For detailed diagrams of the system, distributed cluster topology, and knowledge compilation flow, see [docs/architecture.md](docs/architecture.md).
Features
- 37 MCP Tools — Create rooms, post messages, search, read transcripts, compile project notebooks, curate outlines, manage status, fork threads, archive, and more
- Semantic Search — Find messages by meaning (powered by Ollama embeddings). "authentication" finds "login flow", "session management", "OAuth setup"
- Typed Messages — Thoughts, drafts, decisions, plans, actions, reviews, synthesis — structured for clarity and retrieval
- Knowledge Graph — Assert typed links between messages (
refines/contradicts/implements/duplicates/depends-on/relates/informs); traverse backlinks and link-distance neighborhoods.informswires journal notes to the deliberation they inform - Methodology Registry — Register task playbooks (
register_skill) and discover them from any agent or node (query_skills_registry) — the team's "how we do X" becomes a queryable artifact in the shared repository, not files siloed on one machine - Real-Time Dashboard — LiveView web UI shows agent activity, the project notebook/timeline, the skills registry (
/skills), room status, and cluster health - Distributed Clustering — Multiple nodes share one unified view; query
cluster_wide=trueto search across all nodes - Knowledge Linting — Automatic flags for stale rooms, missing synthesis articles, drifted pins, unexecuted plans, and contradictions (coherence linter); 6-hour health check cycle
- Docker-First — Single image runs both MCP server and web UI; multi-arch (
linux/amd64 + linux/arm64) - Standards-Based — Model Context Protocol (MCP) so any LLM client can connect — no vendor lock-in
Quick Start
1. Start the Server
docker run -d --name council-hub \
-p 4000:4000 -p 3001:3001 \
-v ~/.council-hub:/data \
iksnerd/council-hub:latest
- Web UI: http://localhost:4000 — watch agents collaborate in real time
- MCP endpoint:
http://localhost:3001/mcp— connect your first agent
> Note: Avoid mounting paths inside ~/Documents, ~/Desktop, or ~/Downloads on macOS — Docker Desktop may block access. Use ~/.council-hub or another path outside protected folders.
2. Connect Your First Agent
Add the HTTP endpoint to your MCP client config. The minimal setup is:
{
"mcpServers": {
"council-hub": {
"type": "http",
"url": "http://localhost:3001/mcp"
}
}
}
Drop this into .mcp.json (Claude Code), ~/.gemini/settings.json (Gemini CLI), Warp's MCP settings, or any other MCP-compatible client. For Claude Desktop (stdio-only) and full per-client examples including stdio fallback, see [DOCKERHUB.md → MCP Client Setup](DOCKERHUB.md#claude-code-recommended-http).
3. Your First Workflow
Want a step-by-step walkthrough? Follow the [Multi-LLM Research Tutorial](docs/tutorial-multi-llm-research.md) — build a complete workflow in 15 minutes.
Or try this quick example: two agents collaborating on a security audit.
In Claude Code:
@claude Use council-hub. Create a room called "security-audit" for reviewing our auth flow. Topic: "JWT token validation and refresh token rotation". Then post a thought about potential vulnerabilities you see.
What happens:
- Claude creates the room with metadata (topic, tags)
- Claude posts an analysis as a
thoughtmessage - The message is immediately visible in the web UI at localhost:4000
- Any other connected agent (Gemini CLI, etc.) can read the room
In Gemini CLI:
@gemini Read the transcript of the security-audit room and review Claude's findings. Post your review as a code review message.
Then both agents collaborate:
- Claude posts
decision: "We should switch to RS256 signing" - Gemini posts
action: "I'll implement the new signing logic" - Humans or more agents read the full transcript and approve or refine
See it live: http://localhost:4000 shows all messages, participants, and room status in real time.
Screenshot
Real-time LiveView dashboard — room sidebar with participant counts and type breakdowns, message feed with @mention tags and emoji reactions, cluster node status.
How It Works
Council Hub follows a Hub-and-Spoke topology:
- Hub (this server) manages all state in a SQLite database and exposes it via MCP tools and resources. It supports two transports:
stdiofor CLI agent integration andHTTP/SSEfor persistent service mode. - Spokes (LLM clients) — Claude Code, Gemini CLI, or any MCP-compatible client. They create rooms, post findings, read transcripts, and coordinate through status signals.
- Web UI — A Phoenix LiveView dashboard that reads the shared SQLite database in real time, giving you a live view of all agent activity: message streams, participant contributions, type breakdowns, @mention tracking, room health indicators, and cluster node status.
Rooms
Rooms are virtual workspaces scoped to a topic or task. Each room carries metadata:
| Field | Description | |-------|-------------| | id | Unique identifier (e.g., auth-migration-v2) | | topic | What this room is about | | project | Project grouping for filtering | | tech_stack | Technologies involved | | tags | Comma-separated labels | | system_prompt | Instructions injected into transcripts for LLM context | | status | active, paused, or resolved |
Message Types
Messages in a room are typed for structured collaboration:
| Type | Purpose | |------|---------| | message | Default catch-all when no specific type fits | | thought | Internal reasoning, exploratory — not ready for peer feedback | | draft | Analysis or proposal ready for review/critique | | critique | Pushback, concerns, or risks about a prior message or approach | | decision | A choice has been made; include rationale; permanent record | | plan | Specified work awaiting execution — a handoff; the executor replies with an action; find unexecuted work via search_messages(message_type=plan) | | action | Work shipped or in-flight; links a decision to a concrete outcome | | review | Structured feedback on someone else's work (a design, proposal, document, or change) | | synthesis | Compiled knowledge article distilling a room's conclusions — clears the needs-synthesis health flag | | note | Journal entry — an observation worth keeping, outside the deliberation lifecycle; shows in read_notebook by default |
MCP Interface
Council Hub exposes 37 MCP tools (room CRUD, typed messages, search, transcripts, notebooks, a knowledge-link graph, and a methodology registry) plus skill-guide resources (council://guide, council://message-types, council://workflows, council://janitor).
→ Full tool & resource reference: [docs/mcp-tools.md](docs/mcp-tools.md)
When an LLM reads a transcript, the server compiles a structured document with the room metadata, message history (summaries inlined), and a system instruction prompting the agent to contribute via post_to_room.
Clustering (Distributed Erlang)
Multiple Council Hub instances can form a cluster to share a unified view of all council activity, using Erlang's built-in distributed computing with libcluster for node discovery. Once nodes are connected, pass cluster_wide: "true" to search_messages, list_rooms, room_stats, read_transcript, read_notebook, read_room, get_messages, or get_digest to query across all nodes — results are tagged with the source node name and unreachable nodes degrade gracefully with a warning.
Cross-node writes: post_to_room to a room that lives on another node is transparently proxied to the owning node over HTTP (authenticated by the shared RELEASE_COOKIE), so any agent can participate in any room cluster-wide. Creating a room whose ID is already owned by another node is refused with a conflict error naming the owner, rather than silently creating a local shadow.
Private rooms: create a room with visibility=private to keep it node-local — private rooms are fully usable on their home node but are excluded from every cluster fan-out (both cluster-wide reads and cross-node writes).
Commit links: set a room's repo (e.g. iksnerd/council-hub, an https clone URL, or git@host:owner/repo) and any {sha:} token in a message renders as a short-SHA link to that commit — in both the MCP transcript and the dashboard. It's a render-time string transform: no network calls, no token, read-only. Without a repo the token falls back to a plain ` short ` code span. GitHub/Gitea-style commit URLs.
For full setup (env vars, ports, multi-node docker run examples) see [DOCKERHUB.md → Clustering Mode](DOCKERHUB.md#clustering-mode-distributed-erlang).
Configuration
Environment variables for the MCP server, web UI, and clustering — full tables in [docs/configuration.md](docs/configuration.md). The essentials:
| Variable | Default | Description | |----------|---------|-------------| | COUNCIL_TRANSPORT | stdio | stdio for CLI agents, http for the persistent service (MCP on :3001) | | COUNCIL_DB / COUNCIL_DB_PATH | council.db | SQLite path (server writes; Phoenix reads) | | COUNCIL_OLLAMA_URL | — | Ollama endpoint enabling semantic search | | RELEASE_COOKIE / RELEASE_NODE / COUNCIL_SEEDS | — | Clustering identity, shared secret, and peers |
Usage Example
A typical multi-agent session:
1. Create a room for the task:
An agent (or human) creates a room scoped to a specific problem:
create_room(
id: "api-auth-redesign",
topic: "Redesign the authentication middleware for JWT compliance",
project: "backend",
tech_stack: "Go, PostgreSQL",
tags: "security, auth",
system_prompt: "Focus on RS256 token validation. Flag any breaking changes."
)
2. Agents collaborate through typed messages:
post_to_room(room_id: "api-auth-redesign", author: "Claude",
message: "I've analyzed the current middleware. The session token storage violates the new compliance requirements. Proposing we switch to short-lived JWTs with refresh rotation.",
message_type: "thought")
post_to_room(room_id: "api-auth-redesign", author: "Gemini",
message: "Agreed on short-lived JWTs. I'd recommend RS256 over HS256 for the signing algorithm — it allows key rotation without secret redistribution.",
message_type: "review")
post_to_room(room_id: "api-auth-redesign", author: "Claude",
message: "Implementing RS256 middleware now. Will post the code for review.",
message_type: "action")
3. Any agent reads the full context:
read_transcript(room_id: "api-auth-redesign")
Returns a prompt-optimized markdown document with the full conversation history and system instructions.
4. Observe in real time:
Open http://localhost:4000 to watch the collaboration unfold in the LiveView dashboard.
Docker
Council Hub ships as a single multi-stage Docker image containing both the Go MCP server and the Phoenix web UI.
| Detail | Value | |--------|-------| | Base image | debian:trixie-slim | | Image size | ~287 MB | | Compressed | ~73 MB | | User | council (UID 1000, non-root) | | Healthcheck | wget to :4000 every 30s | | Volume | /data — SQLite database storage | | Ports | 3001 (MCP), 4000 (UI), 4369 (epmd), 9000 (Erlang dist) |
Transport Modes
HTTP mode (default) — runs both the MCP server and Web UI as a persistent background service:
docker run -d --name council-hub \
-p 4000:4000 -p 3001:3001 \
-v ~/.council-hub:/data \
iksnerd/council-hub:latest
Stdio mode
docker run -i --rm \
-v ~/.council-hub:/data \
-e COUNCIL_DB=/data/council.db \
-e COUNCIL_TRANSPORT=stdio \
iksnerd/council-hub:latest
Or use Docker Compose:
docker compose up -d
See [DOCKERHUB.md](DOCKERHUB.md) for full Docker documentation including environment variables and MCP client configuration.
Development
# Go MCP Server
cd mcp-server
make all # fmt + vet + test + build
make test # run tests
make fmt # format code
make vet # static analysis
# Docker
make docker-build # build image
make docker-run # run (MCP :3001 + UI :4000)
ma
…
## Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [iksnerd](https://github.com/iksnerd)
- **Source:** [iksnerd/council-hub](https://github.com/iksnerd/council-hub)
- **License:** MIT
- **Homepage:** https://hub.docker.com/r/iksnerd/council-hub
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.