Skip to main content

minecraft-protocolo-py

A multi-version Minecraft Java Edition client/server protocol library for Python, built on top of two existing pieces instead of reinventing them:

  • protolib — the generic binary protocol engine (reads/writes packets from JSON/YAML schema definitions, in the node-protodef / minecraft-data format).
  • minecraft-data — the actual per-version packet definitions (protocol.json), the same dataset used by node-minecraft-protocol.

minecraft_protocolo is the missing glue layer: pick a Minecraft version, get a working Client or Server that speaks that version's wire protocol — handshake, login, compression, keep-alive, and error handling included.

protolib  (generic protocol engine)
    │
minecraft-data  (per-version protocol.json definitions)
    │
minecraft_protocolo  (this library: Client / Server / version resolver)
    │
your own app  (game logic only)

Install

pip install protolib
pip install minecraft-protocolo-py

protolib is a separate, real dependency — it is never vendored or copied into this package.

Supported versions

Any Minecraft Java Edition version between 1.7 and 1.16.5 that ships with the bundled minecraft-data snapshot (35 versions in total). Well-known build aliases that people actually type — 1.8.9, 1.7.10 — resolve automatically to the entry minecraft-data tracks internally (1.8, 1.7), since the network protocol never changed between those builds.

from minecraft_protocolo import VersionResolver

resolver = VersionResolver()
resolver.list_versions()              # ['1.7', '1.8', ..., '1.16.5']
resolver.protocol_version_number("1.8.9")   # 47

Quick start — client

from minecraft_protocolo import Client

client = Client(host="localhost", port=25565, username="Xd", version="1.8.9")

@client.on("connect")
def on_connect():
    print("connected!")

@client.on("packet")
def on_packet(name, params):
    if name == "chat":
        print("chat:", params["message"])

client.on("error", lambda e: print("error:", e))
client.on("kicked", lambda reason: print("kicked:", reason))

client.connect()  # blocks; pass background=True to run in a thread

