Skip to content

Repository files navigation

Minecraft Server — a Minecraft server in the Omarchy bar

Players online, tick health and world state in the Omarchy 4 (Quattro) bar, with broadcast messages and a restart countdown.

The panel, open

Which servers work

Any Minecraft server that speaks RCON. Everything the widget reads comes from ordinary console commands, so vanilla, Spigot, Paper, Purpur, Folia, Fabric and Forge servers are all supported — nothing has to be installed on the server beyond enabling RCON.

Some rows depend on commands only certain server software provides. Rows the server does not answer are left out rather than rendered empty, so a vanilla server simply shows a shorter panel than a Paper one:

Row Command Available on
Online / offline, MOTD, version, latency Server List Ping every server, no RCON needed
Players online + names list every server
World day and clock time query every server
TPS tps Paper, Spigot, Purpur and forks
MSPT (tick times) mspt Paper and forks

The Server List Ping row is the reason an unreachable server is reported in well under a second: it runs first, on the game port, and RCON is skipped entirely when it fails.

What it can do

  • Broadcast any message to every player, from a text field or one of the presets.
  • Restart countdown — broadcasts a warning at each configured mark (15, 10, 5, 3, 1 minutes by default) and can end by stopping the server.
  • Save world — announces, then runs save-all.
  • Kick a player from the player list, behind a confirmation.

Install

omarchy plugin add https://github.com/webmatze/omarchy-minecraft-server-status.git --enable

The command clones the repo into ~/.config/omarchy/plugins/, validates the manifest and asks where in the bar you want it. Plugins land disabled by default so you can read the code first; --enable turns it on in the same step, or do it separately:

omarchy plugin enable io.github.webmatze.omarchy-minecraft-server-status

Then configure the server connection — see Setup. Until you do, the widget shows a crossed-out block and the panel says why.

Update and removal

omarchy plugin update io.github.webmatze.omarchy-minecraft-server-status
omarchy plugin remove io.github.webmatze.omarchy-minecraft-server-status

Removal takes the plugin out of shell.json and deletes its folder. Your credentials live outside the plugin at ~/.config/omarchy/omarchy-minecraft-server-status/config.json and are deliberately left alone — delete that file yourself if you want it gone.

Setup

1. Enable RCON on the server

In server.properties:

enable-rcon=true
rcon.port=25575
rcon.password=<a long random password>
broadcast-rcon-to-ops=false

Restart the server — RCON is only initialised at startup.

RCON is unencrypted and sends the password in clear text. Only expose the port on a network you trust. Never forward it to the internet; use a VPN or an SSH tunnel if you need it from outside.

2. Credentials on this machine

mkdir -p ~/.config/omarchy/omarchy-minecraft-server-status
cp ~/.config/omarchy/plugins/io.github.webmatze.omarchy-minecraft-server-status/config.example.json \
   ~/.config/omarchy/omarchy-minecraft-server-status/config.json
chmod 600 ~/.config/omarchy/omarchy-minecraft-server-status/config.json
$EDITOR ~/.config/omarchy/omarchy-minecraft-server-status/config.json
{
  "host": "192.168.1.50",
  "rconPort": 25575,
  "gamePort": 25565,
  "password": "your-rcon-password"
}

The password lives here rather than in shell.json because shell.json is a file people paste into issues and copy between machines. The helper reads the file itself, so the password is never passed as a command-line argument and never appears in the process list. The panel warns if the file is readable by anyone but you.

3. Check the helper before trusting the bar

cd ~/.config/omarchy/plugins/io.github.webmatze.omarchy-minecraft-server-status
bin/mc-status status | jq
bin/mc-status status --raw | jq .raw     # every raw RCON reply, verbatim
bin/mc-status say "hello from the bar"

--raw shows exactly what your server answered to each command, which is the quickest way to see why a row is missing on your server software.

Settings

Set inline on the shell.json bar entry, or with omarchy bar set:

omarchy bar set io.github.webmatze.omarchy-minecraft-server-status refreshIntervalSec 30
omarchy bar set io.github.webmatze.omarchy-minecraft-server-status stopAfterCountdown On
Key Default Meaning
credentialsPath "" Override the credentials file. Empty means ~/.config/omarchy/omarchy-minecraft-server-status/config.json.
refreshIntervalSec 15 Poll interval, clamped to at least 5.
restartWarnings "15,10,5,3,1" Minutes before the restart at which a warning is broadcast.
stopAfterCountdown "Off" When On, the countdown may end with /stop — always behind a confirmation.
showPlayerCount true Show the player count next to the bar icon.
lowTpsThreshold 18 Bar icon turns urgent below this TPS. Ignored on servers with no TPS command.

