MCP server for multi-model AI discussions — cloud, agentic CLIs, local GPU models, soul memory
Project description
Chitta Bridge
MCP server for multi-model AI discussions — works with Claude Code and Codex CLI. Connect to any AI backend: cloud agentic CLIs and local GPU models.
Quick Start
uv pip install git+https://github.com/genomewalker/chitta-bridge.git
chitta-bridge-install # both Claude Code + Codex
chitta-bridge-install claude-code # Claude Code only
chitta-bridge-install codex # Codex CLI only
Skills (Codex): /review, /rescue, /room, /soul — plus all mcp__chitta_bridge__* tools.
Features
- Multiple backends: Codex CLI and local GPU models (Ollama/vLLM)
- Continuous sessions: Conversation history persists across messages
- Session warmup: background ping captures session ID — subsequent calls skip cold start
- Agentic execution: Full-auto mode with sandboxed file operations (Codex)
- Variant control: Set reasoning effort (minimal to max)
- File/image attachment: Share code files and images for context
- Discussion rooms: async multi-agent roundtables — any mix of backends respond in parallel, see the full thread, synthesize into one answer
Installation
With uv (recommended)
uv pip install git+https://github.com/genomewalker/chitta-bridge.git
With pip
pip install git+https://github.com/genomewalker/chitta-bridge.git
From source
git clone https://github.com/genomewalker/chitta-bridge.git
cd chitta-bridge
pip install -e .
Register
chitta-bridge-install # install for both Claude Code and Codex
chitta-bridge-install claude-code # Claude Code only (registers MCP server)
chitta-bridge-install codex # Codex CLI only (plugin + skills + MCP)
chitta-bridge-uninstall # uninstall from both
chitta-bridge-uninstall codex # uninstall from Codex only
Verify: claude mcp list (Claude Code) or check ~/.codex/plugins/ (Codex)
Shared With cc-soul
When cc-soul is installed on the same machine, chitta-bridge should be treated as a frontend adapter, not a separate memory stack:
cc-soulowns the shared backend:chittad,chitta,chitta-mcp, and~/.claude/mindchitta-bridgeadds Codex- and MCP-facing tools on top of that backend- updating
chitta-bridgechanges frontend glue, not the shared daemon or memory store
For a dual-frontend setup, install the shared backend first, then add adapters:
cd cc-soul
./scripts/shared-stack.sh install all
Discussion Rooms
Async multi-agent roundtable with agent souls — participants get persistent identity, memory, tools, and structured challenge rounds.
Basic Room
room_create(
room_id="my-room",
topic="What's the best way to design a cache invalidation strategy?",
participants='[
{"name":"Codex","backend":"codex","session_id":"codex-1"},
{"name":"Llama","backend":"local","model":"qwen2.5:32b","base_url":"http://gpunode:11434/v1"}
]'
)
room_run(room_id="my-room", rounds=2)
room_synthesize(room_id="my-room")
Soul-Powered Room
Each participant can have a soul — a system prompt, memory namespace, tools, challenge bias, and response format:
room_create(
room_id="expert-panel",
topic="How should we authenticate ancient DNA from permafrost?",
participants='[
{"name":"Paleogenomicist","backend":"local","model":"qwen2.5:32b",
"base_url":"http://gpunode:11434/v1",
"soul":{
"system_prompt":"You are a senior paleogenomicist with 15+ years experience...",
"realm":"agent:paleogenomicist",
"tools":["recall","remember","web_search","smart_context"],
"max_tool_turns":2,
"challenge_bias":0.7,
"response_format":"### Key Points\\n### Tools & Thresholds\\n### Caveats"
}},
{"name":"Bioinformatician","backend":"local","model":"phi4:14b",
"base_url":"http://gpunode:11434/v1",
"soul":{
"system_prompt":"You are a computational biologist specializing in pipelines...",
"realm":"agent:bioinformatician",
"tools":["recall","remember","smart_context"],
"challenge_bias":0.4
}}
]'
)
# Challenge mode: between rounds, a moderator extracts claims and
# forces participants to disagree, provide evidence, and refine
room_run(room_id="expert-panel", rounds=2, challenge=true)
room_synthesize(room_id="expert-panel")
Soul Features
| Feature | Description |
|---|---|
system_prompt |
Agent identity, expertise, personality |
realm |
Chitta memory namespace — per-agent persistent memory |
tools |
Available tools (see Agent Tools below) |
max_tool_turns |
Max tool-use iterations per response (default 3) |
max_rounds |
Max discussion rounds, 0 = unlimited |
challenge_bias |
0 = agreeable, 1 = devil's advocate |
response_format |
Structured output template |
Challenge Rounds
When challenge=true, a moderator automatically:
- Extracts substantive claims from the previous round
- Injects a challenge prompt requiring each participant to disagree with at least one claim
- Forces evidence-based refinement instead of polite agreement
GPU Contention Handling
When multiple local models share the same GPU endpoint, rooms automatically run participants sequentially to avoid model-swap thrashing. Different endpoints run in parallel.
Conductor Fusion
Runs a conductor-style orchestration (arXiv:2512.04388) as a single call: each agent gets a distinct subtask and explicit visibility over peers, then a judge synthesizes. It compiles the workflow into preambles + a per-round visibility matrix automatically — no manual room_create/room_run needed. Use it for tasks that benefit from information asymmetry (a Thinker proposing blind, Workers extending on different angles, a Verifier checking without cross-contamination).
conductor_fusion runs async: it returns room_id immediately (status "running") instead of blocking for the full discussion, so there's no request timeout on long multi-round runs.
conductor_fusion(
topic="Design a fast HNSW build for 144k vectors",
workflow='[
{"agent":"claude:opus:xhigh", "subtask":"Thinker: propose a complete answer independently.", "sees":"none"},
{"agent":"codex:gpt-5.5", "subtask":"Worker: build on or extend the Thinker.", "sees":["Opus"]},
{"agent":"claude:opus:high", "subtask":"Verifier: critique both, cite 2+ specific issues.", "sees":["Opus","GPT-5.5"]}
]',
rounds=1,
project_roots=["/path/to/target/repo"]
)
# → {"room_id": "conductor-ab12cd34", "status": "running", ...}
room_status(room_id="conductor-ab12cd34") # poll: rounds_done/rounds_total, status
room_read(room_id="conductor-ab12cd34") # once done: full transcript + synthesis
Omit workflow to get the default TRINITY panel shown above (Thinker/Worker/Verifier). Each step takes:
| Field | Description |
|---|---|
agent |
backend:model[:effort] shorthand (same as fusion). Default claude:opus:xhigh |
subtask |
Injected as this agent's preamble |
sees |
Agent name(s) it can see, or "all"/"none" |
name |
Optional explicit display name (else derived from agent) |
role |
Optional explicit role (thinker/worker/verifier/synthesizer); else inferred from subtask keywords |
depends |
Optional scheduling deps; defaults to sees |
Other params: judge (synthesis model, default claude:opus:max), adversarial (majority/minority split), files, preamble (shared across all agents).
project_roots should be set explicitly whenever the target codebase's real paths are only described in subtask/preamble text rather than attached via files — otherwise chittad's code-intel/memory recall are unscoped across every indexed project, and agents can silently ground claims in the wrong repo. Derived automatically from files when present.
All conductor_fusion participants get full tool access (participant_tools=["all"]), including bash — they are not restricted to read-only reasoning unless a step sets quarantine explicitly.
Room Tools
| Tool | Description |
|---|---|
room_create |
Create a discussion room with named participants and optional souls |
room_add_participant |
Add a participant to an existing room |
room_run |
Run N rounds with optional challenge mode |
room_read |
Read the full transcript |
room_synthesize |
Distill the transcript — consensus, disagreements, best answer, open questions |
room_status |
Poll an async room (e.g. conductor_fusion) for rounds-done/total and completion status |
conductor_fusion |
One-call conductor-style orchestration — see above |
Agent Tools
Tools available to soul-powered room participants via mediated XML tool calling. Assign a subset per agent via the tools field.
Memory (core)
| Tool | Description |
|---|---|
recall |
Semantic vector search over agent's memory realm |
remember |
Store an insight or fact in agent's memory realm |
smart_context |
Task-aware context assembly (memories + code symbols + graph) |
Memory (extended)
| Tool | Description |
|---|---|
recall_keyword |
BM25 keyword search — best when exact terms are known |
recall_temporal |
Search memories from a specific time range (since/until) |
hybrid_recall |
Combined vector + BM25 search — best general-purpose recall |
5w_search |
Structured who/what/when/where/why search |
forget |
Remove a memory by similarity match |
Web
| Tool | Description |
|---|---|
web_search |
DuckDuckGo search, returns titles + URLs + snippets |
web_fetch |
Fetch a URL as plain text (HTML stripped, max 8000 chars) |
File operations
| Tool | Description |
|---|---|
read_file |
Read file with line numbers (offset/limit, capped at 500 lines) |
write_file |
Create or overwrite a file (auto-creates parent dirs) |
edit_file |
Targeted string replacement with context display |
glob |
Find files by glob pattern, sorted by modification time |
grep |
Regex search over file contents with context lines |
Shell
| Tool | Description |
|---|---|
bash |
Execute a shell command (sandboxed, 60s timeout, dangerous commands blocked) |
Code intelligence (via chitta)
| Tool | Description |
|---|---|
read_function |
Read a function's source code by name |
read_symbol |
Look up any code symbol (class, function, variable) |
search_symbols |
Search for code symbols matching a query |
codebase_overview |
High-level overview of codebase structure |
Task tracking
| Tool | Description |
|---|---|
todo_add |
Add a task to the agent's personal todo list |
todo_list |
List current todo items |
todo_done |
Mark a todo item as complete |
Synthesis
After running a room, distill the full discussion into a single answer. Any backend can act as synthesizer — Claude (default), local GPU model, or Codex.
room_synthesize(room_id="my-room")
# Use a local model as synthesizer
room_synthesize(
room_id="my-room",
synthesizer='{"name":"Qwen3","backend":"local","model":"qwen3:30b-a3b","base_url":"http://gpunode:11434/v1"}'
)
Local Models (GPU Nodes)
Chat with local LLMs (Ollama / vLLM) running on GPU nodes — via Slurm auto-discovery or direct hostname.
# 1. Start Ollama on a Slurm GPU node — writes URL to
# $CHITTA_BRIDGE_URL_DIR/ollama-server-<model>.url
# (default: ~/.chitta-bridge/endpoints)
slurm-serve-ollama.sh llama3.3:70b
# 2. Discover available nodes and models
local_discover()
# 3. Start a session (auto-discovers endpoint if omitted)
local_start(session_id="llm1", model="llama3.3:70b")
# 4. Chat
local_discuss(message="Explain cache invalidation strategies")
# Or specify node explicitly
local_start(session_id="llm2", model="qwen3:30b-a3b", endpoint="http://gpunode01:11434/v1")
Discovery order
- URL cache files in
$CHITTA_BRIDGE_URL_DIR(default~/.chitta-bridge/endpoints, written byslurm-serve-ollama.sh) - Your running Slurm GPU jobs (
squeue --me) CHITTA_BRIDGE_GPU_NODES=node1,node2environment variablelocalhost:11434fallback
Environment variables
| Variable | Default | Purpose |
|---|---|---|
CHITTA_BRIDGE_URL_DIR |
~/.chitta-bridge/endpoints |
Where slurm-serve-ollama.sh writes endpoint URL files and the bridge reads them. Set to a shared NFS path on multi-node clusters. |
CHITTA_BRIDGE_LOG_DIR |
~/.chitta-bridge/logs |
Slurm/ollama log destination used by slurm-serve-ollama.sh. |
CHITTA_BRIDGE_GPU_NODES |
unset | Comma-separated nodes to probe for Ollama (node1,node2). |
OLLAMA_BIN |
$(command -v ollama) |
Path to the ollama binary used by the slurm script. |
OLLAMA_MODELS |
~/.ollama/models |
Where Ollama stores pulled models. |
Run chitta-bridge-doctor to verify the install: it checks CLI presence, the URL directory, persisted session/job JSON integrity, and any unknown effort/sandbox values in saved state.
| Tool | Description |
|---|---|
local_discover |
Find GPU nodes with Ollama/vLLM running |
local_start |
Start a session (auto-discovers endpoint) |
local_discuss |
Chat with the local model |
local_models |
List models available at an endpoint |
local_sessions |
List active local sessions |
local_switch |
Switch active session |
local_end |
End a session |
local_history |
Show conversation history |
local_health |
Health check |
Web Search
Search the web and fetch pages directly from Claude Code — no API key needed (DuckDuckGo).
# Search
web_search(query="ancient metagenomics DNA damage authentication")
# Fetch a page
web_fetch(url="https://example.com/article", max_chars=12000)
| Tool | Description |
|---|---|
web_search |
Search via DuckDuckGo — returns titles, URLs, snippets |
web_fetch |
Fetch a web page as plain text (HTML stripped) |
Browser Fetch (Cloudflare bypass)
browser_fetch upgrades web_fetch for Cloudflare-protected pages. It uses a
three-tier stack: fast TLS impersonation first, then a headless Firefox cookie mint
only when challenged, then a cached retry — so the heavy browser fires at most once
per domain per ~25 min TTL.
Install the optional stack
# via the Claude Code skill (recommended)
/bridge-install-browser
# or manually
uv pip install "chitta-bridge[browser]" # installs curl_cffi + playwright==1.49
python -m playwright install firefox # base Firefox binary
python -m camoufox fetch # download the fortified camoufox binary (~700 MB)
Note:
camoufoxrequiresplaywright==1.49exactly — newer versions break the binary download. The[browser]extra pins this automatically.
Usage
# Same interface as web_fetch — falls back gracefully if stack is absent
browser_fetch(url="https://cloudflare-protected-site.com/article", render=False)
# render=True forces a full camoufox load for JS-rendered (SPA) pages
browser_fetch(url="https://spa-site.com", render=True)
| Option | Default | Effect |
|---|---|---|
render |
False |
Force full camoufox load (needed for SPA / heavy JS pages) |
max_chars |
20000 |
Truncate output |
If curl_cffi is not installed, browser_fetch falls back to the standard web_fetch
path automatically — no error, just a note in the output.
Soul Memory (chittad)
Bidirectional memory bridge to the cc-soul daemon with realm-scoped memory. Each room participant can have its own memory namespace, and room discussions automatically pull relevant memories as context.
# Check if soul is running
soul_status()
# Recall memories (global or realm-scoped)
soul_recall(query="cache invalidation strategies", limit=5)
# Store a memory
soul_remember(content="Room discussion concluded X is better than Y", kind="episode")
# Smart context (memories + code symbols + graph)
soul_context(task="refactor authentication middleware")
| Tool | Description |
|---|---|
soul_recall |
Search memories by query (supports realm scoping) |
soul_remember |
Store a new memory (supports realm scoping) |
soul_context |
Smart context assembly (memories + symbols + graph) |
soul_status |
Check if chittad is available |
Discussion rooms automatically:
- Seed agent realms on first turn — identity and topic stored for future recall
- Inject soul context at creation — participants see relevant memories (code symbols filtered)
- Store contributions back — each agent's response stored in their realm
- Store synthesis back — room conclusions become soul episodes
- Hybrid recall — vector + BM25 keyword matching for better memory retrieval
Codex Backend
Session tools
| Tool | Description |
|---|---|
codex_start |
Start a new Codex session |
codex_discuss |
Send a message to Codex |
codex_run |
Run a one-off task (stateless, returns session ID) |
codex_model |
Change session model |
codex_config |
Show Codex configuration |
codex_configure |
Set Codex defaults (persisted) |
codex_history |
Show conversation history |
codex_sessions |
List all Codex sessions |
codex_switch |
Switch to another session |
codex_end |
End current session |
codex_health |
Codex health check |
Review (normal + adversarial)
| Tool | Description |
|---|---|
codex_review |
Code review with mode (normal/adversarial), focus, --base, effort, background, sandbox |
Adversarial mode challenges design decisions, architecture, and tradeoffs instead of just finding bugs:
codex_review(mode="adversarial", focus="race conditions and data loss", base="main")
codex_review(mode="adversarial", background=True) # returns job ID
Rescue (background job delegation)
| Tool | Description |
|---|---|
codex_rescue |
Delegate a task to Codex — supports background, resume_from, effort, fresh, sandbox |
codex_job_status |
Check progress of background rescue jobs |
codex_job_result |
Get final output + Codex session ID for codex resume |
codex_job_cancel |
Cancel a running background job |
# Start a background rescue
codex_rescue(task="investigate why the tests started failing", background=True)
# Check progress
codex_job_status()
# Get result (includes session ID for native Codex resume)
codex_job_result()
# Resume a previous session
codex_rescue(task="apply the fix", resume_from="SESSION_ID")
# Full access (network + filesystem)
codex_rescue(task="fetch and apply the upstream patch", sandbox="danger-full-access")
Codex Plugin for Codex CLI
chitta-bridge ships as a proper Codex plugin with skills and MCP tools:
chitta-bridge-install codex # install
chitta-bridge-uninstall codex # uninstall
This installs to ~/.codex/plugins/cache/local/chitta-bridge/local/ and enables:
- Skills:
/review,/rescue,/room,/soul - Tools: All
mcp__chitta_bridge__*tools (soul memory, rooms, web, jobs)
Available Models
Codex
| Model | Description |
|---|---|
| o3 | Default, high capability |
| o4-mini | Faster, lower cost |
| gpt-4.1 | Alternative option |
Local (Ollama / vLLM)
Any model available at your Ollama or vLLM endpoint. Run local_models() to list what's available on a node.
Configuration
Environment variables
# Codex
export CODEX_MODEL="o3"
export CODEX_SANDBOX="workspace-write"
Config file
~/.chitta-bridge/config.json:
{
"codex_model": "o3",
"codex_sandbox": "workspace-write"
}
Codex Sandbox Modes
| Mode | Description |
|---|---|
read-only |
Can only read files |
workspace-write |
Can write to workspace (default) |
danger-full-access |
Full filesystem access (use with caution) |
The full_auto option (default: true) enables low-friction execution with workspace-write sandbox.
Requirements
- Python 3.10+
- Claude Code or Codex CLI (or both)
- Ollama or vLLM on a GPU node for
local_*tools
License
MIT
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 chitta_bridge-0.29.1.tar.gz.
File metadata
- Download URL: chitta_bridge-0.29.1.tar.gz
- Upload date:
- Size: 203.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c3a358320ae8ce1f57210806e9fdb3eb4100f6d311ac2eb22419094ddb3c0af
|
|
| MD5 |
83ed7031975e88a1792dd76824f74493
|
|
| BLAKE2b-256 |
0066e63c5d9231418eb529e2ec5f116cf4b6a84f805ca8e3d24824021cad0b69
|
File details
Details for the file chitta_bridge-0.29.1-py3-none-any.whl.
File metadata
- Download URL: chitta_bridge-0.29.1-py3-none-any.whl
- Upload date:
- Size: 222.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68a026be60a0795fd47253254d87f276c5eab1757b5bd56c5fa020d0b6e23bf7
|
|
| MD5 |
b928bba37e6a906f55d68ced20e8f16d
|
|
| BLAKE2b-256 |
866141c2a52086b0a7e96239371b9bdeb8cd861c361ed1a981355440290ce5ef
|