---
title: "Claude Agent Discord Notifications"
description: "Setup guide for the n8n workflow that sends Discord notifications when Claude Code subagents finish. Covers SubagentStop hook config, n8n webhook setup, Discord variable storage, payload reference, and testing."
type: guide
domain: productivity
tags: [n8n, claude-code, discord, webhook, subagent, notifications, automation]
---

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

```json
{
  "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:

```bash
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`
