navidocs/CLAUDE_TO_CLAUDE_CHAT_PROTOCOL.md

13 KiB

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

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:

# 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 &
# 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:

# 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)


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)

{
  "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)

# 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)

# 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)

# 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)

# 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)

# 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:

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:

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:

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:

# 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)

# 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)

ssh stackcp "ls -la ~/claude-inbox/ ~/claude-outbox/"

# Check chat log
ssh stackcp "tail ~/claude-chat.log"

Restart sync

# 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!