npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

claude-beacon

v1.8.0

Published

Claude Code MCP channel plugin — pushes GitHub Actions CI/CD results into running Claude Code sessions

Downloads

205

Readme

claude-beacon

CI npm

MCP channel plugin that pushes GitHub Actions CI/CD results and PR events directly into running Claude Code sessions — triggering automatic investigation and remediation.

Built on the Claude Code Channels API (research preview, ≥ v2.1.80).

What it does

| GitHub event | Condition | What Claude does | |---|---|---| | workflow_run completed | failure on main/master | Fetches logs, diagnoses root cause, spawns subagent to fix and push | | workflow_run completed | failure on feature branch | Fetches logs, spawns subagent to investigate and fix | | push to main/master | open PRs exist | Checks each PR's merge status; notifies on dirty or behind | | pull_request | mergeable_state: dirty | Spawns subagent to rebase and resolve conflicts | | pull_request | mergeable_state: behind | Spawns subagent to rebase cleanly | | pull_request_review submitted | any non-APPROVED state | Debounced 30 s, then plan mode + pr-comment-response skill | | pull_request_review_comment / issue_comment | — | Accumulated in the same debounce window | | pull_request opened/ready | opt-in (on_pr_opened.enabled) | Notifies on new PRs opened or marked ready for review | | pull_request_review APPROVED | opt-in (on_pr_approved.enabled) | Separate handler — e.g. auto-merge trigger | | dependabot_alert created | opt-in (on_dependabot_alert.enabled) | Notifies about CVE — review and bump the dependency | | code_scanning_alert created | opt-in (on_code_scanning_alert.enabled) | Notifies about SAST finding — review and apply a fix |

push events on main are the only way to detect PRs going behind — GitHub doesn't fire a pull_request event when the base branch advances. Pushing to a feature branch does not trigger PR checks.


Quickstart

The fastest path is mux mode with a GitHub App: one App installation covers your entire org, and one persistent mux process handles all Claude Code sessions.

Requirements: Bun ≥ 1.1.0 · Claude Code ≥ 2.1.80 · cloudflared or ngrok

1. Install

bun add -g claude-beacon

2. Set up secrets

openssl rand -hex 32   # generate a webhook secret — copy the output

echo 'GITHUB_WEBHOOK_SECRET=<paste-secret>' >> .env
echo 'GITHUB_TOKEN=<your-PAT>'             >> .env

GITHUB_TOKEN scopes: fine-grained → Actions: Read + Pull requests: Read; classic → public_repo.

3. Start the tunnel

cloudflared tunnel --url http://localhost:9443
# → prints: https://random-name.trycloudflare.com  ← copy this URL

Keep the tunnel running. For a stable URL that survives restarts (recommended): cloudflared named tunnel or ngrok static domain.

4. Create and install a GitHub App

A GitHub App registers the webhook once at the org level — every repository is covered automatically.

Go to github.com/settings/apps → New GitHub App (or your-org → Settings → Developer settings → GitHub Apps) and fill in:

| Field | Value | |---|---| | GitHub App name | claude-beacon (or any name) | | Webhook → Active | ✓ checked | | Webhook URL | Your tunnel URL from step 3 | | Webhook secret | The secret from step 2 |

Under Repository permissions set these to Read-only: Actions, Pull requests, Issues, Contents (and optionally Code scanning alerts, Dependabot alerts).

Under Subscribe to events tick: Workflow runs, Pull requests, Pull request reviews, Pull request review comments, Pull request review threads, Issue comments, Pushes.

Click Create GitHub App, then Install App → choose your account or org → All repositoriesInstall.

See docs/github-app.md for the full guide including permission details, event list, and webhook URL update commands.

Single-repo alternative: If you only need one repository, skip the GitHub App and register a webhook directly in that repo instead.

5. Start the mux

claude-beacon-mux --author YourGitHubUsername

--author is required. The server refuses to start without it — it prevents Claude from acting on other people's PRs. See allowed_authors.

Keep this running in a tmux pane or background terminal. See docs/multi-session.md for systemd setup.

6. Connect Claude Code to the mux

claude mcp add --transport http claude-beacon http://127.0.0.1:9444/mcp

7. Start Claude Code

claude --dangerously-load-development-channels server:claude-beacon

You should see: Listening for channel messages from: server:claude-beacon

Verify: App settings → Advanced → Recent Deliveries. Trigger a push — green ✓ means it's working. In Claude, watch for [claude-beacon] log lines.

