NOT AN OFFICIAL PAPER PROJECT. PaperProxy is not affiliated with or endorsed by PaperMC. It is an independent fork of Velocity.
PaperProxy is a Minecraft proxy that runs Velocity plugins and BungeeCord/Waterfall plugins side by side on one proxy, and fixes the things that annoy server owners about Velocity and Waterfall today.
Will my plugins work? Check them with the PaperProxy Plugin Checker (runs in your browser, nothing is uploaded). Which plugins were tested, and how thoroughly, is listed under Tested Plugins.
Status: first release. Everything below is implemented and tested on a test network, also with real clients. It is not yet proven on large production networks, so please report anything that breaks.
Today a network has to pick one proxy and live with its gaps. Velocity is fast and secure, but it cannot run the large library of BungeeCord plugins. Waterfall runs them, but it is end of life and gets no more updates. Many networks keep an old proxy alive only for one or two plugins they cannot replace.
PaperProxy removes that choice. It is Velocity, with a BungeeCord layer on top, so you keep Velocity's speed and security and still use the plugins you already have.
- Keep your plugins. Velocity and BungeeCord plugins in the same
plugins/folder, no second proxy, no rewrite. - Move without risk. Drop the jar in, keep your
velocity.toml. Going back to Velocity is the same step in reverse. - Secure forwarding for every backend. Modern forwarding where possible, and PaperGuard (signed, replay-proof) for old servers that only speak BungeeCord forwarding, set per server.
- Less restarting. Reload, load and unload plugins at runtime, change messages and MOTDs
with
/pp reload. - Things you would otherwise install plugins for: maintenance mode, health checks, ping
cache,
/alert,/find, ViaVersion install and per-server version rules. - Small and safe updates. A 2 MB jar that checks every library it downloads, update notices, and an optional auto-updater that only installs signed releases.
- Check first. The Plugin Checker tells you before you switch which of your plugins will work.
Drop BungeeCord plugins into plugins/ next to your Velocity plugins. They run on the original
BungeeCord API, implemented on top of Velocity:
-
Plugins load through BungeeCord's own plugin manager (dependencies,
libraries, lifecycle) -
Players, servers, commands with tab completion, permissions (LuckPerms works), titles, action bars, tab list header, cookies, server links, scheduler, YAML/JSON config
-
Login, ping, connect, kick, chat, command, plugin message and settings events, including async intents
-
getServers().put(...)registers servers like on BungeeCord -
The layer runs in its own class loader and only starts when a BungeeCord plugin is present; Velocity plugins never see BungeeCord classes
-
unsafe().sendPacketworks: scoreboards, teams, tab list entries and boss bars sent by scoreboard and tab plugins are encoded for the player's version (up to 1.21.7, the newest version the BungeeCord protocol classes know)
Not supported: plugins that hook into the Netty pipeline or read packets, reading the backend
scoreboard through getScoreboard(), and dialogs. Such calls log a clear message.
Each backend can use its own forwarding mode in paperproxy.toml:
[forwarding.servers]
lobby = "modern"
old-pvp = "paperguard"PaperGuard is signed, replay-proof forwarding for servers that cannot use modern forwarding. Every login is signed with HMAC-SHA256 over all player data, the target server name, a timestamp and a one-time nonce, using a key derived per server. The backend plugin PaperGuard (Paper 1.12.2+, Folia) verifies it and rejects everyone when it is not configured (fail closed). Replayed, expired, modified or foreign logins are rejected; this is covered by attack tests and shared test vectors. PaperGuard has its own repository with the protocol spec, so other proxies can support it too. It was called PaperProxy-Bridge before.
Setup: set the server to paperguard, run paperproxy paperguard key <server> in the proxy
console, put server name and key into plugins/PaperGuard/config.yml on the backend and
set settings.bungeecord: true in its spigot.yml.
- messages.yml: every proxy message editable, MiniMessage and
&codes,{placeholders}, optional per-client-language files; new keys are merged in after updates, your texts and own sections are kept - motd.yml: rotating or random MOTDs, hover lines, text instead of the player count
- Plugin reload/load/unload for Velocity and BungeeCord plugins, with confirmation, block list and leak detection
- Watchdog that names plugins blocking events
- ViaVersion:
paperproxy via install|updatefrom Modrinth, allowed client versions per server, warning when Via runs on proxy and backend - Server groups:
lobby = ["lobby-1", "lobby-2"]sends players to the emptiest member and skips full or offline ones - Queues: full or offline servers get a queue with position in the action bar and priority permissions; players moved away by a server restart are sent back once it is online again
/hub(and/lobby) for a server or group of your choice- Bot protection: new players must ping the server list before they join (during attacks or always), connection floods switch on attack mode in which only known players can join; optional limit of accounts per IP and blocked name patterns
- Network sync over Redis for several proxies: network wide player count,
/findand/alertacross proxies, no double logins,/pp network - Prometheus metrics at
/metrics(players, servers, queues, logins, connect times, kicks, client versions, memory), off by default, with a ready Grafana dashboard - Restart without kicks:
shutdown.transfer-tohands players to another proxy (1.20.5+) - Update folder: put new jars into
plugins/update, they replace the old version (same file name or same plugin id) on the next start - Hidden commands: keep commands like
/serveror/pluginsout of tab completion - Query passthrough: server queries show the map, version and plugins of a backend
- Limbo: when a server restarts or crashes and no other server can take its players, they stay connected and are sent back as soon as it is online again, no plugin or extra server
- Parties:
/partyand/pc, members follow their leader from server to server - Bans, mutes and kicks for the whole network (opt-in), shared across proxies
- Planned restarts with countdown, titles and transfer to another proxy
- Discord webhook for servers going down, bot attacks, maintenance, updates, bans
/sendfor groups and servers:/send all lobby,/send server game-1 lobby- Health checks: offline servers are skipped and refused with a message, staff is notified
- Maintenance for the whole network or single servers, with whitelist
- Ping cache against server list floods
/alert,/find,/ip- Update notifications from GitHub releases and an optional, signature-verified auto-updater (off by default)
- API for plugins (MIT licensed):
PaperProxy.get()
| Command | Permission |
|---|---|
/paperproxy (/pp) |
everyone, unless paperproxy.command.info is denied |
/pp reload |
paperproxy.command.reload |
/pp servers |
paperproxy.command.servers |
/pp maintenance [on|off] [server] |
paperproxy.command.maintenance |
/pp plugin list|reload|unload|load |
paperproxy.command.plugin |
/pp via install|update |
paperproxy.command.via |
/pp update |
paperproxy.update |
pp paperguard key|rotate |
console only |
/pp network |
paperproxy.command.servers |
/alert, /find, /ip |
paperproxy.command.alert, .find, .ip |
/hub, /lobby |
everyone (when hub-command.target is set) |
/queue, /queue leave |
everyone |
/party, /pc |
everyone |
/ban, /unban, /banlist, /mute, /unmute, /kick |
paperproxy.command.ban, .mute, .kick (only with punish.enabled) |
/paperproxy restart <seconds> [reason], restart cancel |
paperproxy.command.restart |
Other permissions: paperproxy.maintenance.bypass, paperproxy.notify.health,
paperproxy.update (update notice on join), paperproxy.queue.bypass (join full servers),
paperproxy.queue.priority.<0-100>, paperproxy.antibot.bypass (accounts per IP limit),
paperproxy.tabcomplete.bypass (sees hidden commands), paperproxy.punish.exempt,
paperproxy.notify.antibot.
The API is the normal Velocity API plus the PaperProxy extras, MIT licensed. Plugins that use it need Java 25 like current Velocity.
Gradle (Kotlin DSL):
repositories {
mavenCentral()
maven("https://repo.papermc.io/repository/maven-public/") // Velocity's Brigadier
maven("https://codeberg.org/api/packages/LucasTHCR/maven")
}
dependencies {
compileOnly("net.paperstream:paperproxy-api:1.2.3-RELEASE")
annotationProcessor("net.paperstream:paperproxy-api:1.2.3-RELEASE")
}Maven:
<repositories>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>paperproxy</id>
<url>https://codeberg.org/api/packages/LucasTHCR/maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>net.paperstream</groupId>
<artifactId>paperproxy-api</artifactId>
<version>1.2.3-RELEASE</version>
<scope>provided</scope>
</dependency>
</dependencies>To support plain Velocity as well, only touch the PaperProxy classes when they exist:
boolean paperProxy;
try {
Class.forName("net.paperstream.paperproxy.api.PaperProxy");
paperProxy = true;
} catch (ClassNotFoundException e) {
paperProxy = false;
}PaperProxy pp = PaperProxy.get();
pp.getClientVersion(player); // "1.21.4"
pp.getMessage("myplugin.welcome", "player", name);
pp.isOnline("survival");
pp.async(() -> database.save(player));
// Parties
PartyManager parties = pp.getParties();
Party party = parties.create(leader);
parties.addMember(party, player);
parties.getParty(player).ifPresent(p -> p.sendMessage(text));Events: BackendHealthChangeEvent, ClientVersionDeniedEvent, PluginRuntimeChangeEvent,
PartyJoinEvent, PartyLeaveEvent (with the reason) and PartyFollowEvent, which can be
cancelled to keep a member on their server, for example during a minigame round.
Everything else is the normal Velocity API.
Requires Java 25 (same as current Velocity).
./gradlew build- Proxy:
proxy/build/libs/paperproxy-<version>.jar(about 2 MB). On first start it downloads its libraries intolibraries/and checks every file against its SHA-256. - Offline variant with everything inside:
proxy/build/libs/paperproxy-<version>-full.jar - Backend plugin: see PaperGuard
Import pterodactyl/egg-paperproxy.json in your panel
(Admin, Nests, Import Egg). It installs the latest release (or a chosen tag), checks the
SHA-512 checksum and can use the offline -full jar.
PaperProxy reports anonymous usage statistics to
bStats.
They can be disabled in plugins/bStats/config.txt.
Questions and feedback: Discord
Mirror: Codeberg
PaperProxy is based on Velocity by the Velocity contributors and PaperMC. "Paper" and "Velocity" are names of PaperMC projects; PaperProxy is not one of them. The BungeeCord compatibility layer uses the BungeeCord API by md_5 (BSD license).
PaperProxy is licensed under the GNU General Public License v3.0, like Velocity.
The API (api/) is MIT licensed.
