Multi-agent orchestration with loop prevention, contribution scoring, and MCP integration
Project description
Cohort
Multi-agent orchestration with loop prevention, contribution scoring, and MCP integration.
Cohort manages structured discussions between AI agents. It decides who speaks next, prevents conversational loops, and scores contributions across five dimensions -- so your agents stay productive instead of talking in circles.
Why Cohort?
Every multi-agent framework lets agents talk. Cohort decides who should talk, when they should stop, and whether what they said was worth hearing.
| Cohort | CrewAI | LangGraph | |
|---|---|---|---|
| Core deps | 0 | 25+ | 30+ (transitive) |
| Default inference | Local (Ollama / llama.cpp) | Cloud (OpenAI) | Cloud (varies) |
| API key required | No (local) / optional (cloud) | Yes | Yes |
| Contribution scoring | 5-dimension engine | -- | -- |
| Loop prevention | Architectural (recency + novelty + gating) | Max iterations (timeout) | Conditional edges (manual) |
| Data leaves your machine | Your choice (local default) | Yes + telemetry | Optional |
| MCP integration | Built-in (lite + full modes) | -- | -- |
| Cost | $0 local | API + $99-$10K Enterprise | API + $39/seat Platform |
Zero dependencies. pip install cohort pulls nothing. Your agents, your hardware, your data.
Extracted from production. These patterns weren't designed from theory -- they were extracted from a system running 60+ agents, then packaged clean with 785+ tests.
Claude Code Channels Integration
Cohort was the first third-party integration with Claude Code Channels -- Anthropic's protocol for persistent, event-driven agent sessions.
03:00 AM MT -- Anthropic ships Claude Code Channels (research preview)
06:03 AM MT -- Cohort integration committed. Agent pipeline operational.
06:45 AM MT -- Working checkpoint. CLI module, agent enrichment, context hydration.
07:11 AM MT -- First multi-round agent roundtable via Channels.
Channels give Cohort agents persistent sessions with automatic context hydration, idle reaping, and priority-based eviction. Agents respond to events -- CI results, chat messages, monitoring alerts -- even when you're not at the terminal.
This is what Cohort is built for: when a new protocol drops, the orchestration layer is already there. You just plug it in.
Features
- Zero dependencies --
pip install cohortpulls nothing - MCP integration -- Claude Code tools for channels, agents, search, checklists (works standalone or with server)
- Contribution scoring -- 5-dimension relevance matrix (novelty, expertise, ownership, phase alignment, data ownership)
- Loop prevention -- Stakeholder gating keeps agents from repeating each other
- Topic shift detection -- Automatically re-engages relevant agents when the conversation changes direction
- Local LLM -- Hardware detection, Ollama/llama.cpp integration, setup wizard
- Protocol-first design --
AgentProfileandStorageBackendare@runtime_checkableprotocols. Bring your own agents and storage.
Install
pip install cohort # zero-dep core — file storage, CLI, scoring engine
pip install cohort[lite] # same as above, explicit lite path (file-based MCP simulation)
pip install cohort[mcp] # adds MCP server for any client (Cursor, Windsurf, etc.)
pip install cohort[claude] # recommended — full Claude Code experience + setup wizard
pip install cohort[all] # everything including dev tools
Requires Python 3.11+.
MCP Integration
Cohort includes a built-in MCP server with two operating modes:
Lite mode (standalone, no server required):
{
"mcpServers": {
"cohort": {
"command": "cohort",
"args": ["mcp"],
"env": {
"COHORT_DATA_DIR": "/path/to/your/data"
}
}
}
}
Lite mode operates directly on file-based storage. Channels, messages, agent profiles, checklists, and search all work without any server process.
Full mode (auto-detected when Cohort server is running):
If a Cohort server is running on localhost:5100, the MCP server automatically upgrades to full mode with live agent routing, real-time sessions, work queue, and briefing generation.
Available MCP Tools
| Tool | [mcp] |
[claude] |
Description |
|---|---|---|---|
read_channel |
Yes | Yes | Read messages from a channel |
post_message |
Yes | Yes | Post a message to a channel |
list_channels |
Yes | Yes | List all channels |
cohort_create_channel |
Yes | Yes | Create a new channel |
channel_summary |
Yes | Yes | Compact activity summary |
cohort_list_agents |
Yes | Yes | List all agents |
cohort_get_agent |
Yes | Yes | Get agent details |
cohort_get_agent_memory |
Yes | Yes | View agent memory |
cohort_add_fact |
Yes | Yes | Add a learned fact |
cohort_clean_memory |
Yes | Yes | Trim working memory |
cohort_search_messages |
Yes | Yes | Search across channels |
get_checklist |
Yes | Yes | Read to-do checklist |
update_checklist |
Yes | Yes | Add/complete/remove tasks |
condense_channel |
-- | Yes | LLM-powered channel summarisation |
cohort_create_agent |
-- | Yes | Create a new agent |
cohort_discussion |
-- | Yes | Live multi-agent discussion (server required) |
cohort_compiled_discussion |
-- | Yes | Single-call multi-agent discussion (local Ollama) |
cohort_adopt_persona |
-- | Yes | Adopt an agent's persona for the conversation |
Quick Start (Python API)
from cohort import JsonFileStorage, Orchestrator
from cohort.chat import ChatManager
# 1. Set up storage and chat
chat = ChatManager(JsonFileStorage("my_data"))
chat.create_channel("design-review", "API design review")
# 2. Define your agents (triggers and capabilities drive scoring)
agents = {
"architect": {"triggers": ["api", "design"], "capabilities": ["backend architecture"]},
"tester": {"triggers": ["testing", "qa"], "capabilities": ["test strategy"]},
}
# 3. Post a message and start a session
chat.post_message("design-review", sender="user", content="Review the REST API design")
orch = Orchestrator(chat, agents=agents)
session = orch.start_session("design-review", "REST API design review", initial_agents=list(agents))
# 4. Ask who should speak next
rec = orch.get_next_speaker(session.session_id)
print(f"Next speaker: {rec['recommended_speaker']}")
print(f"Reason: {rec['reason']}")
# 5. Record turns and let Cohort manage the flow
orch.record_turn(session.session_id, "architect", "msg-001")
CLI
Cohort includes CLI commands for file-based collaboration. Agents in any language can participate by appending to a shared .jsonl file.
# Append a message
python -m cohort say --sender architect --channel review --file conv.jsonl \
--message "We should use pagination for the list endpoint"
# Check if an agent should respond (exit 0 = speak, exit 1 = don't)
python -m cohort gate --agent tester --channel review --file conv.jsonl \
--agents agents.json --format json
# Rank who should speak next
python -m cohort next-speaker --channel review --file conv.jsonl \
--agents agents.json --top 3
# Generate an executive briefing
python -m cohort briefing generate --hours 24
# Interactive setup wizard (Ollama + model selection)
python -m cohort setup
Architecture
+-----------------+
| Orchestrator | Session management, turn control
+--------+--------+
|
+--------------+--------------+
| |
+--------+--------+ +--------+--------+
| ChatManager | | Meeting |
| channels, messages| | scoring, gating |
+--------+--------+ +-----------------+
|
+--------+--------+
| StorageBackend | (Protocol -- bring your own)
| JsonFileStorage | (default: flat-file JSON)
| SqliteStorage | (optional: SQLite)
+-----------------+
Orchestrator manages sessions: who's invited, whose turn it is, when the topic shifts.
Meeting scores each agent across five dimensions before allowing them to speak:
| Dimension | Weight | What it measures |
|---|---|---|
| Domain expertise | 30% | Keyword overlap between topic and agent triggers/capabilities |
| Complementary value | 25% | Are this agent's partners active? |
| Historical success | 20% | Past performance on similar topics |
| Phase alignment | 15% | Is this the right agent for the current workflow phase? |
| Data ownership | 10% | Does this agent own data relevant to the topic? |
Agents move through stakeholder statuses: active -> approved_silent -> observer -> dormant. Each status raises the threshold to speak, preventing agents from dominating.
Local LLM Integration
Cohort includes built-in support for local inference:
python -m cohort setup # Interactive wizard: detects GPU, installs Ollama, picks model
- Hardware detection -- Identifies GPU VRAM and recommends appropriate models
- Ollama client -- Direct integration for local inference
- llama.cpp support -- For direct GGUF model serving
- Model routing -- Automatic model selection based on task complexity
Protocols
Cohort uses Python protocols -- no base classes required:
from cohort import AgentProfile, StorageBackend
class MyAgent:
name: str = "custom"
role: str = "specialist"
capabilities: list[str] = ["custom-domain"]
def relevance_score(self, topic: str) -> float:
return 0.8 if "custom" in topic else 0.2
def can_contribute(self, context: dict) -> bool:
return True
assert isinstance(MyAgent(), AgentProfile) # True -- duck typing
Development
git clone https://github.com/rwheeler007/cohort.git
cd cohort
pip install -e ".[dev]"
pytest
ruff check cohort/ tests/
mypy cohort/
License
Apache 2.0 -- see LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cohort-0.4.47.tar.gz.
File metadata
- Download URL: cohort-0.4.47.tar.gz
- Upload date:
- Size: 37.3 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4826e3e49df8ad6fff34291d4f495d116a0f9b8022d63e4c3a2426b8a985c92d
|
|
| MD5 |
ea2e619c139eaebb93a411bd5513fc27
|
|
| BLAKE2b-256 |
4e861ef2a338da398a7e4f5bfce40a52b8905175a4973efb3ef2966b5895b5c3
|
Provenance
The following attestation bundles were made for cohort-0.4.47.tar.gz:
Publisher:
ci.yml on rwheeler007/cohort
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cohort-0.4.47.tar.gz -
Subject digest:
4826e3e49df8ad6fff34291d4f495d116a0f9b8022d63e4c3a2426b8a985c92d - Sigstore transparency entry: 1236376089
- Sigstore integration time:
-
Permalink:
rwheeler007/cohort@73534cf2cac53e63f097fa941f4ccbfbe8530f73 -
Branch / Tag:
refs/tags/v0.4.47 - Owner: https://github.com/rwheeler007
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@73534cf2cac53e63f097fa941f4ccbfbe8530f73 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cohort-0.4.47-py3-none-any.whl.
File metadata
- Download URL: cohort-0.4.47-py3-none-any.whl
- Upload date:
- Size: 810.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6aeb0058d1a6c392d7609c4d65e8a55f5596f344bd6979067782ed2a13695065
|
|
| MD5 |
9e2730eea7eb530e786d59ad2efae613
|
|
| BLAKE2b-256 |
b1c040432a90d7bb88b4433c7642b5dffd298a2f42e38689c47fa8580fe383e7
|
Provenance
The following attestation bundles were made for cohort-0.4.47-py3-none-any.whl:
Publisher:
ci.yml on rwheeler007/cohort
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cohort-0.4.47-py3-none-any.whl -
Subject digest:
6aeb0058d1a6c392d7609c4d65e8a55f5596f344bd6979067782ed2a13695065 - Sigstore transparency entry: 1236376191
- Sigstore integration time:
-
Permalink:
rwheeler007/cohort@73534cf2cac53e63f097fa941f4ccbfbe8530f73 -
Branch / Tag:
refs/tags/v0.4.47 - Owner: https://github.com/rwheeler007
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@73534cf2cac53e63f097fa941f4ccbfbe8530f73 -
Trigger Event:
push
-
Statement type: