# Opentakeoff

> Open-source (Apache-2.0) PDF takeoff for construction & flooring — the first engine an AI agent drives natively over MCP, not bolted on. One-click room detection, materials + quantities, built for preconstruction. Runs entirely in your browser.

- **Type:** MCP server
- **Install:** `agentstack add mcp-kentucky-ai-opentakeoff`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Kentucky-ai](https://agentstack.voostack.com/s/kentucky-ai)
- **Installs:** 0
- **Category:** [Web & Browser](https://agentstack.voostack.com/c/web-and-browser)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [Kentucky-ai](https://github.com/Kentucky-ai)
- **Source:** https://github.com/Kentucky-ai/opentakeoff
- **Website:** https://opentakeoff.netlify.app

## Install

```sh
agentstack add mcp-kentucky-ai-opentakeoff
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# OpenTakeoff

**The first takeoff canvas built for people _and_ AI agents.**

Open a building plan and measure it — trace the rooms yourself, or point an AI agent at the
**same engine**. Every measurement carries its **scale** and **how it was made**. Free,
open-source, and it runs in your browser — no account, no upload, no install.

[](LICENSE)
[](https://opentakeoff.netlify.app)
[](#tech-stack)
[](https://github.com/sponsors/Kentucky-ai)

[**▶ Try the live demo**](https://opentakeoff.netlify.app) · [Quick start](#quick-start) · [Features](#features) · [For AI agents](mcp/) · [Deploy it](#run-it--deploy-it) · [Own your data](#own-your-data--the-capture-layer) · [Build on top](#build-on-top-of-it) · [Contributing](CONTRIBUTING.md)

**New — July 2026:** **MCP server** — your AI agent can drive the takeoff engine (`npx opentakeoff-mcp`, on the [official MCP registry](mcp/)) — and **browse the plan set natively**: sheets, title-block text, and rendered pages as [MCP resources](mcp/#resources--browse-before-you-measure) (v0.2.0) · **Voice takeoff** — hold M and say `carpet one, waste seven` (or type it in the Command box); speech is recognized on-device in the browser — audio never leaves your machine ([RFC #59](https://github.com/Kentucky-ai/opentakeoff/issues/59), [docs/VOICE.md](docs/VOICE.md)) · **Provenance** — every shape records how it was measured (its scale, one-click or hand-drawn, and person or agent) · One-Click Area traces **hatched rooms** and **scanned plans** · **Marked Set PDF export** — [full changelog](CHANGELOG.md)

---

OpenTakeoff is a free, open-source canvas for measuring quantities off a building plan — a **takeoff**. What makes it different is who can run it: a person **or** an AI agent, on the **same engine**. You click inside a room and it traces itself; an agent calls the same tool over [MCP](mcp/) and gets the same number. And every measurement records **how it was made** — its scale, whether it was one-click or hand-drawn, and whether a person or an agent made it. The proof travels with the number.

That makes OpenTakeoff the first place an AI agent can measure a real building the way an estimator does — and it's still a genuinely great tool for the person at the canvas.

Until now there has been **no open-source, web-based takeoff canvas at all** — let alone one built for flooring. OpenTakeoff is that tool: a free, open-source alternative, given to the trade.

It started as the takeoff module of a private flooring estimating app, then got carved out, cleaned up, and released. **This is the real measuring engine, not a demo** — including **One-Click Area**, the flood-fill room tracer the $300/mo tools gate behind a subscription.

**Built for flooring, useful for any takeoff.** The measuring engine is general — area, linear, count, and deduct work on anything you'd scale off a plan (drywall, paint, concrete, sitework). What makes it *flooring's* tool is the finish-aware layer on top: conditions with CAD hatches, per-condition waste %, square-yard output, and a coverage-rate **materials buy list** nobody else hands the trade for free.

And there's nothing to set up. Open the page, drag in a plan, start measuring. Your PDFs, your takeoffs — and your voice, if you use dictation — never leave your machine: there is no server in the loop.

## Quick start

You don't need to install anything to *use* it — just open the [**live demo**](https://opentakeoff.netlify.app), drag in a plan, and go.

To run it yourself:

```bash
cd web
npm install
npm run dev        # http://localhost:5173
```

Drag **`demo/sample-plan.pdf`** onto the canvas. The scale auto-detects; pick a condition, hit **One-Click Area**, and click inside a room. Open **Report** to see the breakdown and export CSV / JSON.

## Features

### 1. Open anything, instantly
Drag in a plan **PDF**, an **image** (a scan or a screenshot), or a whole **`.zip` plan set** straight off a bid platform. Zips are unpacked and images wrapped to PDF *in your browser* — multi-page and multi-sheet, with up to **4 sheets side-by-side**. No upload step, no conversion service, no account.

### 2. A real measuring engine — not a counter with a ruler
**One-Click Area** is the headline: click inside a room and the linework bounds it, the polygon traces itself, and the vertices snap to true corners. It reads the drawing the way an estimator does — **hatching and poché don't fool it**: tile grids, plank lines, and section fills are classified as pattern, not wall, so a click inside a fully hatched room still traces the room (and a misread can never make the result worse than the strict fill — it escalates only when the strict pass comes back trapped). **Scanned plans work too**: when a sheet is a scan (no vector linework), the engine reads the rendered pixels instead — adaptive thresholding with a gap-bridging pass — and the same flood/trace machinery runs on the scan ink; the result is badged so you verify the edges before Create. Plus the full manual kit — **Area, Rectangle, Linear, Surface-Area (walls), Count,** and **Deduct** (for columns, voids, and openings). This is the same engine pulled out of a commercial estimating app, not a toy reimplementation.

Manual tracing gets a real drafting aid: **45°/90° angle lock**. Come within a few degrees of square or diagonal and the segment you're drawing locks onto the axis — the click commits the locked point, so walls come out dead square (hold **⇧** to force the lock at any angle). On the canvas the crosshair **is** the cursor: the OS pointer hides, a star marks the crossing, and in-progress work draws in the instrument's own cobalt (committed shapes wear their condition color). The lock reads quietly — the star swells, the preview thickens, and a chip by the cursor shows the locked angle plus the **live segment length**. No extra chrome on your sheet.

### 3. Scale that matches real plan sets
Auto-detects the drawn scale note off the sheet, or **calibrate** from any known dimension (click two points, type the real length). Scale is remembered **per sheet** — because plan sets are never one uniform scale, and tools that assume they are get the numbers wrong.

### 4. Conditions that read like the drawing
A condition is one finish (LVP, carpet, tile, base, …). Each carries a **line/fill color** and a **CAD hatch pattern** (plank, herringbone, tile, terrazzo) so the canvas looks like the real drawing — plus a per-condition **waste %**, an **×N multiplier** for repeated identical units, a default **height** for wall traces, and a **thickness** that turns a linear run into border/feature-strip SF.

### 5. Supporting Materials — labor, subfloor, and the consumables, done right
Per condition: a free-text **labor type** (glue-down, float, nail-down, …) and **subfloor type** (ply, concrete slab, OSB, …), plus the consumables that actually go on the order — adhesive, sealer, polyurethane, thinset, grout, cove-base adhesive. Each material has a **coverage rate** and a **basis** (floor SF / linear LF / each), and the order quantity derives automatically — measured ÷ coverage, **rounded up** to whole units. Adhesive and mortar lines get **coverage presets** (trowel notches, rollers) that fill the spread rate, and grout lines get a **calculator** that derives SF/bag from tile size, thickness, joint width, and bag weight. This is the layer most takeoff tools punt on. It's shipped here.

### 6. Reports & export
A per-condition breakdown — **Floor / Wall / Border SF, LF, EA, total SF, SY**, with and without waste — plus a combined **materials buy list**. Export to **CSV**, **JSON**, or a real **Excel workbook** (Summary, By-sheet, Materials, and Shapes-audit tabs — full-precision cells, formula-shaped names stay inert text), or print it. Waste is applied only in the report (the order quantity), never to the live measured number, so your takeoff and your buy list stay honest about which is which.

And when the numbers need to leave the app: **Marked Set PDF**. One click builds a distribution-ready PDF entirely in your browser — every sheet with the work burned in as drawn (condition colors, hatches, quantity chips, count markers, markups) behind a legend cover with the full totals and a by-sheet breakdown. Send it to a GC who will never install anything.

When the addendum lands: **Revisions**. Save the takeoff as a named revision at each bid revision, then compare any two — or a revision against the live takeoff — as **quantity deltas** per condition, per sheet, and on the buy list, with a compare CSV. Restore auto-banks the live takeoff first, so it's never a one-way door.

### 7. A vector-sharp canvas + plan-set tools
Zoom in and the linework stays **razor-sharp**: past ~1.15× zoom **times your display's pixel ratio** (so it kicks in sooner on a 2×/Retina screen than a 1× monitor) the visible region re-renders straight from the PDF vectors at your current zoom — Bluebeam/AutoCAD-style — instead of magnifying a fixed bitmap, so fine callouts and hatching never blur. It engages after a brief pause in scrolling/pinching rather than on every frame, so a continuous zoom stays on the fast base layer until you stop moving. It overlays just what's on screen, so there's no giant full-sheet bitmap to hold. Plus a **dark view** (☾) that inverts the sheet itself — a true negative print, white linework on black, not a CSS filter — with hatches retuned so takeoffs read as well at night as they do at noon. And a visual **gallery** (`G`) to pick and open sheets, **Regroup** to restore a side-by-side composition in one click, per-sheet **Hi-Res** base rendering, **Snap** (beta) to plan lines and corners, and a separate **markup layer** (revision clouds, callouts, text notes) that's never counted in the totals.

### 8. Yours, locally
Every drawing, scale, condition, and markup autosaves to **your browser** (IndexedDB + localStorage). Nothing is uploaded, there's no account, and there's no server in the default build. Host the static build yourself and it stays exactly that way.

### Optional: team cloud mode (Google sign-in + Drive)

Everything above is the default, and it's unchanged: open the page and you're an
anonymous, local-only user — no account, no upload, nothing to configure. A team
on Google Workspace can *optionally* sign in to unlock a shared mode instead:
projects live as folders in the team's own Google **Drive**, the project list is
deep-linked from your existing **Glide** app, and material costs come from a
synced `pricing.json`. It's strictly additive — turn it off (set nothing) and the
app is exactly the local tool it always was. The security posture stays honest:
still a plain static site, **no secrets in the bundle**, team-only because the
Google OAuth app is **Internal** to your domain, and your data sits in **your own
Drive**. To set it up, see [`docs/GOOGLE_SETUP.md`](docs/GOOGLE_SETUP.md) and
[`docs/GLIDE_INTEGRATION.md`](docs/GLIDE_INTEGRATION.md). A cloud deployment can
also opt into **local-first sync** (`VITE_CLOUD_SYNC=1`): annotations stay canonical
in the browser and sync to Drive in the background, so the canvas is instant and
survives a flaky network — see [`docs/SYNC_ARCHITECTURE.md`](docs/SYNC_ARCHITECTURE.md).
## What's in the box

| Area | What you get |
|---|---|
| **Ingest** | PDF, image, or `.zip` plan set — unpacked in-browser, multi-page, up to 4 sheets side-by-side |
| **Scale** | Auto-detect the drawn scale note, or calibrate from a known dimension — per sheet |
| **Measure** | One-Click Area (flood-fill), Area, Rectangle, Linear, Surface-Area (walls), Count, Eraser (deduct), Zone check (per-region breakdown) — imperial or metric (m²/m, 1:50-style scales) |
| **Drawing aids** | 45°/90° angle lock with ⇧ hard-lock, live angle + segment-length readout at the cursor, endpoint Snap (beta) |
| **Conditions** | Color + CAD hatch per finish, waste %, ×N multiplier, height, thickness → border SF |
| **Supporting Materials** | Per-condition labor type + subfloor type (free text), plus supporting materials with coverage rates → rounded order quantities, per-material coverage presets + grout calculator |
| **Report** | Per-condition Floor/Wall/Border SF, LF, EA, SY, with/without waste + materials buy list |
| **Export** | CSV, JSON, **Excel (.xlsx)**, print, **Marked Set PDF** (sheets + burned-in takeoff + legend cover, built in-browser) |
| **Revisions** | Save the takeoff at each bid revision, compare what moved — quantity deltas per condition, per sheet, and on the buy list; guarded restore |
| **Markups** | Revision clouds, callouts, text notes — separate layer, never counted |
| **View** | Light or **dark (negative print)** — sheet pixels inverted at draw time, persists per browser |
| **Storage** | IndexedDB + localStorage — client-only, nothing uploaded |
| **Capture (opt-in)** | Bundled [capture server](capture/README.md) banks each contributed takeoff as (geometry → label) training rows — a corpus you own, mirrorable to a synced company share |
| **MCP server** | The engine on stdio for your MCP client — load a plan, set the scale, one-click rooms, export the takeoff ([`mcp/`](mcp/README.md)) |
| **Provenance** | Every shape records how it was measured — its scale, one-click or hand-drawn, and whether a person or an agent made it |
| **Deploy** | One static build, hostable on Netlify, Vercel, GitHub Pages, S3, or any static host |

## Run it / deploy it

**To use it, all you need is a browser.** To self-host, it's one static build you can drop anywhere — there's no backend, no database, no environment to stand up.

```bash
cd web
npm install
npm run build      # → web/dist/  (static; host it anywhere)
```

[](https://app.netlify.com/start/deploy?repository=https://github.com/Kentucky-ai/opentakeoff)

The repo ships a root `netlify.toml`, so the button above is genuinely one-click. The same `web/dist/` works on **Vercel, GitHub Pages, Cloudflare Pages, S3** — anywhere that serves static files.

## Own your data — the capture layer

Here's the part of a takeoff nobody talks about: every one you finish is a set of expert decisions — *this* region gets *this* finish, at *this* waste %, yielding *these* quantities. Done once, that's a bid. Banked every time, it's a **labeled dataset nobody else has** — the exact raw material for training a takeoff model on your trade and your market. Today that data evaporates the moment the bid goes out. It doesn't have to.

OpenTakeoff ships an optional **capture layer** so you can keep it:

- The **Contribute** button in the Report builds a derived-only payload — condition labels, shape roles, quantities, normalized geometry, and per-shape provenance (hand-traced vs. machine-proposed, and whether a human corrected it). Never the PDF, file names, project/client names, markups, absolute coordinates, or scale values. The builder is ~150 audited lines: [`web/src/lib/contribute.js`](web/src/lib/contribute.js); the normative wire contract is [`docs/CONTRIBUTION_SPEC.md`](docs/CONTRIBUTION_SPEC.md).
- The bundled **capture server** ([`capture/`](capture/README.md)) — one stdlib-only Python file, no pip install — receives it on localhost and banks one training row per labeled shape, hash-gated so re-contributions never duplicate. v2 rows distinguish what the machine got right from what an expert had to fix — the exact signal a takeoff model trains on. Point it at a synced folder with `--mirror` and the corpus rides your existing OneDrive/SharePoint/Dropbox sync into company storage, atomically, ready to train on.

```bash
python3 capture/capture_server.py    # then, in the app's browser console:
# localStorage.opentakeoff_contribute_endpoint = "http://localhost:8787/contribute"
```

Run OpenTakeoff as-is and none of this exists for you — nothing is captured, nothing leaves your machine. Install it and every takeoff you *choose* to contribute compounds into an asset you own. This is the open edition of the capture layer inside [Spline](https://spline.quisut

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Kentucky-ai](https://github.com/Kentucky-ai)
- **Source:** [Kentucky-ai/opentakeoff](https://github.com/Kentucky-ai/opentakeoff)
- **License:** Apache-2.0
- **Homepage:** https://opentakeoff.netlify.app

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-kentucky-ai-opentakeoff
- Seller: https://agentstack.voostack.com/s/kentucky-ai
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
