Event-driven AI agents with native MCP tools.
Webhooks & RSS feeds in. MCP tools out. AI agent in the middle.
Stripe webhook ──→ Recipe ──→ QuickBooks MCP (create invoice)
GitHub webhook ──→ Recipe ──→ Slack MCP (post message)
HN RSS feed ──→ Recipe ──→ Slack MCP (daily digest)
Any event ──→ Recipe ──→ Any MCP server
HookLaw connects any event source (webhooks, RSS/Atom feeds) to any MCP server through AI agents. Define recipes in YAML, bring your own API keys, self-host it.
Other platforms treat webhooks as just another input channel for their AI assistant. HookLaw is event-first: every event source gets its own AI agent and MCP tool connections.
- Proactive, not just reactive — RSS feeds let your agents monitor the world and act on new information automatically
- Multi-agent chains — recipes trigger other recipes on success/error with depth tracking
- Human-in-the-loop — agents pause for approval before taking action
- Agent memory — conversation context persists across executions
- Conditional routing — AI evaluates which recipe handles each event
- Full observability — traces of every LLM call, tool call, and result
- Config-as-code — one YAML file defines everything, versionable in git
- Self-hosted — your data, your keys, your infrastructure
- Interactive setup — built-in dashboard with guided onboarding wizard
| HookLaw | Others | |
|---|---|---|
| MCP client | Native, via @modelcontextprotocol/sdk |
Shell out to CLI tools |
| Connection | Persistent pool, reusable | Cold-start per call |
| Latency | Sub-second tool calls | ~2.4s overhead per invocation |
| Transport | stdio + SSE | stdio only |
| Management | Dashboard with health checks & install | Manual config |
| Source | How it works |
|---|---|
| Webhooks | POST /h/:slug — receive events from any service |
| RSS/Atom Feeds | Poll feeds on interval, deduplicate via content hash |
A recipe connects an event source to MCP tools through an AI agent. Multiple recipes can share the same slug — one Stripe payment triggers invoice creation AND sends a notification.
┌─────────────┐ ┌───────────────────────────────────────┐ ┌──────────────┐
│ Sources │ │ HookLaw │ │ MCP Servers │
│ │ │ │ │ │
│ Stripe ──┼────▶│ Recipe: payment-to-invoice │────▶│ Stripe MCP │
│ webhook │ │ AI agent orchestrates the flow │────▶│ QuickBooks │
│ │ │ │ │ │
│ GitHub ──┼────▶│ Recipe: pr-review │────▶│ GitHub MCP │
│ webhook │ │ AI agent reviews code │ │ │
│ │ │ │ │ │
│ HN RSS ──┼────▶│ Recipe: hn-digest │────▶│ Slack MCP │
│ feed │ │ AI agent summarizes & posts │ │ │
│ │ │ │ │ │
│ Any src ──┼────▶│ Recipe: your-automation │────▶│ Any MCP │
└─────────────┘ └───────────────────────────────────────┘ └──────────────┘
npx hooklaw startNo config file? HookLaw launches an interactive setup wizard in your browser — pick a provider, choose an event source (webhook or RSS), select integrations, and you're running.
Or install globally:
npm install -g hooklaw
hooklaw startHookLaw includes a built-in web dashboard for managing everything:
- Recipes — view, edit, and create new automation recipes
- Executions — real-time execution logs with payload and agent output
- MCP Servers — health checks, tool discovery, install packages, add new servers
- Feeds — monitor active RSS/Atom feed pollers
- Config — visual YAML config viewer
server:
port: 3007
providers:
anthropic:
api_key: ${ANTHROPIC_API_KEY}
# Shared MCP servers — define once, use in any recipe
mcp_servers:
stripe:
transport: stdio
command: npx
args: ["-y", "@stripe/agent-toolkit", "--tools=all"]
env:
STRIPE_SECRET_KEY: ${STRIPE_SECRET_KEY}
slack:
transport: stdio
command: npx
args: ["-y", "@anthropic/mcp-server-slack"]
# RSS/Atom feed sources
feeds:
hn-top:
url: https://hnrss.org/newest?points=100
slug: hn-digest
refresh: 300000 # poll every 5 minutes
skip_initial: true # don't process existing items on first run
enabled: true
# Recipes connect events → AI agents → MCP tools
recipes:
payment-to-invoice:
description: "Auto-create invoice on Stripe payment"
slug: stripe-payment # POST /h/stripe-payment
mode: async
agent:
provider: anthropic
model: claude-sonnet-4-6
instructions: |
When a Stripe payment succeeds, extract customer details
and create an invoice in QuickBooks.
tools: [stripe, quickbooks] # MCP servers this recipe uses
hn-digest:
description: "Summarize top HN stories and post to Slack"
slug: hn-digest # matches feed slug above
mode: async
agent:
provider: anthropic
model: claude-sonnet-4-6
instructions: |
Summarize this Hacker News story in 2-3 sentences.
Post to #tech-news on Slack with the title, link, and summary.
tools: [slack]
logs:
retention_days: 30Environment variables (${VAR}) are substituted from .env or the environment.
- An event arrives — webhook
POST /h/stripe-paymentor a new RSS item - HookLaw finds all recipes matching the slug
- Each recipe runs its AI agent with the event payload
- Agents use MCP tools to take action (create invoices, send messages, etc.)
- Everything is logged with full execution history
Sync mode — waits for the agent and returns the response in the HTTP reply.
Async mode — returns 200 Accepted immediately, processes in background.
| Method | Path | Description |
|---|---|---|
POST |
/h/:slug |
Receive webhook |
GET |
/health |
Health check |
GET |
/api/recipes |
List all recipes |
POST |
/api/recipes |
Create a recipe |
PATCH |
/api/recipes/:id |
Update a recipe |
GET |
/api/executions |
All executions (filterable) |
GET |
/api/executions/:id/traces |
Agent reasoning traces |
GET |
/api/executions/:id/chain |
Child executions in a chain |
POST |
/api/executions/:id/approve |
Approve/reject execution |
GET |
/api/approvals |
Pending approval queue |
GET |
/api/recipes/:id/memory |
Agent memory for a recipe |
DELETE |
/api/recipes/:id/memory |
Clear agent memory |
GET |
/api/stats |
Execution statistics |
GET |
/api/mcp-servers |
List MCP servers |
POST |
/api/mcp-servers |
Add MCP server |
GET |
/api/mcp-servers/health |
Check all MCP health |
GET |
/api/feeds |
List active feed pollers |
GET |
/api/config |
Redacted config |
Bring your own API keys. Supports:
| Provider | Config key | Notes |
|---|---|---|
| Anthropic | anthropic |
Claude models |
| OpenAI | openai |
GPT models |
| OpenRouter | openrouter |
Multi-model gateway |
| Ollama | ollama |
Local models, set base_url |
HookLaw works with any MCP server. Popular options:
| Server | Transport | Package |
|---|---|---|
| Stripe | stdio | @stripe/agent-toolkit |
| GitHub | stdio | @modelcontextprotocol/server-github |
| Slack | stdio | @anthropic/mcp-server-slack |
| Linear | stdio | mcp-linear |
| Notion | stdio | @anthropic/mcp-server-notion |
| PostgreSQL | stdio | @modelcontextprotocol/server-postgres |
| Filesystem | stdio | @modelcontextprotocol/server-filesystem |
| Any SSE server | sse | Your URL |
hooklaw.config.yaml
│
▼
┌──────────────┐ ┌──────────┐ ┌───────────┐ ┌──────────┐
│ HTTP Server │────▶│ Router │────▶│ Agent │────▶│ MCP Pool │
│ /h/:slug │ │ Recipe │ │ Tool Loop│ │ stdio │
│ /api/* │ │ Matcher │ │ (max 10) │ │ sse │
│ /dashboard │ │ │ │ │ │ │
└──────────────┘ └──────────┘ └───────────┘ └──────────┘
▲ │ │
│ ▼ ▼
┌──────────────┐ ┌──────────┐ ┌──────────┐
│ RSS/Atom │ │ SQLite │ │ External │
│ Feed Poller │ │ (WAL) │ │ MCP Svrs │
└──────────────┘ └──────────┘ └──────────┘
Stack: TypeScript, Node.js, SQLite (better-sqlite3), Zod, Pino
git clone https://github.com/lucianfialho/hooklaw.git
cd hooklaw
pnpm install
pnpm test # vitest
pnpm run typecheck # strict TypeScript
pnpm run dev # start with tsx (hot reload)packages/
├── core/ # Core engine
│ └── src/
│ ├── types.ts # Zod schemas (recipes, MCP servers, providers, feeds)
│ ├── config.ts # YAML loader with ${ENV_VAR} substitution
│ ├── db.ts # SQLite (executions CRUD)
│ ├── mcp.ts # MCP client pool (stdio + SSE, persistent connections)
│ ├── agent.ts # Agentic tool loop (max 10 iterations)
│ ├── feeds.ts # RSS/Atom feed poller with dedup
│ ├── queue.ts # Per-recipe async queue with concurrency control
│ ├── router.ts # Recipe matcher + orchestrator
│ ├── server.ts # HTTP server (webhook receiver + REST API)
│ ├── setup.ts # Interactive setup wizard server
│ ├── index.ts # Bootstrap + wiring
│ └── providers/
│ ├── base.ts # LLM provider interface
│ ├── anthropic.ts # Anthropic provider
│ ├── openai.ts # OpenAI/OpenRouter/Ollama provider
│ └── index.ts # Provider factory + cache
├── dashboard/ # React SPA (Vite + React Router)
├── cli/ # CLI (hooklaw start, hooklaw init)
└── hooklaw/ # Published npm package (re-exports core + cli)
MIT — self-host it, modify it, do whatever you want.
