A fast, async Minecraft Java Edition server scanner with Discord bot integration and tracked player detection.
Scans IP ranges using the Server List Ping (SLP) protocol — the same handshake your Minecraft client sends when it pings a server in the multiplayer menu. No login, no authentication, no game traffic.
Read this before running the scanner.
This tool sends TCP connection attempts and SLP handshake packets to IP addresses. Depending on your jurisdiction and how you use it, this activity may be subject to computer access laws, terms of service agreements, or network abuse policies.
You are responsible for your own use. The authors of this software are not liable for any misuse, legal consequences, service bans, or damages arising from running this tool.
- Opens a TCP connection to a host:port
- Sends a standard SLP handshake packet (identical to what the Minecraft client sends)
- Reads the JSON status response (version, player count, MOTD)
- Closes the connection immediately
- Log in to any server or authenticate as a player
- Send chat messages or interact with game state
- Exploit any vulnerability or bypass any access control
- Store or transmit any personal data beyond what the server publicly broadcasts
-
Do not target private networks. The exclusion list (
EXCLUDE_CIDRS) blocks RFC 1918 ranges and other reserved blocks by default. Do not disable it with--no-excludeunless you know what you are doing. -
Do not scan infrastructure you do not own without authorization. Scanning cloud providers, data centers, or corporate networks at high rates may violate their terms of service and could result in your account being terminated or legal action.
-
Respect rate limits. Use
--stealthor--rate-limitwhen scanning from shared or metered environments (OCI free tier, student VMs, etc.). Generating excessive traffic is considered abuse regardless of the protocol used. -
Do not use scan results to harass, grief, or harm server owners or players. Finding a server's IP is not an invitation to attack it, spam it, or share its address for malicious purposes.
-
Tracked player detection is for observation only. The player list feature is intended for fans who want to know when a public figure is playing on a public server. Do not use it to stalk, dox, or harass individuals.
-
Comply with local law. Laws around unauthorized computer access vary by country. In many jurisdictions, repeatedly probing systems without authorization — even without causing damage — can be a criminal offense. Know the rules where you live.
If you are running this for research, education, or personal curiosity on networks you are authorized to scan, enjoy. If you are not sure whether your use is appropriate, it probably isn't.
Python 3.10+ # no external libraries required for the scanner
pip install discord.py>=2.3.0 # only needed for the Discord botTested on Ubuntu 20.04 / 22.04 / OCI Always Free VM.
Optional but recommended:
uvloop— drop-in asyncio replacement, significantly faster on Linux (pip install uvloop)masscan— for themasscanmode (requires root)
For each target IP:
1. TCP connect (short timeout)
2. Send SLP handshake packet (same as vanilla Minecraft client)
3. Read JSON status response → version, player count, MOTD, player sample
4. Check player names against tracked list
5. Save result to results.json + notify Discord bot via shared SQLite DB
6. Close connection
The scanner never authenticates, never sends chat, and never interacts with game state. It is purely a read-only status query.
| File | Description |
|---|---|
mc_scanner.py |
Main scanner |
discord_bot.py |
Discord bot (reads events from shared IPC database) |
youtubers.txt |
Tracked player nicknames, one per line |
scanner_config.json |
Optional config (IPC path, notification filters) |
scan_cache.db |
SQLite cache of already-scanned IP:port pairs (auto-created) |
bot_ipc.db |
Shared IPC database between scanner and bot (auto-created) |
results.json |
Found servers, written as a JSON array (auto-created) |
youtuber_hits.jsonl |
Player detection log, one JSON object per line (auto-created) |
kr_cidrs.txt |
Cached Korean IP ranges from APNIC (auto-created) |
<cc>_cidrs.txt |
Cached IP ranges for other countries (auto-created per country) |
web_dashboard.py |
Browser-based GUI dashboard (optional, requires Flask) |
| Preset | Concurrency | Rate | Batch | Time Window | Use For |
|---|---|---|---|---|---|
stealth |
512 | 100/s | 1024 + 8s pause | KST 22:00–07:00 only | OCI / shared VPS |
normal |
2048 | 1000/s | 8192 + 2s pause | No restriction | General VPS |
fast |
8192 | Unlimited | No batching | No restriction | Dedicated server |
The stealth preset runs only between 22:00–07:00 KST and sleeps during the day. Safe to leave running 24/7 — it will pause and resume automatically.
python3 mc_scanner.py ping 1.2.3.4
python3 mc_scanner.py ping 1.2.3.4 --port 25570Prints version, player count, MOTD, and current online players.
# Scan a /16 with stealth settings
python3 mc_scanner.py scan 61.32.0.0/16 --stealth stealth
# Custom output file
python3 mc_scanner.py scan 1.208.0.0/12 --output my_results.json# Safe for OCI — nighttime only, auto-pauses during the day
python3 mc_scanner.py korea --stealth stealth
# Skip APNIC fetch, use bundled fallback list
python3 mc_scanner.py korea --stealth stealth --no-apnic
# Use 4 CPU processes in parallel
python3 mc_scanner.py korea --stealth normal --cpu-workers 4Fetches Korean IP blocks from APNIC (~280 CIDRs), shuffles them, and streams through them one CIDR at a time to keep memory usage flat.
# United States
python3 mc_scanner.py country US --stealth normal
# Japan
python3 mc_scanner.py country JP --stealth fast --cpu-workers 4
# Germany
python3 mc_scanner.py country DE --stealth normal
# Brazil
python3 mc_scanner.py country BR --output brazil_results.json
# Use a custom cache path
python3 mc_scanner.py country US --country-cache us_cidrs.txtPulls IP blocks from all five RIR delegation files (APNIC, RIPE, ARIN, LACNIC, AFRINIC) for the given ISO 3166-1 alpha-2 country code. Falls back to a local cache file if all fetches fail. KR also falls back to a bundled hardcoded list.
Supported country codes: any valid ISO 3166-1 alpha-2 code — US, JP, DE, BR, GB, FR, RU, CN, AU, CA, etc.
# ip_list.txt format:
# 1.2.3.4 <- scan all default ports
# 1.2.3.5:25570 <- scan this specific port only
# # lines starting with # are ignored
python3 mc_scanner.py file ip_list.txt --stealth normalRequires masscan installed and root privileges. masscan finds open ports fast; this tool then does SLP on the results.
python3 mc_scanner.py masscan 1.208.0.0/12 --rate 5000
python3 mc_scanner.py masscan 0.0.0.0/0 --stealth fast --rate 100000Polls a list of servers on an interval and alerts (console + Discord) when a tracked player appears.
# Single server, check every 60s
python3 mc_scanner.py watch 1.2.3.4:25565
# Multiple servers
python3 mc_scanner.py watch 1.2.3.4:25565 5.6.7.8:25570
# Load from a previous scan result
python3 mc_scanner.py watch --from-results results.json --interval 30
# Partial matching: "WakgoodTV" matches "Wakgood"
python3 mc_scanner.py watch --from-results results.json --partialpython3 mc_scanner.py youtuber list
python3 mc_scanner.py youtuber add Notch
python3 mc_scanner.py youtuber add Dream
python3 mc_scanner.py youtuber remove Notch
python3 mc_scanner.py youtuber check Dream123 # test if a name would match
python3 mc_scanner.py youtuber hits # show recent detection log
python3 mc_scanner.py youtuber hits --limit 100Already-scanned IP:port pairs are recorded in scan_cache.db and skipped on subsequent runs.
python3 mc_scanner.py cache stats
python3 mc_scanner.py cache clear --confirmpython3 mc_scanner.py config create # write a template scanner_config.json
python3 mc_scanner.py config show # print current configscanner_config.json fields:
| Field | Default | Description |
|---|---|---|
ipc_db |
bot_ipc.db |
Path to shared IPC database |
notify_all_servers |
false |
Send a Discord notification for every server found |
notify_youtubers |
true |
Send a Discord notification on player match |
notify_min_players |
0 |
Minimum online players to trigger a server notification |
| Option | Description | Example |
|---|---|---|
--stealth |
Select speed/stealth preset | --stealth stealth |
--concurrency |
Max concurrent connections | --concurrency 512 |
--timeout |
Connection timeout in seconds | --timeout 4 |
--rate-limit |
Max new connections per second | --rate-limit 100 |
--budget |
Max connections per hour (rate budget) | --budget 80000 |
--scan-hours |
Only scan during these hours (KST) | --scan-hours 0-7,22-24 |
--batch-size |
Connections before a pause | --batch-size 1024 |
--batch-sleep |
Seconds to pause between batches | --batch-sleep 8 |
--ports |
Port list: default, priority, or custom |
--ports 25565,25566 |
--output |
Output file path | --output results.json |
--no-cache |
Disable the dedup scan cache | --no-cache |
--cache-db |
Path to cache database | --cache-db scan_cache.db |
--no-exclude |
Disable private IP exclusion (not recommended) | --no-exclude |
--exclude-file |
Additional CIDRs to exclude | --exclude-file blocklist.txt |
--no-apnic |
Skip RIR fetch, use local cache only | --no-apnic |
--youtubers |
Path to tracked player list | --youtubers youtubers.txt |
--no-youtuber |
Disable player detection entirely | --no-youtuber |
--partial |
Enable partial nickname matching | --partial |
--ytlog |
Path to player detection log | --ytlog hits.jsonl |
--cpu-workers |
Parallel CPU processes for country/korea modes | --cpu-workers 4 |
-v |
Verbose debug logging | -v |
pip install discord.py>=2.3.0
export BOT_TOKEN=your_token_here
python3 discord_bot.pyThe bot and scanner communicate through a shared SQLite database (bot_ipc.db) using WAL mode — no network connection between them is needed.
Slash commands:
| Command | Description |
|---|---|
/setup servers #channel |
Channel for server-found notifications |
/setup alerts #channel |
Channel for player match alerts |
/setup role @role |
Role to ping on player match |
/setup show |
Show current bot config |
/scanner ping host [port] |
Ping a server from Discord |
/scanner stats |
Live scanner progress |
/scanner results [limit] |
Recently found servers |
/scanner cache |
Cache database stats |
/youtuber list |
Show tracked player list |
/youtuber add name |
Add a nickname |
/youtuber remove name |
Remove a nickname |
/youtuber hits [limit] |
Recent player detections |
CLI options:
python3 discord_bot.py --token YOUR_TOKEN
python3 discord_bot.py --ipc-db /path/to/bot_ipc.db
python3 discord_bot.py --youtubers /path/to/youtubers.txt
python3 discord_bot.py -v # verbose loggingweb_dashboard.py is an optional browser-based GUI that runs alongside the scanner. It works on any OS — Windows, Mac, Linux, or a remote VPS — as long as you can open a browser.
Install and run:
pip install flask
# Local PC — browser opens automatically
python3 web_dashboard.py
# VPS — expose to the network (use a firewall to restrict access)
python3 web_dashboard.py --host 0.0.0.0 --port 5000
# Then open: http://<your-vps-ip>:5000 in your browserImportant: Place
web_dashboard.pyin the same folder asmc_scanner.py. The dashboard launches the scanner as a subprocess, so both files must be together.
Tabs:
| Tab | Description |
|---|---|
| Live Log | Real-time scanner output streamed to the browser. Found servers highlighted green, player matches highlighted red. |
| Results | Browse all found servers as cards. Search by IP/MOTD/player, filter by Forge/players online, sort by newest/oldest/most players. Click any card for full detail. |
| Tracked Players | Add or remove nicknames from youtubers.txt directly in the browser. |
| Stats | Live counters — IPs scanned, servers found, cache size, scan rate, target. |
Scan controls (sidebar):
| Control | Description |
|---|---|
| Mode | korea, country, scan (CIDR), file, or watch |
| Preset | stealth, normal, or fast |
| CPU Workers | How many parallel processes to use |
| ▶ Start / ■ Stop | Start or interrupt the scanner |
CLI options:
python3 web_dashboard.py --host 127.0.0.1 # default, local only
python3 web_dashboard.py --host 0.0.0.0 # expose to network
python3 web_dashboard.py --port 8080 # custom port
python3 web_dashboard.py --no-browser # skip auto-open# Step 1: collect servers overnight (auto-pauses during the day)
python3 mc_scanner.py korea --stealth stealth --output servers.json
# Step 2: monitor collected servers indefinitely
python3 mc_scanner.py watch --from-results servers.json --interval 60 --partial
# Run both in the background with screen or tmux
screen -S scanner python3 mc_scanner.py korea --stealth stealth
screen -S bot python3 discord_bot.py
screen -S dashboard python3 web_dashboard.py --host 0.0.0.0If you only want the web dashboard without Discord, just run the scanner and dashboard — the bot is optional.
[
{
"host": "1.2.3.4",
"port": 25565,
"motd": "A Minecraft Server",
"version_name": "1.20.4",
"protocol": 765,
"online": 3,
"max": 20,
"players": ["PlayerOne", "PlayerTwo"],
"mods": [],
"is_forge": false,
"is_legacy": false,
"favicon": true,
"secure_chat": false,
"ping_ms": null,
"found_at": "2026-03-22T04:00:00+00:00",
"youtubers_found": []
}
]ping_ms is always null — the scanner intentionally skips the ping measurement packet to reduce traffic.
One JSON object per line, appended on each match:
{
"host": "1.2.3.4",
"port": 25565,
"motd": "A Minecraft Server",
"version": "1.20.4",
"online": 5,
"max": 20,
"youtubers": [{"player": "Dream123", "matched": "Dream"}],
"all_players": ["Dream123", "PlayerTwo"],
"detected_at": "2026-03-22T04:12:00+00:00"
}RIR/APNIC fetch fails
python3 mc_scanner.py korea --no-apnic
python3 mc_scanner.py country US --no-apnicScan is too slow
# Increase concurrency and remove rate limit
python3 mc_scanner.py scan 1.208.0.0/12 --stealth fast --concurrency 4096Cache is blocking a rescan of already-seen IPs
python3 mc_scanner.py cache clear --confirmScanner running during restricted hours (stealth mode)
The stealth preset only runs between 22:00–07:00 KST. If you want to run at any hour, use --stealth normal or override with --scan-hours.
# Allow all hours explicitly
python3 mc_scanner.py korea --stealth normal
# Or only scan 02:00–06:00 KST
python3 mc_scanner.py korea --scan-hours 2-6Out of file descriptors
ulimit -n 131072
python3 mc_scanner.py korea --stealth fastCountry code not returning results
# Check what was fetched
cat us_cidrs.txt | wc -l
# Force re-fetch by deleting the cache
rm us_cidrs.txt
python3 mc_scanner.py country US