Agent Skills: Status Page Monitoring Skill

Check status pages for down monitors and alert immediately. Uses curl + jq for accurate API parsing. Supports UptimeRobot, PayPal, and other status page providers.

UncategorizedID: ProxiBlue/claude-skills/status-page-monitoring

Install this agent skill to your local

pnpm dlx add-skill https://github.com/ProxiBlue/claude-skills/tree/HEAD/status-page-monitoring

Skill Files

Browse the full folder contents for status-page-monitoring.

Download Skill

Loading file tree…

status-page-monitoring/SKILL.md

Skill Metadata

Name
status-page-monitoring
Description
Check status pages for down monitors and alert immediately. Uses curl + jq for accurate API parsing. Supports UptimeRobot, PayPal, and other status page providers.

Status Page Monitoring Skill

Overview

This skill checks the status of all monitored services and alerts immediately if any monitor is showing DOWN status.

Primary method: curl + jq for accurate JSON parsing (avoids WebFetch AI summarization errors)

Supports multiple status page providers via direct API endpoints.

When to Use This Skill

  • User runs /status-page-monitoring
  • User asks "check status" or "are sites up?"
  • User wants to know if any monitors are down
  • User asks about uptime or service status

Monitoring Workflow

IMPORTANT: Do NOT read scripts or search for configuration files. This skill provides all the information you need.

Step 1: Check Monitor Status

CRITICAL: Use curl + jq for accurate results! WebFetch AI summarization is unreliable for parsing status data. Always use curl + jq to fetch and parse API endpoints directly.

Option A: curl + jq (PREFERRED - Most Accurate)

Use Bash with curl and jq to fetch raw API data and parse it directly. This avoids AI summarization errors.

UptimeRobot Example:

# Fetch and parse UptimeRobot status
curl -s "https://stats.uptimerobot.com/api/getMonitorList/Zk2EbUnM73" | jq -r '.psp.monitors[] | "\(.name): \(.statusClass)"' | sort

Status class mapping:

  • success = UP
  • danger = DOWN
  • paused = PAUSED

Count by status:

# Count monitors by status
curl -s "https://stats.uptimerobot.com/api/getMonitorList/Zk2EbUnM73" | jq -r '
  .psp.monitors | group_by(.statusClass) |
  map({status: .[0].statusClass, count: length}) |
  .[] | "\(.status): \(.count)"'

Get DOWN monitors only:

# List only DOWN monitors
curl -s "https://stats.uptimerobot.com/api/getMonitorList/Zk2EbUnM73" | jq -r '.psp.monitors[] | select(.statusClass == "danger") | .name'

Known API Patterns by Provider

UptimeRobot (Primary - This Project)

Status page: https://stats.uptimerobot.com/{PAGE_ID}
API endpoint: https://stats.uptimerobot.com/api/getMonitorList/{PAGE_ID}

Example: https://stats.uptimerobot.com/api/getMonitorList/Zk2EbUnM73

PayPal Status

# Fetch PayPal component status
curl -s "https://paypal-status.com/api/v1/components" | jq -r '.[] | "\(.name): \(.status)"'

Returns all PayPal services: Checkout, APIs, Account Management, Braintree, Venmo, etc.

Atlassian Statuspage (Generic)

Many services use Atlassian Statuspage. Try these endpoints with curl + jq:

# Summary endpoint
curl -s "https://status.example.com/api/v2/summary.json" | jq -r '.components[] | "\(.name): \(.status)"'

# Components endpoint
curl -s "https://status.example.com/api/v2/components.json" | jq -r '.components[] | "\(.name): \(.status)"'

# Status endpoint (simple)
curl -s "https://status.example.com/api/v2/status.json" | jq -r '.status.description'

AWS Health Dashboard

Status page: https://health.aws.amazon.com/health/status

AWS Health Dashboard is JavaScript-heavy. Try using lynx if installed:

lynx -dump "https://health.aws.amazon.com/health/status" 2>/dev/null | grep -E "(disruption|degraded|operational)"

If lynx is not available, use WebFetch as a fallback (less reliable).

Unknown Provider

If provider is unknown, try these common API patterns with curl:

# Try in order:
curl -s "https://status.example.com/api/v1/components" | jq '.'
curl -s "https://status.example.com/api/v2/components.json" | jq '.'
curl -s "https://status.example.com/api/v2/summary.json" | jq '.'
curl -s "https://status.example.com/api/status" | jq '.'

Option B: WebFetch (Fallback Only)

Use WebFetch only when:

  • No API endpoint is known
  • curl + jq approach doesn't work for the provider

WARNING: WebFetch uses AI summarization which can misinterpret status data. Always verify results if using WebFetch.

Option C: Text Browsers (For JavaScript-heavy pages)

For pages that require JavaScript rendering and have no API:

# Try lynx (preferred)
lynx -dump "https://status.example.com" 2>/dev/null

# Or w3m
w3m -dump "https://status.example.com" 2>/dev/null

# Or links
links -dump "https://status.example.com" 2>/dev/null

