measure-mcp
# measure-mcp
<!-- mcp-name: io.github.purahmanian/measure-mcp -->
**An AI tape measure.** An MCP server that turns iPhone LiDAR captures, depth maps, room scans and photos with a reference card into real-world measurements that Claude (or any MCP client) can use.
- **Kitchen:** "How much does this bowl hold?" Measure your own bowls and pans, then scale a recipe to fit them.
- **Rooms:** "Will this 84 inch sofa fit through the door and on that wall?" Works from RoomPlan, Polycam, Scaniverse and other LiDAR scan exports.
- **Amazon FBA:** size tier, dimensional weight, fee estimate, how close you are to the next tier, and what to shrink to drop one.
- **Moving and storage:** cubic feet and weight from an inventory or a room scan, then the truck, container or storage unit that fits.
Every number comes back with a ± and a confidence level, and the server says plainly when it is guessing.
## How it works
The AI never touches a sensor. Capture happens on the phone (the companion iOS app, a LiDAR scanner app, or the camera), and this server does the geometry on the files. It picks the best depth source available:
1. **Metric depth already in the file:** a 3D scan from a free LiDAR scanner app such as Scaniverse (OBJ or PLY, zipped is fine), an iPhone Pro capture bundle, a depth TIFF/PNG/NPZ, or a RoomPlan USDZ/JSON export.
2. **A depth model on a plain photo** (optional `[depth]` extra, Depth Anything V2 Small, Apache-2.0).
3. **A reference object in frame** (credit card, US letter or A4 sheet, quarter) to fix the scale.
A plain photo with none of these has no real scale. The tools say so instead of inventing a number.
## Install
```bash
pip install measure-mcp # core: all tools, no ML
pip install "measure-mcp[usd]" # + reading RoomPlan .usdz files
pip install "measure-mcp[depth]" # + depth model for plain photos (pulls in PyTorch)
```
Python 3.10 or newer. `uvx measure-mcp` works too.
### Claude Desktop
Add this to `claude_desktop_config.json` (Settings, Developer, Edit Config):
```json
{
"mcpServers": {
"measure": {
"command": "uvx",
"args": ["--from", "measure-mcp[usd]", "measure-mcp"]
}
}
}
```
### Claude Code
```bash
claude mcp add measure -- uvx --from "measure-mcp[usd]" measure-mcp
```
### Load only what you need
All 34 tool descriptions take about 19k tokens of context. Set `MEASURE_MCP_TOOLS` to the groups you want (the core `measure_*` tools always load):
| `MEASURE_MCP_TOOLS` | Tools | Context |
|---|---|---|
| (unset) | 34 | ~19k tokens |
| `kitchen` | 9 | ~4k tokens |
| `room` | 14 | ~6k tokens |
| `moving` | 15 | ~6k tokens |
| `fba` | 14 | ~8k tokens |
```json
"measure": {
"command": "uvx",
"args": ["--from", "measure-mcp", "measure-mcp"],
"env": { "MEASURE_MCP_TOOLS": "fba" }
}
```
Combine groups with commas, for example `kitchen,room`.
### Getting files to the server
Tools take **file paths on the machine running the server**. When you share a photo in chat, save it to `~/measure-mcp-inbox` (or AirDrop it to Downloads) and the AI finds it with `measure_find_files`. Files the tools write (floor plans, inventories) go to `~/measure-mcp-output`, or wherever `MEASURE_MCP_OUTPUT_DIR` points. Tools never write anywhere else.
## Try it
> Measure the bowl in `~/measure-mcp-inbox/bowl_capture.zip` and scale my brownie recipe to it: 1 cup butter, 2 cups sugar, 4 eggs, 1 1/4 cups flour. The original recipe is for a 9x13 pan.
> Here's my living room scan (`~/Downloads/living.usdz`). Will an 84 x 37 x 34 in sofa get through the door, and does it fit on the wall with the window?
> What FBA size tier is a 12 x 9 x 3 in box at 1.4 lb priced at $24, and how close is it to the next tier?
> I'm moving out of a 2 bedroom: queen bed, 3-seat sofa, dining table with 4 chairs, 2 dressers, 30 medium boxes. What truck and storage unit do I need?
## Tools (34)
| Group | Tools |
|---|---|
| Core | `measure_find_files`, `measure_depth_info`, `measure_open_capture`, `measure_object`, `measure_distance_between_points`, `measure_list_reference_objects` |
| Kitchen | `kitchen_measure_vessel`, `kitchen_vessel_from_dimensions`, `kitchen_scale_recipe` |
| Room | `room_load_scan`, `room_summary`, `room_list_walls`, `room_list_openings`, `room_list_objects`, `room_check_fit`, `room_check_doorway`, `room_floor_plan_svg` |
| Amazon FBA | `fba_analyze`, `fba_size_tier`, `fba_fee_estimate`, `fba_tier_headroom`, `fba_audit_listing`, `fba_draft_remeasure_request`, `fba_measure_package`, `fba_data_status` |
| Moving | `moving_estimate_from_inventory`, `moving_estimate_from_scan`, `moving_estimate_object`, `moving_cube_sheet_lookup`, `moving_recommend_truck`, `moving_recommend_container`, `moving_recommend_storage`, `moving_export_inventory`, `moving_data_info` |
Conventions shared by every tool: the input file is `path`, sizes are `dims` (`"12 x 9 x 3 in"`, a list, or a dict), weights are `weight` (`1.4` or `"1.4 lb"`), output units are `units` (`metric`, `imperial`, `both`), and errors come back as `{"error": {"code", "message", "hint"}}`. An argument a tool doesn't take is rejected with the closest valid name, never silently ignored.
## Accuracy
Measured on synthetic scenes with known answers and simulated iPhone LiDAR noise (256 x 192 depth, σ 5 mm). Real-world accuracy will be somewhat worse. Treat these as a ceiling, not a promise.
| What | Result |
|---|---|
| Bowls, pans and pots (12 vessels, 3 camera angles, 108 renders) | median capacity error 0.9%, 90th percentile 2.5%; the reported ± contained the truth in every render |
| Rim diameter | worst error 0.35 cm |
| Bowls from scanner-app meshes (OBJ/PLY, cm or m, Y-up or Z-up, holes, clutter) | median capacity error 0.7% on 16 random scans; the ± contained the truth every time |
| Boxes (single view, any rotation) | footprint within 0.5 cm across 240 camera views |
| Room walls from a LiDAR point cloud | mean 0.13 cm, worst 0.38 cm without drift; 3.5 cm worst with 2 cm drift |
| FBA tier risk flags | caught 100% of boxes whose tier was wrong because of measurement noise |
| Moving estimates (studio to 3 bedroom) | all within published industry ranges |
Known limits:
- **Steep camera angles hide the bottom of deep pots.** At 30° the tools report low confidence and a wide ±.
- **Shallow pans (1 inch deep) come back as low confidence.**
- **A guessed camera lens widens the error bars.** For depth files without camera intrinsics the tools say "field of view unknown" and cap confidence at low.
- **Portrait-mode photos carry relative depth only.** iPhone Portrait mode depth is not a real-world distance, so it needs a reference object.
- **Room accuracy figures are synthetic.** Scanner drift on real phones is the biggest unknown, and real-scan validation is on the roadmap.
## Data and estimates
- **FBA:** size tiers and fee tables live in a versioned data file with an as-of date and sources. Several 2026 figures come from secondary sources and are flagged unverified; `fba_data_status` lists every gap. These are estimates. Amazon's own measurement and fee schedule govern.
- **Moving:** the cube sheet, truck capacities, containers and storage units come from published sources, each row marked verified or not. There are no prices in the data.
## Companion iOS app (in progress)
`ios/` holds the source for a small capture app. One tap saves an iPhone Pro LiDAR depth map, photo and camera calibration as a zip bundle that `measure_open_capture` reads, and it exposes App Intents ("Measure object") to Siri and Shortcuts. It has not been compiled or run on a device yet. See `ios/README.md`.
## HTTP mode
```bash
measure-mcp --transport streamable-http # 127.0.0.1:8765, local only
MEASURE_MCP_TOKEN=... measure-mcp --transport streamable-http --host 0.0.0.0
```
The server reads files on its host, so any non-loopback address requires a bearer token.
## Development
```bash
git clone https://github.com/purahmanian/measure-mcp && cd measure-mcp
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev,usd]"
python -m pytest -q # about 1,300 tests, no network
python -m ruff check .
PYTHONPATH=src:. python bench/kitchen_bench.py --quick
```
Design notes for each feature are in `designs/`.
## License
MIT, Puya Ventures LLC. Depth Anything V2 Small (optional extra) is Apache-2.0.
## Built by
Puya Rahmanian. Need an MCP server or an AI integration built for your product? [puyarahmanian.com](https://puyarahmanian.com)
TDQS
Scored across 34 tools
Domains are cleanly separated by prefix (measure/kitchen/room/fba/moving) and most tools target a distinct input or resource. The main overlap is the FBA cluster, where fba_analyze is explicitly the one-call version of fba_size_tier/fba_fee_estimate/fba_tier_headroom; the descriptions admit this and guide tool selection, which keeps ambiguity manageable rather than confusing.
Strong, predictable domain-prefix + verb_noun convention (measure_object, room_list_walls, kitchen_scale_recipe, moving_estimate_from_inventory, fba_size_tier). A few bare-noun outliers (room_summary, fba_data_status, moving_data_info) and info/analyze names deviate slightly, but overall the pattern is readable and consistent.
34 tools is heavy for a single server and sits above the comfortable 3-15 range. It is partly justified because five genuinely distinct domains (measurement, kitchen, room, FBA, moving) are bundled, but the redundant FBA tier/fee/headroom-versus-analyze cluster suggests some bloat rather than each tool earning a unique slot.
Every domain has full lifecycle coverage: measurement (info, object, distance, references, capture, file discovery), kitchen (measure/from-dims/scale), room (load, summary, walls, openings, objects, fit, doorway, floor plan), FBA (analyze, tier, fee, headroom, package measure, audit, remeasure draft, data status), and moving (lookup, three estimators, truck/container/storage, export, data info). No obvious dead ends.