drive roblox's luau vm from python or claude · over macsploit's own wire
tcpdump → IDA → 80 lines of python → game.Players[*]:Kick()
┌──────── MacSploit.app (the official GUI)
│
◄───┼──────── MCP-Sploit (this project)
│
└──────── anything else that speaks the protocol
│
▼
┌───────────┐
│ Roblox │
│ macsploit │ ◄─── injected dylib, owns the Lua state
│ dylib │
└───────────┘
macsploit is a dylib that gets injected into Roblox. once it's in, it owns the lua state — it can compile and run any luau as if the game itself wrote it. the dylib also opens two local sockets:
tcp 127.0.0.1:5553-5563 single-client script-in
ws 127.0.0.1:8765 alternate channel
the MacSploit.app GUI you normally use is just a client of those sockets. nothing magical. so we cut the GUI out of the loop and connect to the dylib directly. from the dylib's perspective, MCP-Sploit and the official app are indistinguishable.
no fancy tools. one terminal:
$ sudo tcpdump -i lo0 -A 'tcp port 5553'then click Execute in the official app. the wire format falls out:
offset bytes meaning
0 00 00 00 00 00 00 00 00 (zero / unused)
8 LL LL LL LL body length, little-endian u32
12 00 00 00 00 (zero / padding)
16 <body bytes> luau source, utf-8
N-2 0a 00 "\n\0" terminator
the websocket on :8765 is even less exotic — a normal ws frame with
{"op":"load","string":"<luau>"} inside. for the dylib internals i poked
at the binary in IDA, but tcpdump did 95% of the work.
the dylib's tcp listener is single-client. when MacSploit.app is open
it's holding the slot — every connect() after that gets refused. quit the
app and the slot is yours. roblox itself can keep running; the dylib stays
injected the whole time.
(the websocket on :8765 doesn't have this restriction, so MCP-Sploit can
fall back to it.)
both channels are fire-and-forget — the dylib doesn't echo print over
either socket. but it doesn't have to. roblox itself logs every print /
warn / error to:
~/Library/Logs/Roblox/*Player*.log
…under the [FLog::Output] tag. so execute_and_capture is just:
1. wrap the script with begin/end marker prints
2. note current log size
3. send the script
4. tail the log until the end marker shows up
cleaner than sniffing the ws.
git clone https://github.com/Claude-Reverser/MCP-Sploit
cd MCP-Sploit
pip install -e .requires macOS · python ≥ 3.10 · a working macsploit install.
cli
mcp-sploit discover
mcp-sploit exec 'print("hi")'
mcp-sploit exec luau/demos/player_v2.luau
mcp-sploit exec-all luau/demos/esp.luaupython
from mcp_sploit import discover, execute, execute_all
from mcp_sploit.bundle import with_ui
discover() # [Instance(port=5553, protocol='tcp'), ...]
execute('print("hi")')
execute_all('print("hi")') # → {5553: True, 5554: True}
# bundle the in-game ui lib so _G.mcpsploit_ui is available
execute(with_ui([[
local ui = _G.mcpsploit_ui
local win = ui.window("demo")
win:section("hi"):button("click", function() print("clicked") end)
]]))mcp (claude code)
claude mcp add mcp-sploit --scope user -- mcp-sploit-mcpthen ask claude:
"discover any running roblox instances, then notify me with 'hello' and tail the last 20 lines of script output"
| tool | what it does |
|---|---|
discover |
list active macsploit instances |
execute |
run a luau script (fire-and-forget) |
execute_on_all |
broadcast a script to every instance |
notify |
top-right in-game notification |
execute_and_capture |
run a script and tail its print/warn/error |
tail_logs |
recent script output from the roblox client log |
luau/demos/
├── player_v2.luau walkspeed · jump · gravity · fly · noclip
├── esp.luau box / name / health / distance esp with a slider gui
├── aimbot.luau camera lock with fov circle, smoothing, team check
├── combat.luau esp + aimbot in one window (silent-aim hook included)
└── auto_roll.luau toy auto-roller for a ugc roll game
each demo expects _G.mcpsploit_ui to be loaded — pass it through
with_ui() from python or paste the lib first if you're running by hand.
mcp_sploit/ python
├── discovery.py port scanner + Instance dataclass
├── executor.py protocol dispatch
├── bundle.py prepend mcpsploit_ui to a script
├── logs.py roblox log tail / parse
├── mcp_server.py fastmcp server
└── protocols/
├── tcp.py wire format above
└── websocket.py rfc6455 by hand, no extra deps
luau/
├── lib/mcpsploit_ui.luau in-game ui library
└── demos/ examples (see above)
cli.py mcp-sploit {discover,exec,exec-all}
MIT.
for your own roblox sessions, private servers, and study. running an executor in public games is against roblox's tos — that's on you.
built by reading tcpdump -A output until the format clicked.