Skip to main content
Glama
muhib-karim

bounty-radar

by muhib-karim

Bounty Radar is a zero-dependency Node.js toolkit that collects open-source bounty listings, checks that the repository behind each one is still alive, filters known spam patterns, and ranks what is left with a simple, explainable score. The same feed is published as a static HTML board, RSS and JSON, and exposed to AI coding agents through an MCP server.

Key features

  • Six collectors in radar.mjs: Algora org bounty pages, Algora jobs pages, Algora challenges, GitHub issues that mention @algora-io, Opire rewards found via GitHub search, and GitHub issues carrying common bounty labels.

  • Liveness verification through the GitHub CLI: drops archived repos, bounties on forks (for label-sourced issues), repos not pushed within 60 days and issues that are no longer open; counts open PRs that compete for the same issue.

  • Spam and bait filtering: regex blocklist for known fake-bounty repos/orgs and a filter for the copy-pasted [Bounty: $X] title template.

  • Deterministic scoring: points for amount, freshness, claim count, competing PRs and recent repo activity; duplicates are merged keeping the highest amount.

  • Outputs: Markdown digest, JSON (--json), and a static site (build-site.mjs) with index.html, feed.xml (RSS 2.0) and bounties.json.

  • MCP server (mcp-server.mjs): JSON-RPC 2.0 over stdio with four tools (search_bounties, get_listing, whats_new, get_stats). Reads the published feed or a local feed.json.

  • Alerts (notify.mjs): Discord and/or Telegram messages for new listings above a score threshold, with de-duplication state and a --dry-run mode.

  • Optional API (worker/): a Cloudflare Worker serving /v1/listings, /v1/diff, /v1/sources, /v1/stats and an OpenAPI document, with KV-backed API keys and per-IP rate limits.

  • Automation: a scheduled GitHub Actions workflow sweeps every 6 hours, rebuilds the site, deploys GitHub Pages and commits tracking state.

Related MCP server: gibwork-bounty-hunter

Demo

A real terminal session (CLI help and the test suite), rendered to SVG from actual command output:

The board screenshot below is historical. It shows what the generated site looks like, not current listings or availability.

Historical board screenshot

Live board

The scheduled pipeline publishes the board to GitHub Pages: https://muhib-karim.github.io/bounty-radar/ (checked 13 October 2026: HTTP 200, bounties.json generated 2026-10-12 23:52 UTC). The old ai-dev-2024.github.io address from before the account rename no longer resolves, and the optional Cloudflare Worker API returned HTTP 502 in an 11 October 2026 check, so it is not advertised as live.

Filters reduce noise; they do not guarantee that a listing is payable, unclaimed or still available. Always re-check the original listing before investing time.

Quick start

Requirements: Node.js 20 or newer. The live sweep (radar.mjs) also needs the GitHub CLI (gh) authenticated with read access. Tests need neither network nor gh.

git clone https://github.com/muhib-karim/bounty-radar.git
cd bounty-radar
npm test          # no install step: there are no runtime dependencies

Usage

node radar.mjs --help                # options
node radar.mjs                       # Markdown digest to stdout
node radar.mjs --json > feed.json    # JSON feed (progress on stderr)
node radar.mjs --out digest.md       # also write the digest to a file
node radar.mjs --max-age 14          # only listings at most 14 days old

node build-site.mjs feed.json site   # site/index.html, feed.xml, bounties.json
node notify.mjs feed.json --dry-run  # show which alerts would fire, send nothing

Note: radar.mjs writes state/listings-seen.json (first/last-seen timestamps) on every sweep.

MCP server

node mcp-server.mjs --help
node mcp-server.mjs feed.json        # serve a local feed over stdio

Agent configuration:

{ "mcpServers": { "bounty-radar": { "command": "node", "args": ["/path/to/bounty-radar/mcp-server.mjs"] } } }

