# mcstatus: querying Minecraft servers from Python

> mcstatus is a Python library and command line tool for reading publicly available status data from Minecraft servers. It implements the Server List Ping and Query protocols, and exposes one class per edition: JavaServer, LegacyServer and BedrockServer, each with a lookup helper.

**py-mine/mcstatus** — A Python library for checking the status of Minecraft servers

- Repository: https://github.com/py-mine/mcstatus
- Website: https://mcstatus.readthedocs.io
- Stars: 609 · Forks: 40
- Language: Python
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/py-mine-mcstatus

## Two protocols, one library

mcstatus provides an API and a command line script to fetch publicly available data from Minecraft servers, and it does this by implementing two protocols: Server List Ping and Query. The pitch in the documentation is precise about what that saves you. Because of mcstatus, you do not need to fully understand those protocols and can instead skip straight to retrieving Minecraft server data quickly in your own programs. The word publicly is doing real work in that sentence, since both protocols are the client-facing ones, the same ones a player uses to get the server list and the MOTD when they connect. The library is Apache-2.0 licensed, the primary language is Python, and the project publishes on PyPI with documentation hosted at mcstatus.readthedocs.io, alongside a Discord badge and a CI badge for the main workflow.

## Java edition, and the difference between status and ping

The Java edition class is `JavaServer`, and the first thing to know is that it can be constructed with a known host and port or resolved with `lookup`, which takes the same address you would type into the Minecraft address field:

```python
from mcstatus import JavaServer

# You can pass the same address you'd enter into the address field in minecraft into the 'lookup' function
# If you know the host and port, you may skip this and use JavaServer("example.org", 1234)
server = JavaServer.lookup("example.org:1234")

# 'status' is supported by all Minecraft servers that are version 1.7 or higher.
# Don't expect the player list to always be complete, because many servers run
# plugins that hide this information or limit the number of players returned or even
# alter this list to contain fake players for purposes of having a custom message here.
status = server.status()
print(f"The server has {status.players.online} player(s) online and replied in {status.latency} ms")
```

The status call is what gives you the player count and the latency, and the comment about the player list is the most useful warning in the whole example. Many servers run plugins that hide the information, limit the number of players returned, or even alter the list to contain fake players so they can show a custom message. Separately there is `ping`, which is also supported by every server at version 1.7 or higher, is included in a status call, and is exposed on its own if you do not need the additional information.

## Query gives more, and needs a server setting

The third operation on a Java server is `query`, and it carries a warning that is easy to miss: it has to be enabled in the server's server.properties file. When it is available it may give more information than a ping, such as a full player list or mod information, and the example joins the player names from the result:

```python
query = server.query()
print(f"The server has the following players online: {', '.join(query.players.names)}")
```

So the practical shape of the API is three calls with three different requirements. `ping` is always available on a modern server and gives you the round trip time. `status` is also always available and adds the player count, the MOTD and the version. `query` is the richest and the least reliable, because it is off by default on the server side. If you are building a status page, `status` is the one to use, and `query` is worth attempting only if you know the server has it turned on.

## Legacy Java and Bedrock need different classes

Two edition-specific classes handle the rest. `LegacyServer` covers Java edition from Beta 1.8 to 1.6, servers that predate the modern status protocol, and the documentation is clear that its `status` call is supported by all Minecraft servers in that range, unlike the modern class which requires version 1.7 or higher:

```python
from mcstatus import LegacyServer

# You can pass the same address you'd enter into the address field in minecraft into the 'lookup' function
# If you know the host and port, you may skip this and use LegacyServer("example.org", 1234)
server = LegacyServer.lookup("example.org:1234")

# 'status' is supported by all Minecraft servers.
status = server.status()
print(f"The server has {status.players.online} player(s) online and replied in {status.latency} ms")
```

`BedrockServer` handles Bedrock edition, and it has a narrower surface than either Java class. The documentation states that status is the only feature supported by Bedrock at this time, and that in this case the status includes players.online, latency, motd, map, gamemode and players.max, with gamemode given as the example of a field:

```python
from mcstatus import BedrockServer

# You can pass the same address you'd enter into the address field in minecraft into the 'lookup' function
# If you know the host and port, you may skip this and use BedrockServer("example.org", 19132)
server = BedrockServer.lookup("example.org:19132")

# 'status' is the only feature that is supported by Bedrock at this time.
# In this case status includes players.online, latency, motd, map, gamemode, and players.max. (ex: status.gamemode)
status = server.status()
print(f"The server has {status.players.online} players online and replied in {status.latency} ms")
```

Note the default port in that example, 19132 rather than 25565, which is the giveaway that Bedrock is a different protocol stack and not a variant of the Java one.