8. Authorize automatic actions

By default Claude pauses for confirmation before force-pushing or rebasing, even when the notification says "Act immediately". Add this block to ~/.claude/CLAUDE.md to grant standing permission:

## GitHub CI Channel — Automatic Actions
When the `claude-beacon` MCP channel sends a notification, you are pre-authorized to act without additional confirmation:
- Branch behind base: rebase onto base branch, git push --force-with-lease
- Merge conflicts: same rebase workflow, resolve conflicts
- CI failure on main: spawn subagent, fetch logs, diagnose, fix, push
- CI failure on feature branch: spawn subagent, fetch logs, fix, push
- PR review / comments: plan mode, address threads, reply with gh-pr-reply.sh --batch
The channel notification IS the permission. No additional confirmation needed.

9. Register the session filter

The mux routes events by repo and branch. Add this to ~/.claude/CLAUDE.md so Claude registers automatically on session start:

## GitHub CI Channel — session filter
When the claude-beacon MCP server connects, call `set_filter` immediately with:
- repo: run `git remote get-url origin` and parse to owner/repo
- branch: run `git branch --show-current`
- label: same as branch
- worktree_path: run `git rev-parse --show-toplevel`

Optional — Stop hook: When Claude exits while holding a work claim, other sessions wait up to 10 minutes before taking over. Add a Stop hook to ~/.claude/settings.json to release the claim immediately on exit:

{
  "hooks": {
    "Stop": [{"matcher": "", "hooks": [{"type": "command",
      "command": "claim=$(cat ~/.claude/beacon-active-claim 2>/dev/null) && [ -n \"$claim\" ] && curl -sf -X POST http://localhost:9444/release-claim -H 'Content-Type: application/json' -d \"{\\\"claim_key\\\":\\\"$claim\\\"}\" && rm -f ~/.claude/beacon-active-claim || true"
    }]}]
  }
}

Other deployment modes

