For AI agents

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 run

Same 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 calculation

Errors 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.