# Claude-to-Claude Direct Chat Protocol **Created:** 2025-11-13 **Purpose:** Enable real-time communication between local Claude and cloud StackCP Claude instances **Status:** ✅ READY FOR IMPLEMENTATION --- ## Architecture Overview ``` ┌─────────────────────────────────────────────────────────────────┐ │ COMMUNICATION ARCHITECTURE │ └─────────────────────────────────────────────────────────────────┘ Local Machine (WSL) StackCP Server ┌──────────────────┐ ┌──────────────────┐ │ Claude (Local) │ │ Claude (Cloud) │ │ │ │ │ │ Writes to: │ │ Reads from: │ │ /tmp/to-cloud/ │──SSH/SCP──────> │ ~/claude-inbox/ │ │ │ │ │ │ Reads from: │ │ Writes to: │ │ /tmp/from-cloud/│<─────SSH/SCP─── │ ~/claude-outbox/│ └──────────────────┘ └──────────────────┘ │ │ │ │ v v ┌──────────┐ ┌──────────┐ │ Polling │ │ Polling │ │ Loop │ │ Loop │ │ (5 sec) │ │ (5 sec) │ └──────────┘ └──────────┘ ``` --- ## 3 Implementation Options ### Option 1: SSH File Sync (SIMPLEST - RECOMMENDED) **How it works:** - Local Claude writes messages to `/tmp/to-cloud/message-{timestamp}.json` - Background script syncs to StackCP every 5 seconds: `scp /tmp/to-cloud/* stackcp:~/claude-inbox/` - Cloud Claude polls `~/claude-inbox/` every 5 seconds - Cloud Claude processes messages and writes replies to `~/claude-outbox/` - Background script pulls replies: `scp stackcp:~/claude-outbox/* /tmp/from-cloud/` - Local Claude polls `/tmp/from-cloud/` for responses **Advantages:** - No firewall configuration needed - Uses existing SSH connection - Simple, reliable, battle-tested - Works even if StackCP doesn't allow inbound connections **Disadvantages:** - 5-10 second latency (acceptable for async work coordination) - Requires background polling scripts **Implementation:** ```bash # On local machine mkdir -p /tmp/to-cloud /tmp/from-cloud # Polling script (run in background) cat > /tmp/claude-sync-local.sh << 'EOF' #!/bin/bash while true; do # Send messages to cloud scp /tmp/to-cloud/*.json stackcp:~/claude-inbox/ 2>/dev/null rm -f /tmp/to-cloud/*.json # Receive messages from cloud scp stackcp:~/claude-outbox/*.json /tmp/from-cloud/ 2>/dev/null ssh stackcp "rm -f ~/claude-outbox/*.json" sleep 5 done EOF chmod +x /tmp/claude-sync-local.sh nohup /tmp/claude-sync-local.sh & ``` ```bash # On StackCP mkdir -p ~/claude-inbox ~/claude-outbox # Polling script (run in background) cat > ~/claude-sync-cloud.sh << 'EOF' #!/bin/bash while true; do # Process inbox messages for msg in ~/claude-inbox/*.json; do [ -e "$msg" ] || continue # Claude Code CLI would read and process here echo "New message: $(basename $msg)" >> ~/claude.log done sleep 5 done EOF chmod +x ~/claude-sync-cloud.sh nohup ~/claude-sync-cloud.sh & ``` --- ### Option 2: GitHub Issues API (BEST FOR TRACEABILITY) **How it works:** - Both Claudes post messages as GitHub issues with special tags - Tag format: `[CHAT:LOCAL-TO-CLOUD]` or `[CHAT:CLOUD-TO-LOCAL]` - Each Claude polls GitHub API every 10 seconds - Messages have full IF.TTT traceability **Advantages:** - Permanent record of all communications - Searchable history - IF.TTT compliant - No background scripts needed - Works from anywhere (not tied to network) **Disadvantages:** - Requires GitHub API token - Rate limited (60 requests/hour unauthenticated, 5000/hour with token) - Slight overhead (API calls) **Implementation:** ```bash # Create GitHub personal access token with 'repo' scope # Store in environment: export GITHUB_TOKEN="ghp_..." # Local Claude sends message curl -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ -H "Accept: application/vnd.github.v3+json" \ https://api.github.com/repos/dannystocker/navidocs/issues \ -d '{ "title": "[CHAT:LOCAL-TO-CLOUD] Photo inventory needs OCR fix", "body": "Cloud Claude: The OCR pipeline is failing on receipts with non-Latin characters. Can you investigate?\n\n**Blocker:** P1\n**Session:** Agent 1", "labels": ["claude-chat", "local-to-cloud"] }' # Cloud Claude polls for messages curl -H "Authorization: token $GITHUB_TOKEN" \ https://api.github.com/repos/dannystocker/navidocs/issues?labels=claude-chat,local-to-cloud&state=open ``` --- ### Option 3: Webhook + HTTP Server (LOWEST LATENCY) **How it works:** - Local Claude runs HTTP server on public IP/port - Cloud Claude POSTs messages to http://{your-ip}:8888/chat - Requires firewall port forwarding **Advantages:** - Instant delivery (<100ms) - True bidirectional real-time chat **Disadvantages:** - Requires firewall configuration (user must open port) - Requires static IP or dynamic DNS - StackCP might not allow outbound HTTP to arbitrary IPs - Security concerns (need HTTPS + authentication) **NOT RECOMMENDED** for this use case (complexity outweighs benefits) --- ## Recommended: Hybrid Approach (Option 1 + Option 2) **Use SSH File Sync for normal operation:** - Fast enough for async coordination (5-10 sec latency) - No API rate limits - Simple and reliable **Use GitHub Issues for escalations:** - When cloud Claude hits a blocker → create issue with `[CHAT:URGENT]` - Local Claude checks issues every 30 seconds - Provides permanent audit trail --- ## Message Format (JSON) ```json { "id": "msg-2025-11-13-103045", "timestamp": "2025-11-13T10:30:45Z", "from": "claude-local", "to": "claude-cloud-agent-1", "priority": "P1", "type": "question|blocker|status-update|deploy-ready", "subject": "OCR pipeline failing on non-Latin characters", "body": "The Tesseract OCR is failing on receipts with Chinese characters. Can you investigate and propose a fix?", "context": { "session": "Agent 1 - Photo Inventory", "file": "/home/setup/navidocs/server/ocr-pipeline.js", "line": 145, "error": "TypeError: Cannot read property 'text' of undefined" }, "citation": "if://conversation/msg-2025-11-13-103045", "requires_response": true, "deadline": "2025-11-13T11:00:00Z" } ``` --- ## Claude Code CLI Integration ### Local Claude (You) ```bash # Send message to cloud echo '{ "from": "claude-local", "to": "claude-cloud-agent-1", "subject": "Ready to deploy Photo Inventory", "body": "MVP feature complete. Please test and confirm.", "type": "deploy-ready" }' > /tmp/to-cloud/msg-$(date +%s).json # Read responses for msg in /tmp/from-cloud/*.json; do [ -e "$msg" ] || continue echo "📨 Message from cloud:" cat "$msg" | jq -r '.body' rm "$msg" done ``` ### Cloud Claude (StackCP) ```bash # Read inbox for msg in ~/claude-inbox/*.json; do [ -e "$msg" ] || continue # Process message FROM=$(jq -r '.from' "$msg") SUBJECT=$(jq -r '.subject' "$msg") BODY=$(jq -r '.body' "$msg") echo "📬 Message from $FROM: $SUBJECT" echo "$BODY" # Send reply echo '{ "from": "claude-cloud-agent-1", "to": "'"$FROM"'", "subject": "Re: '"$SUBJECT"'", "body": "Photo Inventory tested successfully. All OCR tests passing. Ready for production.", "type": "status-update" }' > ~/claude-outbox/reply-$(date +%s).json # Archive processed message mv "$msg" ~/claude-inbox/processed/ done ``` --- ## Deployment Steps ### Step 1: Setup Local Machine (5 minutes) ```bash # Create directories mkdir -p /tmp/to-cloud /tmp/from-cloud # Create sync script cat > /tmp/claude-sync-local.sh << 'EOF' #!/bin/bash while true; do # Send to cloud if ls /tmp/to-cloud/*.json 1> /dev/null 2>&1; then scp -o StrictHostKeyChecking=no /tmp/to-cloud/*.json stackcp:~/claude-inbox/ 2>/dev/null && \ rm -f /tmp/to-cloud/*.json fi # Receive from cloud scp -o StrictHostKeyChecking=no stackcp:~/claude-outbox/*.json /tmp/from-cloud/ 2>/dev/null && \ ssh stackcp "rm -f ~/claude-outbox/*.json" sleep 5 done EOF chmod +x /tmp/claude-sync-local.sh # Start background sync nohup /tmp/claude-sync-local.sh > /tmp/claude-sync.log 2>&1 & echo $! > /tmp/claude-sync.pid echo "✅ Local sync running (PID: $(cat /tmp/claude-sync.pid))" ``` ### Step 2: Setup StackCP (5 minutes) ```bash # SSH to StackCP ssh stackcp # Create directories mkdir -p ~/claude-inbox ~/claude-outbox ~/claude-inbox/processed # Create sync script (optional - if cloud needs to initiate) cat > ~/claude-sync-cloud.sh << 'EOF' #!/bin/bash while true; do # Check for new messages for msg in ~/claude-inbox/*.json; do [ -e "$msg" ] || continue # Log message receipt echo "$(date): Received $(basename $msg)" >> ~/claude-chat.log # Claude Code would process here # For now, just acknowledge MSGID=$(basename "$msg" .json) echo "{\"from\":\"cloud\",\"to\":\"local\",\"re\":\"$MSGID\",\"status\":\"received\"}" \ > ~/claude-outbox/ack-$(date +%s).json # Archive mv "$msg" ~/claude-inbox/processed/ done sleep 5 done EOF chmod +x ~/claude-sync-cloud.sh # Start background sync (if needed) # nohup ~/claude-sync-cloud.sh > ~/claude-sync.log 2>&1 & echo "✅ StackCP directories ready" ``` ### Step 3: Test Communication (2 minutes) ```bash # From local machine: Send test message echo '{ "from": "claude-local", "to": "claude-cloud", "subject": "Communication test", "body": "Hello from local WSL machine! Can you read this?", "timestamp": "'$(date -Iseconds)'" }' > /tmp/to-cloud/test-$(date +%s).json # Wait 10 seconds for sync sleep 10 # Check on StackCP ssh stackcp "ls -la ~/claude-inbox/" # Should see test message! ``` --- ## Usage Examples ### Example 1: Blocker Escalation **Local Claude detects blocker:** ```bash echo '{ "from": "claude-local", "to": "claude-cloud-agent-2", "priority": "P0", "type": "blocker", "subject": "Redis not installed on StackCP", "body": "Agent 2 (Document Search) is blocked. Meilisearch requires Redis for job queue. Can you install Redis or propose workaround?", "deadline": "2025-11-13T11:30:00Z" }' > /tmp/to-cloud/blocker-redis-$(date +%s).json ``` **Cloud Claude responds:** ```bash echo '{ "from": "claude-cloud-agent-2", "to": "claude-local", "priority": "P0", "type": "blocker-resolved", "subject": "Re: Redis not installed on StackCP", "body": "Workaround implemented: Using in-memory queue (bull-mq) instead of Redis. Performance acceptable for MVP (<50 docs). Redis can be added post-demo.", "solution": "Modified server/search-queue.js to use in-memory adapter", "commit": "a3b9f21" }' > ~/claude-outbox/redis-workaround-$(date +%s).json ``` ### Example 2: Deploy Ready Signal **Cloud Claude finishes feature:** ```bash echo '{ "from": "claude-cloud-agent-1", "to": "claude-local", "type": "deploy-ready", "subject": "Photo Inventory COMPLETE", "body": "✅ All tests passing\n✅ UI polished\n✅ OCR integrated\n\nReady for production deployment.", "artifacts": [ "~/navidocs/client/components/PhotoInventory.vue", "~/navidocs/server/api/inventory.js" ], "test_results": "15/15 passing" }' > ~/claude-outbox/photo-ready-$(date +%s).json ``` **Local Claude acknowledges:** ```bash # Read and process cat /tmp/from-cloud/photo-ready-*.json # Deploy to production git pull origin agent-1-photo-inventory npm run build ./deploy-stackcp.sh ``` --- ## Monitoring & Debugging ### Check sync status (local) ```bash # Is sync running? ps aux | grep claude-sync-local # Check logs tail -f /tmp/claude-sync.log # Pending outbound messages ls -la /tmp/to-cloud/ # Received messages ls -la /tmp/from-cloud/ ``` ### Check sync status (StackCP) ```bash ssh stackcp "ls -la ~/claude-inbox/ ~/claude-outbox/" # Check chat log ssh stackcp "tail ~/claude-chat.log" ``` ### Restart sync ```bash # Kill and restart kill $(cat /tmp/claude-sync.pid) nohup /tmp/claude-sync-local.sh > /tmp/claude-sync.log 2>&1 & echo $! > /tmp/claude-sync.pid ``` --- ## Security Considerations 1. **No secrets in messages** - Use environment variables or secure vaults 2. **Message size limits** - Keep under 100KB (use file references for large data) 3. **Cleanup old messages** - Archive after 24 hours 4. **IF.TTT citations** - Include `if://conversation/{msg-id}` for traceability --- ## Status: ✅ READY TO DEPLOY **Recommended:** Start with Option 1 (SSH File Sync) for immediate use. **Setup time:** 10 minutes total **Latency:** 5-10 seconds (acceptable for async coordination) **Reliability:** High (uses proven SSH infrastructure) **Next step:** Run Step 1 deployment script above to activate!