# Reported issues for OpenTakeoff

Pod holds 17 of 20 problems reported by people outside the maintainer team. Issues filed by the project's own owners, members and collaborators are excluded entirely — a maintainer's release checklist is not a warning to a prospective user.

Back to [OpenTakeoff](/mcp/opentakeoff).

## Most discussed

### RFC: the sheet graph — resolve room tags, schedules, legends, and detail callouts across a plan set

## A single sheet never carries the answer

`A-201` says room `102 — OFFICE`. The finish schedule on `A-001` says `102 → CP-1 / RB-1`. The legend says `CP-1 = carpet tile 24×24`. Wall section `3/A-601` says the partition is `9'-0"`, which is what turns 128 linear feet of wall into a real `RB-1` base quantity.

OpenTakeoff gives an agent `read_sheet_text` — positioned text, one sheet at a time — and nothing else. Every agent that has driven this engine has re-derived the entire cross-reference st

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/87) · 2026-07-22 · closed · 8 comments

### RFC: read the PDF layer tree — Optional Content Groups as first-class geometry filters

## The heuristics exist to recover information the file already states

`classifyHatchSegs` in `web/src/lib/oneclick.ts` is a wall of tuned constants — `HATCH_MIN_RUN`, pitch-regularity bands, `SPAN_PROTECT_RATIO`, the filled-not-stroked poché exemption added after the VA plan drew its walls as solid shapes — and its entire job is to guess which segments are boundary and which are pattern.

A construction document exported from Revit, AutoCAD, or Archicad usually says so outright. PDF Optional C

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/85) · 2026-07-22 · closed · 4 comments

### MCP: a versioned computed-report export — opentakeoff.report.v1

Two downstream consumers have now built pricing tools on top of OpenTakeoff exports, and both hit the same gap: there is no first-class, versioned export of the *computed* takeoff — per-condition totals plus the materials buy list.

**What exists today**