Keep-alive is handled automatically (the client answers the server's keep_alive packets on its own — no need to do it in your handler). Compression is detected and applied automatically as soon as the server sends set_compression during login.

Quick start — server

from minecraft_protocolo import Server

server = Server(host="0.0.0.0", port=25565, version="1.8.9",
                 motd="my server", max_players=20)

@server.on("login")
def on_login(conn):
    print(conn.username, "joined —", conn.uuid)

@server.on("packet")
def on_packet(conn, name, params):
    if name == "chat":
        print(conn.username, ":", params["message"])

server.on("error", lambda e, conn=None: print("error:", e))

server.listen()  # blocks

The server answers server-list pings (MOTD, player count, protocol version) and sends its own periodic keep_alive, kicking players who stop responding — same defaults as node-minecraft-protocol (keepAlive=True, 4s ping interval, 10s kick timeout).

online_mode=True (real Mojang/MSA authentication + encryption) is not implemented yet; the server explicitly refuses that config instead of pretending to support it.

Examples

examples/client.py and examples/server.py are runnable, tested reference implementations built on the library — game logic only, none of the networking (that's all handled by Client/Server):

# a chat bot that responds to !hello and !ping
python examples/client.py <host> <port> <username> [version]

# a genuinely playable flat-world server: real client can log in,
# walk around, and use chat commands (!ping, !online, !spawn,
# !creative, !survival)
python examples/server.py --port 25565 --version 1.8.9 --motd "my server"

These are meant as a starting point to copy from, not a CLI you're expected to use as-is — real projects put their own game logic on top of Client/Server directly.

Error handling

Deserialization failures are wrapped to match the format used by node-minecraft-protocol (PartialReadError), so anyone familiar with that library will recognize the shape immediately:

PartialReadError: Deserialization error for play.toClient : Read error : buffer exhausted at offset=5: needed 1 bytes, 0 remaining

Client/Server never raise these directly into your code — they're emitted through the error event, same as Node's EventEmitter convention (an unhandled 'error' event still gets printed to stderr instead of silently disappearing).

Discovering the packet API

The API is the protocol.json for whatever version you loaded — not a fixed list this README could show (74 packets just for play.toClient in 1.8, times 35 bundled versions). Field names are also case-sensitive and don't always match what the wiki or another bot would lead you to expect (gameMode not gamemode, flyingSpeed not flySpeed). Two ways to find the real name for the version you're using:

# From a live connection (Client or Server's ClientConnection) --
# always exact for whatever version was actually negotiated:
print(client.list_packet_names())          # every valid play.toServer packet name
print(conn.list_packet_names("play", "toClient"))  # play.toClient for a server connection

# Or straight from the bundled data, no connection needed (strip the
# "packet_" prefix and the internal "packet" dispatcher entry itself):
import json
with open("minecraft_protocolo/data/pc/1.8/protocol.json") as f:
    proto = json.load(f)
names = [k[len("packet_"):] for k in proto["play"]["toClient"]["types"] if k.startswith("packet_")]
print(names)

Sending a name that doesn't exist raises UnknownPacketError instead of a confusing low-level error, and lists the valid names for that state. A wrong or missing field inside otherwise-correct params raises SerializationError with a hint pointing at protocol.json.

What's implemented

  • Handshake, login (offline-mode), status/server-list ping
  • zlib packet compression, detected and applied automatically
  • Automatic keep-alive, both directions, with timeout/kick handling
  • Multi-version support in a single Server (version=None) — resolves each connecting client's version from its handshake protocolVersion
  • node-minecraft-protocol-style error formatting

What's not implemented yet

  • online_mode=True (Mojang/MSA auth + AES encryption) — this one is a library limitation, Server/Client don't support it yet.
  • Bedrock Edition (only Java/"pc" protocols are wired up) — also a library limitation.

None of the above is the library's job, and intentionally so — world state, chunks, entity spawning, and physics are game logic, which lives in your own code on top of Client/Server, not in minecraft_protocolo itself. examples/server.py shows a working approach (flat world, chunks, tab list) that a real client can actually join and walk around in — extend that pattern for anything beyond a flat world.

Project layout

minecraft_protocolo/
├── __init__.py
├── version_resolver.py   # "1.12.2" -> a loaded protolib.Protocol
├── client.py              # Client: connect, handshake, login, events
├── server.py               # Server: accept connections, per-player events
├── errors.py                # PartialReadError and friends
├── events.py                  # small Node-style EventEmitter
└── data/                        # bundled minecraft-data (dataPaths.json + pc/)

examples/
├── client.py                     # chat bot example
└── server.py                      # playable flat-world server example

pyproject.toml

Metadata

Release files for minecraft-protocolo-py 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for minecraft-protocolo-py 0.1.2
File Size Uploaded
minecraft_protocolo_py-0.1.2.tar.gz 288.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for minecraft-protocolo-py 0.1.2
File Interpreter ABI Platform
minecraft_protocolo_py-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 607.0 kB

Release files / minecraft_protocolo_py-0.1.2.tar.gz

Download URL minecraft_protocolo_py-0.1.2.tar.gz
Size 288.7 kB
Tags Source
SHA-256 checksum
How to use checksums
f11c1fab15ca1a272d7ee4eaaa51825a076e1fb93588379cdc252cc3e93fa8b6
BLAKE2b-256 checksum
How to use checksums
85b0edab284c393b662b8c974a8771ff46c93245302ef5c0ae09e54dc0c91844
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.13

Release files / minecraft_protocolo_py-0.1.2-py3-none-any.whl

Download URL minecraft_protocolo_py-0.1.2-py3-none-any.whl
Size 318.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e5e9b3489ffcfe476bb2b5888143555580da6cd6327a72e83014b36784a097fb
BLAKE2b-256 checksum
How to use checksums
824253b5747b477783f2206f101a29a3996f4a5bbba9dc70e1a683c6b2b563a1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.13

Release history Release notifications | RSS feed

0.1.4

2 release files

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page