MineChat Protocol Specification
Version 1.0.0
1. Purpose
The MineChat Protocol defines a secure, binary-framed, compressed, client-server protocol that enables users to interact with a Minecraft server's chat system without being logged into Minecraft on the same device.
The protocol is designed to:
- Support multiple external client devices per Minecraft account
- Preserve Minecraft-compatible text formatting
- Allow moderation at both per-device and per-account granularity
- Operate without reliance on public Certificate Authorities
- Be efficient, extensible, and implementation-agnostic
This specification defines wire-level behavior only. User interfaces, database schemas, command names, and server-side storage formats are explicitly out of scope.
2. Terminology and Conventions
The key words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are to be interpreted as described in RFC 2119.
- Client: An external MineChat client application.
- Server: A MineChat server component integrated with a Minecraft server.
- Linking: The process of associating a client device with a Minecraft account.
- Client UUID: A UUID generated by the client to identify a specific device.
- Minecraft UUID: The UUID of a Minecraft account.
- RTT (Round-Trip Time): Time elapsed between sending a PING and receiving the corresponding PONG.
3. Transport and Security
3.1 TLS
All connections MUST be established over TLS.
- Servers MUST present a self-signed TLS certificate.
- Clients MUST perform certificate pinning after linking.
- Public Certificate Authorities are NOT REQUIRED.
3.2 Certificate Pinning
- During initial linking, the client stores the server's certificate or public key.
- On subsequent connections, the client MUST reject the connection if the presented certificate does not match the pinned certificate.
- Behavior on certificate rotation is implementation-defined, but certificate mismatch MUST cause connection failure.
3.3 Default Port
The MineChat protocol does not require a fixed port number.
Implementations SHOULD use TCP port 7632 as the default when no explicit port is configured. The default port is provided for interoperability convenience and does not imply exclusivity.
Implementations MUST allow the port to be configurable.
Clients MUST NOT assume that a server is available on the default port and MUST allow users or configuration to specify an alternate port.
4. Framing Layer
All MineChat messages are transmitted using a length-prefixed binary framing format.
4.1 Frame Structure
Each frame consists of:
[4 bytes decompressed size]
[4 bytes compressed size]
[compressed payload bytes]
4.2 Integer Encoding
- All framing integers MUST be:
- 32-bit signed integers
- Big-endian (network byte order)
- Negative or zero sizes MUST terminate the connection
4.3 Semantics
decompressed sizeindicates the exact byte length after decompression.compressed sizeindicates the byte length of the compressed payload.- Receivers MUST read exactly the specified number of bytes.
- Mismatched sizes or decompression failure MUST result in connection termination.
4.4 Connection Termination
Any event that results in session termination, including:
- client disconnect,
- server kick,
- ban, or
- fatal protocol error
MUST result in the immediate closure of the underlying TCP connection by at least one peer after any required final packet has been transmitted.
4.5 Resource Limits
Implementations MUST enforce implementation-defined limits on frame sizes and resource usage.
In particular:
- The declared
decompressed sizeandcompressed sizefields MUST be validated before allocating memory or attempting decompression. - Implementations SHOULD enforce limits primarily on the
decompressed sizeto prevent excessive memory usage and denial-of-service attacks. - Implementations SHOULD impose a maximum
decompressed sizeof 1 MiB (1,048,576 bytes) by default. - This limit is implementation-defined and MAY be configured differently depending on the deployment environment.
- Frames whose declared sizes exceed the implementation's configured limits MUST be rejected.
- Upon detecting such a violation, the implementation MUST terminate the connection.
- Receivers MUST NOT attempt partial processing of frames that violate these limits.
This specification does not mandate specific size limits; implementations are expected to choose limits appropriate for their environment.
5. Compression
- All payloads MUST be compressed using zstd.
- Compression is mandatory and unconditional.
- There is no negotiation for compression.
- Compression is applied after CBOR serialization.
Pipeline:
CBOR encode → zstd compress → frame → TLS
6. CBOR Usage
6.1 General Rules
This specification defines semantic meaning for CBOR map keys within defined numeric ranges. These ranges are a MineChat protocol convention and are not imposed by CBOR itself. Implementations MUST interpret map keys according to this specification and MUST ignore unknown keys unless explicitly stated otherwise.
- All payloads MUST be encoded as CBOR maps.
- CBOR map keys are semantic identifiers, not ordered fields.
- Implementations MUST NOT rely on map ordering.
- Unknown keys MUST be ignored to allow extensibility.
6.2 Field Types
Unless otherwise stated:
- Integers inside CBOR are standard CBOR integers (variable width).
- Strings are UTF-8 text strings.
- UUIDs are encoded as text strings in canonical UUID format.
6.3 Simplified CBOR Notation
This specification uses a simplified CBOR representation for readability, for example:
{
0: 1,
1: "hello"
}
This notation is illustrative only and represents a CBOR map, not JSON.
7. Packet Model
7.1 Packet Direction
Each packet is either:
- Clientbound (Server → Client)
- Serverbound (Client → Server)
Each packet MUST include a packet type identifier.
7.2 Common Packet Envelope
All packets share the following top-level structure:
{
0: packet_type (int),
1: payload (map)
}
8. Packet Types
8.1 LINK (Serverbound)
Sent by the client during initial linking.
Packet Type: 0x01
Direction: Client → Server
Payload:
{
0: linking_code (string),
1: client_uuid (string)
}
8.2 LINK_OK (Clientbound)
Sent by the server when linking succeeds.
Packet Type: 0x02
Direction: Server → Client
Payload:
{
0: minecraft_uuid (string)
}
8.3 CAPABILITIES (Serverbound)
Sent by the client immediately after linking or reconnecting.
Packet Type: 0x03
Direction: Client → Server
Payload:
{
0: supports_components (bool)
}
8.4 AUTH_OK (Clientbound)
Indicates authentication completion.
Packet Type: 0x04
Direction: Server → Client
Payload:
{}
8.5 CHAT_MESSAGE (Bidirectional)
Packet Type: 0x05
Direction: Client ↔ Server
Payload:
{
0: format (string), ; "commonmark" or "components"
1: content (string)
}
Format Semantics
commonmark:- Content is CommonMark Markdown
- Reference: https://commonmark.org/
components:- Content is a JSON-encoded Minecraft Text Component
- Based on the official text component format: https://minecraft.wiki/w/Text_component_format
- Produced by Paper / Adventure: https://papermc.io/
8.6 PING (Bidirectional)
Packet Type: 0x06
Payload:
{
0: timestamp_ms (int)
}
8.7 PONG (Bidirectional)
Packet Type: 0x07
Payload:
{
0: timestamp_ms (int)
}
The timestamp MUST match the corresponding PING.
8.8 MODERATION (Clientbound)
The MODERATION packet is used by the server to enforce rules on client devices or Minecraft accounts. It communicates actions such as warnings, mutes, kicks, or bans, along with optional details like reason and duration.
Clients MUST enforce these actions locally, applying them according to the specified scope (per client device or per account).
This packet is strictly for moderation purposes and does not convey system or server lifecycle events.
Packet Type: 0x08
Direction: Server → Client
Payload:
{
0: action (int), ; warn=0, mute=1, kick=2, ban=3
1: scope (int), ; client=0, account=1
2: reason (string), ; optional
3: duration_seconds (int) ; optional
}
8.9 SYSTEM_DISCONNECT (Clientbound)
Packet Type: 0x09
Direction: Server → Client
Payload:
{
0: reason_code (int),
1: message (string)
}
The SYSTEM_DISCONNECT packet indicates that the server is intentionally terminating the connection due to a system-level lifecycle event, not a user-targeted moderation action.
Unlike MODERATION, this packet is not related to user behavior enforcement and MUST NOT be used for kicks, bans, mutes, or account-level penalties.
After sending SYSTEM_DISCONNECT, the server MUST immediately close the underlying TCP connection.
Clients MUST treat this packet as terminal and MUST NOT attempt reconnection automatically unless explicitly configured.
Reason Codes
| Value | Meaning |
|---|---|
| 0 | Shutdown |
| 1 | Maintenance |
| 2 | Internal error |
| 3 | Overloaded |
Implementations MAY define additional codes in the 128+ range for private or experimental use.
Interaction with Keep-Alive
SYSTEM_DISCONNECT MAY be sent at any time.
After sending it:
- server SHOULD stop sending further packets
- server MUST close the connection immediately or after flushing pending frames
Clients receiving SYSTEM_DISCONNECT MUST NOT wait for PING/PONG timeout and MUST terminate immediately.
9. Keep-Alive
- Default keep-alive interval: 15 seconds
- Interval MAY be configurable.
- Either side may send PING at any time.
- Failure to receive any packet within the timeout window MUST result in connection termination.
10. Packet Flow
10.1 Linking and Authentication
Player Server Client
| | |
| /minechat link | |
|---------------------->| |
| linking code shown | |
| | |
| |<--- TLS connect ----|
| |---- TLS cert ------>|
| | |
| |<--- LINK -----------|
| |---- LINK_OK --------|
| | |
| |<--- CAPABILITIES ---|
| |---- AUTH_OK --------|
10.2 Sending a Chat Message
Client Server
| |
|--- CHAT_MESSAGE -------------->|
| |
|<-- CHAT_MESSAGE (broadcast) ---|
11. Security Considerations
- TLS provides confidentiality and integrity.
- Certificate pinning prevents MITM attacks.
- Mandatory compression and framing prevent stream desynchronization.
- Client UUIDs prevent trivial ban evasion.
12. Extensibility
- Unknown packet types MUST be ignored.
- Unknown CBOR fields MUST be ignored.
- Packet type identifiers SHOULD be centrally documented.
Appendix A — Packet Reference Table
This section provides a single-glance reference for implementors. All packet structures are defined normatively in Section 8; this table is non-normative but authoritative.
Packet Type Table
| Packet Name | Type ID | Direction | Mandatory | Purpose |
|---|---|---|---|---|
| LINK | 0x01 | Client → Server | Yes | Link client device to Minecraft account |
| LINK_OK | 0x02 | Server → Client | Yes | Confirm successful linking |
| CAPABILITIES | 0x03 | Client → Server | Yes | Declare client-supported features |
| AUTH_OK | 0x04 | Server → Client | Yes | Authentication complete |
| CHAT_MESSAGE | 0x05 | Client ↔ Server | Yes | Chat message transport |
| PING | 0x06 | Client ↔ Server | Yes | Keep-alive and RTT measurement |
| PONG | 0x07 | Client ↔ Server | Yes | Response to PING |
| MODERATION | 0x08 | Server → Client | Optional | Enforce moderation actions |
| SYSTEM_DISCONNECT | 0x09 | Server → Client | Yes | System-level disconnection |
Packet Field Reference
LINK (0x01)
| Key | Name | Type | Required |
|---|---|---|---|
| 0 | linking_code | string | Yes |
| 1 | client_uuid | string | Yes |
LINK_OK (0x02)
| Key | Name | Type | Required |
|---|---|---|---|
| 0 | minecraft_uuid | string | Yes |
CAPABILITIES (0x03)
| Key | Name | Type | Required |
|---|---|---|---|
| 0 | supports_components | bool | Yes |
AUTH_OK (0x04)
No payload fields.
CHAT_MESSAGE (0x05)
| Key | Name | Type | Required |
|---|---|---|---|
| 0 | format | string | Yes |
| 1 | content | string | Yes |
Valid format values:
| Value | Meaning |
|---|---|
commonmark |
CommonMark Markdown |
components |
JSON-encoded Minecraft Text Component |
PING (0x06)
| Key | Name | Type | Required |
|---|---|---|---|
| 0 | timestamp_ms | int | Yes |
PONG (0x07)
| Key | Name | Type | Required |
|---|---|---|---|
| 0 | timestamp_ms | int | Yes |
MODERATION (0x08)
| Key | Name | Type | Required |
|---|---|---|---|
| 0 | action | int | Yes |
| 1 | scope | int | Yes |
| 2 | reason | string | No |
| 3 | duration_seconds | int | No |
Action values:
| Value | Meaning |
|---|---|
| 0 | Warn |
| 1 | Mute |
| 2 | Kick |
| 3 | Ban |
Scope values:
| Value | Meaning |
|---|---|
| 0 | Client UUID |
| 1 | Minecraft UUID |
Appendix B — Numeric Range Reservations
This section is normative.
Packet Type ID Ranges
| Range | Reservation |
|---|---|
| 0x00 | Reserved (invalid) |
| 0x01-0x1F | Core protocol packets (this spec) |
| 0x20-0x3F | Future protocol extensions |
| 0x40-0x7F | Experimental / non-standard |
| 0x80-0xFF | Implementation-private |
Rules:
- Core protocol packets MUST use IDs in
0x01-0x1F - Implementations MUST NOT redefine core packet IDs
- Experimental packets MUST NOT be required for interoperability
- Private packets MUST NOT be sent unless both sides explicitly support them
CBOR Map Key Ranges
CBOR map keys inside packet payloads follow this reservation:
| Key Range | Meaning |
|---|---|
| 0-31 | Core fields (this spec) |
| 32-63 | Reserved for future core extensions |
| 64-127 | Optional extensions |
| 128+ | Implementation-defined |
Rules:
- Core fields MUST use keys
0-31 - Unknown keys MUST be ignored
- Implementations MUST NOT assume key ordering