- \`export_takeoff\` emits \`opentakeoff.takeoff_canvas.v1\` — the raw annotations payload, exactly what the app autosaves. Perfect for round-tripping into the canvas; wrong shape for a consumer that wants totals.
- \`takeoff_summary\` computes

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/132) · 2026-07-29 · closed · 1 comment

### MCP: waste is real math the agent can't reach — no tool sets a condition's waste_pct

## The gap

`takeoff_summary` emits `waste_pct` and waste-adjusted `*_net` order quantities per condition — net figures are a first-class output of the server. But no tool can set waste: conditions minted through `one_click` / `measure_polygon` / `measure_line` / `edit_materials` start at `waste_pct: 0` and nothing in the tool surface changes it (`grep -i waste mcp/src/tools.ts` matches only the `takeoff_summary` description). So for every agent-driven takeoff, net === gross.

Surfaced concretel

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/131) · 2026-07-29 · closed · 1 comment

### MCP: computed-report export — opentakeoff.report.v1 (totals + materials buy list), not just the raw canvas payload

## The gap

The MCP server has two ways to get numbers out of a session:

- `takeoff_summary` — per-condition quantities (floor/wall/border SF, LF, EA, SY, gross and `*_net`) plus grand totals. **By design it strips materials** for a compact quantities-only reply (`mcp/src/outputs.ts`, the `edit_materials` description).
- `export_takeoff` — the exact `opentakeoff.takeoff_canvas.v1` autosave payload. Materials appear here as **config rows** (`{name, per, basis, unit, round}`), not as computed ord

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/130) · 2026-07-29 · closed · 1 comment

### MCP: structured tracing on tool calls (opt-in, stderr)

An opt-in OPENTAKEOFF_MCP_TRACE=1 that logs one structured line per tool call to stderr (tool, duration, sheet, result size — never document content). Makes agent transcripts debuggable without corrupting the stdio wire. Design constraint: stdout is sacred (see mcp/bin.js).

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/28) · 2026-07-13 · closed · 1 comment

### Symbol tool: the canvas face for the sweep engine — marquee one device, count every placement

**The state of things**

`symbol_sweep` can take one marquee around a duplex receptacle and return every placement on the sheet — 0/90/180/270 and mirrored, near-matches withheld with reasons, and as of 0.9.43 a `complete` flag that refuses to let a truncated count read as a total (#261). The engine is `web/src/lib/symbolsweep.ts`, 546 lines, deterministic vector constellation matching with a 0.92 commit bar and a 0.75–0.92 withheld band, cross-sheet via the sheet graph's plan-role classificatio

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/264) · 2026-08-16 · closed · 0 comments

### MCP: correction rules — an imported rule an agent can re-run

The canvas turns an estimator's correction into a deterministic, re-runnable rule (#88): a deduct drawn fully inside a floor_area room becomes a rule, Preview stages the proposals, Apply commits one undoable batch.

Over the wire there is no verb. `import_takeoff` carries `rules: []` into a session faithfully — and then nothing can run them. An agent that receives a takeoff whose estimator taught it "every room like this loses the mechanical chase" cannot apply the lesson; it can only re-derive 

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/207) · 2026-08-04 · closed · 0 comments

## Most recent

### MCP: cut_out — a real hole, reconciled, the way the canvas cuts one

An estimator has Cut Outs (#137): draw a hole inside a parent shape and the engine subtracts it for real — N holes per parent, overlap never double-deducts, the report and legend read the reconciled number, and the whole thing is one undo step.

An agent has `role: "deduct"`. That commits an *independent* overlay shape: nothing links it to a parent, `accumulateRole` treats it as its own scope, and the marked set paints a decal rather than a hole. The two paths disagree about what a deduction *is

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/206) · 2026-08-04 · closed · 0 comments

### MCP: raster one_click for scanned sheets — wire the fallback the canvas already has

The canvas one-click falls back to a raster mask on scanned sheets (`web/src/lib/rastermask.ts`: Bradley adaptive threshold, vector-always-wins, `raster_traced` provenance). The MCP server refuses instead: 'This sheet has no vector linework… raster fallback not yet available in the MCP server.' The engine code exists and is pure; this is wiring, provenance passthrough, and a fixture. (Filed for completeness — vector-plan users never hit it, scanned-set users hit it immediately.)

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/154) · 2026-07-31 · closed · 0 comments

### MCP: one document per session — a bid set is plans + schedule + addenda, not one PDF

`load_plan` replaces the whole session, so `resolve_tag` can never chain a plan tag to a finish schedule that lives in a separate PDF — which is how bid sets actually arrive — and an addendum can't be reconciled against traced work. Needs a design pass: an additive `load_plan {merge: true}` (sheet keys already carry the file name, so the codec survives), a cross-file sheet graph, and a stated answer for what addendum replacement means for committed shapes.

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/152) · 2026-07-31 · closed · 0 comments

### MCP: import_takeoff — round-trip a saved takeoff into a session

`export_takeoff` is one-way. There is no way to resume yesterday's session, extend a takeoff a human already reviewed, or audit an existing `takeoff_canvas.v1` file. The web app already has the merge rules, pure and tested (`web/src/lib/importTakeoff.js`: operator's calibration/conditions/workspace win, machine shapes stay pencil, idempotent re-import). `import_takeoff {path}` should consume the same payload through the same rules — nothing new to invent, one implementation to share.

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/151) · 2026-07-31 · closed · 0 comments

### MCP: annotate lacks arrow and bubble — the two markup types flooring drawings use most

The canvas and the marked set draw arrows (plank/seam direction, north arrows) and bubbles (detail/keynote circles), but MCP `annotate` stops at cloud/text/callout/highlight. An agent reading 'ALIGN CPT TO WALL' off a finish plan cannot leave the direction arrow an estimator would. Extend `annotate` with `arrow {from, to}` and `bubble {at, r}` — the storage schema already round-trips them (`markup.type`), so this is schema + conversion at the tool boundary.

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/150) · 2026-07-31 · closed · 0 comments

### MCP: list_shapes — mid-session shape inventory

Shape ids exist only in the replies that committed them. An agent that lost its earlier context — or one auditing a session it didn't build — has to pull the entire `export_takeoff` payload inline to find one shape to `edit_shape` or `delete_shape`. A compact `list_shapes {sheet?, condition?}` (id, sheet, condition, role, quantities, reviewed state, agent_edits) is the inventory read every mutating tool already assumes you have.

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/149) · 2026-07-31 · closed · 0 comments

### MCP: derive_base — mint the base LF from committed rooms

The most mechanical derivation in Division 9: wall base LF = room perimeter minus door openings. Every committed `floor_area` shape already carries `perimeter_lf`; nothing turns it into a linear base condition. An agent (or a human on the canvas) re-traces every wall run by hand.

Sketch: `derive_base {source_condition, condition, openings?: [{shape_id, lf}]}` — for each floor shape of the source condition, commit a linear shape re-using its ring, `length = perimeter_lf − stated openings`, prove

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/148) · 2026-07-31 · closed · 0 comments

### MCP: roll goods are agent-invisible — no way to set roll_setup

The seam/cut layout engine (#136) triggers off `roll_setup` on a condition, and no MCP tool can set it. `opentakeoff.report.v1`'s `roll_goods` block is documented as 'always empty for a headless session today'. An agent can measure broadloom SF but can never figure seams, roll order LF, or roll count — the part of carpet estimating where the order actually gets written.

Proposal: `edit_condition` grows `roll_setup` (material class, roll width, max roll length, seam/wall allowances, run directio

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/147) · 2026-07-31 · closed · 0 comments

### MCP: the missing measure roles — surface_area (wall SF) and count (EA)

The engine, canvas, totals, and marked set all speak four quantity families — floor SF, wall/surface SF, linear LF, count EA — but the MCP tools only commit `floor_area`, `deduct`, and `linear`. An agent cannot take off wall tile, wainscot, or a resinous wall system, and cannot count thresholds, stair nosings, or floor boxes. The bundled VA demo plan specifies PT-1/PT-2 **walls** in every toilet room; the agent has no verb for them.

Canvas parity to hold:
- `surface_area` is an **open run** tra

[Read the thread](https://github.com/Kentucky-ai/opentakeoff/issues/146) · 2026-07-31 · closed · 0 comments

The remaining reports are on [the project's issue tracker](https://github.com/Kentucky-ai/opentakeoff/issues).
