ChatKeeper is a lightweight Paper plugin for cleaner Minecraft chat. Built for servers that want chat quality controls with automatic capitalization, excessive-caps cleanup, warnings, an in-game admin GUI, and runtime reloads without restarting the server.
- Automatic first-letter and sentence-start capitalization for player chat messages.
- Repeated-character flood cleanup for messages like
hellooooooo. - Message cooldown control for configurable message bursts.
- Anti-repeat spam blocking for consecutive similar messages like
Hello,Hello,Hello. - Anti-advertisement blocking for URLs, domains, Discord invites, IP addresses, blocked domains, and domain whitelist mode.
- Light anti-evasion for links such as
discord dot gg/code,discord[.]gg/code,example . com, and configured shorteners likebit ly/code. - URL/domain/IP/invite preservation when capitalization or flood cleanup transforms otherwise valid chat text.
- Excessive-caps normalization for messages that cross configurable thresholds.
- Permission-based bypass for excessive-caps correction, cooldown checks, anti-repeat blocking, and anti-advertisement checks.
- Case-insensitive ignore list for server-specific words like usernames, VIP, STAFF, GG, AFK, LOL, or XD.
- Optional player warnings when flood or excessive caps are corrected.
- Chat and action bar warning delivery toggles.
- Configurable staff and console notifications when players are warned.
- In-game admin GUI for player admins through
/chatkeeper gui. - Hot reloads for configuration, language files, modules, command aliases, and online player state.
- Runtime status output for module rules, moderation actions, anti-repeat thresholds, anti-advertisement lists, world filters, warnings, and alias conflicts.
- Paper servers 26.1.2 or newer.
- Java 25.
- Download the plugin jar.
- Place the jar in your server's
pluginsfolder. - Start or restart the server.
- Edit
plugins/ChatKeeper/config.ymlif needed. - Run
/chatkeeper reloadafter configuration changes, or use the reload item in/chatkeeper gui.
| Command | Permission | Description |
|---|---|---|
/chatkeeper help |
chatkeeper.command.help |
Shows the commands available to the sender. |
/chatkeeper reload |
chatkeeper.command.reload |
Hot-reloads configuration, language files, modules, command aliases, and online player state. |
/chatkeeper lang <language> |
chatkeeper.command.lang |
Changes the plugin language and hot-reloads ChatKeeper. |
/chatkeeper status |
chatkeeper.command.status |
Shows modules, rules, actions, anti-repeat thresholds, anti-advertisement lists, world filters, warning status, and alias conflicts. |
/chatkeeper gui |
chatkeeper.gui.view |
Opens the player-only admin GUI. |
/chatkeeper menu, /chatkeeper admin, /chatkeeper panel |
chatkeeper.gui.view |
Aliases for /chatkeeper gui. |
/ck, /chk, /ckp, /chatk, /keepc |
chatkeeper.command |
Configurable aliases for /chatkeeper. |
| Permission | Default | Description |
|---|---|---|
chatkeeper.command |
op |
Allows access to the main ChatKeeper command. |
chatkeeper.command.reload |
op |
Allows hot-reloading ChatKeeper. |
chatkeeper.command.lang |
op |
Allows changing the plugin language. |
chatkeeper.command.status |
op |
Allows viewing module status, rule status, actions, thresholds, world filters, warnings, and alias conflicts. |
chatkeeper.command.gui |
op |
Legacy full-access GUI permission that grants chatkeeper.gui.view, chatkeeper.gui.toggle, and chatkeeper.gui.reload. |
chatkeeper.command.help |
op |
Allows viewing ChatKeeper command help. |
chatkeeper.gui.view |
op |
Allows opening the admin GUI in view mode. |
chatkeeper.gui.toggle |
op |
Allows toggling modules and features from the admin GUI. |
chatkeeper.gui.reload |
op |
Allows hot-reloading ChatKeeper from the admin GUI. |
chatkeeper.notify |
op |
Receives warning notifications for staff. |
chatkeeper.bypass.excessive-caps |
false |
Bypasses excessive-caps correction and warnings. |
chatkeeper.bypass.cooldown |
false |
Bypasses message cooldown checks and warnings. |
chatkeeper.bypass.anti-repeat |
false |
Bypasses anti-repeat spam blocking and warnings. |
chatkeeper.bypass.anti-advertisement |
false |
Bypasses link, Discord invite, IP, and domain blocking. |
chatkeeper.links.allow.urls |
false |
Allows URLs, domains, shorteners, blocked domains, and whitelist-restricted domains. |
chatkeeper.links.allow.discord |
false |
Allows Discord invites without bypassing URL or IP checks. |
chatkeeper.links.allow.ips |
false |
Allows IP addresses without bypassing URL or Discord invite checks. |
/chatkeeper gui opens a player-only inventory menu for admins with chatkeeper.gui.view. The same GUI is available through /chatkeeper menu, /chatkeeper admin, and /chatkeeper panel.
The main view toggles the capitalization, flood, cooldown, anti-repeat, and anti-advertisement modules for players with chatkeeper.gui.toggle, opens a feature controls view, reloads ChatKeeper for players with chatkeeper.gui.reload, or closes the menu. The feature view can toggle first-letter capitalization, excessive-caps normalization, capitalization prefix ignores, anti-repeat prefix ignores, and anti-advertisement URL, domain, Discord invite, IP address, domain whitelist, and prefix-ignore controls when their parent modules are enabled. It also shows status-only entries for repeated-character flood cleanup, message cooldown, consecutive repeat spam, anti-advertisement shortener/whitelist/anti-evasion metadata, warnings, and the world filter.
Module and feature changes made from the GUI are saved to config.yml, immediately refresh the active chat modules without re-registering command aliases, play a short confirmation sound, refresh the changed items in-place, use a short click cooldown to prevent accidental double toggles, and write one audit line to the console with the player name and old/new state.
/chatkeeper reload, /chatkeeper lang <language>, and the GUI reload item all use the same hot reload path. ChatKeeper reloads config.yml, reloads the selected language file, refreshes tracked online player state, reloads enabled modules and their listeners, re-registers /chatkeeper aliases from command.aliases, and updates command suggestions for online players.
# Language file used from the lang folder without the .yml extension.
language: english
# Controls whether chat modules skip messages whose first visible character is a configured prefix.
ignore-prefixed-messages:
enabled: true
prefixes:
- "/"
- "!"
- "#"
- "@"
modules:
capitalization: true
flood: false
cooldown: false
anti-repeat: true
anti-advertisement: true
# Controls correction warnings for all chat modules.
warnings:
# Sends a warning to the player when their message is corrected.
enabled: true
# Sends the warning as a normal chat message.
chat: true
# Sends the warning above the hotbar.
actionbar: true
# Notifies staff and/or console when a player is warned.
notify:
# Sends the warning reason to online staff with this permission.
staff: true
staff-permission: chatkeeper.notify
# Sends the warning reason to the server console.
console: true
# Controls in which worlds all chat modules can run.
worlds:
# Enables or disables global world filtering.
enabled: true
# whitelist applies modules only in these worlds.
# blacklist applies modules everywhere except these worlds.
mode: whitelist # whitelist, blacklist
# Use ALL to target every world at once.
# In whitelist mode, ALL allows modules in every world.
# In blacklist mode, ALL disables modules in every world.
worlds:
- ALL
# - spawn
# - lobby
# - survival
# - world
# Controls repeated character flood cleanup in chat messages.
flood:
# Enables or disables repeated character correction.
enabled: true
# Action used when repeated character flood is detected.
# warn-only corrects and warns. block cancels the message and warns.
action: warn-only # block, warn-only
# Amount of consecutive equal letters, numbers, or symbols required before correction.
minimum-repetitions: 6
# Amount of repeated characters left after correction.
# Example: "helloooooooo" becomes "hello" with the default value.
replacement-repetitions: 1
# Controls how many chat messages a player can send in a short time.
cooldown:
# Enables or disables message cooldown checks.
enabled: true
# Action used when the message limit is exceeded.
# block cancels the message and warns. warn-only only warns.
action: block # block, warn-only
# Players with this permission skip cooldown checks and warnings.
bypass-permission: chatkeeper.bypass.cooldown
# Maximum amount of messages allowed inside the time window.
# With the default value, the sixth message in 5 seconds is blocked.
max-messages: 5
# Time window, in seconds, used to count messages.
time-window-seconds: 5
# Controls consecutive repeated-message spam.
anti-repeat:
# Enables or disables repeated-message blocking.
enabled: true
# Action used when repeated-message spam is detected.
# block cancels the message and warns. warn-only only warns.
action: block # block, warn-only
# Players with this permission skip anti-repeat blocking and warnings.
bypass-permission: chatkeeper.bypass.anti-repeat
# Maximum amount of consecutive similar messages allowed inside the time window.
# With the default value, the fifth similar message is blocked.
max-repeated-messages: 4
# Time window, in seconds, used to count consecutive similar messages.
time-window-seconds: 15
# Minimum similarity percentage required to consider two messages repeated.
# Example: 85 means messages must be at least 85% similar.
minimum-similarity-percentage: 85
# Minimum normalized message length required before anti-repeat is checked.
minimum-message-length: 8
# Controls links, Discord invites, IP addresses, and domain advertising.
anti-advertisement:
# Enables or disables link/domain/IP blocking.
enabled: true
# Action used when advertising is detected.
# block cancels the message and warns. warn-only only warns.
action: block # block, warn-only
# Players with this permission skip anti-advertisement checks and warnings.
bypass-permission: chatkeeper.bypass.anti-advertisement
detect:
urls: true
domains: true
discord-invites: true
ip-addresses: true
# Domains that are always blocked. Subdomains are included automatically.
blocked-domains: []
# Known shortener domains blocked by default. Admins can edit this list.
shorteners:
domains:
- bit.ly
- tinyurl.com
- t.co
- is.gd
- goo.gl
- ow.ly
# When enabled, every detected domain must be listed here to be allowed.
whitelist:
enabled: false
domains:
- yourserver.com
# Full Discord invite URLs listed here are treated as concrete invite whitelist entries.
# - discord.gg/your-server
# Allows only these concrete Discord invite codes while keeping other Discord invites blocked.
# Each entry can be a bare invite code, discord.gg/code, or discord.com/invite/code.
discord-invites:
- your-server
# Fine-grained allow permissions. The bypass-permission above still skips the entire module.
allow-permissions:
urls: chatkeeper.links.allow.urls
discord: chatkeeper.links.allow.discord
ips: chatkeeper.links.allow.ips
# Controls automatic chat capitalization corrections.
capitalization:
# Enables or disables every capitalization feature below.
enabled: true
# Words ignored by first-letter and excessive-caps corrections.
# Matching is case-insensitive. Online player usernames are ignored automatically.
ignored-words:
- VIP
- STAFF
- ADMIN
- MOD
- HELPER
- GG
- AFK
- LOL
- XD
# Capitalizes the first visible letter of each message and after ., ?, or !.
first-letter:
enabled: true
# Normalizes messages that contain too many uppercase letters.
excessive-caps:
enabled: true
# Action used when excessive caps are detected.
# warn-only corrects and warns. block cancels the message and warns.
action: warn-only # block, warn-only
# Players with this permission skip excessive-caps correction and warnings.
bypass-permission: chatkeeper.bypass.excessive-caps
# Minimum amount of letters required before checking for excessive caps.
minimum-letters: 12
# Percentage of uppercase letters required to trigger the correction.
uppercase-percentage: 70
# Controls command aliases for /chatkeeper.
command:
# Short command names registered by ChatKeeper.
# If another plugin already uses one of these aliases, ChatKeeper will keep
# working through /chatkeeper and will warn about the conflicting alias.
aliases:
- ck
- chk
- ckp
- chatk
- keepcShort aliases are shared by every plugin on the server. If another plugin already owns /ck, ChatKeeper will warn at startup, show the conflict in /chatkeeper status, and /chatkeeper will remain available.
Admins who want to force /ck to ChatKeeper can add this to the server's commands.yml:
aliases:
ck:
- 'chatkeeper:chatkeeper $1-'Open an issue on GitHub with:
- Your server software and version.
- Your Java version.
- The ChatKeeper version.
- Relevant console logs or configuration snippets.
ChatKeeper is licensed under the MIT License. Commercial use, modification, distribution, and private use are allowed under the license terms. See LICENSE for details.