Note: Install text browsers if needed:

apt install lynx    # Debian/Ubuntu
brew install lynx   # macOS

Step 2: Identify Down Monitors

For UptimeRobot, use this command to get only DOWN monitors:

curl -s "https://stats.uptimerobot.com/api/getMonitorList/Zk2EbUnM73" | jq -r '
  .psp.monitors[] | select(.statusClass == "danger") |
  "DOWN: \(.name)"'

For a full summary with counts:

curl -s "https://stats.uptimerobot.com/api/getMonitorList/Zk2EbUnM73" | jq -r '
  (.psp.monitors | length) as $total |
  (.psp.monitors | map(select(.statusClass == "success")) | length) as $up |
  (.psp.monitors | map(select(.statusClass == "danger")) | length) as $down |
  (.psp.monitors | map(select(.statusClass == "paused")) | length) as $paused |
  "Total: \($total) | UP: \($up) | DOWN: \($down) | PAUSED: \($paused)"'

Step 3: Alert Format

If ALL monitors are UP:

STATUS: ALL SYSTEMS OPERATIONAL

[count] monitors checked - all UP
[count] monitors PAUSED (intentional)
Last check: [timestamp]

If ANY monitor is DOWN:

ALERT: MONITOR(S) DOWN

DOWN:
  - [Monitor Name] - [URL]
    Status: DOWN for [duration]
    Incident ID: [id]

UP: [count] monitors operational
PAUSED: [count] monitors paused

Recommended Actions:
1. Check the affected URL directly
2. SSH to server and check services
3. Review server logs

Step 4: Quick Status Filters

To check only DOWN monitors:

mcp-cli call uptimerobot/list-monitors '{"filter": ["DOWN"], "limit": 100}'

Alert Severity Levels

| Status | Severity | Action | |--------|----------|--------| | DOWN | CRITICAL | Immediate alert, investigate now | | PAUSED | INFO | Informational, monitor intentionally stopped | | UP | OK | No action needed |

Example Output

All Systems OK

STATUS CHECK COMPLETE

All 22 monitors are UP

Sites monitored:
- NTO Tank (ntotank.com)
- Protank (protank.com)
- PVC Pipe Supplies (pvcpipesupplies.com)
- IBC Tanks (ibctanks.com)

1 monitor PAUSED (Protank & Equipment - intentional)

No action required.

System Down

CRITICAL ALERT

1 MONITOR DOWN:

  NTO Tank
  URL: https://www.ntotank.com
  Status: DOWN
  Duration: 5 minutes
  Incident: #269634131363671187

IMMEDIATE ACTIONS:
1. Check https://www.ntotank.com directly
2. SSH to server and check services
3. Review error logs
4. Check DNS/SSL status

21 other monitors operational.

Claude Code Status Bar Integration

Display monitor status directly in the Claude Code status bar for always-visible monitoring.

How It Works

┌─────────────────────────────────────────────────────────────┐
│ [Opus] $0.12 | 21 OK                    <- All systems up   │
│ [Opus] $0.12 | 21 1 (NTO HomePage)      <- 1 monitor down   │
│ [Opus] $0.12 | ? stale                  <- Cache outdated   │
└─────────────────────────────────────────────────────────────┘

Architecture:

  1. Cron job runs periodically, invokes Claude CLI with this skill
  2. Claude uses the skill to fetch and parse status from any supported provider
  3. Bash script captures Claude's JSON output, writes to cache file
  4. Status bar script reads cache file, displays in Claude Code status line

This approach leverages Claude's ability to parse multiple status page providers using the skill's documented patterns.

Setup Instructions

Step 1: Scripts Location

The scripts are located in your project:

.claude/scripts/status-monitor-cron.sh   # Cron job - fetches & caches status
.claude/scripts/statusline-with-monitors.sh  # Status bar - displays cached status

Step 2: Configure Cron Job

Add to crontab to run the status check periodically:

crontab -e

Add this line (adjust path to your project):

# Every 5 minutes (recommended - balances freshness vs API costs)
*/5 * * * * /var/www/html/.claude/scripts/status-monitor-cron.sh

# Every 15 minutes (lower cost)
*/15 * * * * /var/www/html/.claude/scripts/status-monitor-cron.sh

Note: This invokes Claude CLI which uses API credits. Choose interval based on:

  • How critical real-time status is for you
  • Your API usage budget
  • The skill handles any provider (UptimeRobot, PayPal, AWS, etc.) automatically

⚠️ COST ALERT: Review the cost estimates below before configuring cron frequency!

Cron Job Cost Estimates

Running this skill via cron invokes Claude CLI, which consumes API credits. Plan your monitoring frequency accordingly.

Token Usage Per Check (Estimated)

| Component | Tokens | |------------------------|--------------| | Prompt + skill context | ~2,000-4,000 | | Bash (curl + jq) call | ~50 | | Bash result | ~100-200 | | JSON output | ~50 | | Total | ~2,500-4,500 |

Note: curl + jq uses fewer tokens than WebFetch since it returns raw data without AI summarization overhead.

