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 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.1

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.1
File Size Uploaded
minecraft_protocolo_py-0.1.1.tar.gz 288.7 kB Details

Built distribution (wheel)

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

Total release size: 607.0 kB

Release files / minecraft_protocolo_py-0.1.1.tar.gz

Download URL minecraft_protocolo_py-0.1.1.tar.gz
Size 288.7 kB
Tags Source
SHA-256 checksum
How to use checksums
c4d5a67be36a2e75bf9be6568bc2681a1508366c4a91a95e22928f9edbf50f39
BLAKE2b-256 checksum
How to use checksums
588b9d2e7c0b29a95a9f95bfde1d1cddbc54be34ce28cee43ef9772892e4334c
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.1-py3-none-any.whl

Download URL minecraft_protocolo_py-0.1.1-py3-none-any.whl
Size 318.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1037a4dd4e58015ea52660854a1dfe052363c559efdf382bc8eda8abb8bf7b4b
BLAKE2b-256 checksum
How to use checksums
7fafacf653b635ac6ad5053db91fb1fbe35cb75c4d5c46d1af8e7b51176b4d15
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

0.1.2

2 release files

This release

0.1.1 This release

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