mlua-probe-core 0.1.2

Core debug engine for mlua — breakpoints, stepping, variable inspection
Documentation

mlua-probe

Lua debugger and test runner for mlua — breakpoints, stepping, variable inspection, expression evaluation, and a built-in test framework.

Designed for programmatic access: attach to a running mlua::Lua instance and control it from any frontend (MCP server, DAP adapter, etc.).

Crates

Crate Description
mlua-probe-core Core debug engine and test framework
mlua-probe-mcp MCP server binary (stdio transport)

Architecture

The engine uses a VM-thread blocking model:

  1. A Lua debug hook pauses the VM thread when a breakpoint or step condition is met
  2. While paused, inspection commands (locals, upvalues, evaluate) run on the VM thread — required because lua_getlocal and friends are not thread-safe
  3. A resume command (continue / step) unblocks the hook
┌──────────┐     commands      ┌──────────────┐
│ Frontend │ ───────────────► │  Controller  │
│ (MCP/..) │ ◄─────────────── │              │
└──────────┘     events        └──────┬───────┘
                                      │ mpsc
                               ┌──────▼───────┐
                               │ Debug Engine │
                               │  (VM thread) │
                               └──────────────┘

Quick start

As a library

use mlua::prelude::*;
use mlua_probe_core::{DebugSession, DebugEvent};

let lua = Lua::new();
let (session, controller) = DebugSession::new();
session.attach(&lua).unwrap();

controller.set_breakpoint("@main.lua", 3, None).unwrap();

let handle = std::thread::spawn(move || {
    lua.load(r#"
        local x = 1
        local y = 2
        local z = x + y
        return z
    "#)
    .set_name("@main.lua")
    .eval::<i64>()
});

let event = controller.wait_event().unwrap();
controller.continue_execution().unwrap();

let result = handle.join().unwrap().unwrap();
assert_eq!(result, 3);

As an MCP server

cargo run --bin mlua-probe-mcp

Add to your MCP client configuration:

{
  "mcpServers": {
    "lua-debugger": {
      "command": "mlua-probe-mcp"
    }
  }
}

MCP tools

Tool Description
debug_launch Launch a Lua debug session with source code
set_breakpoint Set a breakpoint at source:line
remove_breakpoint Remove a breakpoint by ID
list_breakpoints List all breakpoints
continue_execution Resume execution
step_into Step into the next line
step_over Step over (skip function bodies)
step_out Step out of current function
pause Request VM to pause
wait_event Block until next debug event
get_stack_trace Get current call stack
get_locals Get local variables at a frame
get_upvalues Get captured variables at a frame
evaluate Evaluate a Lua expression
get_state Get session state
disconnect End debug session
Testing
test_launch Run Lua tests with the lust framework and return structured results

Testing

The test_launch tool runs Lua test code with the lust framework pre-loaded and returns structured JSON results (passed/failed counts and per-test details).

local describe, it, expect = lust.describe, lust.it, lust.expect
describe('math', function()
    it('adds numbers', function()
        expect(1 + 1).to.equal(2)
    end)
end)

The testing module is independent of the debug session. To debug a failing test, pass the same Lua code to debug_launch — breakpoints and stepping work inside test code as usual.

Requirements

  • Rust 1.77+
  • Lua 5.4 (vendored via mlua)

Contributing

Bug reports and feature requests are welcome — please open an issue. Pull requests are also appreciated.

License

Licensed under either of

at your option.