๐งฉ A Forge mod that runs a WebSocket server on the Minecraft client (single-player / LAN), allowing external applications to execute commands and interact with the game in real time.
๐ก How it works โ When you play single-player or open to LAN, your client runs an integrated server underneath โ the same command engine, world ticking, and gameplay loop as a dedicated server.
โ๏ธ๐ค In Minecraft, "single-player", "multiplayer", "LAN", and "server" all run the same server code โ there's no essential difference. LCon taps into this integrated server and starts a WebSocket server alongside it, so external tools can control the game without needing a separate dedicated server.
LCon starts a WebSocket server inside your Minecraft client when you're in a world (single-player or LAN). You can connect to it from any WebSocket client โ a Python script ๐ค, a chatbot ๐ฌ, a web dashboard ๐ โ and:
| ๐ท๏ธ Prefix | โก Action |
|---|---|
[chat]<message> |
Send a chat message as the player |
[message]<message> |
Display a message to the player only |
[system]<message> |
Display a system message in chat |
[client]/<command> |
Execute a client-side command |
[server]/<command> |
Execute a server-side command |
โ No Mixin, no coremod, no overwrites โ purely event-driven, safe for any modpack.
- Download the latest
.jarfrom Releases - Place it in your client's
mods/folder - Launch Minecraft โ
lcon-ws-server.tomlis auto-generated inconfig/on first load
โ ๏ธ mods/andconfig/must be at the same directory level.
Typical structure:.minecraft/mods/lcon-*.jar+.minecraft/config/lcon-ws-server.toml
uv venv --python 3.13
uv pip install websocket-client
uv run python -c "
import websocket; ws = websocket.create_connection('ws://localhost:58115?token=your_secret_token')
while True:
msg = ws.recv(); print(msg)
if 'โ
' in msg or 'ready' in msg: break
ws.send('[server]/say awa!'); print(ws.recv()); ws.close()
"npx wscat -c ws://localhost:58115?token=your_secret_tokenOnce connected, you'll receive welcome messages from the server:
< ๐ 200:Welcome to LCon! Have fun! Don't forget to use prefixes with every message you send to me.
< ๐ 200:Valid prefixes:
< ๐ฌ 200:[chat] - send message to Minecraft chat.
< ๐ฉ 200:[message] - display message for player only.
< ๐ 200:[system] - display system message in chat (for player only).
< ๐ฅ๏ธ 200:[client] - execute client-side command.
< ๐ง 200:[server] - execute server-side command.
< โ
201:ready.
Then send commands with prefixes (> is what you type, < is the server response):
> [server]/say Hello everyone!
# (command executed โ no response text, but the chat message appears in-game)
> [chat]Hello!
# (message sent as the player in chat)
> [server]/give @s diamond 64
# (command executed โ diamonds appear in your inventory)
> unknown-qwq
< โ 400:Error! Send message prefix first! [chat], [message], [system], [client], [server] are valid prefixes.A Textual-based terminal UI with tabbed interface (Console, Commands, Settings, About).
git clone https://github.com/VincentZyuApps/lcon.git
cd lcon
uv venv --python 3.13
uv pip install textual websocket-client
uv run python ./client/main.py| ๐ท๏ธ Variable | ๐ Default | ๐ Description |
|---|---|---|
LCON_HOST |
localhost |
WebSocket server address |
LCON_PORT |
58115 |
WebSocket server port |
LCON_TOKEN |
your_secret_token |
Authentication token |
LCON_SOFT_WRAP |
true |
Enable soft word wrap in console log (true/false) |
LCON_LOG_BUFFER |
1000 |
Maximum lines to keep in console log buffer |
LCON_AUTO_MODE |
true |
Auto-prepend prefix before sending messages (true/false) |
Copy the example and edit:
cp config/.env.example config/.envPriority: environment variable โ config/.env โ hardcoded default.
bash (Linux / macOS / WSL / Git Bash):
LCON_HOST=192.168.1.100 LCON_PORT=58115 LCON_TOKEN=your_secret_token
uv run python client/main.pyPowerShell (Windows):
$env:LCON_HOST="192.168.1.100"; $env:LCON_PORT="58115"; $env:LCON_TOKEN="your_secret_token"
uv run python client/main.pyCMD (Windows):
set LCON_HOST=192.168.1.100 && set LCON_PORT=58115 && set LCON_TOKEN=your_secret_token
uv run python client/main.pyFile: .minecraft/config/lcon-ws-server.toml
| โ๏ธ Option | ๐ท๏ธ Type | ๐ Default | ๐ Description |
|---|---|---|---|
enable_mod |
boolean | true |
Enable the WebSocket server |
port |
int | 58115 |
WebSocket server port |
token |
string | your_secret_token |
Auth token. Clients pass ?token=xxx on connect |
command_permission_level |
int | 4 |
OP level for [server] commands (0-4). 4 = full access without enabling cheats |
serializer_mode |
string | json |
Component serialization: json (recommended for Python TUI) or tostring |
enable_message_emoji |
boolean | true |
Master switch for message emoji |
emoji_* |
string | various | 13 per-message emoji settings (e.g. emoji_welcome, emoji_chat) |
msg_* |
string | various | 13 per-message text settings (e.g. msg_welcome, msg_chat) |
[mclistener].enable |
boolean | true |
Enable the mclistener JSON WebSocket server on port 60626 |
[mclistener].host |
string | 0.0.0.0 |
Listen address for the mclistener server |
[mclistener].port |
int | 60626 |
Port for the mclistener server |
[mclistener].token |
string | "" |
Auth token for mclistener. Empty = no auth |
[mclistener].enable_player_join_broadcast |
boolean | true |
Broadcast player_join events to mclistener clients |
[mclistener].enable_player_leave_broadcast |
boolean | true |
Broadcast player_leave events to mclistener clients |
[mclistener].enable_player_chat_broadcast |
boolean | true |
Broadcast player_chat events to mclistener clients |
[mclistener].player_chat_capture_mode |
string | event |
Player chat capture mode: event (recommended), text, or both |
[mclistener].enable_receive_group_message |
boolean | true |
Accept chat_platform_to_server messages and relay them in-game |
[mclistener].group_message_format |
string | ยง6ยงl[{group_name}]ยงr ยง7({group_id})ยงr ยงaยงo{nickname}ยงrยงf: {message} |
In-game format for relayed group messages |
[mclistener].exec_command_mode |
string | disabled |
Remote command execution mode: disabled or client |
[mclistener].command_tracking_mode |
string | single |
Command tracking mode: single (recommended) or parallel (experimental, may be unstable or produce mixed results) |
๐ก When using the Python TUI client, set
serializer_mode = "json"inlcon-ws-server.tomlfor best compatibility.๐ก For mclistener command execution, keep
command_tracking_mode = "single"unless you explicitly want best-effort parallel tracking.
./gradlew build๐ฆ Output: build/libs/lcon-*.jar
Push to any branch with specific keywords in the commit message:
| Commit message contains | What happens |
|---|---|
build action |
Build + upload artifact |
build release |
Build + create GitHub Release |
git commit -m "fix: something; build action"
git commit -m "feat: something; build release"| Dependency | Version | Description |
|---|---|---|
| 17 | Runtime | |
| 47.2.19 | Mod loader | |
| 8.1.1 | Build tool | |
| 7.1.0 | Fat-jar plugin | |
| 1.5.6 | WebSocket server (fat-jarred) | |
| โ | GitHub CI/CD |
| Dependency | Version | Description |
|---|---|---|
| 3.13 | Runtime | |
| โฅ8.2 | TUI framework | |
| โฅ1.9 | WebSocket client |




