README.md

June 30, 2026 ยท View on GitHub

oss-scout

oss-scout

Find open source issues personalized to your contribution history

npm downloads CI License Node 20+ Claude Code Plugin

Most issue finders search GitHub for good first issue labels and hand you a list. You could do that yourself in 30 seconds.

oss-scout is different. It knows which repos you've contributed to, which maintainers have merged your work before, and which projects are actively maintained. It searches strategically, vets every result, and tells you where your next PR has the highest chance of getting merged.

Getting Started

Prerequisites

  • Node.js 20+
  • GitHub CLI โ€” gh auth login (install) or set GITHUB_TOKEN env var

Install

npx @oss-scout/core setup    # configure (no install needed)
npx @oss-scout/core search   # find issues

Or install globally: npm install -g @oss-scout/core

First run

1. Configure your preferences:

$ oss-scout setup

๐Ÿ”ง oss-scout setup

Detecting GitHub username...
GitHub username [yourname]:
Preferred languages (or "any" for all) [any]: typescript, rust
Issue labels to search for [good first issue, help wanted]:
Difficulty scope (beginner, intermediate, advanced) [all]: beginner, intermediate
Minimum repo stars [50]: 100
Project categories (nonprofit, devtools, infrastructure, web-frameworks, data-ml, education) [none]: devtools
Repos to exclude (owner/repo, comma-separated, optional):

โœ… Setup complete! Preferences saved.

