Block VPNs, proxies, bots, and malicious connections with real-time IP intelligence. Built-in moderation, AutoMod chat filtering, alt detection, and MySQL multi-server sync — all in one lightweight plugin.
ProtectCord connects every joining player against a live threat intelligence database before they ever reach your server. Combined with a full moderation suite, it's the only tool you need to keep your server clean and your community safe.
bStats: https://bstats.org/plugin/bukkit/Protectcord/24623
1h, 7d, 30d)/pc alts <player>) — names only, never raw IPsBLOCK, WARN, KICK, MUTE, or TEMPMUTE/pc migrate/pc purge192.168.1.*) until they earn the protectcord.ip.full permission/report; staff are notified in-game and via Discord/pc stats/pc check <player|ip> for on-demand threat analysis| Platform | Versions | Notes |
|---|---|---|
| Paper | 1.13 – 1.21+ | Recommended for standalone servers |
| Spigot | 1.8.8 – 1.21+ | Full legacy support |
| Folia | 1.19+ | Multithreaded scheduler support |
| Velocity | 3.0+ | Recommended for proxy networks |
| BungeeCord | 1.8.8 – 1.21+ | Waterfall compatible |
| Forge | 1.20.1+ | Server-side only; checks at post-login |
Network tip: Install only on your proxy (Velocity/BungeeCord) to protect all backend servers with a single API key.
plugins/ folder (or mods/ for Forge)plugins/ProtectCord/config.yml/protectcord reload or restartThe config file is auto-generated at plugins/ProtectCord/config.yml on first run. Every option is explained below.
Velocity uses
config.toml(same structure, TOML syntax). Forge usesconfig/protectcord-forge.toml.
# Your ProtectCord API key — get one free at https://protectcord.com/dashboard/api-keys
api-key: "YOUR_API_KEY_HERE"
# How long to wait (ms) for the API to respond before giving up
api-timeout:
connect: 15000 # Time to establish the connection (default: 15s)
read: 15000 # Time to wait for a response after connecting (default: 15s)
# Automatic retry for failed/timed-out API requests
api-retry:
max-attempts: 3 # Max number of retries before allowing/denying the player (1–5)
initial-delay: 1000 # Wait this long before the first retry (ms)
max-delay: 5000 # Never wait longer than this between retries (ms)
multiplier: 2.0 # Multiply delay by this factor each retry (exponential backoff)
# Used for player tracking and multi-server MySQL identification
server:
name: "My Server" # Friendly name — stored in MySQL as server_id on every row
ip: "" # Your public IP — leave blank to auto-detect
port: 25565 # Your server port
type: "spigot" # Platform: paper / spigot / bungeecord / velocity / forge / folia
# UUID-based tracking via the ProtectCord API
player-tracking:
enabled: true
block-flagged-players: true # Block players flagged as malicious by the API
block-inactive-players: false # Block players whose accounts are marked inactive
# Master switch — set to false to disable all IP checking (not recommended)
enable-ip-check: true
# Choose which connection types to block
block-vpn: true # Virtual private networks (ban evaders, alt accounts)
block-proxy: true # HTTP/SOCKS proxies and anonymizers
block-tor: true # Tor exit nodes
block-datacenter: true # Hosting provider IPs (common source of bots)
block-bogon: true # Invalid, reserved, or unroutable IP ranges
# Risk-based blocking (optional, runs in addition to the flags above)
# Enable this to block by overall threat score instead of (or as well as) individual flags
enable-risk-level-blocking: false
blocked-risk-level: "HIGH"
# Levels (each blocks itself and everything above it):
# LOW — blocks LOW, MEDIUM, HIGH, CRITICAL (very strict)
# MEDIUM — blocks MEDIUM, HIGH, CRITICAL
# HIGH — blocks HIGH, CRITICAL (recommended if enabling)
# CRITICAL — blocks CRITICAL only (very lenient)
geo-blocking:
enabled: false
mode: "blacklist" # "blacklist" = block listed countries
# "whitelist" = ONLY allow listed countries (everyone else blocked)
countries: # ISO 3166-1 alpha-2 country codes
- "CN"
- "RU"
# Limit how many Minecraft accounts can connect simultaneously from the same IP
account-per-ip-limit:
enabled: false
max-accounts: 3 # Maximum simultaneous connections from one IP
enforcement: "BLOCK" # "BLOCK" — deny the new connection
# "KICK_OLDEST" — kick the oldest session to make room
discord-webhook:
enabled: false
url: "" # Paste your Discord webhook URL here
timeout: 10000 # HTTP timeout for sending the webhook (ms)
# Retry failed webhook deliveries
retry:
enabled: true
max-attempts: 3 # How many times to retry a failed delivery (1–10)
initial-delay: 1000 # Wait before first retry (ms)
max-delay: 10000 # Maximum wait between retries (ms)
multiplier: 2.0 # Exponential backoff multiplier
# Rate limiting — Discord allows ~5 requests per 2 seconds per webhook
rate-limit:
max-per-second: 2 # Requests sent per second (1–5)
burst-limit: 5 # Maximum burst before throttling kicks in
# Which events send a webhook message
events:
denied: true # Player was blocked by ProtectCord
accepted: false # Player passed all checks and joined (high volume — off by default)
whitelisted: true # A whitelisted player joined
error: true # An API error occurred during a check
# Which data fields appear in the embed
data-fields:
show-country: true
show-country-flag: true # 🇺🇸 flag emoji next to country name
show-city: true
show-vpn: true
show-proxy: true
show-datacenter: true
show-tor: true
show-mobile: true
show-satellite: true
show-crawler: true
show-bogon: true
show-risk-level: true
show-abuser: true
show-blacklisted: true
show-company: true # ISP / hosting provider name
show-company-risk: true
# Customise the appearance of each embed type
embeds:
denied:
title: "Connection Denied"
emoji: "x"
color: 15158332 # Decimal RGB — red
footer: "" # Optional footer text
thumbnail-url: "" # Optional image in top-right corner
accepted:
title: "Connection Accepted"
emoji: "white_check_mark"
color: 3066993 # Green
footer: ""
thumbnail-url: ""
whitelisted:
title: "Whitelisted Player Joined"
emoji: "white_circle"
color: 16776960 # Yellow
footer: ""
thumbnail-url: ""
error:
title: "API Error"
emoji: "warning"
color: 15105570 # Orange
footer: ""
thumbnail-url: ""
# Advanced webhook behaviour
advanced:
validate-url-on-startup: true # Send a test ping when the plugin loads
log-failures: true # Print failed deliveries to console
log-retries: true # Print retry attempts to console
queue-size: 100 # Max webhooks queued before dropping oldest
# In-game and Discord notifications for moderation actions
alerts:
enabled: true
# Broadcast to online staff with the protectcord.alerts permission
in-game:
enabled: true
# Separate webhook channel just for mod-team events
discord-webhook:
enabled: false
url: ""
# Fine-tune exactly which actions trigger an alert
events:
kick: true
ban: true
unban: true
warn: true
clear-warnings: true
remove-warning: true
automod: true
mute: true
unmute: true
tempmute: true
tempban: true
warnings:
# Automatically take action when a player accumulates enough warnings
auto-action:
enabled: true
action: "BAN" # "BAN" — permanent ban | "KICK" — kick only
threshold: 3 # Number of warnings before auto-action fires
# Kick the player with a "final warning" message at a lower threshold
kick-on-warn:
enabled: true
threshold: 2 # Kick at this warning count (before the ban threshold)
# Warnings older than this are not counted toward thresholds
expiry:
duration: "0" # "0" = warnings never expire
# Examples: "7d", "30d", "90d"
# Escalation tiers — overrides auto-action when enabled
# Each tier fires when warning count reaches `count`
escalation:
enabled: false
tiers:
- count: 1
action: "WARN"
- count: 2
action: "TEMPMUTE"
duration: "1h"
- count: 3
action: "TEMPBAN"
duration: "1d"
- count: 4
action: "TEMPBAN"
duration: "7d"
- count: 5
action: "BAN"
# Available actions: WARN, KICK, MUTE, TEMPMUTE, TEMPBAN, BAN
# Duration format: 30s, 10m, 1h, 7d, 30d
automod:
enabled: false # Master switch — must be true for any rules to run
# Blocked actions apply to the message that triggered the rule.
# Available actions for all rules: BLOCK, WARN, KICK, MUTE, TEMPMUTE
# TEMPMUTE duration is set by tempmute-duration below.
tempmute-duration: "10m"
# Block links in chat
anti-link:
enabled: true
action: "BLOCK"
whitelisted-domains: # These domains are allowed through
- "yourdomain.com"
- "discord.gg/yourserver"
# Block spam (too many messages too fast, or too many duplicates)
anti-spam:
enabled: true
action: "BLOCK"
max-messages: 5 # Max messages allowed within the time window
time-window-seconds: 10 # Rolling window size in seconds
max-duplicates: 3 # Max identical messages allowed in the window
# Block server IPs and Discord invite links
anti-advertising:
enabled: true
action: "BLOCK"
block-server-ips: true # Blocks patterns like "play.someserver.net"
block-discord-invites: true # Blocks discord.gg/... links
whitelisted-domains:
- "yourdomain.com"
- "discord.gg/yourserver"
# Block profanity and custom banned words
anti-swear:
enabled: false
action: "BLOCK"
use-regex: false # Set true to treat blocked-words entries as regex patterns
blocked-words:
- "badword1"
- "badword2"
whitelisted-words: # These words are never blocked even if they match a pattern
- "scrapbook"
# Block excessive CAPS LOCK
anti-caps:
enabled: false
action: "BLOCK"
min-message-length: 5 # Ignore short messages (e.g. "OK", "YES")
threshold-percent: 70.0 # Block if more than this % of letters are uppercase
# Block character flooding (aaaaaaaaaa, !!!!!!!!!)
anti-flood:
enabled: false
action: "BLOCK"
max-repeated-chars: 5 # Consecutive identical characters before blocking
min-message-length: 3 # Ignore very short messages
# Block Unicode abuse and Zalgo text
anti-unicode:
enabled: false
action: "BLOCK"
block-zalgo: true # Block combining diacritical mark stacking (z͎̤̙̘̭͇͠a̵͔͓l̡͔͍̦͚͙g̢͕̲͔͔͕ö̥́)
max-unicode-percent: 50.0 # Block if more than this % of chars are non-ASCII
reports:
enabled: true
cooldown-seconds: 60 # How long a player must wait between reports
# Post reports to a Discord channel
discord-webhook:
enabled: false
url: ""
mention-role-id: "" # Optional — ping a role when a report comes in (e.g. "123456789")
notify-staff: true # Broadcast reports to online staff with protectcord.alerts
predefined-reasons: [] # Optional list of reasons shown in tab-complete
# Example: ["Hacking", "Spam", "Harassment", "Inappropriate name"]
database:
type: "YAML" # "YAML" — flatfile storage (default, no setup needed)
# "MYSQL" — MySQL/MariaDB (required for multi-server sync)
mysql:
host: "localhost"
port: 3306
database: "protectcord" # Database name (must exist before starting)
username: "root"
password: ""
table-prefix: "pc_" # All tables prefixed with this (e.g. pc_warnings, pc_bans)
# HikariCP connection pool settings
pool:
max-pool-size: 10 # Maximum simultaneous database connections
min-idle: 2 # Minimum idle connections kept open
connection-timeout: 30000 # Max wait for a connection from the pool (ms)
idle-timeout: 600000 # Close idle connections after this long (ms)
max-lifetime: 1800000 # Recycle connections after this long (ms)
# Control how IP addresses appear to staff in command output
# Staff with the protectcord.ip.full permission always see the full IP
ip-masking:
enabled: false
mask-format: "last-octet"
# "last-octet" → 192.168.1.* (hides last segment)
# "last-two-octets" → 192.168.*.* (hides last two segments)
# "full-mask" → *.*.*.* (hides everything)
# All messages support & colour codes. Placeholders listed per message.
messages:
# Shown to players blocked by IP check — {reason}, {risk}
connection-denied: |
&c&lConnection Denied
&7Your connection has been blocked by ProtectCord.
&7Reason: &c{reason}
&7Risk Level: &c{risk}
&7If you believe this is an error, please contact server staff.
# Shown when the API is unreachable during a check
api-error: |
&c&lTemporary Connection Issue
&7We're unable to verify your connection at the moment.
&7Please try again later.
# Shown to a player blocked by the accounts-per-IP limit — {max}, {current}
account-limit-reached: |
&c&lConnection Limit Reached
&7Maximum accounts per IP: &c{max}
&7Current connections from your IP: &c{current}
&7Please disconnect another account before connecting.
# Shown to the oldest session kicked by KICK_OLDEST enforcement — {max}
account-limit-kicked: |
&c&lYou have been disconnected
&7A new account connected from your IP address.
&7Maximum accounts per IP: &c{max}
# Shown when player-tracking blocks a flagged player — {flags}
player-flagged: |
&c&lConnection Denied
&7Your account has been flagged.
&7Flags: &c{flags}
&7If you believe this is an error, please contact server staff.
# Shown when player-tracking blocks an inactive player
player-inactive: |
&c&lConnection Denied
&7Your account has been deactivated.
&7Please contact server staff.
# Shown in chat to whitelisted players who bypass the IP check
whitelist-bypass: "&aYou have bypassed IP verification."
Aliases: /pc, /protect
| Command | Description |
|---|---|
/pc reload | Reload config, whitelist, and storage |
/pc stats | View API usage and rate limits |
/pc check <player|ip> | On-demand IP threat analysis |
/pc version | Plugin version and platform info |
/pc health | API connectivity health check |
/pc alerts | Toggle in-game staff alerts on/off |
| Command | Description |
|---|---|
/pc whitelist add player <name> | Whitelist a player by name |
/pc whitelist add uuid <uuid> | Whitelist by UUID |
/pc whitelist add ip <address> | Whitelist an IP address |
/pc whitelist remove <type> <value> | Remove whitelist entry |
/pc list | List all whitelisted entries |
| Command | Description |
|---|---|
/pc kick <player> [reason] | Kick an online player with IP info |
/pc warn <player> <reason> | Issue a warning (auto-escalates) |
/pc warnings <player> | View full warning history |
/pc clear warning <player> | Clear all warnings |
/pc clear ban <player> | Clear a ban record |
/pc remove warning <player> [#] | Remove a specific warning by index |
/pc ban <player> <reason> | Permanently ban a player |
/pc tempban <player> <duration> <reason> | Temp-ban (1h, 7d, 30d) |
/pc unban <player> | Unban a player |
/pc mute <player> <reason> | Permanently mute a player |
/pc tempmute <player> <duration> <reason> | Temp-mute |
/pc unmute <player> | Unmute a player |
/pc alts <player> | Find alt accounts by shared IP |
| Command | Description |
|---|---|
/pc migrate <yaml|mysql> | Migrate all data between storage backends |
/pc purge <type> <days> | Delete data older than X days |
Purge types: warnings, bans, mutes, iplogs, auditlog, inactive, all
| Command | Description |
|---|---|
/report [player] <reason> | Report a player (or submit an anonymous report) |
| Permission | Description | Default |
|---|---|---|
protectcord.admin | All /pc commands | OP |
protectcord.bypass | Bypass IP checks on join | false |
protectcord.alerts | Receive in-game staff alerts | OP |
protectcord.ip.full | See unmasked IPs in command output | OP |
protectcord.automod.bypass.* | Bypass all AutoMod checks | false |
Automatically escalate discipline based on warning count. Two modes available:
| Warning | Action |
|---|---|
| 1st | In-game warning message |
| 2nd | Kicked with "final warning" message |
| 3rd | Permanent ban |
Fully custom escalation — any combination of WARN → TEMPMUTE → TEMPBAN → BAN:
1 warning → Warning message
2 warnings → Temp mute (1 hour)
3 warnings → Temp ban (1 day)
4 warnings → Temp ban (7 days)
5 warnings → Permanent ban
Warnings can optionally expire after a configured duration (7d, 30d, etc.) so past behavior doesn't follow players forever.
Protect your chat without lifting a finger. Each AutoMod rule runs independently and can be configured to BLOCK, WARN, KICK, MUTE, or TEMPMUTE the offending player.
| Rule | What It Catches |
|---|---|
| Anti-Link | URLs, with per-domain whitelist |
| Anti-Advertising | Other server IPs, Discord invites |
| Anti-Spam | Message rate and duplicate flooding |
| Anti-Swear | Custom word list, with regex and exceptions |
| Anti-Caps | Excessive uppercase by percentage |
| Anti-Flood | Repeated character abuse |
| Anti-Unicode | Zalgo text and invisible character abuse |
Find players evading bans or using multiple accounts with a single command:
/pc alts Notch
→ [ProtectCord] Alt accounts for Notch:
- Notch2 (shared IPs: 2)
- AltAccount99 (shared IPs: 1)
IPs are never displayed in alt output — staff see player names only, protecting privacy while identifying evaders.
Store all data (warnings, bans, mutes, IP history, audit logs) in MySQL instead of local YAML files.
/pc migrate mysql/pc migrate mysql
→ Migrated 47 players, 12 IP bans, 203 audit entries.
→ Update database.type in config.yml and run /pc reload.
Keep your database clean with fine-grained purge commands:
/pc purge warnings 90 — remove warnings older than 90 days
/pc purge bans 30 — remove expired bans older than 30 days
/pc purge mutes 30 — remove expired mutes older than 30 days
/pc purge iplogs 365 — remove IP history older than 1 year
/pc purge auditlog 90 — trim the audit log
/pc purge inactive 180 — remove player records unseen for 6 months
/pc purge all 90 — run all of the above
Get a rich Discord embed every time a player is blocked, accepted, or whitelisted:
Separate webhook for moderation events: bans, unbans, warns, kicks, mutes, AutoMod actions — so your mod team always knows what's happening.
config.yml:discord-webhook:
enabled: true
url: "https://discord.com/api/webhooks/YOUR_WEBHOOK"
/pc reloadEvery connecting player's IP is sent to the ProtectCord API for evaluation:
| Check | What It Detects |
|---|---|
| VPN | Virtual private networks used to hide location |
| Proxy | HTTP/SOCKS proxies and anonymizers |
| Tor | Tor exit nodes |
| Datacenter | Hosting providers (common bot source) |
| Bogon | Invalid or reserved IP ranges |
| Risk Score | AI-powered score from UNKNOWN to CRITICAL |
| Geo | Country of origin (for geo-blocking) |
No API call is made for:
127.0.0.1, ::1)192.168.x.x, 10.x.x.x, 172.16–31.x.x)Is this free? Yes. The free API key includes 32 requests per minute, enough for most servers.
Will it lag my server? No. All IP checks are fully asynchronous and never block the main thread.
Can legitimate players get blocked?
Rarely. Use /pc check <player> to see why, then /pc whitelist add player <name>. You can also raise blocked-risk-level to CRITICAL for less aggressive blocking.
Does it work with offline mode? Yes. The plugin functions in both online and offline mode.
What about proxy networks? Install only on the proxy (BungeeCord or Velocity). All backend servers are automatically protected with one plugin and one API key.
What if the API is down? Players are allowed to connect by default during API outages. This prevents lockouts and can be changed in config.
Do you store player data? Only IP addresses are sent to the ProtectCord API. No usernames or UUIDs are transmitted externally. See our privacy policy.
Can I sync bans across servers? Yes — enable MySQL storage and point all servers at the same database. Bans and mutes are enforced network-wide automatically.
"API KEY NOT CONFIGURED!"
Get your key at protectcord.com/dashboard, add it to config.yml, run /pc reload.
Player blocked incorrectly
Run /pc check <player> to see the reason. Whitelist with /pc whitelist add player <name> or lower blocked-risk-level.
Rate limit hit Free tier: 32 req/min (~1 player every 2 seconds). Solutions: whitelist regulars to skip API calls, or install only on your proxy instead of all backends.
Discord webhook silent
Verify URL is correct, enabled: true, events are enabled, and check console for errors.
MySQL connection failed
Check host/port/credentials in config. Ensure the MySQL user has CREATE TABLE privileges. Check console for the HikariCP error message.
Made with ❤️ for the Minecraft community — ProtectCord, because prevention is better than moderation.

Protectcord is an anti VPN/Proxy plugin it uses an advanced API to check if an IPv4/IPv6 is a VPN or Proxy!