Per-repo webhook (single repository) {#per-repo-webhook-single-repository}

If you only need one repository, skip the GitHub App and register a webhook directly in that repo's settings.

Follow steps 1–3 of the Quickstart (install, secrets, tunnel), then:

Repo → Settings → Webhooks → Add webhook:

  • Payload URL — paste the tunnel URL
  • Content typeapplication/json
  • Secret — paste the webhook secret from step 2
  • Events — select individually: Workflow runs, Workflow jobs, Check suites, Pull requests, Pull request reviews, Pull request review comments, Pull request review threads, Issue comments, Pushes

Then continue with Quickstart steps 5–9 (start mux, connect Claude, etc.).

The only difference from the GitHub App path: webhook URL must be updated manually when the tunnel restarts; new repos require a separate webhook registration.

Standalone (single Claude session)

If you only ever run one Claude Code window, skip the mux and let Claude Code spawn the server as a subprocess. Add to ~/.mcp.json or .mcp.json in your project:

{
  "mcpServers": {
    "claude-beacon": {
      "command": "/home/you/.bun/bin/claude-beacon",
      "args": ["--author", "YourGitHubUsername"],
      "env": {
        "GITHUB_WEBHOOK_SECRET": "your-webhook-secret",
        "GITHUB_TOKEN": "your-pat"
      }
    }
  }
}

Use absolute paths (echo $HOME, which claude-beacon). Follow Quickstart steps 1–4 and 7–9; skip steps 5–6.

CLI Events watcher (no tunnel)

Polls the GitHub Events API using your existing gh CLI session — no tunnel or webhook config needed.

Trade-offs: ~30–60 s latency · WorkflowRunEvent only (no PR or job events) · no behind-PR detection.

{
  "mcpServers": {
    "claude-beacon": {
      "command": "/home/you/.bun/bin/bun",
      "args": ["run", "/path/to/claude-beacon/src/ghwatch.ts"],
      "env": { "WATCH_REPOS": "owner/repo1,owner/repo2" }
    }
  }
}

Hub mode (company-wide, multi-user)

Run a single claude-beacon-hub instance shared across a whole team or org. Each developer connects their Claude Code sessions with a personal Bearer token; events are routed by PR author to the right person's sessions. If a user's sessions are offline, an Anthropic SDK fallback worker handles the work and posts a summary to the PR.

No --author flag — in hub mode your GitHub identity comes from your Bearer token, not a CLI flag.

Minimal single-user setup

Good for a single developer who wants Bearer token auth (or plans to add teammates later):

1. Generate a token and create a minimal config:

bun add -g claude-beacon
TOKEN=$(openssl rand -hex 32)
echo "Your token: $TOKEN"

cat > hub-config.yaml << EOF
hub:
  users:
    - github_username: YourGitHubUsername
      token: "$TOKEN"
EOF

2. Start the hub (same machine as Claude Code — no reverse proxy needed):

GITHUB_WEBHOOK_SECRET=<secret> GITHUB_TOKEN=<pat> \
  claude-beacon-hub --config hub-config.yaml

3. Update your MCP config (replaces the old claude mcp add command from mux mode):

# Remove old mux entry if present
claude mcp remove claude-beacon

# Add hub entry with your Bearer token
claude mcp add --transport http claude-beacon http://127.0.0.1:9444/mcp \
  --header "Authorization: Bearer $TOKEN"

Or edit ~/.mcp.json directly:

{
  "mcpServers": {
    "claude-beacon": {
      "url": "http://127.0.0.1:9444/mcp",
      "type": "http",
      "headers": { "Authorization": "Bearer <your-token>" }
    }
  }
}

4. Start Claude Code and register the session filter — same as the Quickstart (steps 7–9).

The hub confirms: Filter registered for @YourGitHubUsername: owner/repo@feat/branch.

Team / company setup

For a shared instance accessible to the whole org, add a reverse proxy (nginx or Caddy) for TLS and point the url at your HTTPS endpoint. Each teammate gets their own token entry in hub:users. See docs/hub-mode.md for the full setup guide including reverse proxy config, systemd, fallback worker, and daemon sessions.


Multi-session coordination

When multiple Claude Code sessions receive the same notification, the claim API ensures only one acts:

claim_notification("<repo>:<branch>")
  → "ok"            — you have the lock, proceed
  → "already_owned" — you already hold it, continue
  → "conflict:X"    — session X claimed it first, stop
  → "expired"       — claim timed out, stop

Claims expire after 10 minutes (server.claim_ttl_ms). Release explicitly with release_claim("<key>") or automatically via the Stop hook (see Quickstart step 9).

If a webhook arrives before any session has called set_filter, the mux queues it (up to 50 events per repo, 2-hour TTL) and flushes it when a session registers.


Configuration

All settings are optional — the defaults work for most setups. Pass a YAML file with --config my-config.yaml (or via .mcp.json args). Environment variables (GITHUB_WEBHOOK_SECRET, GITHUB_TOKEN, WEBHOOK_PORT, REVIEW_DEBOUNCE_MS) always override YAML.

cp config.example.yaml my-config.yaml   # start from the annotated template
claude-beacon-mux --author YourGitHubUsername --config my-config.yaml

allowed_authors (required) {#allowed_authors-required}

claude-beacon refuses to start without at least one entry. Two kinds:

  • Username (no @) — matched against pr.user.login, the PR author's GitHub handle.
  • Email (contains @) — matched against Co-Authored-By commit trailers. Use when an AI agent (Devin, etc.) creates the PR on your behalf.
webhooks:
  allowed_authors:
    - YourGitHubUsername
    - [email protected]   # for AI-agent co-authored PRs

Server options

| Key | Default | Description | |---|---|---| | server.port | 9443 | HTTP port for the webhook receiver | | server.debounce_ms | 30000 | Accumulate review events for this many ms before firing | | server.cooldown_ms | 300000 | Suppress duplicate notifications for the same PR | | server.max_events_per_window | 50 | Maximum review events buffered per debounce window | | server.main_branches | ["main","master"] | Branch names treated as production | | server.claim_ttl_ms | 600000 | How long a work-context claim is held before expiring |

Webhook filters

| Key | Default | Description | |---|---|---| | webhooks.allowed_authors | required | GitHub usernames and/or emails whose PRs trigger actions | | webhooks.allowed_events | [] (all) | Allowlist of GitHub event types. Empty = accept all | | webhooks.allowed_repos | [] (all) | Allowlist of repos as "owner/repo". Empty = accept all |

Behavior hooks

Each hook has an instruction template with {placeholder} substitution. Opt-in hooks default to enabled: false.

| Key | Triggered by | Flags | |---|---|---| | behavior.on_ci_failure_main | workflow_run failure on main | upstream_sync, use_agent | | behavior.on_ci_failure_branch | workflow_run failure on feature branch | upstream_sync, use_agent | | behavior.on_pr_review | PR review / comment events (debounced) | require_plan, skill, use_worktree | | behavior.on_merge_conflict | PR with mergeable_state: dirty | — | | behavior.on_branch_behind | PR with mergeable_state: behind | — | | behavior.on_pr_opened | PR opened / ready for review | enabled (default false) | | behavior.on_pr_approved | APPROVED review submitted | enabled (default false) | | behavior.on_dependabot_alert | Dependabot CVE alert | enabled (default false), min_severity | | behavior.on_code_scanning_alert | CodeQL / SAST alert | enabled (default false), min_severity |

behavior.code_style — free-form string prepended to every PR review notification. Describe your project's coding conventions here.

Notable flags:

  • use_agenttrue (default) spawns a subagent to fix CI, keeping the main session free. Set false to act inline.
  • upstream_synctrue (default) rebases from main before diagnosing. Set false if main is frequently broken.
  • behavior.worktrees.mode"temp" (default, shell git worktree add/remove) or "native" (Claude Code isolation="worktree").
  • behavior.worktrees.base_dir — base directory for temporary worktrees (default /tmp). Path: {base_dir}/{repo}-pr-{N}-rebase.

Security alert hooks broadcast to all sessions registered for the repo. Enable only on the single instance responsible for security triage to avoid multiple sessions racing on the same CVE.

Template placeholders

| Placeholder | Available in | |---|---| | {repo} | all hooks | | {branch} | CI failure hooks, code scanning | | {run_url}, {workflow}, {status}, {commit} | CI failure hooks | | {use_agent_preamble} | CI failure hooks (use_agent toggle) | | {health_check_step} | CI failure hooks (upstream_sync toggle) | | {pr_number}, {pr_title}, {pr_url} | PR state, on_pr_opened, on_pr_approved | | {head_branch}, {base_branch} | PR state, on_pr_opened | | {worktree_steps} | PR state (auto-generated rebase commands) | | {skill}, {worktree_preamble} | on_pr_review | | {author} | on_pr_opened | | {reviewer} | on_pr_approved | | {cve}, {package}, {patched_version} | on_dependabot_alert | | {rule}, {tool} | on_code_scanning_alert | | {severity}, {alert_url} | both security hooks |


Troubleshooting

MCP shows red / "Failed to reconnect"
Port 9443 is held by a previous session. Run lsof -i :9443, kill the PID, restart Claude Code.

401 Unauthorized on webhooks
Secret mismatch. Check GITHUB_WEBHOOK_SECRET in .mcp.json exactly matches GitHub. A .env in the repo directory can shadow it — delete it or make both match.

No notification when a PR falls behind
Ensure Pushes is ticked in GitHub webhook events and GITHUB_TOKEN is set. Note: only pushes to main/master trigger PR checks, not pushes to feature branches.

Mux sends to too many sessions
Stale sessions auto-expire after 30 minutes of inactivity. Restart the mux to clear them immediately.

"bun: command not found" in MCP logs
Use the absolute path in .mcp.json: "command": "/home/you/.bun/bin/bun". Find with which bun.

claude_desktop_config.json vs .mcp.json
~/.config/Claude/claude_desktop_config.json is for Claude Desktop. ~/.mcp.json / .mcp.json is for Claude Code CLI. --dangerously-load-development-channels reads from .mcp.json.

Claude receives notifications but doesn't act automatically
The CLAUDE.md permissions block is missing — add it as described in Quickstart step 8.

No notifications ever arrive — checklist

  1. App → Advanced → Recent Deliveries → green ✓? If not, secret or URL is wrong.
  2. Tunnel still running? Restart = new URL → update the App's Webhook URL in settings.
  3. All required event types subscribed in App settings?
  4. --author exactly matches the GitHub login of the PR author (case-sensitive).
  5. Claude Code started with --dangerously-load-development-channels server:claude-beacon.
  6. In mux mode: set_filter called in the session?

GITHUB_TOKEN 401 on startup
The mux loads .env from its working directory, not your home directory. Confirm via the CWD log line at startup. For fine-grained tokens: resource owner must be the org, and the org must have approved the token.


Development

bun test            # run tests
bun run typecheck   # tsc --noEmit
bun run lint        # Biome v2
bun run build       # bundle to dist/

Security: HMAC-SHA256 verification uses timingSafeEqual (constant-time). Raw payloads are never forwarded to Claude — only sanitized fields reach the notification. GITHUB_TOKEN is read-only. GITHUB_WEBHOOK_SECRET is required; set WEBHOOK_DEV_MODE=true to bypass in local dev only.

See AGENTS.md for the architecture reference and contributor guide.