GitHub | Documentation | License
Event-driven orchestration for Claude Code. Metarelay replaces GitHub API polling with a lightweight webhook relay — GitHub pushes events to Supabase, and your local daemon dispatches AI agents in response.
CI fails? An agent investigates and pushes a fix. PR review posted? An agent addresses the feedback. No polling, no manual intervention.
GitHub webhooks ──→ Supabase Edge Function ──→ PostgreSQL
│
Realtime WebSocket
│
Local daemon
│
┌─────────────────────┼──────────────────────┐
▼ ▼
~/.metarelay/events.jsonl One-shot handlers
│ (claude -p, curl,
tail -f (push) any command)
│
Persistent subagent
wakes up and acts
Metarelay supports two dispatch models:
- File-based (recommended): The daemon appends events to
.metarelay/events.jsonlin each repo's local checkout. A persistent subagent runstail -fon the file — zero polling, zero latency, zero process spawns. When an event lands, the agent wakes up, acts, and goes back to waiting. - Subprocess: The daemon runs a shell command per event (e.g.,
claude -p '...'). Simple for one-shot handlers like Slack notifications or custom scripts.
On startup, the daemon catches up on any events it missed (cursor-based pagination). Then it subscribes to live events via WebSocket. Events are deduplicated at both cloud and local levels — handlers never fire twice for the same event.
# Install
git clone https://github.com/dsifry/metarelay.git
cd metarelay
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
# Configure (after setting up Supabase — see cloud/setup.md)
mkdir -p ~/.metarelay
cp config.example.yaml ~/.metarelay/config.yaml
# Edit with your Supabase URL, key, and repo name/path
# Run
metarelay startSee INSTALL.md for detailed installation instructions.
Add this handler to your ~/.metarelay/config.yaml:
handlers:
- name: "fix-ci-failure"
event_type: "check_run"
action: "completed"
command: >-
claude -p 'CI check "{{summary}}" failed on branch {{ref}}
in {{repo}}. Conclusion: {{payload.conclusion}}.
Investigate the failure and push a fix.'
filters:
- "payload.conclusion == 'failure'"When CI fails, metarelay resolves the {{variables}} against the event and runs the command. Claude Code investigates, identifies the issue, and pushes a fix — all automatically.
| Document | Description |
|---|---|
| INSTALL.md | Prerequisites, installation, and setup |
| USAGE.md | Configuration, CLI reference, writing handlers, troubleshooting |
| AGENTS.md | How metarelay integrates with Claude Code and other AI agents |
| CONTRIBUTING.md | Development setup, architecture, testing, PR process |
| cloud/setup.md | Supabase and GitHub App setup (step-by-step) |
| CLAUDE.md | Instructions for AI agents working on this codebase |
metarelay start [-c CONFIG] [-v] Start the daemon (foreground)
metarelay sync [-c CONFIG] [-v] One-shot catch-up (no live subscription)
metarelay status [-c CONFIG] Show cursor positions per repo
metarelay --version Print version
| Event | Use Case |
|---|---|
check_run |
CI check pass/fail |
check_suite |
CI suite results |
workflow_run |
GitHub Actions workflow results |
pull_request_review |
PR review submissions |
pull_request_review_comment |
PR inline comments |
Hexagonal architecture with dependency injection. Business logic depends on abstract ports, not concrete implementations — making it straightforward to test (158 tests, 100% coverage) and extend.
core/interfaces.py ← Ports (abstract)
adapters/ ← Implementations (Supabase, SQLite, subprocess)
container.py ← Wires ports to adapters
daemon.py ← Event loop (catch-up → subscribe → dispatch)
handlers/registry.py ← Routes events to handlers
See CONTRIBUTING.md for the full architecture guide.
- goodtogo — Claude Code workflow system (PR Shepherd, session management, task tracking)