Nightly SBIR opportunity crawler focused on AI-powered reverse engineering tools.
uv venv
uv pip install -e .[dev]
uv run sbir-search --config config.toml --dry-runEdit config.toml:
| Setting | Description |
|---|---|
keywords |
Terms to match (case-insensitive) |
min_score |
Minimum keyword hits to trigger a match |
agencies |
Optional filter (e.g., ["DOD", "NSF"]) |
open_only |
Only open solicitations |
state_path |
Where to store seen IDs between runs |
| Source | Config Section | API Key | Default |
|---|---|---|---|
| SBIR.gov | [match] |
No | Primary |
| SAM.gov | [sam] |
Yes (SAM_API_KEY) |
Fallback |
| DARPA Topics | [dod] |
No | Fallback |
| NSF Seed Fund | [nsf] |
No | Fallback |
| NIH Guide | [nih] |
No | Fallback |
| Grants.gov RSS | [rss] |
No | Fallback |
Set fallback_only = false to always run a source regardless of SBIR.gov status.
export SAM_API_KEY="your-key"Get a free key at https://sam.gov → Account Details → Request Public API Key.
Webhook (simplest):
export DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..."Bot token:
export DISCORD_TOKEN="your-bot-token"
export DISCORD_CHANNEL_ID="your-channel-id"Test without crawling:
uv run sbir-search --config config.toml --test-discordsbir-search --config config.toml # Run crawler
sbir-search --config config.toml --dry-run # Print matches, don't notify
sbir-search --config config.toml --explain # Show match/skip decisions
sbir-search --config config.toml --test-discord "message" # Test DiscordThe workflow in .github/workflows/sbir-crawl.yml runs nightly (UTC) using DISCORD_WEBHOOK_URL from repo secrets. State is cached to avoid duplicate notifications.
MIT Copyright (c) 2025 blacktop