## The command line interface

The library includes a simple CLI, and the documentation gives one command for it:

```bash
python3 -m mcstatus --help
```

The description is deliberately modest, a simple CLI, and that is worth taking at face value. This is a library first, with a command line entry point so you can check a server from a shell script or a cron job without writing Python. The `python3 -m` form also means there is no separate console script to install and no path configuration to fight, which is the right default for a tool whose main use is as a dependency. The `mcstatus` package directory sits at the top level of the repository alongside `docs/`, `tests/`, a `pyproject.toml`, a `uv.lock`, a `.readthedocs.yaml` and a `.pre-commit-config.yaml`, so the packaging, the docs and the tests all live in one place.

## The dependency set, and what it implies

The project metadata is short and modern, and the two runtime dependencies tell you how the library works. The dependencies are `asyncio-dgram` at 2.1.2 or newer and `dnspython` at 2.4.2 or newer. The first is a UDP library for asyncio, which is how the Query protocol is spoken, since Query is UDP based while Server List Ping moved to TCP. The second is a DNS resolver, and its presence is the reason `lookup` can take a hostname at all, so the library resolves the name itself rather than requiring an address. Everything else is development tooling, with pytest and pytest-asyncio and pytest-cov for the tests, ruff for linting, basedpyright for type checking, and pre-commit to tie them together. The project requires Python 3.11 or newer and the classifiers list 3.11 through 3.15, and the package is marked as typed, with the `Typing :: Typed` classifier and a dedicated type checking tool in the lint group. The development status is Production/Stable and the topic classifiers place it under games and entertainment, Python modules and system monitoring.

## Where this is the wrong choice

The limits follow from the design. First, the library only sees what a client can already see, so the accuracy of anything you build on it is the server's to decide, and the player list is the clearest case, since plugins commonly hide it, cap it, or fill it with placeholder names. Any dashboard built on mcstatus inherits that uncertainty, and the fix is in the server configuration, not in your code. Second, there is no server administration here. If you want to list players, whitelist, send commands or change server settings, you need the server-side protocol and a server-side library, and this one is explicitly about status and capabilities. Third, the protocol surface is small. The documentation lists three operations on the Java class, one on the legacy class and one on the Bedrock class, and the details for each are in the Read the Docs site rather than in the repository, so a serious integration means reading the docs as well as the code. Fourth, the version line moves fast. The releases are v14.2.0 from 2026-09-02, v14.1.0 from 2026-08-16 and v14.0.0 from 2026-06-26, three minor versions in a quarter, and the majors are frequent enough that you should read the changelog before upgrading. Fifth, the legacy class exists for servers that almost nobody runs any more, so if your use case is old servers, good, and if not, the modern class and the Bedrock class are the two that matter.

## Conclusion

mcstatus fits a developer building a server list, a status page or a Discord bot, because it removes the need to understand either protocol and gives one API across the Java, legacy and Bedrock editions. It is the wrong tool if you need anything beyond what the server publicly reports, since the library only reads what a client can already see, and the player list in particular is often incomplete. It is also the wrong choice if you want to run server administration, which is a different protocol entirely. Before you rely on the numbers, read the note about the player list not always being complete, because servers commonly hide or limit it, and check the Python requirement, which is 3.11 or newer. The last push was on 2026-10-19, the newest release is v14.2.0 from 2026-09-02, and the licence is Apache-2.0.

## FAQ

### How do I install mcstatus and check a Minecraft server?

Install it with `python3 -m pip install mcstatus`, then use the class for your edition, for example `JavaServer.lookup("example.org:1234")` and call `status()` for the player count and latency. The command line interface is available with `python3 -m mcstatus --help`.

### What is the difference between status, ping and query in mcstatus?

Ping and status are supported by all Minecraft servers at version 1.7 or higher, and ping is included in a status call but exposed separately if you do not need the extra information. Query may give more, such as a full player list or mod information, but it has to be enabled in the server's server.properties file first.

### Does mcstatus support Bedrock servers?

Yes, through the BedrockServer class, whose lookup uses port 19132. Status is the only feature supported by Bedrock at this time, and it includes players.online, latency, motd, map, gamemode and players.max.

## Sources

- [License: Apache-2.0](https://github.com/py-mine/mcstatus/blob/main/LICENSE)
- [Project website](https://mcstatus.readthedocs.io)
- [py-mine/mcstatus on GitHub](https://github.com/py-mine/mcstatus)
- [README](https://github.com/py-mine/mcstatus/blob/main/README.md)
- [Releases](https://github.com/py-mine/mcstatus/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/py-mine-mcstatus
