/webhook-subscriptions
Webhook subscriptions: event-driven agent runs.
$ npx -y skills add devsoul2026/hermes-one-click --skill webhook-subscriptions --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/webhook-subscriptions
Context preview
The summary Claude sees to decide when to auto-load this skill.
Webhook subscriptions: event-driven agent runs.
SKILL.md
webhook-subscriptions.SKILL.mdname: webhook-subscriptions
description: "Webhook subscriptions: event-driven agent runs."
version: 1.1.0
platforms: [linux, macos, windows]
metadata:
hermes:
tags: [webhook, events, automation, integrations, notifications, push]Webhook Subscriptions
Create dynamic webhook subscriptions so external services (GitHub, GitLab, Stripe, CI/CD, IoT sensors, monitoring tools) can trigger Hermes agent runs by POSTing events to a URL.
Setup (Required First)
The webhook platform must be enabled before subscriptions can be created. Check with:
hermes webhook list
If it says "Webhook platform is not enabled", set it up:
Option 1: Setup wizard
hermes gateway setup
Follow the prompts to enable webhooks, set the port, and set a global HMAC secret.
Option 2: Manual config
Add to `~/.hermes/config.yaml`:
platforms:
webhook:
enabled: true
extra:
host: "0.0.0.0"
port: 8644
secret: "generate-a-strong-secret-here"Option 3: Environment variables
Add to `~/.hermes/.env`:
WEBHOOK_ENABLED=true
WEBHOOK_PORT=8644
WEBHOOK_SECRET=generate-a-strong-secret-here
After configuration, start (or restart) the gateway:
hermes gateway run
# Or if using systemd:
systemctl --user restart hermes-gateway
Verify it's running:
curl http://localhost:8644/health
Commands
All management is via the `hermes webhook` CLI command:
Create a subscription
hermes webhook subscribe <name> \
--prompt "Prompt template with {payload.fields}" \
--events "event1,event2" \
--description "What this does" \
--skills "skill1,skill2" \
--deliver telegram \
--deliver-chat-id "12345" \
--secret "optional-custom-secret"Returns the webhook URL and HMAC secret. The user configures their service to POST to that URL.
List subscriptions
hermes webhook list
Remove a subscription
hermes webhook remove <name>
Test a subscription
hermes webhook test <name>
hermes webhook test <name> --payload '{"key": "value"}'Prompt Templates
Prompts support `{dot.notation}` for accessing nested payload fields:
- `{issue.title}` — GitHub issue title
- `{pull_request.user.login}` — PR author
- `{data.object.amount}` — Stripe payment amount
- `{sensor.temperature}` — IoT sensor reading
If no prompt is specified, the full JSON payload is dumped into the agent prompt.
Common Patterns
GitHub: new issues
hermes webhook subscribe github-issues \
--events "issues" \
--prompt "New GitHub issue #{issue.number}: {issue.title}\n\nAction: {action}\nAuthor: {issue.user.login}\nBody:\n{issue.body}\n\nPlease triage this issue." \
--deliver telegram \
--deliver-chat-id "-100123456789"Then in GitHub repo Settings → Webhooks → Add webhook:
- Payload URL: the returned webhook_url
- Content type: application/json
- Secret: the returned secret
- Events: "Issues"
GitHub: PR reviews
hermes webhook subscribe github-prs \
--events "pull_request" \
--prompt "PR #{pull_request.number} {action}: {pull_request.title}\nBy: {pull_request.user.login}\nBranch: {pull_request.head.ref}\n\n{pull_request.body}" \
--skills "github-code-review" \
--deliver github_commentStripe: payment events
hermes webhook subscribe stripe-payments \
--events "payment_intent.succeeded,payment_intent.payment_failed" \
--prompt "Payment {data.object.status}: {data.object.amount} cents from {data.object.receipt_email}" \
--deliver telegram \
--deliver-chat-id "-100123456789"CI/CD: build notifications
hermes webhook subscribe ci-builds \
--events "pipeline" \
--prompt "Build {object_attributes.status} on {project.name} branch {object_attributes.ref}\nCommit: {commit.message}" \
--deliver discord \
--deliver-chat-id "1234567890"Generic monitoring alert
hermes webhook subscribe alerts \
--prompt "Alert: {alert.name}\nSeverity: {alert.severity}\nMessage: {alert.message}\n\nPlease investigate and suggest remediation." \
--deliver originDirect delivery (no agent, zero LLM cost)
For use cases where you just want to push a notification through to a user's chat — no reasoning, no agent loop — add `--deliver-only`. The rendered `--prompt` template becomes the literal message body and is dispatched directly to the target adapter.
Use this for:
- External service push notifications (Supabase/Firebase webhooks → Telegram)
- Monitoring alerts that should forward verbatim
- Inter-agent pings where one agent is telling another agent's user something
- Any webhook where an LLM round trip would be wasted effort
hermes webhook subscribe antenna-matches \
--deliver telegram \
--deliver-chat-id "123456789" \
--deliver-only \
--prompt "🎉 New match: {match.user_name} matched with you!" \
--description "Antenna match notifications"The POST returns `200 OK` on successful delivery, `502` on target failure — so upstream services can retry intelligently. HMAC auth, rate limits, and idempotency still apply.
Requires `--deliver` to be a real target (telegram, discord, slack, github_comment, etc.) — `--deliver log` is rejected because log-only direct delivery is pointless.
Security
- Each subscription gets an auto-generated HMAC-SHA256 secret (or provide your own with `--secret`)
- The webhook adapter validates signatures on every incoming POST
- Static routes from config.yaml cannot be overwritten by dynamic subscriptions
- Subscriptions persist to `~/.hermes/webhook_subscriptions.json`
How It Works
1. `hermes webhook subscribe` writes to `~/.hermes/webhook_subscriptions.json` 2. The webhook adapter hot-reloads this file on each incoming request (mtime-gated, negligible overhead) 3. When a POST arrives matching a route, the adapter formats the prompt and triggers an agent run 4. The agent's response is delivered to the configured target (Telegram, Discord, Git
Read more
name: webhook-subscriptions
description: "Webhook subscriptions: event-driven agent runs."
version: 1.1.0
platforms: [linux, macos, windows]
metadata:
hermes:
tags: [webhook, events, automation, integrations, notifications, push]Webhook Subscriptions
Create dynamic webhook subscriptions so external services (GitHub, GitLab, Stripe, CI/CD, IoT sensors, monitoring tools) can trigger Hermes agent runs by POSTing events to a URL.
Setup (Required First)
The webhook platform must be enabled before subscriptions can be created. Check with:
hermes webhook list
If it says "Webhook platform is not enabled", set it up:
Option 1: Setup wizard
hermes gateway setup
Follow the prompts to enable webhooks, set the port, and set a global HMAC secret.
Option 2: Manual config
Add to `~/.hermes/config.yaml`:
platforms:
webhook:
enabled: true
extra:
host: "0.0.0.0"
port: 8644
secret: "generate-a-strong-secret-here"Option 3: Environment variables
Add to `~/.hermes/.env`:
WEBHOOK_ENABLED=true WEBHOOK_PORT=8644 WEBHOOK_SECRET=generate-a-strong-secret-here
After configuration, start (or restart) the gateway:
hermes gateway run # Or if using systemd: systemctl --user restart hermes-gateway
Verify it's running:
curl http://localhost:8644/health
Commands
All management is via the `hermes webhook` CLI command:
Create a subscription
hermes webhook subscribe <name> \
--prompt "Prompt template with {payload.fields}" \
--events "event1,event2" \
--description "What this does" \
--skills "skill1,skill2" \
--deliver telegram \
--deliver-chat-id "12345" \
--secret "optional-custom-secret"Returns the webhook URL and HMAC secret. The user configures their service to POST to that URL.
List subscriptions
hermes webhook list
Remove a subscription
hermes webhook remove <name>
Test a subscription
hermes webhook test <name>
hermes webhook test <name> --payload '{"key": "value"}'Prompt Templates
Prompts support `{dot.notation}` for accessing nested payload fields:
- `{issue.title}` — GitHub issue title
- `{pull_request.user.login}` — PR author
- `{data.object.amount}` — Stripe payment amount
- `{sensor.temperature}` — IoT sensor reading
If no prompt is specified, the full JSON payload is dumped into the agent prompt.
Common Patterns
GitHub: new issues
hermes webhook subscribe github-issues \
--events "issues" \
--prompt "New GitHub issue #{issue.number}: {issue.title}\n\nAction: {action}\nAuthor: {issue.user.login}\nBody:\n{issue.body}\n\nPlease triage this issue." \
--deliver telegram \
--deliver-chat-id "-100123456789"Then in GitHub repo Settings → Webhooks → Add webhook:
- Payload URL: the returned webhook_url
- Content type: application/json
- Secret: the returned secret
- Events: "Issues"
GitHub: PR reviews
hermes webhook subscribe github-prs \
--events "pull_request" \
--prompt "PR #{pull_request.number} {action}: {pull_request.title}\nBy: {pull_request.user.login}\nBranch: {pull_request.head.ref}\n\n{pull_request.body}" \
--skills "github-code-review" \
--deliver github_commentStripe: payment events
hermes webhook subscribe stripe-payments \
--events "payment_intent.succeeded,payment_intent.payment_failed" \
--prompt "Payment {data.object.status}: {data.object.amount} cents from {data.object.receipt_email}" \
--deliver telegram \
--deliver-chat-id "-100123456789"CI/CD: build notifications
hermes webhook subscribe ci-builds \
--events "pipeline" \
--prompt "Build {object_attributes.status} on {project.name} branch {object_attributes.ref}\nCommit: {commit.message}" \
--deliver discord \
--deliver-chat-id "1234567890"Generic monitoring alert
hermes webhook subscribe alerts \
--prompt "Alert: {alert.name}\nSeverity: {alert.severity}\nMessage: {alert.message}\n\nPlease investigate and suggest remediation." \
--deliver originDirect delivery (no agent, zero LLM cost)
For use cases where you just want to push a notification through to a user's chat — no reasoning, no agent loop — add `--deliver-only`. The rendered `--prompt` template becomes the literal message body and is dispatched directly to the target adapter.
Use this for:
- External service push notifications (Supabase/Firebase webhooks → Telegram)
- Monitoring alerts that should forward verbatim
- Inter-agent pings where one agent is telling another agent's user something
- Any webhook where an LLM round trip would be wasted effort
hermes webhook subscribe antenna-matches \
--deliver telegram \
--deliver-chat-id "123456789" \
--deliver-only \
--prompt "🎉 New match: {match.user_name} matched with you!" \
--description "Antenna match notifications"The POST returns `200 OK` on successful delivery, `502` on target failure — so upstream services can retry intelligently. HMAC auth, rate limits, and idempotency still apply.
Requires `--deliver` to be a real target (telegram, discord, slack, github_comment, etc.) — `--deliver log` is rejected because log-only direct delivery is pointless.
Security
- Each subscription gets an auto-generated HMAC-SHA256 secret (or provide your own with `--secret`)
- The webhook adapter validates signatures on every incoming POST
- Static routes from config.yaml cannot be overwritten by dynamic subscriptions
- Subscriptions persist to `~/.hermes/webhook_subscriptions.json`
How It Works
1. `hermes webhook subscribe` writes to `~/.hermes/webhook_subscriptions.json` 2. The webhook adapter hot-reloads this file on each incoming request (mtime-gated, negligible overhead) 3. When a POST arrives matching a route, the adapter formats the prompt and triggers an agent run 4. The agent's response is delivered to the configured target (Telegram, Discord, Git
Hermes One-Click: Windows desktop client for Hermes — one-click setup, Tauri + embedded Python. Build from source with clear docs.
Other skills on hermes-one-click.
macos-computer-use
Drive the macOS desktop in the background — screenshots, mouse, keyboard, scroll, drag — without stealing the user's cursor,…

