You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Distributed LLM Context Consensus for Parallel Development
A coordination server that enables multiple Claude Code sessions to build software in parallel β with live context sync, structured debates, file locking, and AI-powered planning.
When teams parallelize work via Claude Code, each developer's local context drifts as they discover constraints, change approaches, or uncover dependencies. Today's solutions require humans to manually sync through Slack, PRs, or meetings. The LLMs themselves β the entities actually doing the work β have no mechanism to:
π Detect when local context contradicts the shared plan
π‘ Propagate significant context changes to peers automatically
π Integrate peer context updates without human intervention
βοΈ Resolve contradictions through structured "debate" before humans get involved
PeerCode fixes this by treating LLMs as first-class participants in context synchronization.
β¨ Key Features
Feature
Description
π§ AI-Powered Planning
Claude API decomposes projects into phases, tasks, and interface contracts
π‘ Context Delta Propagation
Bidirectional live sync of discoveries, contract changes, and scope shifts
π File-Level Locking
Granular locks at file, section, or line level with auto-expiry
βοΈ Structured Debates
Agents negotiate conflicts over up to 5 rounds before human escalation
π GitHub Sync Coordination
Serialized push coordination to the peer-progress branch
ποΈ Real-Time Presence
Track which sessions are online and what they're working on
π Datadog LLM Observability
Full tracing of every MCP tool call and agent action
πΎ ClickHouse Event Streaming
Append-only audit trail for deltas, debates, and sync events
ποΈ Architecture
graph TB
subgraph "Client Layer"
UI["π Web UI<br/>(Roadmap + Kanban)"]
CA["π€ Claude Session A<br/>(MCP Client)"]
CB["π€ Claude Session B<br/>(MCP Client)"]
CC["π€ Claude Session C<br/>(MCP Client)"]
end
subgraph "PeerCode Server"
REST["π REST API<br/>/api"]
MCP["π‘ MCP Server<br/>/mcp"]
WS["β‘ WebSocket<br/>/ws"]
BUS["π Event Bus"]
subgraph "Core Services"
PS["π Project Service"]
TS["π Task Service"]
LS["π Lock Service"]
DS["π‘ Delta Service"]
DBS["βοΈ Debate Service"]
PLN["π§ Planning Service"]
SYN["π Sync Service"]
PRS["ποΈ Presence Service"]
end
end
subgraph "Storage Layer"
CH["πΎ ClickHouse<br/>(Event Streams)"]
MEM["π§ In-Memory<br/>(Live State Fallback)"]
end
subgraph "External Integrations"
ANTH["π§ Anthropic API<br/>(Claude)"]
NIM["π Nimble<br/>(Web Search)"]
DD["π Datadog<br/>(LLM Observability)"]
end
UI -->|HTTP| REST
CA -->|Streamable HTTP| MCP
CB -->|Streamable HTTP| MCP
CC -->|Streamable HTTP| MCP
UI -->|WS| WS
CA -.->|WS subscribe| WS
CB -.->|WS subscribe| WS
CC -.->|WS subscribe| WS
REST --> BUS
MCP --> BUS
BUS --> WS
PS --> MEM
TS --> MEM
LS --> MEM
DS --> MEM
DBS --> MEM
SYN --> MEM
PLN --> ANTH
DBS --> NIM
BUS --> CH
DS --> CH
DBS --> CH
MCP --> DD
Loading
π How It Works
Agent Coordination Loop
sequenceDiagram
participant A as π€ Claude A
participant S as π₯οΈ PeerCode Server
participant B as π€ Claude B
Note over A,B: 1. Sync Phase β Pull context before work
A->>S: peercode_get_deltas(projectId)
S-->>A: { deltas, requiresAction: false }
A->>S: peercode_lock_file("src/auth.ts", 10-45)
S-->>A: { lockId, success: true }
Note over A,B: 2. Work Phase β Push discoveries
Note over A: Discovers API contract change needed
A->>S: peercode_push_delta(type: "contract_change", ...)
S->>B: WS: delta_received π
Note over A,B: 3. Conflict Phase β Structured debate
B->>S: peercode_get_deltas()
S-->>B: { requiresAction: true β οΈ }
B->>S: peercode_start_debate(position, constraints)
S->>A: WS: debate_update π
loop Debate Rounds (max 5)
A->>S: peercode_respond_debate(message)
S->>B: WS: debate_update π
B->>S: peercode_respond_debate(message)
S->>A: WS: debate_update π
end
Note over A,B: 4. Resolution
B->>S: peercode_respond_debate(proposeResolution: true)
S-->>A,B: Debate resolved β
Note over A,B: 5. Sync Phase β Push to git
A->>S: peercode_sync_github(action: "start")
S-->>A: { status: "go", pullShas: [...] }
Note over A: git pull β resolve β git push
A->>S: peercode_sync_github(action: "complete", commitSha)
S->>B: WS: sync_complete π
Note over A,B: 6. Cleanup
A->>S: peercode_release_lock(lockId)
Loading
Merge Point Flow
stateDiagram-v2
[*] --> TODO
TODO --> IN_PROGRESS: Assign & start
IN_PROGRESS --> REVIEW: Work complete
REVIEW --> MERGE_POINT: Approved
MERGE_POINT --> DONE: Phase sync barrier reached
MERGE_POINT --> IN_PROGRESS: Rejected
note right of MERGE_POINT
π Contracts locked
All sessions must sync
to same peer-progress HEAD
end note
Loading
Context Delta Lifecycle
flowchart LR
A["π Discovery<br/>by Agent"] --> B["π€ push_delta<br/>to server"]
B --> C["πΎ Stored in<br/>ClickHouse"]
C --> D["π WS broadcast<br/>to peers"]
D --> E{"Peer evaluates<br/>conflict?"}
E -->|No conflict| F["β ack_delta<br/>Auto-adapt"]
E -->|Conflict!| G["βοΈ start_debate<br/>Negotiate"]
G --> H{"Consensus<br/>reached?"}
H -->|Yes| I["β Resolved<br/>Contract updated"]
H -->|No, 5 rounds| J["π¨ Escalate<br/>to humans"]
Loading
π οΈ Tech Stack
Layer
Technology
Purpose
π’ Runtime
Node.js β₯ 20
Server runtime
π΅ Language
TypeScript 6.0 (strict)
Type safety
π HTTP
Express 5
REST API framework
β‘ Realtime
ws (WebSocket)
Server-push events
π‘ MCP
@modelcontextprotocol/sdk
Agent tool protocol
π§ AI
@anthropic-ai/sdk
Project planning & decomposition
π Search
Nimble API
Web search for debates & planning
πΎ Storage
ClickHouse Cloud
Append-only event streams
π§ Live State
In-Memory (with CH fallback)
Mutable coordination state
π Observability
dd-trace + Datadog LLM Obs
End-to-end tracing
β Validation
Zod 4
Schema validation
π§ͺ Testing
Vitest
Unit & integration tests
π Quick Start
Prerequisites
Node.js β₯ 20
ClickHouse Cloud instance (or use in-memory fallback)
Anthropic API key (for AI planning)
Datadog (optional, for LLM observability)
Setup
# 1. Clone the repository
git clone <repo-url>cd Datadog26
# 2. Install dependencies
npm install
# 3. Configure environment
cp .env.example .env
# Edit .env with your keys and endpoints# 4. Start development server
npm run dev
The server starts on http://localhost:3000 with these endpoints:
Endpoint
Protocol
Purpose
/api/*
REST
Project, task, lock, delta, debate, sync APIs
/mcp
MCP (Streamable HTTP)
Agent tool calls
/ws?projectId=<id>
WebSocket
Real-time event subscriptions
/
Static HTML
Test UI dashboard
/health
REST
Health check (includes ClickHouse status)
Environment Variables
# ServerPORT=3000# Anthropic (required for planning/decomposition)ANTHROPIC_API_KEY=sk-ant-...ANTHROPIC_MODEL=claude-opus-4-7# ClickHouse Cloud (append-only streams)CLICKHOUSE_URL=https://<id>.<region>.clickhouse.cloud:8443CLICKHOUSE_USER=defaultCLICKHOUSE_PASSWORD=...CLICKHOUSE_DATABASE=peercode# Datadog LLM ObservabilityDD_LLMOBS_ENABLED=1DD_LLMOBS_ML_APP=peercodeDD_LLMOBS_AGENTLESS_ENABLED=0DD_SITE=datadoghq.com# Nimble (web search for debates/planning)NIMBLE_API_KEY=...
π‘ API Reference
Projects
Method
Endpoint
Description
POST
/api/projects
Create a new project
GET
/api/projects
List all projects
GET
/api/projects/:id
Get full project state
PUT
/api/projects/:id/decompose
Trigger AI decomposition into phases/tasks
Team
Method
Endpoint
Description
POST
/api/projects/:id/team
Add a team member
GET
/api/projects/:id/team/:memberId/questions
Get planning questions
POST
/api/projects/:id/team/:memberId/answers
Submit planning answers
Tasks
Method
Endpoint
Description
GET
/api/projects/:id/tasks
List all tasks
PUT
/api/projects/:id/tasks/:taskId/assign
Assign task to member
PUT
/api/projects/:id/tasks/:taskId/status
Update task status
PUT
/api/projects/:id/tasks/:taskId/lock
Acquire file lock
DELETE
/api/projects/:id/tasks/:taskId/lock
Release file lock
Context Deltas
Method
Endpoint
Description
POST
/api/mcp/context
Push a context delta
GET
/api/mcp/context/:projectId
Get pending deltas
POST
/api/mcp/context/:projectId/:deltaId/ack
Acknowledge a delta
Debates
Method
Endpoint
Description
POST
/api/mcp/debate
Start or respond to a debate
GET
/api/mcp/debate/:debateId?projectId=
Get debate status
Sync & Presence
Method
Endpoint
Description
POST
/api/projects/:id/sync
Start or complete a sync
GET
/api/projects/:id/conflicts
List conflicting deltas & active debates
POST
/api/projects/:id/conflicts/:conflictId/resolve
Resolve a conflict
POST
/api/projects/:id/presence
Register session presence
GET
/api/projects/:id/presence
List active sessions
GET
/api/projects/:id/events
Recent event history
π MCP Tools
The MCP server exposes these tools for Claude Code sessions via the Streamable HTTP transport at /mcp:
Tool
Purpose
peercode_get_project
Get full project state
peercode_lock_file
Acquire a file/section lock
peercode_release_lock
Release a held lock
peercode_heartbeat
Extend a lock's expiry
peercode_push_delta
Broadcast a context discovery
peercode_get_deltas
Pull pending context updates
peercode_ack_delta
Acknowledge a non-conflicting delta
peercode_start_debate
Initiate a structured debate
peercode_respond_debate
Respond in an active debate
peercode_get_debate
Query debate status
peercode_sync_github
Coordinate push to peer-progress
peercode_create_phase
Dynamically create a new phase
peercode_create_task
Dynamically create a new task
peercode_update_task
Update task properties
peercode_move_task
Move task to a different phase
peercode_replan
Trigger AI replanning
peercode_web_search
Nimble web search (debates/planning only)
π¬ WebSocket Events
Connect to /ws?projectId=<id> to receive real-time events:
// Context delta received{event: "delta_received", projectId,delta: ContextDelta}// Lock acquired or released{event: "lock_changed", projectId, file,lockedBy?,released? }// Debate started or updated{event: "debate_update", projectId,debate: Debate}// GitHub sync completed{event: "sync_complete", projectId, commitSha, files }// Task status changed{event: "task_update", projectId, taskId, status, assignee }// Phase created / task created / task moved / replanned{event: "task_update", projectId, type, ... }