Project: Metabigor - OSINT intelligence tool without API key hassle Version: v2.2.0 Language: Go 1.24.0 Author: @j3ssie License: MIT
Metabigor is a command-line OSINT (Open Source Intelligence) tool designed to perform network reconnaissance and intelligence gathering without requiring API keys. It's part of the Osmedeus Engine ecosystem and focuses on seven core capabilities:
- Network Discovery (
net) - Find IP ranges (CIDRs) from ASN, organization, domain, or IP - Certificate Transparency (
cert) - Discover subdomains via crt.sh certificate logs - IP Enrichment (
ip) - Get port/service/vulnerability data via Shodan InternetDB (free) - GitHub Code Search (
github) - Find secrets and credentials in public repos via grep.app - IP Clustering (
cluster) - Group IPs by ASN for infrastructure mapping - Related Domains (
related) - Discover related domains via cert logs, WHOIS, analytics - CDN/WAF Detection (
cdn) - Identify if IPs are behind CDN or WAF providers - URL Collection (
url) - Collect known URLs from web archives and indexes, including endpoints mined out of GhostArchive WARC files
It also ships a maintenance command, Skills (skills), that lists, prints, and installs the
embedded agentskills.io skill bundle teaching a coding agent how to drive
the CLI.
metabigor/
├── cmd/metabigor/ # Main application entry point
├── internal/ # Internal packages (not importable by external projects)
│ ├── asndb/ # ASN database management (local CSV lookups)
│ ├── cert/ # Certificate transparency search (crt.sh)
│ ├── cli/ # Cobra CLI commands and subcommands
│ ├── core/ # Core constants and configuration
│ ├── countrydb/ # Country database management
│ ├── gitsearch/ # GitHub code search via grep.app
│ ├── httpclient/ # HTTP client utilities (retryable, Chrome-based)
│ ├── ipinfo/ # IP enrichment (Shodan InternetDB) and clustering
│ ├── netdiscovery/ # Network discovery (static DB + dynamic sources)
│ ├── options/ # Global CLI options and configuration
│ ├── output/ # Output formatting (JSON, CSV, flat) and logging
│ ├── related/ # Related domain discovery (crt, WHOIS, analytics)
│ ├── runner/ # Core execution runner and input processing
│ ├── skill/ # SKILL.md frontmatter parsing for the skills command
│ └── urlsource/ # URL collection sources (Wayback, Common Crawl, ...)
├── public/ # Embedded assets: ASN/country databases + skills/ bundles
│ └── skills/ # Coding-agent skill bundles (SKILL.md + references/)
├── build/ # Release tooling (not compiled into the binary)
│ ├── npm/ # @j3ssie/metabigor packaging: build.mjs + launcher/
│ └── scripts/ # bump-version.sh, github-release.sh
└── test/ # End-to-end test scripts
- Internal-only packages: All logic is in
internal/to prevent external imports - Cobra CLI framework: Each command is a separate file in
internal/cli/ - Runner pattern:
internal/runnerprocesses input (stdin, flags, files) and routes to handlers - Output abstraction:
internal/outputprovides consistent formatting across all commands - Embedded databases:
public/contains CSV databases embedded via//go:embedfor offline use
- User input → CLI command (
internal/cli/) - CLI initializes runner →
internal/runner/runner.go - Runner processes input sources (stdin,
-i,-I,--input) - Runner calls module-specific handler (
cert,net,ip, etc.) - Handler queries data sources (local DB, APIs, web scraping)
- Results formatted via
internal/output/writer.go - Output to stdout or file (
-oflag)
-
ASN Database:
~/.metabigor/ip-asn-combined.csv(2M+ entries)- Downloaded via
metabigor update - Source: https://github.com/iplocate/ip-address-databases
- Used by
netandclustercommands for offline ASN lookups
- Downloaded via
-
Country Database:
~/.metabigor/ip-country-combined.csv- Used for geolocation enrichment
- Same source as ASN database
- Retryable HTTP: Uses
hashicorp/go-retryablehttpfor resilient API calls - Chrome CDP: Uses
chromedpfor JavaScript-heavy sites (grep.app, builtwith.com) - Rate limiting: Concurrent execution controlled via
-cflag (default: 10).githubignores it and runs sequentially, to stay inside grep.app's limit.
- crt.sh: Certificate transparency logs (cert, related commands)
- Shodan InternetDB: Free IP enrichment API (no key required)
- grep.app: GitHub code search
- bgp.he.net: Live BGP routing data (dynamic network discovery)
- viewdns.info: Reverse WHOIS lookups
- builtwith.com: Analytics tracking correlation (Google Analytics, GTM)
- projectdiscovery/cdncheck: CDN/WAF detection library
- web.archive.org: Wayback Machine CDX index (
urlcommand) - index.commoncrawl.org: Common Crawl CDX indexes (
url); index list cached 30 days in~/.metabigor - otx.alienvault.com: AlienVault OTX URL lists (
url) - urlscan.io: Scan history search (
url);URLSCAN_API_KEYoptional - ghostarchive.org: Archived pages plus WARC mining for sub-request URLs (
url) - virustotal.com: v3 domain relationships (
url); requiresVT_API_KEY - intelx.io: Phonebook search (
url); requiresINTELX_API_KEY
The tool remains key-free by default. The url command reads optional keys from the environment
only (VT_API_KEY/VIRUSTOTAL_API_KEY, INTELX_API_KEY, URLSCAN_API_KEY) — never from a config
file or flag. Sources requiring a key are skipped silently when it is absent, unless the user named
that source explicitly, which is an error.
make build # Build and install to $GOPATH/bin
make install # Install directly via go install
make test # Run unit tests with race detection
make e2e # Run end-to-end tests
make build-all # Cross-compile for all platforms- No external imports: Keep all logic in
internal/ - Error handling: Always check errors; use
output.Error()for user-facing messages - Logging: Use
outputpackage methods (Info,Good,Warn,Error,Verbose,Debug). Results go to stdout; every log line goes to stderr. - Log levels:
Verboserequires-v;Debugrequires--debug;-qsilences all but errors - Input flexibility: Always support stdin,
-i,-Ifile, and--inputflag - Output formats: Results are
output.Recordimplementations (Text,Flat,CSV); the writer picks the rendering from-f/--format. Never format results in the CLI layer. - Exit codes: Commands use
RunEand return errors;Executemaps them to exit 1
- Version is defined in
internal/core/constants.go - Build metadata (commit, date) injected via ldflags in Makefile
- Use semantic versioning (vMAJOR.MINOR.PATCH)
- Unit tests: Place in same package as code (
*_test.go) - E2E tests: Shell scripts in
test/directory - Test commands:
make test(unit),make e2e(end-to-end)
- Create new CLI command file in
internal/cli/(e.g.,internal/cli/newcmd.go) - Implement Cobra command with flags and input handling
- Create handler package in
internal/(e.g.,internal/newfeature/) - Add handler logic and data source integration
- Give the result type
Text() []string,Flat() []string, andCSV() ([]string, [][]string)so it satisfiesoutput.Recordand renders in all four formats for free - Start the command with
setup(cmd)for input reading and writer creation - Put
LongandExample(via theexamples()helper) in the command file itself - Register the command in its
init()with aGroupIDand anAnnotations["sample"]target - Add examples to README.md
make update-ip-data # Downloads latest ASN and country databases to public/Then rebuild to embed the new databases:
make buildVERSION in internal/core/constants.go is the single source of truth. It drives the Makefile
ldflags, the goreleaser build, the npm package version, and the git tag — never bump any of them
by hand.
make bump-version # v2.2.0 -> v2.2.1 in constants.go
# PART=minor|major|pre|release, LABEL=beta, SET=v2.3.0
git commit -am "Release v2.2.1" # goreleaser refuses a dirty worktree
make npm-publish # -> npm (needs NPM_TOKEN; DRY_RUN=1 to preview)
make github-release # -> tag + GitHub release (needs GITHUB_TOKEN)npm-publish rebuilds the binaries via make snapshot whenever dist/ is empty or was built
for a different version, so a bump can never ship a stale binary under a fresh npm version
(npm versions are immutable — a bad publish cannot be replaced, only deprecated).
Homebrew is refreshed from a separate repo, j3ssie/homebrew-tap, and installs the npm
artifacts rather than the GitHub release archives — so it only needs make npm-publish to have
finished, not the GitHub release:
cd ../j3ssie-homebrew-tap
./scripts/update-formula.sh # follows @j3ssie/metabigor@latest
git commit -am "metabigor 2.2.1" && git pushThat script downloads each published platform tarball, hashes it (npm's metadata exposes only
sha1/sha512, Homebrew wants sha256), and regenerates Formula/metabigor.rb. .goreleaser.yaml
deliberately has no homebrew block — see the comment there.
Update README.md with any new features before bumping.
- Input handling: ALL commands must support stdin,
-i,-I, and--input— usesetup() - Output modes: One
-f/--formatflag covers text, flat, json, and csv. Do not add per-command format flags; implementoutput.Recordinstead - Log levels: Progress is quiet by default; keep step-by-step detail in
output.Verbose - Error handling: Return errors from
RunE; useoutput.Error()for non-fatal problems - Conflicting flags: Declare them with
cmd.MarkFlagsMutuallyExclusiverather than resolving conflicts silently in code - Concurrency: Respect
-cflag for concurrent operations
- Don't break stdin piping: Always test with
echo "input" | metabigor cmd - Don't read stdin when targets were already given: it blocks forever in scripts and CI
- Don't hardcode paths: Use
options.DataDir()for database paths - Don't skip retries: Use retryable HTTP client for external API calls
- Don't assume online: Commands should work offline when using local DB
- Don't ignore cleanup: Close HTTP clients, Chrome instances, file handles
- No credentials in code: This tool specifically avoids API keys
- Input validation: Sanitize user input before passing to external commands
- Safe web scraping: Respect rate limits, use retries, handle timeouts
- No destructive operations: Tool is read-only OSINT, never modifies targets
- Use goroutines: For bulk operations (IP scanning, subdomain enumeration)
- Batch processing: Process inputs in chunks when possible
- Database caching: Load ASN/country DB once, reuse across lookups
- HTTP connection pooling: Reuse HTTP clients across requests
github.com/spf13/cobra- CLI frameworkgithub.com/projectdiscovery/cdncheck- CDN/WAF detectiongithub.com/projectdiscovery/mapcidr- CIDR manipulationgithub.com/chromedp/chromedp- Headless Chrome for JS-heavy sitesgithub.com/hashicorp/go-retryablehttp- Resilient HTTP clientgithub.com/PuerkitoBio/goquery- HTML parsinggithub.com/charmbracelet/glamour- Markdown rendering in terminal
Before committing changes:
- Run
make test- all unit tests pass - Run
make fmt- code is formatted - Run
make vet- no vet warnings - Test stdin input:
echo "input" | metabigor <cmd> - Test file input:
metabigor <cmd> -I file.txt - Test output file:
metabigor <cmd> -o output.txt - Test every format:
metabigor <cmd> -f text|flat|json|csv - Test quiet mode:
metabigor <cmd> -q(results only, no logs) - Confirm failures exit non-zero:
metabigor <cmd>; echo $? - Run
make e2e- the CLI contract suite passes - Update README.md if adding features, including the upgrade table for renames
# Build and test
make build # Build binary to bin/metabigor
make test # Run tests
make e2e # End-to-end tests
make lint # Run golangci-lint
# Database management
make update-ip-data # Update embedded ASN/country databases
metabigor update # Download databases at runtime (user command)
# Release
make bump-version # Bump VERSION in internal/core/constants.go
make snapshot # Test goreleaser build (cross-platform binaries in dist/)
make npm-pack # Stage npm packages + .tgz tarballs in build/dist-npm/
make npm-publish # Publish @j3ssie/metabigor (needs NPM_TOKEN; DRY_RUN=1 previews)
make github-release # Tag + GitHub release via goreleaser (needs GITHUB_TOKEN)
# Development
go run ./cmd/metabigor # Run without building
go mod tidy # Clean up dependenciesMetabigor's core philosophy is API-free OSINT. When adding features:
- Prefer free data sources over API-based services
- Respect rate limits and implement retries
- Work offline when possible (local databases)
- Pipeline-friendly (stdin/stdout, clean output)
- Zero configuration (no config files, no setup beyond
metabigor update)
- GitHub Issues: https://github.com/j3ssie/metabigor/issues
- Documentation: README.md and
metabigor <cmd> --help - Part of: Osmedeus Engine (@OsmedeusEngine)
- Author: @j3ssie