2. Import your GitHub history (so the tool knows where you've contributed before):

$ oss-scout bootstrap

Imported 23 merged PRs, 4 closed PRs, 142 starred repos
Scored 8 repositories

3. Search for issues:

$ oss-scout search

Found 8 issue candidates:

  โœ… owner/repo#123 [92/100]
     Add timeout option to res.download()
     https://github.com/owner/repo/issues/123
     Repo: 9/10, 2 merged PRs

  โœ… org/project#456 [85/100]
     Support NO_COLOR in browser builds
     https://github.com/org/project/issues/456
     Repo: 8/10, 1 merged PRs

  โš ๏ธ user/library#789 [78/100]
     Add encoding option to execaNode
     https://github.com/user/library/issues/789

Results are automatically saved. View them later with oss-scout results.

How Search Works

oss-scout runs four search strategies in priority order:

StrategyFlagWhat it searchesWhy it matters
mergedPhase 0Repos where you have merged PRsHighest merge probability
starredPhase 1Your GitHub starred reposImplicit interest
broadPhase 2General label/language filteredDiscovery
maintainedPhase 3Actively maintained repos by topicExploration

Run all strategies (default), or pick specific ones:

oss-scout search --strategy merged           # only repos you've contributed to
oss-scout search --strategy starred,broad     # starred repos + general discovery
oss-scout search --strategy all               # all strategies (default)

Heavy strategies (broad, maintained) are automatically skipped when your GitHub API quota is low.

Why Not Just Search GitHub?

FeatureLabel searchoss-scout
Personalized to your historyNoYes โ€” prioritizes repos you've contributed to
Checks if issue is claimedNoYes โ€” scans comments for claim phrases
Checks for existing PRsNoYes โ€” uses timeline API
Project health checkNoYes โ€” commit recency, stars, CONTRIBUTING.md
Viability scoringNoYes โ€” 0-100 with transparent factors
Rate limit awareNoYes โ€” adaptive budget, never wastes quota
Spam detectionNoYes โ€” filters label farming, templated titles

Vetting

Every issue candidate goes through 6 parallel checks:

CheckWhat it detectsMethod
Existing PRsSomeone already submitted a fixTimeline API
Claimed"I'm working on this" in commentsComment text scanning
Project healthIs the repo active and maintained?Commit history, stars, forks
Clear requirementsCan you actually implement this?Body analysis (steps, code blocks)
Contribution guidelinesBranch naming, test framework, CLACONTRIBUTING.md probing
Your merge historyHave your PRs been merged here before?Search API (cached)

Vet a specific issue:

$ oss-scout vet https://github.com/owner/repo/issues/123

โœ… owner/repo#123: APPROVE
   Add timeout option to res.download()

Reasons to approve:
  + Trusted project (2 PRs merged)
  + Clear requirements
  + Contribution guidelines found

Project health: Active
  Last commit: 2 days ago

Re-vet all saved results to check for staleness:

$ oss-scout vet-list --prune

  โœ… owner/repo#123 โ€” still_available [92/100]
  ๐Ÿ”’ user/library#789 โ€” claimed [78/100]
  ๐Ÿ”€ org/project#456 โ€” has_pr [85/100]

๐Ÿ”” Changes since last check (1):
  user/library#789: still_available โ†’ claimed

Summary: 5 available, 1 claimed, 1 has PR, 1 closed
Pruned 3 unavailable issues from saved results.

Each run records every saved result's status, so the next vet-list reports just what changed ("was available, now claimed"). The transitions are also in the --json envelope (transitions[]), so a scheduler can act on them without re-diffing.

Saved Results

Search results are automatically saved to ~/.oss-scout/state.json after each search. Results deduplicate across runs โ€” if the same issue appears again, scores are updated but the first-seen date is preserved.

oss-scout results             # view saved results
oss-scout results --json      # structured JSON output
oss-scout results clear       # wipe saved results
oss-scout vet-list --prune    # re-vet and remove stale issues

Skip list

Skip issues you don't want to see again. Skipped issues are excluded from future search results and auto-expire after 90 days.

oss-scout skip add https://github.com/owner/repo/issues/123    # skip an issue
oss-scout skip list                                              # show skipped issues
oss-scout skip remove https://github.com/owner/repo/issues/123  # unskip
oss-scout skip clear                                             # clear all skips

Skipping an issue also removes it from saved results. When you skip an issue that was in your saved results, metadata (repo, title, number) is preserved in the skip entry for context.

Cross-machine sync with gist persistence

Enable gist persistence to sync your state (preferences, repo scores, PR history, saved results) across machines via a private GitHub gist:

oss-scout config set persistence gist

Your GitHub token needs the gist scope: gh auth refresh -s gist

State is automatically pushed to the gist after each search, vet-list, or bootstrap. When you run oss-scout on a different machine, it finds the gist and pulls the latest state.

Configuration

Interactive setup

oss-scout setup    # first-run interactive configuration

View and update individual settings

oss-scout config                                    # show all preferences
oss-scout config --json                             # JSON output
oss-scout config set languages "typescript,rust"    # set languages
oss-scout config set minStars 100                   # minimum repo stars
oss-scout config set includeDocIssues false          # exclude doc-only issues
oss-scout config set excludeRepos "+spam/repo"       # append to exclude list
oss-scout config set excludeRepos -- "-spam/repo"   # remove ("--" escapes the dash)
oss-scout config reset                               # reset to defaults

All configuration options

KeyTypeDefaultDescription
githubUsernamestring(detected)Your GitHub login; seeds personalization
languagesstring[]any (all languages)Programming language filter (use "any" for no filter)
labelsstring[]good first issue, help wantedIssue label filter
scopeenum[]allDifficulty: beginner, intermediate, advanced
minStarsnumber50Minimum repo star count
maxIssueAgeDaysnumber90Skip issues older than this
includeDocIssuesbooleantrueInclude documentation-only issues
minRepoScoreThresholdnumber4Skip repos scoring below this (1-10)
excludeReposstring[][]Repos to never search
excludeOrgsstring[][]Orgs to never search
aiPolicyBlockliststring[]matplotlib/matplotlibRepos with anti-AI policies
projectCategoriesenum[][]Topic filter: devtools, web-frameworks, etc.
defaultStrategyenum[]allDefault search strategies: merged, starred, broad, maintained
interPhaseDelayMsnumber30000Delay between search phases (rate-limit pacing)
broadPhaseDelayMsnumber90000Extra delay before the broad phase
skipBroadWhenSufficientResultsnumber8Skip the broad phase once this many candidates from new repos are found (0 disables). Candidates from your affinity (Phase 0) and starred (Phase 1) repos do not count, so the broad phase still runs to surface repos you haven't contributed to.
persistenceenumlocalState storage: local or gist
preferLanguagesstring[][]Soft-boost ranking for these repo languages (the --prefer-languages flag overrides)
preferReposstring[][]Soft-boost ranking for these owner/repo slugs (the --prefer-repos flag overrides)
diversityRationumber0Fraction of result slots (0-1) reserved for unboosted candidates (the --diversity-ratio flag overrides)
slmTriageModelstring(disabled)Ollama model id for local SLM pre-triage during vetting (e.g. gemma4:e4b); empty disables it
slmTriageHoststring(127.0.0.1:11434)Override the Ollama HTTP host when it runs on another machine
featuresAnchorThresholdnumber3Min merged-PR count for a repo to be a features anchor (1-50)
featuresSplitRationumber0.6features quick-wins / bigger-bets split (0-1)

Install Options

npm install -g @oss-scout/core
oss-scout setup
oss-scout bootstrap
oss-scout search

Claude Code Plugin

/plugin marketplace add costajohnt/oss-scout
/plugin install oss-scout@oss-scout

Restart Claude Code. Commands:

  • /scout โ€” Multi-strategy issue search with interactive results
  • /scout-setup โ€” Configure preferences

Agents (dispatched automatically by Claude):

  • issue-scout โ€” Autonomous issue discovery and vetting
  • repo-evaluator โ€” Repository health assessment before contributing

MCP Server (Cursor, Claude Desktop, Codex, Windsurf)

{
  "mcpServers": {
    "oss-scout": {
      "command": "npx",
      "args": ["@oss-scout/mcp@latest"]
    }
  }
}

Tools: search, scout-features, vet, skip, config, config-set, sync Resources: scout://config, scout://results, scout://scores

Scheduled digest (GitHub Action)

Run search on a schedule and open/update a digest issue in your repo with the top candidates. Copy examples/weekly-digest.yml into .github/workflows/ in your own repo:

on:
  schedule:
    - cron: "0 14 * * 1" # Mondays 14:00 UTC
permissions:
  issues: write
jobs:
  digest:
    runs-on: ubuntu-latest
    steps:
      - uses: costajohnt/oss-scout@v1
        with:
          github-username: your-github-login
          search-token: ${{ secrets.OSS_SCOUT_TOKEN }} # PAT for personalization (optional)

Inputs: github-username, search-token, issue-token, max-results, strategy, issue-title, issue-label, version. The action reuses the existing CLI (search + results --markdown); no extra machinery.

As a Library

npm install @oss-scout/core
import { createScout } from '@oss-scout/core';

const scout = await createScout({ githubToken: process.env.GITHUB_TOKEN });
const results = await scout.search({ maxResults: 10 });

for (const c of results.candidates) {
  console.log(`${c.issue.repo}#${c.issue.number}: ${c.viabilityScore}/100`);
}

Three persistence modes:

  • 'local' (default) โ€” loads and saves ~/.oss-scout/state.json
  • 'gist' โ€” oss-scout manages state via a private GitHub gist
  • 'provided' โ€” caller owns the state object (for embedding in other tools)
// Host application provides and owns the state
const scout = await createScout({
  githubToken: token,
  persistence: 'provided',
  initialState: existingState,
});

// Record PR outcomes to improve future search quality
scout.recordMergedPR({ url, title, mergedAt, repo });
scout.recordClosedPR({ url, title, closedAt, repo });

// checkpoint() persists according to the mode: it writes local state in
// 'local' mode and pushes the gist in 'gist' mode. In 'provided' mode the
// caller owns persistence, so checkpoint() does not write โ€” read scout.getState().
await scout.checkpoint();

Viability Scoring (0-100)

FactorPointsCondition
Base50Always
Repo score+0 to +20From 1-10 repo quality rating
Repo quality bonus+0 to +12Stars and forks tiers
Merged PRs in repo+15You've had PRs merged here
Clear requirements+15Issue body has steps, code blocks, keywords
Fresh issue+0 to +15Updated within 14 days (full), 15-30 days (partial)
Contribution guidelines+10CONTRIBUTING.md found and parsed
Org affinity+5Merged PRs in other repos under same org
Category match+5Matches your preferred project categories
Existing PR-30Someone already submitted a fix
Claimed-20Someone commented they're working on it
Closed-without-merge history-15Repo has rejected your PRs before (no merges)

Score is clamped to 0-100. Results sorted by: search priority > recommendation > score.

CLI Reference

oss-scout [--debug] <command> [--json]

Note: --debug is program-level; --json is a per-subcommand flag (it goes after
the command, e.g. `oss-scout search --json`, not `oss-scout --json search`).

Setup:
  setup                         Interactive first-run configuration
  bootstrap                     Import starred repos and PR history from GitHub
  sync                          Reconcile tracked open PRs (mark merged/closed)

Search:
  search [count]                Search for issues (default: 10)
    --strategy <s>              Strategies: merged,starred,broad,maintained,all
    --prefer-languages <list>   Soft-boost ranking for matching repo languages
    --prefer-repos <list>       Soft-boost ranking for these owner/repo slugs
    --diversity-ratio <n>       Reserve a fraction (0-1) of slots for unboosted
  features [count]              Feature opportunities in repos with 3+ merged PRs
    --anchor-threshold <n>      Override featuresAnchorThreshold (1-50)
    --split-ratio <r>           Override featuresSplitRatio (0-1)
    --broad                     Search across the ecosystem, not just anchors
  vet <issue-url>               Vet a specific issue
  vet-list                      Re-vet all saved results
    --prune                     Remove unavailable issues
    --concurrency <n>           Max parallel API requests (default: 5)

Results:
  results                       Show saved search results
    --markdown                  Render as a markdown table (for digests)
    --new-only                  Only results first seen since the last search
    --since <date>              Only results first seen at/after this date
  results clear                 Clear saved results

Skip:
  skip add <issue-url>          Skip an issue (exclude from searches)
  skip list                     Show all skipped issues
  skip remove <issue-url>       Unskip an issue
  skip clear                    Clear all skipped issues

Config:
  config                        Show current preferences
  config set <key> <value>      Update a preference
  config reset                  Reset to defaults

Global:
  --debug                       Debug logging
  --json                        Structured JSON output
  --version                     Show version

Spam Detection

Automatically filtered out:

  • Label farming โ€” repos with 5+ beginner labels per issue
  • Templated titles โ€” mass-created issues ("Add Question #42", "Add Question #43")
  • Anti-AI policies โ€” repos in the aiPolicyBlocklist (configurable)

Architecture

@oss-scout/core
โ”œโ”€โ”€ OssScout class          Public API, implements ScoutStateReader
โ”œโ”€โ”€ IssueDiscovery          Multi-phase search orchestrator
โ”œโ”€โ”€ IssueVetter             Parallel vetting pipeline
โ”œโ”€โ”€ issue-eligibility       PR checks, claim detection, requirements analysis
โ”œโ”€โ”€ issue-scoring           Viability scoring (pure functions)
โ”œโ”€โ”€ issue-filtering         Spam detection, doc-only filtering, per-repo caps
โ”œโ”€โ”€ anti-llm-policy         Detect repos with anti-AI contribution policies
โ”œโ”€โ”€ feature-discovery       `scout features` anchor + broad discovery
โ”œโ”€โ”€ personalization         preferLanguages/preferRepos boosts + diversity
โ”œโ”€โ”€ linked-pr / roadmap     Stalled-PR detection, ROADMAP.md scraping
โ”œโ”€โ”€ slm-triage              Optional local Ollama SLM pre-triage
โ”œโ”€โ”€ search-phases           GitHub Search API helpers, caching, batching
โ”œโ”€โ”€ search-budget           Rate limit tracking (30 req/min sliding window)
โ”œโ”€โ”€ repo-health             Project health checks, CONTRIBUTING.md parsing
โ”œโ”€โ”€ category-mapping        Project categories to GitHub topic mapping
โ”œโ”€โ”€ http-cache              ETag response caching, in-flight deduplication
โ”œโ”€โ”€ gist-state-store        Gist-backed persistence with conflict resolution
โ””โ”€โ”€ ScoutState (Zod)        Preferences, repo scores, PR history, saved results

License

MIT

  • OSS Autopilot โ€” full AI copilot for managing open source contributions (uses oss-scout for issue discovery)