A Node library and CLI to check whether a Minecraft server is online and get live player counts, MOTD, version, latency and favicon, on both Java and Bedrock Edition. It speaks the raw protocols directly over TCP and UDP, resolves _minecraft._tcp SRV records the way the vanilla client does, and has zero runtime dependencies.
npx mc-status play.talonmc.netonline play.talonmc.net:25565 (java)
players 1613 / 5000
version Velocity 1.7.2-1.21.10 (protocol 773)
latency 195ms
motd TalonMC | COBBLEMON NOW RELEASED!
motd Join Now | discord.gg/talonserver
srv java.talonmc.net:25565
- Java Edition ping over the 1.7+ Server List Ping protocol (handshake, status, ping/pong latency)
- Bedrock Edition ping over RakNet
UNCONNECTED_PING, including gamemode and server GUID - SRV resolution for
_minecraft._tcp.<host>, sorted by priority then weight, exactly like the client - MOTD handling for both legacy
§strings and modern JSON chat components, with a plain-text version ready to print - Favicon returned as the server's original
data:image/png;base64URI - Timeouts and
AbortSignalon every call, so a dead host can never hang your process - Zero dependencies, ESM, first-class TypeScript types
- Works on Node 18 and newer
npm install mc-statusOr run the CLI without installing anything:
npx mc-status play.hypixel.netimport { status } from "mc-status";
const server = await status("play.hypixel.net");
console.log(server.players.online); // 31930
console.log(server.players.max); // 200000
console.log(server.version.name); // "Requires MC 1.8 / 1.21"
console.log(server.latency); // 209
console.log(server.motd.clean); // "Hypixel Network [1.8/26.2]\n SB 0.27 TORRHUS & SAFARI | SUMMER EVENT"Bedrock uses UDP on port 19132 by default and does not use SRV records.
import { statusBedrock } from "mc-status";
const server = await statusBedrock("play.talonmc.net");
console.log(server.edition); // "bedrock"
console.log(server.version.name); // "26.45"
console.log(server.gamemode); // "Survival"
console.log(server.players.online); // 1613statusAuto pings Java and Bedrock at the same time and resolves with whichever answers first.
import { statusAuto } from "mc-status";
const server = await statusAuto("play.hypixel.net");
console.log(`${server.edition} server with ${server.players.online} players`);A port in the address string wins over SRV. You can also pass it explicitly.
import { status, statusBedrock } from "mc-status";
await status("play.example.com:25566");
await status("play.example.com", { port: 25566 });
await status("203.0.113.10", { port: 25565, resolveSrv: false });
await statusBedrock("203.0.113.10", { port: 19133 });import { status, McStatusError } from "mc-status";
const controller = new AbortController();
setTimeout(() => controller.abort(), 3000);
try {
const server = await status("play.example.com", {
timeout: 2500,
signal: controller.signal,
});
console.log("up", server.players.online);
} catch (error) {
if (error instanceof McStatusError) {
console.log("down", error.code); // TIMEOUT, CONNECTION_FAILED, MALFORMED, ...
}
}import { writeFile } from "node:fs/promises";
import { status } from "mc-status";
const server = await status("play.hypixel.net");
if (server.favicon) {
const base64 = server.favicon.replace(/^data:image\/png;base64,/, "");
await writeFile("favicon.png", Buffer.from(base64, "base64"));
}import { statusAuto } from "mc-status";
const addresses = ["play.hypixel.net", "play.talonmc.net", "play.example.com"];
const results = await Promise.all(
addresses.map(async (address) => {
try {
const server = await statusAuto(address, { timeout: 3000 });
return { address, online: true, players: server.players.online };
} catch {
return { address, online: false, players: 0 };
}
}),
);
console.table(results);mc-status <address> [options]
Options:
--bedrock Ping as Bedrock Edition (UDP RakNet, default port 19132)
--auto Try Java and Bedrock, report whichever answers first
--json Print the full result as JSON
--quiet Print nothing, exit 0 if online and 1 if offline
--port <number> Override the port (disables SRV lookup for Java)
--timeout <ms> Milliseconds before giving up (default 5000)
--protocol <number> Handshake protocol version (default -1)
--no-srv Skip the _minecraft._tcp SRV lookup
-h, --help Show this help
The CLI exits 0 when the server answered and 1 when it did not, so it drops straight into a health check:
mc-status play.example.com --quiet || echo "server is down"Pipe the JSON into jq for scripting:
npx mc-status play.hypixel.net --json | jq '.players.online'Pings a Java Edition server. address may include a port (host:port). Rejects with McStatusError if the server does not answer.
Pings a Bedrock Edition server over UDP. Defaults to port 19132. Never performs an SRV lookup.
Races a Java and a Bedrock ping, resolving with the first success. Rejects with code UNREACHABLE only if both fail. Accepts javaPort and bedrockPort in addition to the normal options.
Convenience wrapper around statusAuto that never throws.
Lower-level entry points that take a bare hostname rather than an host:port string.
Splits host, host:port, [ipv6]:port and scheme-prefixed strings. port is undefined when the address did not carry one.
Looks up _minecraft._tcp.<host> and returns the highest-priority record, or null if there is none. Returns null immediately for literal IP addresses.
Removes legacy § colour and style codes, including BungeeCord §x§r§r§g§g§b§b hex sequences.
Flattens a modern JSON chat component (with extra, color, bold, and friends) into a legacy §-coded string.
parseAdvertisement(string), buildUnconnectedPing(timestamp, guid) and readUnconnectedPong(buffer) are exported so you can build your own RakNet tooling or unit test against captured packets.
| Option | Type | Default | Applies to | Description |
|---|---|---|---|---|
port |
number |
25565 Java, 19132 Bedrock |
both | Explicit port. Setting it disables the SRV lookup. |
timeout |
number |
5000 |
both | Milliseconds before the ping is abandoned. |
protocolVersion |
number |
-1 |
Java | Handshake protocol version. -1 means "undefined", which every modern server accepts. |
resolveSrv |
boolean |
true |
Java | Set to false to skip the SRV lookup. |
signal |
AbortSignal |
- | both | Aborts the ping early. |
javaPort |
number |
- | statusAuto |
Port used for the Java attempt only. |
bedrockPort |
number |
- | statusAuto |
Port used for the Bedrock attempt only. |
| Field | Type | Description |
|---|---|---|
edition |
"java" | "bedrock" |
Which protocol produced this result. |
host |
string |
The hostname you asked for, before SRV resolution. |
port |
number |
The port actually connected to. |
srvRecord |
{ host, port } | null |
The SRV record that was followed, if any. |
version.name |
string |
Version string as the server reports it. Often a brand name, not a number. |
version.protocol |
number | null |
Numeric protocol version. |
players.online |
number |
Players currently online. |
players.max |
number |
Slot limit as advertised. |
players.sample |
{ name, id }[] |
Sample player list. Java only, and frequently empty or spoofed. |
motd.raw |
string |
MOTD with § codes intact. |
motd.clean |
string |
MOTD with all formatting stripped. |
motd.json |
unknown | null |
The original chat component, when the server sent one. |
favicon |
string | null |
data:image/png;base64,... URI. Java only. |
latency |
number |
Round-trip milliseconds. |
gamemode |
string | null |
Bedrock only. |
serverGuid |
string | null |
Bedrock only. |
raw |
unknown |
The untouched payload, for fields this library does not model. |
Thrown for every failure. Carries code, host and port.
| Code | Meaning |
|---|---|
TIMEOUT |
No reply within timeout milliseconds. |
CONNECTION_FAILED |
DNS, refused connection or socket error. |
CONNECTION_CLOSED |
Server hung up before sending a status. |
MALFORMED |
Reply was not valid protocol or valid JSON. |
ABORTED |
The supplied AbortSignal fired. |
UNREACHABLE |
statusAuto only, both editions failed. |
Java Edition uses the Server List Ping flow introduced in 1.7. The client sends a handshake packet with next-state 1, then an empty status request. The server replies with a JSON document describing itself. A ping packet carrying a timestamp is then exchanged to measure latency. Packets are length-prefixed with VarInts, so this library buffers until a complete frame has arrived rather than assuming one packet per TCP read.
Bedrock Edition uses RakNet's offline UNCONNECTED_PING packet: a 33-byte UDP datagram containing a timestamp, the 16-byte RakNet magic, and a client GUID. The server answers with UNCONNECTED_PONG carrying a semicolon-separated advertisement string:
MCPE;<motd line 1>;<protocol>;<version>;<online>;<max>;<server guid>;<motd line 2>;<gamemode>;<gamemode id>;<port v4>;<port v6>
SRV records let a server advertise play.example.com while running on a different host and port. Java clients look up _minecraft._tcp.play.example.com before connecting, and so does this library. Bedrock clients do not, so statusBedrock skips it.
- Servers below 1.7 use the older legacy ping and are not supported.
players.sampleis under the server's control. Many networks spoof it or leave it empty, so do not treat it as a real player list.players.onlinereflects whatever the server chooses to advertise. Proxies commonly report a whole network's count on every backend.- Query protocol (GameSpy, port 25565 UDP) is not implemented. Server List Ping covers what most tools need.
Built and maintained by Best Minecraft Server Lists. Every ranking below is ordered on player counts taken from a direct server ping, never on numbers a server reports about itself.
- Best Cobblemon servers - The Best Cobblemon Servers, Top 10, Rated fairly
- Best Minecraft Prison servers - The Best Prison Servers, Top 10, Rated fairly
- Best Minecraft Skyblock servers - The Best Skyblock Servers, Top 10, Rated fairly
- Best Minecraft SMP servers - The Best SMP Servers, Top 10, Rated fairly
- Best Minecraft Survival servers - The Best Survival Servers, Top 10, Rated fairly
- Free rankings JSON API - Every ranking above as JSON, CC BY 4.0, no key and no sign-up
Sister libraries:
- mc-motd - render a MOTD to ANSI, HTML or plain text
- mc-votifier - send and receive Votifier votes
- mc-rankings-client - typed client for the rankings feeds above
Issues and pull requests are welcome. Run the test suite with:
npm install
npm testMIT