{
  "name": "Agent Bridge Watchdog Health Monitor",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [{ "field": "minutes", "minutesInterval": 5 }]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [0, 300],
      "id": "watchdog-trigger",
      "name": "Every 5 Minutes"
    },
    {
      "parameters": {
        "method": "GET",
        "url": "http://YOUR_AGENT_BRIDGE_HOST:3333/health",
        "options": { "timeout": 10000 }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [220, 300],
      "id": "health-check",
      "name": "Ping /health",
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "conditions": {
          "options": { "caseSensitive": true, "leftValue": "" },
          "conditions": [
            {
              "leftValue": "={{ $json.status }}",
              "rightValue": "ok",
              "operator": { "type": "string", "operation": "equals" }
            }
          ]
        }
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [440, 300],
      "id": "status-check",
      "name": "Status OK?"
    },
    {
      "parameters": {
        "jsCode": "// Get or initialize failure counter from static data\nconst staticData = $getWorkflowStaticData('global');\nconst previousFailures = staticData.consecutiveFailures || 0;\n\n// Reset counter on success\nstaticData.consecutiveFailures = 0;\n\n// Check if we were previously failing (recovery)\nif (previousFailures >= 3) {\n  return [{ json: { status: 'recovered', previousFailures, agents: $json.agents_available || 'unknown', uptime: $json.uptime || 'unknown' } }];\n}\n\n// Healthy, was healthy before — do nothing\nreturn [];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [680, 200],
      "id": "handle-success",
      "name": "Handle Success / Recovery"
    },
    {
      "parameters": {
        "jsCode": "// Increment failure counter\nconst staticData = $getWorkflowStaticData('global');\nstaticData.consecutiveFailures = (staticData.consecutiveFailures || 0) + 1;\nconst failures = staticData.consecutiveFailures;\n\nreturn [{ json: { consecutiveFailures: failures, threshold: 3, shouldAlert: failures >= 3, timestamp: new Date().toISOString() } }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [680, 400],
      "id": "handle-failure",
      "name": "Increment Failure Counter"
    },
    {
      "parameters": {
        "conditions": {
          "options": { "caseSensitive": true, "leftValue": "" },
          "conditions": [
            {
              "leftValue": "={{ $json.shouldAlert }}",
              "rightValue": "true",
              "operator": { "type": "boolean", "operation": "true" }
            }
          ]
        }
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [900, 400],
      "id": "alert-threshold",
      "name": "3+ Failures?"
    },
    {
      "parameters": {
        "fromEmail": "watchdog@yourdomain.com",
        "toEmail": "you@yourdomain.com",
        "subject": "🔴 ALERT: Agent Bridge DOWN — {{ $json.consecutiveFailures }} consecutive failures",
        "emailType": "html",
        "html": "=<div style=\"font-family: sans-serif; max-width: 480px; margin: 0 auto;\">\n<div style=\"background: #DC2626; color: white; padding: 16px 24px; border-radius: 8px 8px 0 0;\">\n<h2 style=\"margin: 0;\">⚠️ Agent Bridge Health Alert</h2>\n</div>\n<div style=\"background: white; padding: 24px; border: 1px solid #E5E7EB; border-radius: 0 0 8px 8px;\">\n<p><strong>Status:</strong> UNREACHABLE</p>\n<p><strong>Consecutive Failures:</strong> {{ $json.consecutiveFailures }}</p>\n<p><strong>Since:</strong> {{ $json.timestamp }}</p>\n<hr style=\"border: none; border-top: 1px solid #E5E7EB; margin: 16px 0;\">\n<p style=\"font-size: 13px; color: #6B7280;\">Check Docker container status:<br><code>docker ps | grep agent-bridge</code><br><code>docker logs agent-bridge --tail 20</code></p>\n</div>\n</div>",
        "options": {}
      },
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [1140, 340],
      "id": "send-alert",
      "name": "Send DOWN Alert",
      "credentials": {
        "smtp": { "id": "YOUR_CREDENTIAL_ID", "name": "SMTP" }
      }
    },
    {
      "parameters": {
        "fromEmail": "watchdog@yourdomain.com",
        "toEmail": "you@yourdomain.com",
        "subject": "🟢 RECOVERED: Agent Bridge is back online",
        "emailType": "html",
        "html": "=<div style=\"font-family: sans-serif; max-width: 480px; margin: 0 auto;\">\n<div style=\"background: #059669; color: white; padding: 16px 24px; border-radius: 8px 8px 0 0;\">\n<h2 style=\"margin: 0;\">✅ Agent Bridge Recovered</h2>\n</div>\n<div style=\"background: white; padding: 24px; border: 1px solid #E5E7EB; border-radius: 0 0 8px 8px;\">\n<p><strong>Status:</strong> HEALTHY</p>\n<p><strong>Agents Available:</strong> {{ $json.agents }}</p>\n<p><strong>Previous Consecutive Failures:</strong> {{ $json.previousFailures }}</p>\n<p style=\"font-size: 13px; color: #6B7280;\">Service recovered automatically. No action needed.</p>\n</div>\n</div>",
        "options": {}
      },
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [1140, 160],
      "id": "send-recovery",
      "name": "Send Recovery Notice",
      "credentials": {
        "smtp": { "id": "YOUR_CREDENTIAL_ID", "name": "SMTP" }
      }
    }
  ],
  "connections": {
    "Every 5 Minutes": { "main": [[{ "node": "Ping /health", "type": "main", "index": 0 }]] },
    "Ping /health": { "main": [[{ "node": "Status OK?", "type": "main", "index": 0 }], [{ "node": "Increment Failure Counter", "type": "main", "index": 0 }]] },
    "Status OK?": { "main": [[{ "node": "Handle Success / Recovery", "type": "main", "index": 0 }], [{ "node": "Increment Failure Counter", "type": "main", "index": 0 }]] },
    "Handle Success / Recovery": { "main": [[{ "node": "Send Recovery Notice", "type": "main", "index": 0 }]] },
    "Increment Failure Counter": { "main": [[{ "node": "3+ Failures?", "type": "main", "index": 0 }]] },
    "3+ Failures?": { "main": [[{ "node": "Send DOWN Alert", "type": "main", "index": 0 }], []] }
  },
  "active": false,
  "settings": { "executionOrder": "v1" },
  "meta": {
    "notes": "SETUP: 1) Replace YOUR_AGENT_BRIDGE_HOST with your server IP or hostname (e.g., localhost, 100.90.244.89 for Tailscale). 2) Add SMTP credentials. 3) Replace email addresses. 4) Activate. The workflow uses static data to track consecutive failures across executions.",
    "author": "Edward Chalupa — echalupa.com",
    "article": "echalupa.com/blog/nxtops-multi-agent-stack"
  }
}