Cost Per Check (Claude Sonnet Pricing)

| Type | Tokens | Rate | Cost | |--------|--------|--------|---------| | Input | ~4,000 | $3/1M | $0.012 | | Output | ~200 | $15/1M | $0.003 | | Total | | | ~$0.015 |

Daily/Monthly Cost by Interval

| Interval | Checks/day | Cost/day | Cost/month | |--------------|------------|----------|------------| | Every 1 min | 1,440 | ~$21.60 | ~$648 | | Every 5 min | 288 | ~$4.32 | ~$130 | | Every 15 min | 96 | ~$1.44 | ~$43 | | Every 30 min | 48 | ~$0.72 | ~$22 | | Every 1 hour | 24 | ~$0.36 | ~$11 |

Recommendations

| Use Case | Recommended Interval | Estimated Cost | |----------|---------------------|----------------| | Production-critical sites | Every 5-15 min | $1.50-4.50/day | | General awareness | Every 15-30 min | $0.70-1.50/day | | Low-priority/dev sites | Every 30-60 min | $0.35-0.70/day |

Cost-saving tips:

  • Use longer intervals (15-30 min) for non-critical monitoring
  • Consider using free UptimeRobot email alerts as primary notification
  • Use this cron integration for status bar visibility, not primary alerting
  • curl + jq is more cost-effective than WebFetch (fewer tokens, more accurate)

Step 3: Configure Claude Code Status Line

Add to your Claude Code settings file.

Project-level (.claude/settings.local.json):

{
  "statusLine": {
    "type": "command",
    "command": "/var/www/html/.claude/scripts/statusline-with-monitors.sh"
  }
}

Or user-level (~/.claude/settings.json):

{
  "statusLine": {
    "type": "command",
    "command": "/path/to/your/project/.claude/scripts/statusline-with-monitors.sh"
  }
}

Step 4: Verify Setup

  1. Test cron script manually (this will invoke Claude CLI):
.claude/scripts/status-monitor-cron.sh
cat /tmp/monitor-status.json

Expected output:

{"up": 21, "down": 1, "paused": 1, "down_names": "NTO HomePage", "timestamp": "..."}
  1. Test status line script:
echo '{"model":{"display_name":"Test"},"cost":{"total_cost_usd":0.05}}' | .claude/scripts/statusline-with-monitors.sh
  1. Restart Claude Code to load the new status line configuration.

Status Bar Display

| Display | Meaning | |---------|---------| | 21 OK | All 21 monitors are UP (green) | | 21 1 (Name) | 21 UP, 1 DOWN - shows name of down monitor | | 21 3 | 21 UP, 3 DOWN (red) | | ? stale | Cache file older than 5 minutes (yellow) | | ! error | API fetch failed (yellow) | | - | No cache file found |

Environment Variables

| Variable | Default | Description | |----------|---------|-------------| | STATUS_CACHE_FILE | /tmp/monitor-status.json | Where to store cached status | | CLAUDE_CMD | claude | Path to Claude CLI executable |

Cache File Format

The cron job writes JSON to the cache file:

{
    "up": 21,
    "down": 1,
    "paused": 1,
    "down_names": "NTO HomePage",
    "timestamp": "2026-01-15T22:30:00+00:00",
    "error": false
}

Troubleshooting

Status bar shows -:

  • Cron job hasn't run yet, or cache file doesn't exist
  • Run manually: .claude/scripts/status-monitor-cron.sh
  • Check cache: cat /tmp/monitor-status.json

Status bar shows ? stale:

  • Cron job not running or failing
  • Check cron logs: grep CRON /var/log/syslog
  • Verify crontab: crontab -l

Status bar shows ! error:

  • Claude CLI failed or returned invalid output
  • Test manually: .claude/scripts/status-monitor-cron.sh && cat /tmp/monitor-status.json
  • Check Claude CLI is installed: which claude
  • Check Claude CLI auth: claude --version

Status bar not updating:

  • Claude Code status line updates every 300ms max
  • Restart Claude Code if settings changed
  • Check script is executable: chmod +x .claude/scripts/statusline-with-monitors.sh

Claude CLI not found:

  • Ensure Claude CLI is in PATH for cron
  • Use full path in cron: CLAUDE_CMD="/path/to/claude" /path/to/status-monitor-cron.sh

jq not found:

  • Install jq: apt install jq or brew install jq

Customization

Change cache location:

# In crontab
*/5 * * * * STATUS_CACHE_FILE="/custom/path/status.json" /path/to/status-monitor-cron.sh

Specify Claude CLI path:

# In crontab (if claude not in PATH)
*/5 * * * * CLAUDE_CMD="/usr/local/bin/claude" /path/to/status-monitor-cron.sh

Extend status bar script to show additional info by editing .claude/scripts/statusline-with-monitors.sh.

Success Criteria

  • Monitor status always visible in status bar
  • DOWN monitors highlighted in red
  • No latency impact (reads from cache, not API)
  • Stale/error states clearly indicated
  • Works across Claude Code sessions