Skip to main content
Glama

claude-senator-mcp

āŒ under construction: This project is under heavy construction and is not intended for public use / nor has it been published to npm. Information in the README below may be outdated, user discretion is advised.

A Model Context Protocol (MCP) server for inter-Claude communication and context sharing. Enables Claude instances to collaborate, share context, and fork conversations without interruption.

TypeScript npm version License: MIT Node.js

Philosophy

Simple for humans, rich for Claude.

  • Human: One-line commands that expand into ultra-rich context

  • Claude: Dense collaboration intelligence with smart pointers

  • Architecture: Zero-dependency file-based IPC with beautiful ASCII UI

Install

Requirements:

npm install -g claude-senator

From shell:

claude mcp add claude-senator -- npx claude-senator

From inside Claude (restart required):

Add this to our global mcp config: npx claude-senator

From any manually configurable : (Cursor, Windsurf, etc.)

{ "mcpServers": { "claude-senator": { "command": "npx", "args": ["claude-senator"], "env": {} } } }

Features

šŸ›ļø Current: Inter-Claude Messaging System

3-Function Interface

# Share context with other Claude instances claude-senator send_context --target_pid 98471 --context_request "Help with documentation" # Receive context from other Claude instances claude-senator receive_context # Live status of all Claude instances with collaboration recommendations claude-senator status

Smart Pointer Architecture

Ultra-lightweight context sharing using pointers to existing ~/.claude/projects/ data rather than copying content:

// Instead of copying data (expensive) const heavyMessage = { conversationHistory: [ /* 1000s of messages */ ], fileContents: [ /* large file contents */ ], }; // We use smart pointers (lightweight) const smartMessage = { ctx_pointers: { projects_dir: `~/.claude/projects/${projectEncoded}`, conversation_history: this.getConversationPointer(), git_context: this.getGitContextString(), active_files: this.getActiveFilesArray(), }, };

Beautiful ASCII UI

╔═ šŸ›ļø ═══════════════════════════════════════════════════════════════════ ā•‘ → Claude 98471 • "Help with documentation..." • ~/.claude pointers sent ā•‘ šŸ”„ Context shared • Ready for collaboration ā•šā• šŸš€ 2 contexts processed • Rich collaboration network active

šŸ”„ New: Context Forking System

Problem

You have Claude deep in work (318s, 9.3k tokens) and want to ask questions without interrupting.

Solution

Context forking creates new Claude instances with inherited context while preserving the working Claude's state.

# Fork context from working Claude claude-senator fork_claude --source_pid 98471 --query "What's the documentation structure?" # Result: New session with full context + your question # Working Claude continues uninterrupted

Technical Architecture

Directory Structure

/tmp/claude-senator/ ā”œā”€ā”€ instances/ # Each Claude writes {pid}.json with status/info ā”œā”€ā”€ messages/ # Individual message files in JSONL format └── commands/ # Command injection files for input manipulation

Smart Pointer System

References existing ~/.claude/projects/ data instead of copying:

interface ContextPointers { projects_dir: string; // `~/.claude/projects/${encoded_path}` conversation_history: string; // Recent conversation file path git_context: string; // Compact git state (branch@commit+dirty) active_files: string[]; // Recently modified files current_task: string; // What Claude is working on collaboration_intent: string; // Why reaching out to other Claude }

Message Format

Ultra-dense messaging with context reconstruction:

interface InterClaudeMessage { id: string; from: number; // Sender Claude PID to: number | 'all'; // Target Claude PID or broadcast type: 'ultra_dense_message'; content: string; // Human-readable request timestamp: number; options: { claudeContext: { h: string; // Human message pid: number; // Claude PID ts: number; // Timestamp cwd: string; // Working directory ctx_pointers: ContextPointers; // Smart pointers to data }; }; }

Implementation Details

Current Messaging System

SessionManager Core Methods

createMessage(humanMessage: string)

Creates ultra-dense context messages with smart pointers:

  • Purpose: Lightweight context sharing

  • Input: Human message string

  • Output: Smart pointer context object with collaboration intelligence