Without a file argument the server fetches the feed from BOUNTY_RADAR_FEED (defaults to the project's GitHub Pages bounties.json).

Alerts

Set DISCORD_WEBHOOK_URL and/or TELEGRAM_BOT_TOKEN + TELEGRAM_CHAT_ID in the environment, then run node notify.mjs feed.json. Use --dry-run first. Never commit webhook URLs or tokens.

Architecture

flowchart LR
  subgraph Sources
    A1[Algora bounties / jobs / challenges]
    A2[GitHub search: labels, @algora-io mentions, Opire]
  end
  A1 -->|fetch + text parsing| R[radar.mjs<br/>collect, filter, verify, score]
  A2 -->|gh CLI| R
  R -->|gh api: repo + issue + PRs| R
  R --> F[(feed.json)]
  R --> S[(state/listings-seen.json)]
  F --> B[build-site.mjs]
  B --> P[GitHub Pages<br/>index.html, feed.xml, bounties.json]
  F --> N[notify.mjs<br/>Discord / Telegram]
  P --> M[mcp-server.mjs<br/>stdio JSON-RPC]
  P --> W[worker/<br/>Cloudflare Worker API]
  GA[GitHub Actions<br/>sweep-and-publish, every 6h] -.runs.-> R & B & N
  • radar.mjs is the core. Its pure logic (argument parsing, HTML-text parsers, spam/bait filters, scoring, ranking, Markdown rendering) is exported for tests; the network sweep runs only when the file is executed directly.

  • build-site.mjs turns a feed into a static site; if the feed is missing or older than 20 hours it runs a fresh sweep first.

  • mcp-server.mjs and worker/ are read-only consumers of the published bounties.json.

  • hn-monitor.mjs, launch-digest.mjs, build-dashboard.mjs and preflight.mjs are launch-time helpers (Hacker News thread monitoring, digests and a pre-launch link checker).

Testing

npm run check   # node --check on every script (syntax)
npm test        # node:test: unit, MCP protocol and CLI smoke tests

The suite has 31 tests and runs offline against a fixture feed (test/fixtures/feed.json):

  • test/radar.test.mjs: argument parsing, spam/bait filters, Algora text parsers, scoring tiers, ranking, max-age filtering, listing ids, Markdown rendering.

  • test/mcp-server.test.mjs: spawns the MCP server and drives it over stdio (initialize, tools/list, every tool, error codes).

  • test/cli.test.mjs: --help smoke tests, notify.mjs --dry-run, and a full build-site.mjs render into a temp directory.

CI (.github/workflows/ci.yml) runs both commands on Node 20 and 22.

Project structure

radar.mjs               core sweep: collectors, verification, scoring, digest
build-site.mjs          static HTML / RSS / JSON generator
mcp-server.mjs          MCP server (stdio, JSON-RPC 2.0)
notify.mjs              Discord / Telegram alerts with dedup state
hn-monitor.mjs          Hacker News thread + PR watcher (launch helper)
launch-digest.mjs       hourly launch-day digest (launch helper)
build-dashboard.mjs     launch dashboard SVG
build-social-banner.mjs social preview image generator
render-chart.mjs        SVG to PNG via sharp (CI only)
preflight.mjs           pre-launch link and claim checker
worker/                 optional Cloudflare Worker API (wrangler)
state/                  tracking state committed by the scheduled workflows
test/                   node:test suites and fixture feed
docs/                   banner, screenshots, launch notes
.github/workflows/      ci, sweep-and-publish, hn-monitor, launch-digest

Limitations

  • Algora pages are parsed from rendered HTML text, so a markup change on their side can silently reduce results.

  • Opire listings are only included when the amount appears in the issue title; the Opire platform itself was returning 502 in September 2026, so claims may not be possible.

  • Escrow is not verified for GitHub-label or mention sources; those listings are marked unknown.

  • Verification uses several GitHub API calls per candidate and is subject to gh rate limits.

  • The scheduled workflows have side effects (Pages deploys, state commits, alert webhooks). Review them before running manually in a fork.

License

MIT. Source data and linked opportunities retain their own terms.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to discover Gibwork bounties, verify their Solana escrow accounts on-chain, rank opportunities by value, competition and deadline, diff captures over time, and export Markdown/CSV/JSON reports through four read-only MCP tools requiring no wallet or API key.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables developers and AI agents to discover, rank, watch, and draft submissions for Gibwork coding bounties through MCP tools, with optional wallet-authenticated SDK support.
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables any MCP host to search job listings and retrieve individual job details from a public job board's API/RSS through standardized tools. It provides read-only search and detail lookup with polite rate limiting and remote/location filtering.
    MIT