OpenTakeoff
The measurement engine for building plans—built so an AI agent can drive it, and so an estimator wants to.
A takeoff is the act of measuring quantities off a construction drawing. OpenTakeoff does it two ways over one engine: 58 MCP tools for an agent, and a browser canvas for a person. Agents and people share the takeoff document and quantity calculations. Each sheet carries its calibration; measurements carry geometry, method and authorship. Recalibration updates quantities together, incompatible imports report scale conflicts, and agent measurements carry an explicit review status. See the Phase 1 test guide.
For agents · Try the canvas · The engine's contract · For the person at the canvas · The data layer · Research · Fork it · Contribute
The two manuals: agent manual · user manual
Protocol work: Takeoff Protocol draft and compatibility status—formalizing existing records; current takeoff behavior is unchanged.
Read this in: 日本語 · 한국어 · 简体中文
Watch it: an autonomous agent runs a takeoff, live, no cuts (2:47) · hospital finish plan → report in about a minute (1:14) · canvas walkthrough (1:10) · One-Click Area (0:51)
One-Click Area is temporarily gated. The flood engine is being re-validated against a wider plan corpus. Until that finishes the One-Click tool is off the canvas rail (
Oreports the gate) and theone_click/detect_roomsMCP verbs are not registered (a default build ships 58 tools). Trace rooms with Area (A) in the canvas andmeasure_polygonover MCP; every other tool, sweep and derivation is unchanged. A build lifts the gate withVITE_ONE_CLICK=1(canvas) /OPENTAKEOFF_ONE_CLICK=1(server). Sections and videos below that show One-Click describe the engine as it returns — seedocs/design/ONE_CLICK_GATE.md.
The Premium workspace offers compact controls, searchable actions and sheets, personal panel arrangements, adjustable surfaces and larger sheet previews. It is the default when this browser has no saved layout choice; Classic layout remains available. See the workspace design and research.
Sheet navigation releases closed PDFs and embedded fonts from the tile workers; see the 30-flip rendering check. Beyond the PDFs in open tabs, at most four idle PDFs stay loaded (two on a phone or tablet, or a browser that reports 4 GB of memory or less), least recently used out first; see the 12-PDF check.
Start here
| You are | Go here |
|---|---|
| An estimator with a bid due | Open the canvas—drag in a plan, no account, nothing uploads. The user manual gets you from a blank tab to an exported takeoff in five minutes, and its working order is the sequence to run on a real bid set. |
| An AI agent—or the person wiring one up | npx -y opentakeoff-mcp, then the agent manual: the operating model, the standard finish every takeoff ends with, what the engine refuses to guess, and why. Tool-by-tool reference is mcp/README.md. |
| A developer building on the engine | AGENTS.md is the repo map and the ship discipline; FEATURES.md maps every capability to the code that does it. |
| A crew that wants its own copy | Fork it—your own instance on your own URL in a few minutes, AGPL-3.0, nothing phones home. Same path if you're going to send a pull request. |
Windows, macOS, Linux — all of it
OpenTakeoff is a client-only browser app, so the canvas runs the same on Windows, macOS, ChromeOS and Linux in any current Chrome, Edge, Firefox or Safari. Nothing installs, nothing uploads, and no feature is gated on an operating system.
- Shortcuts are platform-aware. The app labels modifiers for the keyboard in front of you —
Ctrl/Alt/Shifton Windows and Linux,⌘/⌥/⇧on a Mac — and the handlers have always treated⌘andCtrlas the same key. Press?in the canvas for the current list. - The MCP server is tested on Windows.
npx -y opentakeoff-mcpruns on Windows, macOS and Linux, and CI runs the full MCP suite — typecheck, tests, build and the packaged smoke test — onwindows-latestas well asubuntu-lateston every change. - Optional extras. The bundled capture server is stdlib Python 3 and runs anywhere
Python does — on Windows invoke it with
python capture\capture_server.py selftest(or thepylauncher) rather thanpython3. Neither it nor the optionalserver/AI sandbox is needed to use the canvas. - Locked-down enterprise fleets (MSIX packaging, Windows Sandbox, Intune silent deploy) are tracked in #226 and not yet built.
What this is
Measuring quantities off a plan is the input to every construction bid—how much floor, how much wall, how many fixtures, at what scale, on which sheet. It happens thousands of times a day. Until OpenTakeoff there was no open-source takeoff engine at all, web-based or otherwise, and nothing an autonomous agent could call.
OpenTakeoff is that engine, with two front ends sharing geometry and quantity modules:
- Review cleanup—agents can edit annotation text with undo while preserving geometry and review; RFI-linked notes require browser review. Scope warnings distinguish numeric edge residue from real small overlaps.
- A stdio MCP server—
npx -y opentakeoff-mcp, 58 tools, on the official MCP registry. An agent opens a plan, reads the title block, sets the scale, traces the rooms to their wall faces (the flood engine stays gated), checks its own work on a rendered overlay, and hands back a marked-up planset PDF. - A browser canvas—no backend, no account, no upload. An estimator drags in a plan set and traces it, using One-Click room detection, CAD hatches, roll-goods seam layout, a materials buy list, and exports.
Neither is a wrapper around the other. The MCP server imports shared web modules, so quantity math and takeoff records are compatible. Browser and MCP room-detection paths currently differ; shared code does not guarantee identical boundaries on every plan. One-Click remains gated while that boundary is re-validated.
Provenance is the load-bearing part. Every shape records the scale it was measured at, the method that produced it (vector flood, raster trace, hand-drawn, agent-proposed), whether a human corrected it, and the machine's original boundary frozen beside the correction. This includes agent shapes drawn with manual measurement tools; the actor and drawing method are separate fields. Downstream, that's an audit trail a PM can read. Upstream, it's a labeled (geometry → finish) pair—the training signal takeoff models have never had at scale. That second use is not a side effect; see the data layer.
Recently shipped
- Tracing rules an agent actually reads—the room-boundary conventions an estimator uses
(innermost wall face, door openings crossed on the wall centerline, columns and chases wrapped,
never a hatch edge or a door leaf, a tight overlay check per ring) now ship inside the server:
takeoff://wiki/workflows, the initialize instructions and themeasure_polygondescription. On a task with no conventions in it, one unprompted run went from 0 of 6 rooms with door notches to 6 of 6 (#423, MCP 0.9.84) - A plan set with reference rings, and blind runs against it—three public floor plans (a VA
healthcare finish plan, a VA clinic floor plan, a city public-domain ADU) with estimator-trace
references, a scorer profile for concave rooms and finish splits, and published blind agent
runs with frozen exports, scores and overlays. The runs found defects in the references first;
the references are v2 and still unreviewed by a person, and the open estimator questions are
listed (#421,
#422,
evals/mcp-workflow-bench/plan-set/) - The human review loop, start to finish—import an agent's takeoff, correct a ring, accept the batch, export, and reopen the archive on a clean machine with geometry and review state intact, with screenshots of the real app in the user manual (#424)
- The Takeoff Protocol draft, one shared wiki, and a scripted workflow benchmark—the existing record fields inventoried and formalized as draft schemas with an executable compatibility matrix (10 conform, 1 needs an adapter, 5 unsupported and named); one wiki for people and agents, packaged as MCP resources and checked against source in CI; and a workflow benchmark that drives the built server flat and staged, scores geometry separately from totals, and reopens the export in a fresh process (#406–#419, roadmap)
- Stitched sheets—a floor split across a match line becomes one working surface; a room that crosses the seam traces as one shape, One-Click included (#161)
- PDF layer roles—CAD-exported sheets state what their ink is, so One-Click reads the layer tree instead of inferring boundaries from hatch, with a Layers panel on the canvas and scored corpus IoU (#85)
- The sheet graph—an agent asks "what finish is in room 134, and how do you know" and
gets the schedule row with a citation per cell, across continuation sheets, rotated headers,
and multi-building keys:
sheet_graph/resolve_tag/find_schedule(#87) - Roll goods—opt a condition into broadloom or sheet material and the engine figures the seams: lanes, multi-roll splits, cuts drawn to scale over their rooms in cutting order, a to-scale roll diagram with drag-to-reorder, and order footage beside the measured quantities (#136)
- Transitions, at the canvas—⟂ Transitions… in the Takeoffs panel derives the line where
two finishes meet from rooms you already measured;
derive_transitionsdoes the same over MCP. Flood-traced rooms don't share edges, so what's actually there is proximity in two flavors that mean different things: finishes changing inside one open space commit as a butt joint, while rooms parallel across a partition come back withheld as questions—the transition is a threshold in a doorway, and nothing in a trace record says where the doorway is. Committing 34 LF of threshold because two rooms share 34 LF of wall would be a wrong bid with a machine's confidence behind it (#202) symbol_sweep—every instance of a repeated symbol from one marqueed example, crossing scales only by a stated ratio, never a searched onemark_verdict/delete_verdict—an agent signs its own work as a graphiteAGENTdiamond; only a human hand mints the greenAPPROVEDseal- One-Click accuracy wave—face extraction and gap tolerance from RFC #60 (contributed by @knmurphy), hairline runs shadowing a heavier wall classified as annotation rather than boundary, and an in-swing door's sector taken behind the leaf instead of the arc
- Voice takeoff (gated off the toolbar by default;
VITE_COMMAND_BOX=1builds it back)—holdMand saycarpet one, waste seven; recognition is whisper-tiny.en in WebAssembly on your machine, audio never leaves the browser (docs/VOICE.md)
Full history: CHANGELOG.md · every capability mapped to its code: FEATURES.md
For agents — start here
Point any stdio MCP client at the published package. Node 20+, no clone, no build:
{
"mcpServers": {
"opentakeoff": {
"command": "npx",
"args": ["-y", "opentakeoff-mcp"]
}
}
}
If you carry a GitHub identity, fork the repository as well: that's where an engine change you make gets tested—every pull request from a fork runs the full CI with a read-only token—and tested pull requests from agents merge under the same bar as anyone else's. The contributor path is the same one.
New here? Connect OpenTakeoff to your AI walks Claude Code, Codex, Cursor and Claude Desktop step by step and runs a first command on the demo plan.
Claude Code: claude mcp add opentakeoff -- npx -y opentakeoff-mcp. Claude Desktop users can
double-click the opentakeoff-mcp.mcpb bundle from the
latest release instead—it excludes the
optional native canvas on purpose, so every JSON tool works everywhere and the rendering
surfaces (view_sheet, the sheet-image resource) say exactly what's missing where they can't
run. Docker and a local clone are both supported: mcp/README.md.
A real run (3× speed): the agent takes off patient rooms 161–163 on a federal finish plan, exporting after each commit. Every shape lands in the app as a dashed pencil proposal and becomes ink only when the operator clicks Accept. The full run, live and uncut, is on YouTube (2:47).
The tools
| Group | Tools |
|---|---|
| Open and orient | load_plan · sheet_info · sheet_context · get_sheet_vectors · read_sheet_text · find_text · view_sheet |
| Scale | set_scale |
| Measure | one_click · detect_rooms · measure_polygon · cut_out · measure_line · measure_surface · place_count |
| Repeat and derive | symbol_sweep · sweep_schedule_row · derive_base · derive_transitions · apply_rules |
| Read the drawing set | sheet_graph · resolve_tag · find_schedule |
| Edit and audit | list_shapes · edit_shape · edit_condition · edit_materials · duplicate_condition · split_condition · delete_shape · undo_last |
| Mark and sign | annotate · list_annotations · link_annotation · mark_verdict · delete_verdict |
| Ask | create_rfi · list_rfis · resolve_rfi · delete_rfi |
| Hand off | takeoff_summary · export_takeoff · export_report · export_marked_pdf · export_dxf · import_takeoff |
Plus browsable sheet resources (takeoff://sheets) so an agent can see the working set, not
only act on it. Multi-document sessions are first-class: a bid set is plans plus schedule
plus addenda, and load_plan --merge adds a document without disturbing existing scales,
conditions, or shapes—the sheet graph then spans the whole set, so a room tag on one file
resolves to a schedule row in another. edit_condition reaches the waste %, the ×N multiplier,
and roll_setup, so an agent's takeoff doesn't ship with net === gross.
The agent's manual is docs/AGENT_GUIDE.md—the counterpart to the
estimator's: the operating model in six facts, the standard finish every takeoff ends with, the
withheld-is-the-answer doctrine, what has no agent verb and why, and a refusal-to-next-move table.
Tool-by-tool reference: mcp/README.md. The same surface in prose, with the
she