Using it

  • Left click opens the panel, middle click refreshes immediately.
  • In the panel: r refreshes, b jumps to the broadcast field, Escape closes (once to leave the text field, again to close the panel), Tab switches to the neighbouring bar panel.
  • The bar icon turns urgent when the server is down, RCON is refusing, or TPS has fallen below lowTpsThreshold. A crossed-out block means no credentials.
  • Restart countdown: with stopAfterCountdown set to On the countdown ends by running /stop, which is why it asks for confirmation before starting rather than at the end — by then nobody may be at the keyboard.
  • The countdown lives in the shell process. omarchy restart shell, a logout or a shell crash ends it, and the panel says so while one is running.

Not included: RAM, CPU and uptime

These are deliberately absent. The obvious source would be the spark profiler, but spark renders /spark health and /spark tps asynchronously: over RCON the reply is empty except for the occasional lucky call, which would make those rows flicker in and out between polls. A row that is sometimes there is worse than no row.

Host metrics need a host-level source — SSH into the machine, or a hypervisor API — which is outside what this plugin does today. Issues and pull requests welcome.

Troubleshooting

omarchy-shell io.github.webmatze.omarchy-minecraft-server-status diagnose | jq
omarchy-shell io.github.webmatze.omarchy-minecraft-server-status refresh
omarchy-shell io.github.webmatze.omarchy-minecraft-server-status say "test"
quickshell list --all && quickshell log -i <instance> -t 100

diagnose returns the full parsed server state plus the resolved helper and credentials paths — start there when a row is missing or the widget looks stuck.

A QML load failure is silent on screen: the widget simply does not appear. The quickshell log is the place to look.

For contributors: editing a .qml file reloads it automatically, but .js files do not hot-reload — run omarchy restart shell after changing Model.js. The Canvas in MinecraftIcon.qml also keeps its last painted frame across a hot reload, so a shell restart is the only way to see an edited icon.

Dependencies and privileges

Runs entirely as your user and never asks for elevation.

  • On this machine: Python 3 standard library only. No AUR package, no pip install, no mcrcon. The RCON and Server List Ping clients are implemented in bin/mc-status.
  • On the server: RCON enabled. Nothing else — no plugin, no mod.
  • Network: outbound TCP to the configured host on the RCON and game ports. Nothing else is contacted; there is no telemetry and no third-party API.
  • Files: reads ~/.config/omarchy/omarchy-minecraft-server-status/config.json (or credentialsPath). Writes nothing outside its own plugin folder.

Anything the plugin can do to your server, it does through RCON commands you could type into the console yourself: list, tps, mspt, time query, say, save-all, kick, and — only when you switch it on and confirm — stop.

Treating the server as untrusted

The server on the other end declares its own frame sizes and decides how many packets to send, so the helper bounds all of it rather than believing any of it. Every limit is far above what a healthy server produces:

Bound Limit
Server List Ping payload 256 KB, rejected before anything is allocated
RCON packet 8 KB (the protocol caps the payload at 4096)
RCON fragments per command 256
RCON reply, accumulated 256 KB
Whole handshake / command / ping 12 s monotonic deadline, re-checked per read
A whole status poll 20 s, one budget shared by the connect and every command
Text each parser scans 256 B for counts, 1 KB for tps/mspt, 32 KB for names
Numbers derived from server text must be finite, or the row is left out
Player names kept from list 500, each capped at 32 characters
MOTD tree depth 16, 512 characters
JSON printed to the shell 512 KB, re-checked by the QML side

Server-authored strings — player names, MOTD, version — never reach a Text that could interpret them. Our own Text elements set textFormat: Text.PlainText, but tooltips and confirmation dialogs are kit components whose Text we do not own, and Qt's default AutoText promotes anything markup-shaped to rich text — enough for a player named <img src=…> to make the shell fetch a remote URL. Angle brackets and control characters are therefore stripped before a string leaves the helper, and again in Model.plainText() before it enters any component the plugin does not configure. Player names additionally go through an allowlist of the characters a Minecraft name can actually contain.

The parsers only ever scan a window large enough for a real reply, because a reply of pure digits makes the count and triple regexes backtrack quadratically — and that work happens after the socket read, where no deadline covers it. Numbers are rejected unless math.isfinite, so a server cannot turn a row into Infinity and make the printed document stop being JSON. Whatever still goes wrong is caught and reported as {"error": ...}: the helper's contract with the panel is always JSON on stdout and always exit 0, so a traceback would leave the widget with nothing to parse and no reason why.

The restart countdown counts down tick by tick rather than measuring against a wall-clock end time, and clamps any single tick to five seconds. Suspending the laptop or an NTP step would otherwise fire every warning at once and run /stop minutes before it was announced.

The credentials file is opened once with O_NOFOLLOW and O_NONBLOCK and validated on that same descriptor with fstat — regular file, owned by you, not group- or world-writable, within 64 KB — before a byte is read. A symlink, a FIFO or a file owned by someone else is refused with an explanatory message; merely being group-readable is a warning shown in the panel.

License

MIT — see LICENSE.

About

Minecraft server status in the Omarchy bar: players, TPS, world state and RCON broadcasts. Works with any RCON-capable server.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages