CLI
@riavzon/bot-detector ships a CLI with four subcommands. You can run them with npx without a global install, or directly as bot-detector after installing the package.
npx @riavzon/bot-detector <command>
pnpm dlx @riavzon/bot-detector <command>
yarn dlx @riavzon/bot-detector <command>
bunx @riavzon/bot-detector <command>
init
Runs the installation wizard. init verifies that mmdbctl is installed and installs it automatically if it is not found. It then prompts for a BGP.tools contact string, which is required to download BGP and ASN data from their API.
Once dependencies are confirmed, the command compiles all data sources in parallel and writes them to _data-sources/ inside the package directory:
- BGP and ASN data
- City and geography databases
- Tor node lists
- Proxy and anonymizer lists
- FireHOL threat levels 1-4 and the anonymous feed
- Verified crawler IP ranges (Googlebot, Bingbot, Apple, Meta, and others)
- User-Agent pattern database (
useragent.mdb)
npx @riavzon/bot-detector init
pnpm dlx @riavzon/bot-detector init
yarn dlx @riavzon/bot-detector init
bunx @riavzon/bot-detector init
To skip the interactive prompt in CI or automated environments, pass your contact string directly with the --contact flag:
npx @riavzon/bot-detector init --contact="MyApp - [email protected]"
pnpm dlx @riavzon/bot-detector init --contact="MyApp - [email protected]"
yarn dlx @riavzon/bot-detector init --contact="MyApp - [email protected]"
bunx @riavzon/bot-detector init --contact="MyApp - [email protected]"
init skips silently when the databases already exist. If they do not exist and no contact string is provided, it prints a warning and exits without failing.refresh
Redownloads and recompiles all data sources using the configuration cached from the last init run. This command requires init to have been run at least once.
npx @riavzon/bot-detector refresh
pnpm dlx @riavzon/bot-detector refresh
yarn dlx @riavzon/bot-detector refresh
bunx @riavzon/bot-detector refresh
Run refresh at least once every 24 hours to keep threat intelligence feeds current. Add it to a cron job or a scheduled CI pipeline:
# Example: daily cron at 3am
0 3 * * * cd /your/app && npx bot-detector refresh
generate
Reads your database and compiles two custom MMDB files from your visitor history:
banned.mmdb: Built from all rows in thebannedtable with a non-null IP address.highRisk.mmdb: Built from rows in thevisitorstable wheresuspicious_activity_scoreis greater than or equal togenerator.scoreThreshold(default70).
These files are written to _data-sources/ and are loaded by the enableKnownBadIpsCheck checker on startup. Once generated, previously identified threats are checked synchronously in the cheap phase, making repeat offenders extremely fast to reject.
Flags
The generate command accepts the following flags:
| Flag | Type | Description | Default |
|---|---|---|---|
--db | enum: sqlite | mysql-pool | postgresql | cloudflare-d1 | planetscale | Database driver to use | sqlite |
--db-name | string | Database name (or binding name for Cloudflare D1) | — |
--db-host | string | Database host (for MySQL/Postgres) | — |
--db-user | string | Database user | — |
--db-password | string | Database password | — |
--db-url | string | Connection URL (for Planetscale) | — |
--mmdbctl | string | Path to the mmdbctl binary | mmdbctl |
--types | boolean | Generate TypeScript types | false |
--delete | boolean | Delete rows that compiled in this run | false |
--score | number | Threat score considered "high" | 70 |
Example usage:
npx @riavzon/bot-detector generate --db mysql-pool --db-host=localhost --db-user=root --db-password=secret --db-name=botdb --mmdbctl=/usr/local/bin/mmdbctl --score=80 --delete
pnpm dlx @riavzon/bot-detector generate --db=mysql-pool --db-host=localhost --db-user=root --db-password=secret --db-name=botdb --mmdbctl=/usr/local/bin/mmdbctl --score=80 --delete
yarn dlx @riavzon/bot-detector generate --db=mysql-pool --db-host=localhost --db-user=root --db-password=secret --db-name=botdb --mmdbctl=/usr/local/bin/mmdbctl --score=80 --delete
bunx @riavzon/bot-detector generate --db=mysql-pool --db-host=localhost --db-user=root --db-password=secret --db-name=botdb --mmdbctl=/usr/local/bin/mmdbctl --score=80 --delete
generate requires mmdbctl. When the binary cannot be found at the path configured in generator.mmdbctlPath, the command prompts you to install it and exits with instructions.
generate periodically and after bulk ban operations so the compiled databases reflect your latest visitor history.load-schema
Creates the required database tables (visitors and banned) in the database configured by defineConfiguration. Run this once after your first configuration before starting the server.
Flags
The load-schema command accepts these flags to select and configure the database connection used to create tables:
| Flag | Type | Description | Default |
|---|---|---|---|
--db | enum: sqlite | mysql-pool | postgresql | cloudflare-d1 | planetscale | Database driver to use | sqlite |
--db-name | string | Database name (or binding name for Cloudflare D1) | — |
--db-host | string | Database host (for MySQL/Postgres) | — |
--db-user | string | Database user | — |
--db-password | string | Database password | — |
--db-url | string | Connection URL (for Planetscale) | — |
Example usage:
npx @riavzon/bot-detector load-schema --db mysql-pool --db-host=localhost --db-user=root --db-password=secret --db-name=botdb
pnpm dlx @riavzon/bot-detector load-schema --db=mysql-pool --db-host=localhost --db-user=root --db-password=secret --db-name=botdb
yarn dlx @riavzon/bot-detector load-schema --db=mysql-pool --db-host=localhost --db-user=root --db-password=secret --db-name=botdb
bunx @riavzon/bot-detector load-schema --db=mysql-pool --db-host=localhost --db-user=root --db-password=secret --db-name=botdb
load-schema reads the active defineConfiguration call to determine the database driver and connection. Your application entry point must export or call defineConfiguration before this command can resolve the connection.
load-schema before starting the server for the first time. It is safe to skip on subsequent restarts.