MC Adapter
About 3025 wordsAbout 10 min
nonebot-adapter-minecraft is NoneBot's Minecraft protocol adapter, used together with UniBot to interconnect with server-side plugins / Mods via the QueQiao protocol. The full documentation is available in its Wiki.
Installation
UniBot already includes this adapter as a built-in dependency, so no separate installation is needed. To use it standalone:
Install the adapter package
pip install nonebot-adapter-minecraftRegister the adapter
Register it in
pyproject.toml:[[tool.nonebot.adapters]] name = "Minecraft" module_name = "nonebot.adapters.minecraft"
Connection Modes
The adapter (i.e. the core of this project, running on the NoneBot server) communicates with the MC server side (MCDR plugin / official QueQiao implementation) over WebSocket. There are two connection modes, and you can choose either one:
- Method 1: The MC server actively connects to the core (Recommended)
- Method 2: The core actively connects to the MC server
Both modes require server_name and access_token to match on both ends, otherwise the connection will be rejected. See the Connecting Modes section for each plugin / Mod's connection configuration examples below.
Method 1: MC Server Actively Connects to the Core (Recommended)
This is the recommended mode. That is, the MC server actively connects to the core: the QueQiao plugin / Mod on the MC server side acts as the connection initiator and actively connects to the WebSocket address exposed by the core (path /minecraft/ws).
Advantages
- Minecraft servers are often located behind intranets / NAT and cannot easily open inbound ports, while the server's outbound access to the public network / the core's address is usually unrestricted, so there is no need to open any port on the server.
- The core does not actively connect outward, so
MINECRAFT_WS_URLSin.envcan stay empty, making the configuration simpler.
Disadvantages
- The core's WebSocket address (
/minecraft/ws) must be reachable by the MC server, meaning the core needs a public address or must be on the same intranet as the server.
Method 2: Core Actively Connects to the MC Server
That is, the core actively connects to the MC server: the core acts as the connection initiator and actively connects to the WebSocket address exposed by the QueQiao plugin / Mod on the MC server side. In this case, what MINECRAFT_WS_URLS in .env holds is exactly the WebSocket address of the MC server side.
Advantages
- The core does not need to expose any port, suitable for scenarios where the core is on a strict intranet and cannot be reached by the MC server.
Disadvantages
- The MC server side needs to open a listening port to the outside, requiring the server to be able to expose ports (having a public address or being able to do port mapping).
- You need to manually fill in the address of each server in
MINECRAFT_WS_URLSin.env, making the configuration relatively tedious.
MC Server-Side Integration
The adapter communicates with the plugin / Mod on the MC server side through the QueQiao protocol. The MC server side can choose as follows:
- MCDReforged: use the MCDR Plugin
- Other server types: use the Official QueQiao Implementation
When integrating, ensure both ends match:
- Server name:
server_namemust match on both ends (under Method 2 "Core actively connects to the MC server", the key name inMINECRAFT_WS_URLSmust match the MC server side'sserver_name). - Authentication token:
MINECRAFT_ACCESS_TOKENmust match the MC server side'saccess_token(verified when not empty). - Address reachability: the WebSocket address and port must be reachable by both ends.
Official QueQiao Implementation
The official QueQiao implementation applies to Spigot / Paper / Folia / Forge / Fabric / NeoForge / Velocity / Vanilla and other server types. The full documentation is available in the Official QueQiao Docs.
Supported Server Types
| Type | Description | Version Range |
|---|---|---|
| Spigot / Paper / Folia | Bukkit-series plugin | From 1.12.2 |
| Forge / NeoForge | Mod loader | From 1.7.10 |
| Fabric | Mod loader | From 1.16.5 |
| Velocity | Proxy-side plugin | 3.3.0 |
| Vanilla | Standalone program (runs independently) | Vanilla |
Supported Server Types
Installation
From Modrinth or CurseForge, download the plugin / Mod for the corresponding server type, place it in the server's corresponding directory, and start the server.
The plugin version and the mod version have different config file paths. The plugin version is at ./plugins/QueQiao/config.yml, and the mod version is at ./config/QueQiao/config.yml.
Configuration
The core config.yml configuration is as follows:
enable: true # Whether to enable the plugin/mod
server_name: "Server" # Server name, use a different name for multiple servers
access_token: "" # Verified on connection, no Bearer prefix needed; leave empty to skip verification
# Message prefix (not including Title, ActionBar), empty means no prefix is added
message_prefix: "[鹊桥]"
# Whether to enable message translation (converts translation keys such as achievements and deaths into localized text)
enable_translation: false
# WebSocket Server configuration (forward WebSocket)
websocket_server:
enable: true # Whether to enable
host: "127.0.0.1" # WebSocket Server address
port: 8080 # WebSocket Server port
# WebSocket Client configuration (reverse WebSocket)
websocket_client:
enable: false # Whether to enable
reconnect_interval: 5 # Reconnect interval (seconds)
reconnect_max_times: 5 # Maximum reconnect attempts
url_list:
- "ws://127.0.0.1:8080/minecraft/ws"
# Rcon client configuration
rcon:
enable: false # Whether to enable
port: 25575 # Rcon port
password: "" # Rcon password
# Subscribed event configuration
subscribe_event:
player_chat: true # Player chat
player_death: true # Player death
player_join: true # Player join
player_quit: true # Player quit
player_command: true # Player command
player_advancement: true # Player advancement
# Ignored commands list; e.g. ["tp"] means command events starting with /tp are not broadcast
ignored_commands: []Field Reference
| Field | Description |
|---|---|
enable | Whether to enable the plugin / mod |
server_name | Server name, used for the Header x-self-name and event identification |
access_token | Authentication token; leave empty to skip verification |
message_prefix | Message prefix, supports MC text component JSON |
enable_translation | Whether to enable the translation feature |
websocket_server | Enable under Method 2 (core actively connects to the MC server), opens a listening port |
websocket_client | Enable under Method 1 (MC server actively connects to the core), actively connects outward to the core |
rcon | RCON client configuration |
subscribe_event | Subscribed event toggles |
ignored_commands | Ignored commands list |
config.yml Field Reference
Translation Feature (Optional)
After enabling enable_translation: true, you also need to create a translate folder in the same directory as config.yml (plugin version at ./plugins/QueQiao/translate/, mod version at ./config/QueQiao/translate/), and place JSON language files there (such as zh_cn.json extracted from the client jar). This feature can convert translation keys in achievement and death events into localized text.
Connecting Modes
The official QueQiao implementation supports both modes described in Connection Modes above; choose either one:
Enable it in websocket_client and fill in the core's WebSocket address in url_list. The MC server actively connects outward to the core without opening any port. This suits scenarios where the server is on an intranet and cannot expose ports, and is the recommended choice in the vast majority of cases.
Core side (.env)
# The core does not actively connect outward; keep it empty {} and do not fill in any address
MINECRAFT_WS_URLS={}
# Authentication token, keep consistent with the MC server side's access_token
# If the MC server side's access_token is empty, leave this empty too
MINECRAFT_ACCESS_TOKEN="your_access_token"MC server side (config.yml)
server_name: "survival" # Server name, must match the key name in the core's MINECRAFT_WS_URLS
access_token: "your_access_token" # Authentication token, must match the core's MINECRAFT_ACCESS_TOKEN
# Reverse WebSocket: the MC server actively connects outward to the core
websocket_client:
enable: true
reconnect_interval: 5
reconnect_max_times: 5
url_list:
- "ws://<core-ip>:8000/minecraft/ws" # The core's WebSocket address
# Forward WebSocket: disabled in this mode
websocket_server:
enable: falseHere port 8000 is the bot core's listening port (PORT in .env, default 8000), and the path is fixed at /minecraft/ws.
Enable it in websocket_server and listen on the address / port; the MC server opens a listening port and waits for the core to connect. This suits scenarios where the server can expose ports to the outside and the core connects actively.
Core side (.env)
# The key name is the server name, and the value is the MC server side's WebSocket address list
# The key name must match the MC server side's server_name
MINECRAFT_WS_URLS={"survival": ["ws://<mc-server-ip>:8080/mc"]}
# Authentication token, keep consistent with the MC server side's access_token
# If the MC server side's access_token is empty, leave this empty too
MINECRAFT_ACCESS_TOKEN="your_access_token"MC server side (config.yml)
server_name: "survival" # Server name, must match the key name in the core's MINECRAFT_WS_URLS
access_token: "your_access_token" # Authentication token, must match the core's MINECRAFT_ACCESS_TOKEN
# Forward WebSocket: the MC server opens a listening port and waits for the core to connect
websocket_server:
enable: true
host: "0.0.0.0"
port: 8080
# Reverse WebSocket: disabled in this mode
websocket_client:
enable: falseHeader Authentication
When using either connection mode, the following Headers must be carried or verified:
| Header | Required | Description |
|---|---|---|
x-self-name | Server name, must match server_name in config.yml | |
Authorization | Authentication, Bearer <access_token>; can be omitted when access_token is empty | |
x-client-origin | Source marker of the integrating project, e.g. minecraft / nonebot; recommended to fill in |
Header Authentication
In-Game Commands
| Command | Permission Node | Description |
|---|---|---|
/queqiao help | queqiao.help | Shows help |
/queqiao reload | queqiao.reload | Reloads the config and restarts WebSocket |
/queqiao client reconnect [all] | queqiao.client.reconnect | Reconnects the WebSocket Client (all forces reconnecting all) |
In-Game Commands
The mod side determines permissions by int Level; all commands in this mod have a permission of 2.
MCDR Plugin
The MCDR plugin of QueQiao runs on top of MCDReforged and connects the Minecraft server to the QueQiao protocol. This plugin only supports the MCDReforged server. If you use other server types such as Spigot / Paper / Fabric / Forge / NeoForge, please refer to Official QueQiao Implementation above.
Features
- Dual-mode WebSocket: supports client mode (active connection) and server mode (passive listening).
- Auto-reconnect: client mode allows configuring the reconnect interval and the maximum retry count.
- Hot reload:
!!queqiao reloadreloads the config and reuses existing connections without restarting the server. - Game event forwarding: player join / quit / chat / command / death / advancement.
- API command execution: broadcast, private message, Title, ActionBar, RCON commands, status query.
Installation
Download queqiao-vX.X.X.mcdr from Releases, place it in MCDR's plugins/ directory, and restart MCDR.
git clone https://github.com/Minecraft-UniBot/QueQiao.MCDReforged.git
cd MCDReforged
uv syncPlace the entire directory as a Directory Plugin into the MCDR plugin directory, or package it yourself:
uv run python -m mcdreforged packDependencies
- MCDReforged ≥ 2.15.0
- Python ≥ 3.12
- Python packages:
websockets≥ 16.0,PyYAML≥ 6.0,psutil≥ 5.9 - MCDR plugin dependencies:
| Plugin | Purpose | Required |
|---|---|---|
| MoreGameEvents | Player death and advancement events | |
| Minecraft Data API | Player coordinates, health, experience level | |
| online_player_api | Online players list | Optional (falls back to MCDR built-in API when missing) |
MCDR Plugin Dependencies
Configuration
On first load, a default configuration is generated at config/queqiao/config.json:
{
"server_name": "MCDR",
"access_token": "",
"client_origin": "mcdr",
"minecraft": {
"host": "",
"port": 0
},
"client": {
"enable": false,
"url": "ws://127.0.0.1:8080/minecraft/ws",
"reconnect_interval": 5,
"reconnect_max_times": 0
},
"server": {
"enable": false,
"host": "0.0.0.0",
"port": 8080
},
"log_events": true
}Field Reference
| Field | Description |
|---|---|
server_name | This server's name, used for Header x-self-name and event identification |
access_token | Authentication token; when empty, the Authorization header is not sent |
client_origin | Client origin identifier, default mcdr |
minecraft.host / minecraft.port | MC server address, used for Server List Ping. Leave empty to resolve automatically from MCDR, falling back to 127.0.0.1:25565 if unresolved |
client.enable | Set to true under Method 1 (MC server actively connects to the core) |
client.url | The core's WebSocket address (filled in under Method 1) |
client.reconnect_interval | Reconnect interval (seconds) |
client.reconnect_max_times | Maximum reconnect attempts; 0 means retry indefinitely |
server.enable | Set to true under Method 2 (core actively connects to the MC server) |
server.host / server.port | WebSocket listening address (filled in under Method 2) |
log_events | Whether to print event forwarding records in the log |
config.json Field Reference
Connecting Modes
The MCDR plugin supports both modes described in Connection Modes above; choose either one:
Set client.enable to true and fill in the core's WebSocket address (client.url). In this mode the MC server actively connects to the core and must keep server_name and access_token consistent with the core.
This is the recommended mode. When the server is on an intranet and cannot directly expose ports to the outside, the MC server can actively connect outward without opening any listening port on the server.
Core side (.env)
# The core does not actively connect outward; keep it empty {} and do not fill in any address
MINECRAFT_WS_URLS={}
# Authentication token, keep consistent with the MC server side's access_token
# If the MC server side's access_token is empty, leave this empty too
MINECRAFT_ACCESS_TOKEN="your_access_token"MC server side (config.json)
{
"server_name": "survival",
"access_token": "your_access_token",
"client": {
"enable": true,
"url": "ws://<core-ip>:8000/minecraft/ws"
},
"server": {
"enable": false
}
}Here port 8000 is the bot core's listening port (PORT in .env, default 8000), and the path is fixed at /minecraft/ws.
Set server.enable to true; the plugin will start a WebSocket server listening on server.host:server.port, waiting for the core to connect. You need to fill in the plugin's listening address in the core's MINECRAFT_WS_URLS.
Core side (.env)
# The key name is the server name, and the value is the MC server side's WebSocket address list
# The key name must match the MC server side's server_name
MINECRAFT_WS_URLS={"survival": ["ws://<mc-server-ip>:8080/mc"]}
# Authentication token, keep consistent with the MC server side's access_token
# If the MC server side's access_token is empty, leave this empty too
MINECRAFT_ACCESS_TOKEN="your_access_token"MC server side (config.json)
{
"server_name": "survival",
"access_token": "your_access_token",
"server": {
"enable": true,
"host": "0.0.0.0",
"port": 8080
},
"client": {
"enable": false
}
}Commands
| Command | Permission | Description |
|---|---|---|
!!queqiao | 2 | Shows help |
!!queqiao status | 2 | Shows connection status (mode, players, CPU, memory, MOTD, etc.) |
!!queqiao reload | 2 | Reloads the config and reconnects |
Command List
Bedrock Support
This plugin runs on top of MCDReforged, and MCDR manages different types of Minecraft servers through Server Handlers. With the Bedrock Liteloader Handler handler, MCDR can directly host Bedrock Dedicated Servers (BDS), allowing this plugin to also connect Bedrock servers to QueQiao.
How It Works
bedrock_liteloader_handler is an MCDR server handler that parses BDS's standard output into MCDR events (player join / quit, chat, etc.). Therefore, this plugin's event forwarding (player join/quit, chat) works out of the box on Bedrock servers, with no changes to the plugin code.
Installation and Configuration
Install the handler: download the latest
.mcdrpackage from liteloader_handler Releases and place it in MCDR'splugins/directory.Install this plugin: install the QueQiao MCDR plugin per Installation above.
Configure the handler: after starting MCDR, a config file for the handler is generated under
config/; select the corresponding Bedrock handler (the vanilla handler is used by default), then reload the config.Configure the QueQiao plugin: fill in
config/queqiao/config.jsonper Configuration above, keepingserver_name/access_tokenconsistent with the adapter.
Chat Output
The vanilla BDS does not output player chat by default. To have player chat events captured and forwarded by MCDR, you need to enable chat output through a behavior pack or by modifying the server; otherwise, player chat cannot be forwarded to QueQiao.
Known Limitations
Bedrock and Java are two different games, and some of this plugin's capabilities differ on Bedrock:
| Capability | Java Edition | Bedrock (BDS) |
|---|---|---|
| Player join / quit events | ✅ | ✅ (parsed via handler) |
| Player chat events | ✅ | ✅ (requires behavior pack / modified server to enable output) |
| Player death / advancement events | ✅ (MoreGameEvents) | depends on Java events, usually not available |
| Player coordinates / health, etc. | ✅ (minecraft_data_api) | ❌ not available, field is None |
| Server List Ping (MOTD / online count) | ✅ (Java SLP protocol) | ❌ Bedrock uses the RakNet protocol, ping fails, get_status falls back |
Broadcast / private message (tellraw) | ✅ | command syntax differs, needs adaptation |
| Title / ActionBar | ✅ | command syntax differs (e.g. titleraw) |
| RCON commands | ✅ | command set differs |
Bedrock Capability Comparison
Because the command systems of Bedrock and Java differ greatly, if you need to use broadcast, private message, Title and other APIs on Bedrock, it is recommended to raise a request or submit an adaptation in the QueQiao.MCDReforged repository.
Notes
- LeviLamina: After LeviLamina 1.0.0, MCDR cannot directly obtain the modified server output; you need an application supporting pty as a bridge (see liteloader_handler#13).
- Unicode fix: Affected by BDS-3791, non-ASCII characters such as Chinese may display abnormally; you can install UnicodeFixer to fix it.
- Plugin compatibility: Bedrock and Java are like two different games; before using other MCDR plugins, confirm whether they are compatible with Bedrock.
Data Model
The adapter provides the following core types:
Bot: bot instanceMessage/MessageSegment: message objectsAdapter: adapter class- Various event models (player events, chat events, etc.)
Development and Debugging
You can run the adapter's test suite in the tests/ directory:
uv run pytestContribution and Support
- For usage issues, please submit Issues
- Code contributions are welcome via Pull requests
