A Rust library and command-line tool for querying the status of Minecraft servers, supporting both Java Edition (PC) and Bedrock / Pocket Edition (PE).
- Java Edition: the TCP-based Server List Ping (SLP) protocol, default port
25565. - Bedrock Edition: the UDP-based RakNet Unconnected Ping protocol, default port
19132.
mcget is both a dependable async Rust library (using a reqwest-style Client + RequestBuilder design) and a curl-like command-line tool that lets players check server status in one line.
cargo install mcgetOr build from source:
git clone https://github.com/EaseCation/mcget
cd mcget
cargo build --release
# binary at target/release/mcget# Auto-detect edition (try Java first, then Bedrock on failure)
mcget mc.hypixel.net
mcget play.easecation.net
# Force an edition
mcget -j mc.hypixel.net # Java Edition
mcget -b play.easecation.net # Bedrock Edition
# Measure and show latency (Java does an extra ping/pong round trip)
mcget -t mc.hypixel.net
# JSON output (for jq pipelines)
mcget --json mc.hypixel.net | jq '.players.online'
# Multiple targets
mcget mc.hypixel.net play.cubecraft.net play.easecation.net
# Timeout control (seconds)
mcget --max-time 5 mc.hypixel.net
# Full help
mcget --helpHuman-readable (default):
--- mc.hypixel.net (Java) ---
Version: Requires MC 1.8 / 1.21 (protocol 47)
Players: 31496/200000
MOTD: §aHypixel Network [1.8/26.1]
Favicon: provided (15738 chars)
Latency: 198.5ms
JSON (--json):
{
"edition": "Java",
"host": "mc.hypixel.net",
"version": { "name": "Requires MC 1.8 / 1.21", "protocol": 47 },
"players": { "max": 200000, "online": 31496 }
}mcget uses a reqwest-style Client + RequestBuilder design; fully async, built on tokio.
The library has no built-in timeout -- callers compose one with tokio::time::timeout.
use mcget::java;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Option 1: convenience free function (one-shot query).
let status = java::ping(("mc.hypixel.net", 25565)).await?;
println!("{} online {}/{}", status.version.name, status.players.online, status.players.max);
// Option 2: Client + RequestBuilder (reusable, configurable, latency measurement).
let client = java::Client::new();
let (status, latency) = client
.ping(("mc.hypixel.net", 25565))?
.with_latency()
.send()
.await?;
println!("latency: {:?}", latency);
Ok(())
}use mcget::bedrock;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = bedrock::Client::new();
let resp = client.ping(("play.nethergames.org", 19132))?.send().await?;
println!("{} online {}/{}", resp.version_name, resp.player_count, resp.max_players);
Ok(())
}use std::time::Duration;
use mcget::java::Client;
use mcget::PingError;
# async fn run() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let status = tokio::time::timeout(
Duration::from_secs(5),
client.ping(("mc.hypixel.net", 25565))?.send(),
).await
.map_err(|_| PingError::Protocol("timed out".into()))??;
# Ok(())
# }cargo run --example ping_java
cargo run --example ping_bedrockThe library uses a reqwest-style three-layer structure:
| Layer | Java | Bedrock | Description |
|---|---|---|---|
Client |
java::Client |
bedrock::Client |
Reusable client, created with new() |
RequestBuilder |
java::RequestBuilder / LatencyRequestBuilder |
bedrock::RequestBuilder |
Chain config, send() issues the request |
| Convenience fn | ping_java(addr) |
ping_bedrock(addr) |
One-shot query |
Address arguments accept HostAddr (e.g. a "host:port" string, a ("host", port) tuple, or a SocketAddr).
When a string carries no port the edition-specific default is filled in (25565 for Java, 19132 for Bedrock); IPv6 bracket form is supported.
- reqwest style:
Client(reusable, zero-cost clone) ->RequestBuilder(chain config) ->send()(future). HostAddrgeneric:Client::ping<A: HostAddr>(addr: A). DNS resolution happens synchronously at theping()call (on failurePingError::Iois returned).- No built-in timeout: the library does not manage timeouts; callers compose one with
tokio::time::timeout. - Single error type: all errors are unified as
PingError(Io/Json/Protocol), derived viathiserror.
Each packet is prefixed with a VarInt length; the handshake protocol version is -1 (any). Flow: Handshake(0x00) -> Status Request(0x00) -> Status Response(JSON) -> optional Ping/Pong for latency.
description supports both a plain string and the {"text": ..., "extra": [...]} object form.
Fixed magic 00 ff ff 00 fe fe fe fe fd fd fd fd 12 34 56 78. The server_id_string is semicolon-separated with the official standard field order:
edition;motd1;protocolVersion;versionName;playerCount;maxPlayers;
serverUniqueId;motd2;gamemode;gamemodeNumeric;portIpv4;portIpv6
cargo testMIT or Apache-2.0, at your option.