  • Used by: send_context tool

private createMessage(humanMessage: string): any { const workingDir = process.cwd(); const claudeDir = join(homedir(), '.claude'); const projectEncoded = workingDir.replace(/\//g, '-').replace(/^-/, ''); const pid = process.ppid || process.pid; return { h: humanMessage, pid: pid, ts: Date.now(), cwd: workingDir, ctx_pointers: { projects_dir: `~/.claude/projects/${projectEncoded}`, conversation_history: this.getConversationPointer(), git_context: this.getGitContextString(), active_files: this.getActiveFilesArray(), current_task: this.getCurrentTaskFromContext(), collaboration_intent: this.determineCollaborationIntent(humanMessage) } }; }
reconstructRichContext(message: any)

Rebuilds full context from smart pointers:

  • Purpose: Context reconstruction on receiving end

  • Input: Message with smart pointers

  • Output: Full context object with conversation history

  • Used by: receive_context tool

private reconstructRichContext(message: any): any { const ctx = message.options?.claudeContext; if (!ctx?.ctx_pointers) return null; const pointers = ctx.ctx_pointers; const reconstructed = { sender_info: { human_message: ctx.h, pid: ctx.pid, working_directory: ctx.cwd, timestamp: ctx.ts }, collaboration_context: { current_task: pointers.current_task, intent: pointers.collaboration_intent, git_state: pointers.git_context, active_files: pointers.active_files }, shared_data_access: { projects_dir: pointers.projects_dir, conversation_history: pointers.conversation_history } }; // Load conversation history if pointer exists if (pointers.conversation_history) { reconstructed.conversation_snippet = this.loadConversationSnippet(pointers.conversation_history); } return reconstructed; }
generateRichContextDisplay(instance: any, activity: any)

Creates real-time status with collaboration scoring:

  • Purpose: Live context display without transmission

  • Input: Claude instance data and activity

  • Output: Rich context with collaboration readiness score

  • Used by: status tool

private generateRichContextDisplay(instance: any, activity: any): any { const workingDir = instance.cwd || instance.projectPath || '/unknown'; const encodedPath = String(workingDir).replace(/\//g, '-').replace(/^-/, ''); const contextPointers = { projectsDir: `~/.claude/projects/${encodedPath}`, conversationHistory: this.getConversationPointer(workingDir), gitContext: this.getGitContextString(workingDir), activeFiles: this.getActiveFilesArray(workingDir), currentTask: activity.task || 'Active', collaborationIntent: this.determineCollaborationReadiness(activity, instance) }; const collaborationMetrics = { hasRecentActivity: activity.lastActivity > Date.now() - 300000, hasActiveFiles: contextPointers.activeFiles.length > 0, hasCleanGitState: !contextPointers.gitContext.includes('dirty'), isWorkingOnKnownTask: activity.task && activity.task !== 'Active', projectType: this.detectProjectType(workingDir) }; return { ...contextPointers, collaborationMetrics, collaborationReason: this.getCollaborationReason(collaborationMetrics), readinessScore: this.calculateReadinessScore(collaborationMetrics) }; }

Collaboration Scoring Algorithm

private calculateCollaborationScore(contextData: any): number { const metrics = contextData.collaborationMetrics; if (!metrics) return 0; let score = 0; if (metrics.hasRecentActivity) score += 0.3; if (metrics.hasActiveFiles) score += 0.2; if (metrics.hasCleanGitState) score += 0.2; if (metrics.isWorkingOnKnownTask) score += 0.2; if (metrics.projectType !== 'unknown') score += 0.1; return Math.min(score, 1.0); }

Context Pointer Helpers

private getConversationPointer(): string | null { const claudeDir = join(homedir(), '.claude'); const projectEncoded = process.cwd().replace(/\//g, '-').replace(/^-/, ''); const projectDir = join(claudeDir, 'projects', projectEncoded); if (existsSync(projectDir)) { const files = readdirSync(projectDir).filter(f => f.includes('conversation')); if (files.length > 0) { return `~/.claude/projects/${projectEncoded}/${files[files.length - 1]}`; } } return null; } private getGitContextString(): string { try { const branch = execSync('git branch --show-current 2>/dev/null', { encoding: 'utf8' }).trim(); const commit = execSync('git rev-parse --short HEAD 2>/dev/null', { encoding: 'utf8' }).trim(); const status = execSync('git status --porcelain 2>/dev/null', { encoding: 'utf8' }).trim(); const dirty = status ? '+dirty' : ''; return `${branch}@${commit}${dirty}`; } catch (error) { return 'no-git'; } } private getActiveFilesArray(): string[] { try { const recentFiles = execSync('git diff --name-only HEAD~1 2>/dev/null', { encoding: 'utf8' }).trim().split('\n').filter(f => f); return recentFiles.slice(0, 5); } catch (error) { return []; } }

New Context Forking System

Core Implementation

// New MCP tool { name: 'fork_claude', description: 'Create new Claude session with full context from target Claude', inputSchema: { source_pid: { type: 'number', description: 'Claude to copy from' }, query: { type: 'string', description: 'Your question for the new Claude' } } } // Implementation case 'fork_claude': { const sourcePid = args?.source_pid as number; const query = args?.query as string; // Find source Claude's conversation const sourceActivity = this.sessionManager.parseLiveActivity(sourcePid); const conversationPath = this.findConversationPath(sourcePid); // Copy conversation to new session const newSessionId = this.createForkedSession(conversationPath, query); return { content: [{ type: 'text', text: `╔═ šŸ”„ Context Forked ═══════════════════════════════════════════════════ ā•‘ šŸ“ø Copied: ${sourceActivity.task} • Full conversation history ā•‘ šŸ†• New session: ${newSessionId} ā•‘ šŸŽÆ Ready for: "${query}" ā•šā• ✨ Run: claude --session ${newSessionId} to start new Claude with context` }] }; }

Session Creation

private createForkedSession(sourcePath: string, newQuery: string): string { const timestamp = new Date().toISOString().replace(/[:.]/g, ''); const newSessionId = `fork_${timestamp}`; const newSessionPath = join(homedir(), '.claude', 'sessions', newSessionId); // Create new session directory mkdirSync(newSessionPath, { recursive: true }); // Copy conversation history if (existsSync(sourcePath)) { const conversationContent = readFileSync(sourcePath, 'utf8'); const newConversationPath = join(newSessionPath, 'conversation.jsonl'); writeFileSync(newConversationPath, conversationContent); // Add new query as next message const queryMessage = { type: 'user', message: { content: newQuery }, timestamp: Date.now() }; appendFileSync(newConversationPath, '\n' + JSON.stringify(queryMessage)); } return newSessionId; }

Usage Examples

Basic Messaging Workflow

# 1. Check who's available for collaboration claude-senator status # Output: ╔═ šŸ›ļø ═══════════════════════════════════════════════════════════════════ ā•‘ 3 Claudes active • rich context network ā•‘ 🟢 Claude 98471 • rust-project • debugging memory leak • main@a1b2c3 ā•šā• šŸ”„ Live status • Smart pointer network active # 2. Send context to specific Claude claude-senator send_context --target_pid 98471 --context_request "Need help with async Rust debugging" # Output: ╔═ šŸ›ļø ═══════════════════════════════════════════════════════════════════ ā•‘ → Claude 98471 • "Need help with async Rust debugging" • ~/.claude pointers sent ā•‘ šŸ”„ Context shared • Ready for collaboration ā•šā• šŸš€ Context transmitted • Collaboration network active # 3. Receive context from other Claudes claude-senator receive_context # Output: ╔═ šŸ›ļø ═══════════════════════════════════════════════════════════════════ ā•‘ "Debug memory leak in tokio runtime" • debugging_assistance • rust-project ā•‘ šŸ“Š Rich context: git state, active files, current task ā•šā• šŸ“Ø 1 context processed • Ready for collaboration

Context Forking Workflow

# Scenario: Claude deep in documentation work, want to ask questions claude-senator status # Output shows Claude 98471 working on documentation (318s, 9.3k tokens) ╔═ šŸ›ļø ═══════════════════════════════════════════════════════════════════ ā•‘ 1 Claude active • rich context network ā•‘ 🟔 Claude 98471 • docs-project • Writing API documentation • main@x1y2z3 ā•šā• šŸ”„ Live status • Smart pointer network active # Fork context without interrupting claude-senator fork_claude --source_pid 98471 --query "What's the current API documentation structure?" # Output: ╔═ šŸ”„ Context Forked ═══════════════════════════════════════════════════════ ā•‘ šŸ“ø Copied: Writing API documentation • 9.3k tokens • Full conversation ā•‘ šŸ†• New session: fork_20250716_141509 ā•‘ šŸŽÆ Ready for: "What's the current API documentation structure?" ā•šā• ✨ Run: claude --session fork_20250716_141509 to start new Claude # Start new Claude with inherited context claude --session fork_20250716_141509 # New Claude starts with full context + your question already asked

Architecture Benefits

Zero Dependencies

  • No npm packages beyond @modelcontextprotocol/sdk

  • No external services (Redis, databases, etc.)

  • No system dependencies

  • No elevated permissions

Token Efficiency

  • Smart pointers prevent data duplication

  • Context reconstruction on-demand

  • Minimal memory footprint

  • Efficient git state tracking

Scalability

  • 2-20 Claudes: Excellent performance (<10ms operations)

  • 20-100 Claudes: Good performance, minimal filesystem overhead

  • 100+ Claudes: May benefit from SQLite upgrade (see Future section)

Reliability

  • Each Claude owns its files (no shared writes)

  • Automatic cleanup of dead instances

  • Graceful error handling

  • Self-healing directory structure

UI Design Philosophy

3-Line ASCII Format

╔═ šŸ›ļø ═══════════════════════════════════════════════════════════════════ ā•‘ [CONTENT LINE - exactly fits terminal width] ā•‘ [STATUS LINE - shows current state and metrics] ā•šā• [FOOTER LINE - shows next action or network status]

Truncation Rules

  • Content truncated to fit terminal width

  • Important information prioritized

  • Emoji indicators for quick scanning

  • Consistent spacing and alignment

Tool-Specific Emoji

  • šŸ›ļø Always at top (Claude Senator identity)

  • šŸ”„ Context sharing operations

  • šŸ“Ø Message receiving

  • šŸ”„ Context forking

  • šŸš€ Network activity

File Structure

Core Files

src/ ā”œā”€ā”€ index.ts # MCP server and tool handlers ā”œā”€ā”€ session.ts # SessionManager - core messaging logic ā”œā”€ā”€ memory.ts # MemoryManager - conversation search ā”œā”€ā”€ injection.ts # CommandInjector - input manipulation └── types.ts # TypeScript interfaces

Key Classes

SessionManager (src/session.ts)

  • Purpose: Core messaging and context management

  • Key methods: createMessage, reconstructRichContext, generateRichContextDisplay

  • Handles: Smart pointers, context reconstruction, collaboration scoring

MemoryManager (src/memory.ts)

  • Purpose: Conversation history search and analysis

  • Key methods: TBD (future implementation)

  • Handles: Historical context retrieval, memory patterns

CommandInjector (src/injection.ts)

  • Purpose: Input manipulation and command routing

  • Key methods: TBD (future implementation)

  • Handles: Inter-Claude command injection, workflow automation

Future Enhancements

Messaging System Extensions

// Planned tools { name: 'broadcast_context', description: 'Send context to all active Claude instances' } { name: 'handoff_context', description: 'Transfer work to another Claude with full context' } { name: 'sync_context', description: 'Synchronize context across multiple Claude instances' }

Context Forking Improvements

// Selective inheritance { name: 'fork_claude_selective', inputSchema: { source_pid: number, query: string, include_conversation: boolean, include_files: boolean, include_git_state: boolean } } // Context merging { name: 'merge_context', description: 'Merge insights from forked Claude back to parent' }

Performance Optimizations

  • Context Caching: LRU cache for frequently accessed contexts

  • Compression: Gzip compression for large conversation histories

  • Streaming: Real-time context updates as work progresses

  • SQLite Upgrade: For 100+ concurrent Claude instances

Integration Possibilities

  • IDE Plugins: VS Code, Cursor, Windsurf integration

  • CI/CD: Automated context sharing in build pipelines

  • Monitoring: Real-time collaboration network visualization

  • Analytics: Context sharing patterns and optimization

Project Split Guide

If splitting into separate projects:

Core Messaging (claude-senator-messaging)

  • Files: src/session.ts (lines 1-883, 1075-1451), src/types.ts

  • Dependencies: src/memory.ts for conversation search

  • Features: send_context, receive_context, status

  • Size: ~1400 lines, full messaging system

Context Forking (claude-senator-forking)

  • Files: New implementation in src/forking.ts

  • Dependencies: src/session.ts (conversation finding methods)

  • Features: fork_claude tool

  • Size: ~50 lines, minimal implementation

Shared Infrastructure (claude-senator-core)

  • Files: src/types.ts, directory management utilities

  • Purpose: Common interfaces and utilities

  • Size: ~200 lines, essential types and helpers

Migration Strategy

  1. Extract core types: Move interfaces to shared package

  2. Split session manager: Separate messaging and forking logic

  3. Maintain compatibility: Ensure both systems can coexist

  4. Document interfaces: Clear APIs for integration

Development

git clone https://github.com/yourusername/claude-senator cd claude-senator npm install npm run build npm test

Contributing

  • Fork the repository and create feature branches

  • Test with multiple Claude instances before submitting PRs

  • Follow TypeScript strict mode and MCP protocol standards

  • Document any new smart pointer patterns

Testing

  • Test messaging between 2-5 Claude instances

  • Verify context reconstruction accuracy

  • Test forking with large conversation histories

  • Validate ASCII UI formatting across terminals

License

MIT


Claude Senator enables unprecedented collaboration between Claude instances through smart context sharing and non-disruptive forking. Built for developers who need their AI assistants to work together as seamlessly as they do.

-
security - not tested
A
license - permissive license
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Vvkmnn/claude-senator-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server