debugmcp

package
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 5, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package debugmcp exposes a luapure debug Session over the Model Context Protocol (MCP), so an LLM agent can drive breakpoints, stepping and expression evaluation through tool calls. It speaks MCP's JSON-RPC 2.0 wire format with no external dependencies — only the Go standard library and the luapure package.

The protocol surface is intentionally small: initialize, tools/list and tools/call, plus a set of debug tools (see Server). Transport is abstracted (Transport), so the same Server runs over stdio today and HTTP later. The debuggee's source need not live with the client: source text is fetched on demand through a SourceResolver, mirroring the luapure Session design.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Server

type Server struct {
	// NewState returns a fresh, library-loaded LState for each launch. Required.
	NewState func() *luapure.LState
	// Source resolves a program id to its Lua source text — used to load a
	// program launched by id, and to serve display context for get_source. May
	// be nil if every launch passes its source inline.
	Source luapure.SourceResolver
	// Name and Version are reported to the client at initialize.
	Name    string
	Version string
	// contains filtered or unexported fields
}

Server exposes a luapure debug session over MCP. Construct it with a state factory and a source resolver, then run Serve over a Transport.

Lifecycle. The debuggee runs on its own goroutine; the control tools (launch, continue, step_*) block until the program next stops (a breakpoint) or finishes, returning that outcome, while the inspection tools (stack, variables, evaluate, get_source) read the paused state. This maps the inherently stateful debug loop onto MCP's request/response model: one tool call advances or queries, exactly once.

func (*Server) HandleMessage

func (s *Server) HandleMessage(msg []byte) []byte

HandleMessage processes one JSON-RPC message and returns the reply frame, or nil for a notification (no reply). It is the shared core behind the stdio/TCP Serve loop and the HTTP Handler. Safe for concurrent calls (the HTTP server invokes it per request); blocking control tools do not hold the server lock, so a pause can land while a continue is in flight.

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler returns an http.Handler implementing MCP's Streamable HTTP transport for this server: a POST carries one JSON-RPC message and the response body is the single JSON-RPC reply. There is no SSE stream — this debug server never pushes unsolicited messages (a control tool returns its stop synchronously), so plain JSON replies suffice.

SECURITY. The handler performs no authentication, TLS, Origin validation or rate limiting, and it executes arbitrary Lua on the caller's behalf — exposing it unguarded is remote code execution. Mount it behind middleware that enforces auth and validates Origin (DNS-rebinding protection), bind to localhost unless the front is trusted, and prefer a sandboxed NewState for untrusted callers. One Server is one debug session; route each session (e.g. by its Mcp-Session-Id) to its own Server and Handler.

Control tools (launch/continue/step_*) block until the next stop, so the POST is held open until then — configure generous server write/idle timeouts, and send pause as a separate concurrent request to interrupt a long run.

func (*Server) Serve

func (s *Server) Serve(t Transport) error

Serve runs the MCP message loop over t until the peer closes (io.EOF) or a transport error occurs. It is the blocking entry point.

type Transport

type Transport interface {
	Read() ([]byte, error) // next message frame; io.EOF when the peer closes
	Write(msg []byte) error
	Close() error
}

Transport carries whole JSON-RPC messages as byte frames. Read returns the next inbound message; Write sends one; both are one message per call. An implementation must be safe for one reader and one writer used concurrently.

func NewStdioTransport

func NewStdioTransport(r io.Reader, w io.Writer, closer io.Closer) Transport

NewStdioTransport builds a transport over r/w; closer (may be nil) is run by Close. For a process spawned by an MCP client, pass os.Stdin and os.Stdout.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL