Theodosia turns a Burr state machine into an MCP server. An agent gets a single step(action, inputs) tool. The server enforces graph transitions: call an action that isn’t reachable from the current state and you get a structured refusal listing what is reachable. Every step is recorded to a replayable trace. The model can be wrong; the model cannot lie about state.
from theodosia import mount
server = mount(application)
server.run()
The four-tool surface (step, reset_session, fork_at, fork_from_past) stays constant regardless of FSM complexity. State lives on the server. The reachable action set is the graph, enforced at the protocol layer rather than asked of the model.
Ships with a CLI for session introspection (theodosia sessions ls, theodosia watch, theodosia logs --refusals), OpenTelemetry, and a Burr UI replay. Examples cover order flows, incident response, code review, LLM-in-the-graph, and upstream tool calling.
642 tests. Apache 2.0.