claude-home/productivity/n8n/workflows/claude-agent-notifications.md
Cal Corum 0726d0337b feat: add SubagentStop → Discord notification via n8n (#4)
- Add SubagentStop HTTP hook to .claude/settings.json pointing at n8n
- Add importable n8n workflow (claude-agent-done.json): webhook trigger →
  extract agent name → POST to Discord
- Add setup guide (claude-agent-notifications.md) with payload reference,
  test curl command, and future extension notes
- Update n8n CONTEXT.md and workflows/README.md with new workflow entry

Discord webhook URL is stored as n8n variable DISCORD_CLAUDE_ALERTS_WEBHOOK
to keep it out of local config files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 14:30:43 +00:00

3.0 KiB

Claude Agent Done → Discord Notifications

Notifies a Discord channel via webhook when a Claude Code subagent finishes. Useful for long-running pipelines (10+ minutes) where you want a heads-up when work completes.

Architecture

Claude Code (SubagentStop hook)
  │
  │  POST raw event JSON
  ▼
n8n Webhook: /webhook/claude-agent-done
  │
  │  Extract agent name, build message
  ▼
Discord Webhook (stored as n8n variable)
  │
  ▼
"🏁 Claude agent **{name}** has finished."

Why n8n as the middle layer?

Claude Code HTTP hooks send raw event JSON — you can't customize the body. Discord requires {"content": "..."}. n8n does the transformation and keeps the Discord webhook URL out of local config files.

Setup

1. n8n workflow

Import claude-agent-done.json into n8n:

  1. n8n → Workflows → Import from File → select claude-agent-done.json
  2. Set the workflow to Active
  3. Note the production webhook URL: http://10.10.0.210:5678/webhook/claude-agent-done

2. Discord webhook

  1. Open the target Discord channel → Edit Channel → Integrations → Webhooks → New Webhook
  2. Copy the webhook URL

3. n8n variable

Store the Discord URL so it stays out of config files:

  1. n8n → Settings → Variables → Add Variable
  2. Key: DISCORD_CLAUDE_ALERTS_WEBHOOK
  3. Value: your Discord webhook URL

4. Claude Code hook config

The hook is configured in .claude/settings.json at the repo root:

{
  "hooks": {
    "SubagentStop": [
      {
        "type": "http",
        "url": "http://localhost:5678/webhook/claude-agent-done",
        "async": true
      }
    ]
  }
}

Note: Update localhost:5678 to match your n8n host if running remotely (e.g. http://10.10.0.210:5678).

Testing

Send a test payload to verify the pipeline end-to-end:

curl -X POST http://10.10.0.210:5678/webhook-test/claude-agent-done \
  -H "Content-Type: application/json" \
  -d '{"hook_event_name": "SubagentStop", "session_id": "abc12345", "subagent_name": "test-agent"}'

Switch to /webhook/ (not /webhook-test/) once confirmed working.

Payload reference

Claude Code sends a JSON payload on SubagentStop. Known fields:

Field Description
hook_event_name Always "SubagentStop"
session_id Agent session identifier
subagent_name Name of the subagent (if set)

The n8n workflow uses subagent_name if present, falling back to the first 8 chars of session_id.

Future extensions

  • Route different agent names to different Discord channels
  • Add rich embeds with duration and success/failure status
  • Filter by agent name (only notify for specific long-running pipelines)
  • Route to local TTS/voice server for audio alerts

Change Log

2026-03-04 - Initial setup

  • Created n8n webhook workflow (claude-agent-done.json)
  • Added SubagentStop HTTP hook to .claude/settings.json
  • Discord webhook URL stored as n8n variable DISCORD_CLAUDE_ALERTS_WEBHOOK