the agent-first IFC parser

Open any IFC.
Ask any question.

Fast native IFC parsing for AI agents, RPA, and analytics pipelines. 20–30× faster than ifcopenshell.open. Spatial-relationship graph built in. Self-describing. MCP-compatible.

$ pip install ifcfast$ python -c "import ifcfast; ifcfast.open(ifcfast.example_path()).summary()"
python
What you get

Built for the workflow,
not the file format.

Parse

Tier-1 in milliseconds

Rust core + memchr-accelerated tokenizer. 905 ms cold on an 834 MB / 14.3M-record MEP IFC. Byte-level parity vs ifcopenshell on 234K products from 5 authoring tools.

Graph

Spatial relationships built in

m.contained_in / .aggregates / .storey_building DataFrames + seven traversal helpers. m.ancestors(wall_guid) walks storey → building → site → project in a single call.

Diff

Model versions, compared

m.diff(other) returns added / removed / changed products, type cardinality deltas, storey elevation changes — JSON-friendly. "What changed since v3?" is a one-liner.

Types

Type-first extraction

m.type_summary() emits one record per IFC entity with counts, storeys, predefined types, and sample GUIDs. Matches the abstraction your TypeBank already speaks.

Cache

Hot reload in tens of milliseconds

Parquet cache keyed on file hash. Second open of a 200 MB IFC returns in 30 ms. Edit the file, cache invalidates. No bookkeeping.

Agents

MCP server, drop-in

ifcfast-mcp speaks the Model Context Protocol. Claude Desktop, Cursor, ChatGPT-via-MCP — point at the server, get 18 tools and a guide resource. Zero glue code.

Same model. Three lenses.

One parse,
everything you need.

A public-license IFC opened with ifcfast.open(path) — rendered geometry from ifcfast-mesh, a QTO rollup from m.type_summary(), and the spatial hierarchy from m.aggregates + m.contained_in. All from a single 1.5 MB Python wheel.

ifcfast-mesh → glTF
3D viewer
loading...
loading...

Source IFC: buildingSMART community sample — Duplex Apartment (CC BY 4.0).

Benchmarks

An order of magnitude.
Sometimes two.

Warm-cache reads finish in tens of milliseconds. Cold parse on an 834 MB MEP IFC is 905 ms. The same file OOMs ifcopenshell.open on an 8 GB box.

20–30×
speedup
19 ms
hot reload
234K
audit corpus
cold parse, best of 5

ifcfast vs ifcopenshell.open

Small ARK model22 MB · 8.8K products
34× faster
ifcopenshell
1.0 s
ifcfast
29 ms
Federated mid-size187 MB · 21K products
51× faster
ifcopenshell
7.8 s
ifcfast
152 ms
Large MEP834 MB · 87K · 14.3M records
33× faster
ifcopenshell
30.0 s
ifcfast
905 ms
Byte-level parity vs ifcopenshell across 234,144 products from 5 authoring tools. ST28_RIV (834 MB) opens in <1 GB resident — the same file OOMs ifcopenshell.open() on an 8 GB box.
For agents

Plug into Claude.
Or Cursor. Or anything MCP.

ifcfast-mcp exposes the full parse + spatial-graph + diff surface as Model Context Protocol tools. Add one line to your MCP client config and your agent can drive IFCs directly — without you writing any glue code.

Paste ifcfast.system_prompt() into the system prompt for instant ramp-up.
1
Install
pip install 'ifcfast[mcp]'
2
Add to Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json (macOS) %APPDATA%/Claude/claude_desktop_config.json (Windows)

{
  "mcpServers": {
    "ifcfast": {
      "command": "ifcfast-mcp"
    }
  }
}
3
Restart the client

ifcfast appears as 18 tools + ifcfast://agents-guide resource. Your agent can now open IFCs, walk the spatial graph, run drift, and extract type catalogues — without any glue code.

The API

Pandas out. No kernel.

Everything is a long-format DataFrame or a JSON-friendly dict. Filter, join, dump to Excel. No ifcopenshell.open() on the hot path; ifcopenshell is an optional dev dep used only for cross-checking parity in tests.

Data layers
import ifcfast

m = ifcfast.open("model.ifc")

# Long-format pandas tables, lazy.
m.psets             # property sets
m.quantities        # base quantities
m.materials         # IfcMaterial / IfcMaterialLayerSet
m.classifications   # NS 3451 / Uniformat / OmniClass
Spatial graph
# Spatial-relationship graph
m.contained_in       # product → storey edges
m.aggregates         # child → parent edges
m.storey_building    # storey → building edges

# Traversal helpers
m.parent(g);   m.children(g)
m.ancestors(g);   m.descendants(g)
m.storey_of(g);   m.building_of(g)
m.products_in(parent_g)
Drift
# What changed between v1 and v2?
delta = m1.diff("model_v2.ifc")

delta["products"]
# {'added_count': 47, 'removed_count': 12,
#  'changed_count': 8, 'added': [...], ...}

delta["type_deltas"]["IfcWall"]
# {'left': 142, 'right': 148, 'delta': 6}