Configure Agent-Loop to send notifications via Email, Slack, or Webhooks.
All notification types support the following events:
| Event | Description |
|---|---|
task_completed |
Triggered when a task completes successfully |
task_failed |
Triggered when a task fails |
human_intervention |
Triggered when human intervention is required |
session_started |
Triggered when a new session starts |
session_ended |
Triggered when a session ends |
- SMTP server credentials (Gmail, Outlook, etc.)
- App password if using Gmail (requires 2FA)
Edit .agent/config.json:
{
"email": {
"enabled": true,
"smtp_host": "smtp.gmail.com",
"smtp_port": 587,
"smtp_user": "your-email@gmail.com",
"smtp_password": "your-app-password",
"use_tls": true,
"from_name": "Agent-Loop",
"from_email": "agent-loop@yourcompany.com",
"to_emails": ["admin@yourcompany.com", "team@yourcompany.com"],
"events": ["task_completed", "task_failed", "human_intervention"],
"timeout": 30
}
}- Enable 2-Factor Authentication on your Google account
- Go to https://myaccount.google.com/apppasswords
- Generate an App Password for "Mail"
- Use the App Password as
smtp_password
# Test via API
curl -X POST http://localhost:8000/api/v1/email/test \
-H "Content-Type: application/json" \
-d '{
"smtp_host": "smtp.gmail.com",
"smtp_port": 587,
"smtp_user": "your-email@gmail.com",
"smtp_password": "your-app-password",
"to_emails": ["test@example.com"]
}'
# Or via CLI (if implemented)
uv run python main.py test-emailEmails are sent with the following format:
Subject: [Agent-Loop] Task Completed: {task_name}
Body:
Agent-Loop Notification
Event: Task Completed
Task: {task_name}
Description: {task_description}
Status: {status}
Time: {timestamp}
View details at: {dashboard_url}
- Slack workspace
- Incoming Webhook URL
- Go to https://api.slack.com/messaging/webhooks
- Select your workspace
- Create a new Slack app (or use existing)
- Enable "Incoming Webhooks"
- Create a new webhook URL
- Copy the webhook URL
Edit .agent/config.json:
{
"slack": {
"enabled": true,
"webhook_url": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
"channel": "#agent-loop",
"username": "Agent-Loop",
"icon_emoji": ":robot_face:",
"events": ["task_completed", "task_failed", "human_intervention"],
"timeout": 10,
"retry_count": 3,
"retry_interval": 2
}
}| Option | Description |
|---|---|
channel |
Override the default channel from webhook |
username |
Custom bot name |
icon_emoji |
Emoji icon for the bot |
icon_url |
Custom icon URL (optional) |
curl -X POST http://localhost:8000/api/v1/slack/test \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
}'Agent-Loop sends rich messages using Slack Block Kit:
{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Task Completed :white_check_mark:"
}
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": "*Task:*\nFeature Implementation"},
{"type": "mrkdwn", "text": "*Status:*\nCompleted"}
]
},
{
"type": "context",
"elements": [
{"type": "mrkdwn", "text": "Agent-Loop • 2026-03-08 10:30 AM"}
]
}
]
}- Publicly accessible endpoint URL
- (Optional) Secret for request signing
Edit .agent/config.json:
{
"webhook": {
"enabled": true,
"url": "https://your-server.com/webhook",
"secret": "your-webhook-secret",
"timeout": 10,
"events": ["task_completed", "task_failed", "human_intervention"],
"retry_count": 3,
"retry_interval": 2
}
}{
"event": "task_completed",
"timestamp": "2026-03-08T10:30:00Z",
"data": {
"task_id": "feat-001",
"task_name": "Implement Feature",
"task_description": "Description here",
"status": "completed",
"duration_seconds": 120,
"session_id": "sess-abc123"
}
}| Header | Description |
|---|---|
Content-Type |
application/json |
X-Agent-Loop-Event |
Event type |
X-Agent-Loop-Signature |
HMAC-SHA256 signature (if secret configured) |
Verify webhook authenticity using the signature:
import hmac
import hashlib
def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)curl -X POST http://localhost:8000/api/v1/webhook/test \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhook",
"secret": "your-secret"
}'You can enable multiple notification channels simultaneously:
{
"email": {
"enabled": true,
"events": ["task_completed", "task_failed"]
},
"slack": {
"enabled": true,
"events": ["task_completed", "task_failed", "human_intervention"]
},
"webhook": {
"enabled": true,
"url": "https://your-server.com/webhook",
"events": ["task_completed"]
}
}- Connection refused: Check SMTP host and port
- Authentication failed: Verify username/app password
- TLS errors: Ensure
use_tls: truefor port 587
- Invalid webhook: Verify the webhook URL is correct
- Channel not found: Bot needs to be invited to the channel
- Rate limited: Slack has rate limits for webhooks
- Connection timeout: Ensure endpoint is publicly accessible
- SSL errors: Use valid HTTPS certificates
- 404 errors: Verify endpoint path is correct
Enable debug logging to troubleshoot:
export LOG_LEVEL=DEBUG
uv run python main.py run