Add n8n workflow for Claude Code SubagentStop → Discord webhook notifications #4

Closed
opened 2026-03-01 22:29:26 +00:00 by cal · 1 comment
Owner

Summary

Long-running Claude Code subagents (like the retrosheet-card-update and live-series-card-update pipelines) can take 10+ minutes. It would be helpful to get a Discord notification when they complete.

Approach

Use Claude Code's native HTTP hook on the SubagentStop event, pointed at an n8n webhook endpoint. n8n transforms the payload into Discord's expected {"content": "..."} format and forwards it.

Why n8n instead of direct HTTP hook?

Claude Code HTTP hooks always send the raw event JSON as the POST body — you can't customize it. Discord webhooks require {"content": "message"}. n8n acts as the transformer layer.

Why not a command hook?

A command hook with curl would also work and is simpler, but the n8n approach:

  • Uses the built-in HTTP hook type
  • Gives a visual workflow editor for tweaking message format
  • Can be extended easily (e.g., different channels per agent, rich embeds, etc.)
  • Keeps webhook URLs out of local config files

Implementation

1. Claude Code hook config (.claude/settings.json)

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

2. n8n workflow

  • Trigger: Webhook node listening on /claude-agent-done
  • Transform: Extract subagent_name (and optionally result/session_id) from incoming JSON
  • Format: Build Discord message: "🏁 Claude agent **{name}** has finished."
  • POST: HTTP Request node to Discord webhook URL (stored as n8n credential)

3. Discord webhook

  • Create in target channel's Integrations settings
  • Store URL as n8n credential, not in Claude config

Future extension

  • Could also route to a local voice/TTS server for audio alerts (see related investigation)
  • Rich embeds with agent duration, success/failure status
  • Filter by agent name (only notify for long-running pipelines)
## Summary Long-running Claude Code subagents (like the `retrosheet-card-update` and `live-series-card-update` pipelines) can take 10+ minutes. It would be helpful to get a Discord notification when they complete. ## Approach Use Claude Code's native HTTP hook on the `SubagentStop` event, pointed at an n8n webhook endpoint. n8n transforms the payload into Discord's expected `{"content": "..."}` format and forwards it. ### Why n8n instead of direct HTTP hook? Claude Code HTTP hooks always send the raw event JSON as the POST body — you can't customize it. Discord webhooks require `{"content": "message"}`. n8n acts as the transformer layer. ### Why not a command hook? A command hook with curl would also work and is simpler, but the n8n approach: - Uses the built-in HTTP hook type - Gives a visual workflow editor for tweaking message format - Can be extended easily (e.g., different channels per agent, rich embeds, etc.) - Keeps webhook URLs out of local config files ## Implementation ### 1. Claude Code hook config (`.claude/settings.json`) ```json { "hooks": { "SubagentStop": [ { "type": "http", "url": "http://localhost:5678/webhook/claude-agent-done", "async": true } ] } } ``` ### 2. n8n workflow - **Trigger**: Webhook node listening on `/claude-agent-done` - **Transform**: Extract `subagent_name` (and optionally `result`/`session_id`) from incoming JSON - **Format**: Build Discord message: `"🏁 Claude agent **{name}** has finished."` - **POST**: HTTP Request node to Discord webhook URL (stored as n8n credential) ### 3. Discord webhook - Create in target channel's Integrations settings - Store URL as n8n credential, not in Claude config ## Future extension - Could also route to a local voice/TTS server for audio alerts (see related investigation) - Rich embeds with agent duration, success/failure status - Filter by agent name (only notify for long-running pipelines)
cal added the
ai-working
label 2026-03-04 06:31:20 +00:00
Author
Owner

PR #5 implements this: #5

Changes:

  • .claude/settings.jsonSubagentStop HTTP hook → http://localhost:5678/webhook/claude-agent-done (async)
  • productivity/n8n/workflows/claude-agent-done.json — importable n8n workflow (webhook → extract name → Discord POST)
  • productivity/n8n/workflows/claude-agent-notifications.md — setup guide with payload reference and test curl command

After merging, you'll need to:

  1. Import claude-agent-done.json into n8n and activate it
  2. Create a Discord webhook in the target channel
  3. Add n8n variable DISCORD_CLAUDE_ALERTS_WEBHOOK with the Discord URL
  4. Update the hook URL in .claude/settings.json to http://10.10.0.210:5678/webhook/claude-agent-done (n8n isn't on localhost)
PR #5 implements this: https://git.manticorum.com/cal/claude-home/pulls/5 **Changes:** - `.claude/settings.json` — `SubagentStop` HTTP hook → `http://localhost:5678/webhook/claude-agent-done` (async) - `productivity/n8n/workflows/claude-agent-done.json` — importable n8n workflow (webhook → extract name → Discord POST) - `productivity/n8n/workflows/claude-agent-notifications.md` — setup guide with payload reference and test curl command **After merging**, you'll need to: 1. Import `claude-agent-done.json` into n8n and activate it 2. Create a Discord webhook in the target channel 3. Add n8n variable `DISCORD_CLAUDE_ALERTS_WEBHOOK` with the Discord URL 4. Update the hook URL in `.claude/settings.json` to `http://10.10.0.210:5678/webhook/claude-agent-done` (n8n isn't on localhost)
cal added
ai-failed
and removed
ai-working
labels 2026-03-04 06:35:02 +00:00
cal closed this issue 2026-03-10 18:26:37 +00:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: cal/claude-home#4
No description provided.