Skip to content
mc-protocol
Esc
↑↓navigate↵open⌘Jpreview
On this page

Introduction

What mc-protocol is, what it does for you, and what it leaves to you.

Build a custom Minecraft server, connect a bot, or inspect packets through a proxy. mc-protocol handles the network encoding so you can work with named packets and JavaScript objects.

It ships Minecraft Java 26.2 (protocol 776), with readers and writers for 257 packets. The protocol version is negotiated per connection at the handshake, and import { Server } from "mc-protocol/26.2" pins a version explicitly; the root import always tracks the newest one. You own the game logic; the library handles framing, compression, and packet encoding.

It gives you three classes and a few helpers:

  • Server accepts TCP connections, parses packets, and by default walks each player through login and configuration for you.
  • Client opens a connection to a server (or wraps a socket the server accepted) and gives you sendPacket plus events for everything it receives.
  • Proxy accepts players, opens an upstream connection for each one, and forwards packets by name with optional handlers.
  • helpers.ChunkHelper builds lit LevelChunkWithLight payloads so you can put a player on solid ground without writing a chunk serializer.
  • helpers.createSlot("diamond_sword", options) builds a custom item stack by name. helpers.emptySlot() clears a slot, and helpers.getItemId(name) resolves names for fields that need a numeric ID.
  • helpers.createCommandTree([...]) turns nested literal / argument nodes into the Commands packet, indices and flags included.
  • helpers.createParticle("dust", { color: "#ff8800" }) and helpers.createParticlePacket(...) build particle values and the LevelParticles payload by name.
  • helpers.createEntityMetadata("player", { glowing: true, health: 20 }) produces SetEntityData entries from named fields for verified entity kinds.
import { Server } from "mc-protocol";

const server = new Server({ port: 25565 });

server.on("playerJoin", (client, session) => {
  console.log(`${session.username} joined`);
});

What it handles

  • Frame length prefixes and zlib compression, including the LoginCompression switch.
  • Connection state tracking on both directions independently (see Connection states).
  • Protocol version negotiation from Intension, with a clear LoginDisconnect for versions that are not built in (see Versions).
  • Offline-mode login, known packs, registry data, tags, and FinishConfiguration when autoInit is on.
  • Keep-alive pings, latency measurement, and dropping clients that stop answering when autoKeepAlive is on.
  • Parsing every packet into a plain object with named fields. Most fields also accept the vanilla name as an alias when you write them.

What it does not handle

  • Online mode. There is no encryption or Mojang session verification; autoInit assigns each player an offline profile.
  • Game logic. Nothing moves, ticks, or persists. You send the packets; the library encodes them.
  • Vanilla world generation. createNoiseWorld can make deterministic terrain, caves, ores, trees, and reusable structures, but uses one biome ID and does not reproduce vanilla terrain, aquifers, loot, or mobs.

See Limitations for the current list of known gaps.

Where to go next

  • Installation to add the library to a project.
  • Your first server for a complete join sequence that puts a player on generated terrain.
  • Packets for the field-level reference of every packet.
  • Types for the primitive wire types the packets are built from.

Was this page helpful?