A spreadsheet engine built for AI agents
Agents that work with spreadsheets today mostly don't compute. The popular Excel MCP servers read and write cells but can't evaluate a formula. The workaround — shelling out to headless LibreOffice for a recalc — is what even first-party agent tooling ships. That means slow round-trips, a process to babysit, and results that can change under the agent's feet.
An agent needs three things from a spreadsheet engine, and they're the three things Formualizer was built around.
1. Deterministic evaluation
An agent that can't reproduce a result can't verify its own work. Formualizer lets you freeze every source of nondeterminism — volatile functions, the clock, the timezone, the RNG:
import datetimefrom formualizer import SheetPortSession, Workbookmanifest_yaml = """spec: fiospec_version: "0.3.0"manifest: id: pricing-model name: Pricing Model workbook: uri: memory://pricing.xlsx locale: en-US date_system: 1900ports: - id: base_price dir: in shape: scalar location: { a1: Inputs!A1 } schema: { type: number } - id: final_price dir: out shape: scalar location: { a1: Outputs!A1 } schema: { type: number }"""wb = Workbook()wb.add_sheet("Inputs")wb.add_sheet("Outputs")wb.set_formula("Outputs", 1, 1, "=Inputs!A1*1.2")session = SheetPortSession.from_manifest_yaml(manifest_yaml, wb)session.write_inputs({"base_price": 100.0})out = session.evaluate_once( freeze_volatile=True, rng_seed=42, deterministic_timestamp_utc=datetime.datetime(2026, 1, 1, tzinfo=datetime.timezone.utc), deterministic_timezone="utc",)# same inputs + same seed + same frozen clock => identical outputs, every runSame inputs, same outputs — NOW(), TODAY(), RAND() included. That turns "run the model" into a pure function an agent can retry, cache, and test against.
2. Typed contracts over workbooks: SheetPort
A workbook is an API with no schema. SheetPort adds one: a manifest declares named input and output ports (cell locations + JSON-schema types), and the session validates inputs, writes them, evaluates once, and reads typed outputs back:
ports: - id: base_price dir: in shape: scalar location: { a1: Inputs!A1 } schema: { type: number } - id: final_price dir: out shape: scalar location: { a1: Outputs!A1 } schema: { type: number }The agent stops guessing which cells matter. The spreadsheet becomes a typed, deterministic function — callable from a tool definition like any other.
3. A dependency graph the agent can interrogate
Formualizer maintains an incremental dependency graph: edits recompute only the dirty subgraph, cycles are detected and reported, and the formula structure is inspectable — parse any formula to a typed AST, walk its references:
import formualizer as fzast = fz.parse("=SUM(A1:B2) + VLOOKUP(C1, D:E, 2, FALSE)")# typed AST — walk references, inspect structure, explain the calculationErrors are values ({'type': 'Error', 'kind': 'Div'}), not exceptions — an agent inspects failures cell-by-cell instead of losing the whole evaluation to one bad divide.
The MCP server
spreadsheet-mcp puts this engine behind the Model Context Protocol: native recalculation (no LibreOffice), dependency tracing, and fork/diff/verify loops — an agent forks the workbook, makes a change, recalculates, and diffs the result before committing. It is, as far as we know, the only MCP server that computes rather than just reads.
Runs where agents run
Rust core, permissively licensed (MIT). Python wheels for CPython 3.10–3.13, a JS/WASM package for browser and Node, and a Pyodide wheel for in-browser Python. No GPL wall, no office-suite dependency, no license fee to embed it in your product.
The engine also powers the SheetPort workflows documented across the docs and the broader open-source project.
FAQ
Why does determinism matter for an agent?
Because verification requires reproducibility. If NOW() or RAND() shifts between runs, the agent can't distinguish "my edit changed the output" from "the clock did." Frozen-clock, seeded evaluation makes model runs pure functions.
Can't I just use a headless LibreOffice recalc?
You can — that's what most agent tooling does today. You pay process-spawn latency per recalculation, add a system dependency, and get no dependency tracing or typed I/O. A library call is faster and gives the agent structure to reason over.
What makes spreadsheet-mcp different from other Excel MCP servers?
Most Excel MCP servers manipulate cells but cannot compute a formula. spreadsheet-mcp evaluates natively with this engine and adds dependency tracing and fork/diff/verify workflows.
Is the license safe for commercial agents?
Yes — MIT. Embed it in commercial products, SaaS, or internal tools without copyleft obligations.
Give your agent a real engine
Start with a quickstart, wire up the MCP server, and inspect the dependency graph your agent reasons over.