Groups

Define what runs in your network: server software, Minecraft version, memory and how many servers start automatically.

A group is a file under groups/. It describes what should run, not what is running right now. MuteCloud reconciles the target state with reality every two seconds and never rewrites the file, which allows it to be kept under version control.

groups/lobby.toml
name = "Lobby"
memory = 1024
layers = ["global", "lobby"]
fallback = true

[software]
kind = "paper"
version = "26.2"

[scale]
min = 2
max = 6
keep_free = 1
full_at = 0.8

[restart]
at = ["04:00"]

[[plugins]]
modrinth = "luckperms"

Fields

FieldMeaning
namename of the group, servers become Lobby-1, Lobby-2, ...
kindserver or proxy
memoryRAM per server in MB
layerswhich templates get copied in, in this order
persistentkeep the world, the directory stays under static/
fallbackwhere players land on join and when a server fails
maintenancegroup in maintenance, nobody gets in
enabledfalse starts nothing new, running servers stay
port_rangerange ports are taken from
jvm_flagsextra JVM switches
envenvironment variables for the server process
requiresgroups that must be ready first
drain_secshow long a draining server waits for its players
nodeswhich nodes may run this group, empty means all; at runtime groups <name> set nodes +node-2, see Adding a node
rolloutauto or freigabe, see below

[software]

version is the Minecraft version; without one MuteCloud takes the newest stable one. build pins a build where the source has builds, default is latest.

kindWhere it comes from
paper, foliaPaperMC
purpurPurpurMC
leafLeafMC, a performance fork of Paper
pufferfishPufferfish CI, also a performance fork
pandaspigothpfxd, PvP fork of 1.8.8, runs on Java 21
vanillaMojang
fabricFabricMC, loader and installer are resolved for the version
velocityPaperMC, the proxy to use today
bungeecordmd-5 CI, the older proxy, still everywhere
waterfallPaperMC, discontinued upstream, use velocity
urlthe address in url, any server jar
customthe file in jar, brought by a layer

Pufferfish builds one job per minor line, so version = "1.21.4" picks the 1.21 job and you get the newest patch it has built. MuteCloud reads the real version out of the file it downloaded and uses that, for the Java runtime as well. BungeeCord has no Minecraft version at all; leave version out.

PandaSpigot exists only for 1.8.8. Unlike a regular 1.8 server it gets Java 21 by default, so current plugins such as ViaVersion or LuckPerms load. The bridge follows the Minecraft version, so the server still gets the legacy bridge despite Java 21.

Anything not in the list is one line away as long as it is a jar that starts with java -jar:

groups/bedwars.toml
[software]
kind = "url"
version = "1.8.8"
url = "https://example.com/downloads/server-1.8.8.jar"

The file is fetched once and cached under cache/, keyed by address and version, so a changed address means a fresh download and an unchanged one costs nothing.

What this does not cover yet is software that needs an installer run before the first start, such as Forge and NeoForge, and anything that is not started with java -jar, such as the Bedrock server or a proxy shipped as a native binary.

Servers without a Bukkit or Velocity plugin, so vanilla, fabric and most things behind url, run perfectly well but stay unbridged: MuteCloud starts, watches and restarts them and sees their port, while player counts, ranks and punishments come from the bridge and therefore stay empty.

[java]

major forces a Java version. Without it MuteCloud derives it from the Minecraft version: 1.8.8 gets Java 8, 26.2 gets Java 25. The runtime is downloaded on demand and lives under runtimes/.

[scale]

FieldMeaning
minthis many always run
maxnever more than this
keep_freethis many should sit empty and ready
full_atone more starts at this load, 0.8 is eighty percent
cooldown_secsquiet time between two starts

[restart]

[restart]
at = ["04:00"]
every_hours = 0
warn_seconds = [600, 300, 60, 10]
message = "&7This server restarts in &f{time}&7."

at restarts at fixed times, every_hours in fixed intervals, counted from the moment a server accepts players. If both are set, every_hours wins. warn_seconds defines how many seconds beforehand the players on that server are warned; {time} becomes "10 seconds" or "5 minutes". The servers of a group take their turn half a minute apart, so Lobby-2 thirty seconds after Lobby-1, and each one is drained instead of stopped. Nobody gets dropped.

[backup]

For persistent servers only. at = ["03:00"] saves at those times, keep says how many archives stay. Manual runs: groups <name> backup.

[[plugins]]

[[plugins]]
modrinth = "viaversion"

[[plugins]]
url = "https://example.com/Custom.jar"
sha256 = "..."

Plugins are placed in the last template of the group. groups <name> plugins update downloads them again.

Rolling out template changes

When a template changes, running servers are outdated. For game servers, MuteCloud starts the replacement alongside the existing server and drains the old one only once the new one accepts players, so the change remains invisible to players.

A proxy has no stand-in; replacing it disconnects every player. Proxy groups therefore wait for explicit approval:

groups Proxy rollout

While something is pending, the group list shows "Freigabe nötig" and a message goes to the webhook. Change it per group with groups <name> set rollout auto or freigabe, standard returns to the default.

Persistent and ephemeral

Without persistent, every server receives a fresh working directory under run/ that is removed when the server stops. This is the usual case for lobbies and match servers.

With persistent = true the directory resides under static/ and is kept. On start only the template files are refreshed while the world remains untouched. This applies to build servers and any installation whose state grows over time.

On this page