# 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](docs/PHASE_1_TESTING.md).
[](LICENSE)
[](https://opentakeoff.kentucky-ai.com)
[](https://registry.modelcontextprotocol.io)
[](https://www.npmjs.com/package/opentakeoff-mcp)
[](https://union.kentucky-ai.com)
[](https://openarena.to/en/projects/cmsgykvsq0000mkuv7byhlgnl)
[](https://github.com/sponsors/Kentucky-ai)
[**For agents**](#for-agents--start-here) · [**Try the canvas**](https://opentakeoff.kentucky-ai.com) · [The engine's contract](#the-contract-that-makes-it-drivable) · [For the person at the canvas](#for-the-person-at-the-canvas) · [The data layer](#the-data-layer--why-this-engine-exists) · [Research](#the-research-program) · [Fork it](#fork-it) · [Contribute](#contributing)
**The two manuals:** [agent manual](docs/AGENT_GUIDE.md) · [user manual](docs/USER_GUIDE.md)
**Protocol work:** [Takeoff Protocol draft and compatibility status](docs/TAKEOFF_PROTOCOL.md)—formalizing existing records; current takeoff behavior is unchanged.
**Read this in:** [日本語](README.ja.md) · [한국어](README.ko.md) · [简体中文](README.zh-Hans.md)
**Watch it:** [an autonomous agent runs a takeoff, live, no cuts (2:47)](https://youtu.be/e--kXxSGv7Y) · [hospital finish plan → report in about a minute (1:14)](https://youtu.be/cNDpPkTLY1k) · [canvas walkthrough (1:10)](https://youtu.be/aHiW8H2TSBs) · [One-Click Area (0:51)](https://youtu.be/YIjWZ-BAhLE)
> **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 (`O` reports the gate) and the `one_click` / `detect_rooms` MCP verbs are **not registered** (a default build ships 58 tools). Trace rooms with **Area** (`A`) in the canvas and `measure_polygon` over MCP; every other tool, sweep and derivation is unchanged. A build lifts the gate with `VITE_ONE_CLICK=1` (canvas) / `OPENTAKEOFF_ONE_CLICK=1` (server). Sections and videos below that show One-Click describe the engine as it returns — see [`docs/design/ONE_CLICK_GATE.md`](docs/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](docs/design/PERSONAL_WORKSPACE.md).
Sheet navigation releases closed PDFs and embedded fonts from the tile workers;
see the [30-flip rendering check](docs/review/508/README.md).
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](docs/review/302-doc-lru/README.md).
## Start here
| You are | Go here |
|---|---|
| **An estimator with a bid due** | [Open the canvas](https://opentakeoff.kentucky-ai.com)—drag in a plan, no account, nothing uploads. The [**user manual**](docs/USER_GUIDE.md) gets you from a blank tab to an exported takeoff in five minutes, and its [working order](docs/USER_GUIDE.md#the-working-order-on-a-real-bid) 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**](docs/AGENT_GUIDE.md): 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`](mcp/README.md). |
| **A developer building on the engine** | [`AGENTS.md`](AGENTS.md) is the repo map and the ship discipline; [`FEATURES.md`](FEATURES.md) maps every capability to the code that does it. |
| **A crew that wants its own copy** | [**Fork it**](#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` / `Shift` on Windows and Linux, `⌘` / `⌥` / `⇧` on a Mac — and the handlers have
always treated `⌘` and `Ctrl` as the same key. Press `?` in the canvas for the current list.
- **The MCP server is tested on Windows.** `npx -y opentakeoff-mcp` runs on Windows, macOS and
Linux, and CI runs the full MCP suite — typecheck, tests, build and the packaged smoke test — on
`windows-latest` as well as `ubuntu-latest` on every change.
- **Optional extras.** The bundled [capture server](capture/) is stdlib Python 3 and runs anywhere
Python does — on Windows invoke it with `python capture\capture_server.py selftest` (or the `py`
launcher) rather than `python3`. Neither it nor the optional [`server/`](server/) AI sandbox is
needed to use the canvas.
- **Locked-down enterprise fleets** (MSIX packaging, Windows Sandbox, Intune silent deploy) are
tracked in [#226](https://github.com/Kentucky-ai/opentakeoff/issues/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](https://registry.modelcontextprotocol.io). 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](#the-data-layer--why-this-engine-exists).
## 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 the `measure_polygon` description.
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](https://github.com/Kentucky-ai/opentakeoff/pull/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](https://github.com/Kentucky-ai/opentakeoff/pull/421),
[#422](https://github.com/Kentucky-ai/opentakeoff/pull/422),
[`evals/mcp-workflow-bench/plan-set/`](evals/mcp-workflow-bench/plan-set/README.md))
- **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](docs/USER_GUIDE.md#reviewing-an-agents-takeoff-start-to-finish)
([#424](https://github.com/Kentucky-ai/opentakeoff/pull/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](https://github.com/Kentucky-ai/opentakeoff/pull/406)–[#419](https://github.com/Kentucky-ai/opentakeoff/pull/419),
[roadmap](docs/ROADMAP.md))
- **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](https://github.com/Kentucky-ai/opentakeoff/issues/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](https://github.com/Kentucky-ai/opentakeoff/issues/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](https://github.com/Kentucky-ai/opentakeoff/issues/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](https://github.com/Kentucky-ai/opentakeoff/issues/136))
- **Transitions, at the canvas**—**⟂ Transitions…** in the Takeoffs panel derives the line where
two finishes meet from rooms you already measured; `derive_transitions` does 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](https://github.com/Kentucky-ai/opentakeoff/issues/202))
- **`symbol_sweep`**—every instance of a repeated symbol from one marqueed example, crossing
scales only by a *stated* ratio, never a searched one
- **`mark_verdict` / `delete_verdict`**—an agent signs its own work as a graphite `AGENT`
diamond; only a human hand mints the green `APPROVED` seal
- **One-Click accuracy wave**—face extraction and gap tolerance from
[RFC #60](https://github.com/Kentucky-ai/opentakeoff/issues/60) (contributed by
[@knmurphy](https://github.com/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=1` builds it back)—hold `M` and say `carpet one, waste seven`; recognition is
whisper-tiny.en in WebAssembly on your machine, audio never leaves the browser
([docs/VOICE.md](docs/VOICE.md))
Full history: [CHANGELOG.md](CHANGELOG.md) · every capability mapped to its code:
[FEATURES.md](FEATURES.md)
---
## For agents — start here
Point any stdio MCP client at the published package. Node 20+, no clone, no build:
```json
{
"mcpServers": {
"opentakeoff": {
"command": "npx",
"args": ["-y", "opentakeoff-mcp"]
}
}
}
```
If you carry a GitHub identity, [fork the repository](https://github.com/Kentucky-ai/opentakeoff/fork)
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](#fork-it) is the same one.
**New here? [Connect OpenTakeoff to your AI](docs/CONNECT.md)** 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](https://github.com/Kentucky-ai/opentakeoff/releases) 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`](mcp/README.md).