Skip to main content
Glama
bimq

bimq

by aec-platform

bimq

A read-only BIM query server for agents. Point it at an IFC or gbXML model and it answers structured questions — fire-rated doors on level 3, elements with no material assigned, spaces below the minimum daylight area — bounded by a policy file, with deterministic results and a citation back to the GlobalId and source line behind every row.

Zero dependencies. Python 3.11+. MCP server over stdio, plus a CLI that answers the same questions so you can check a policy before you trust an agent to it.

bimq query elements_by_property model.ifc \
    type=IfcDoor storey="Level 3" property=FireRating op=exists
id                      type     name      tag   storey_name  source          match
----------------------  -------  --------  ----  -----------  --------------  -------------------------------
0XBbD$nZDLuRru91_CQ_xe  IfcDoor  Door-302  D302  Level 3      office.ifc:314  Pset_DoorCommon.FireRating=EI60
31kamnSrrNbf3eF0_vhXrJ  IfcDoor  Door-301  D301  Level 3      office.ifc:304  Pset_DoorCommon.FireRating=EI60

2 row(s)
digest: sha256:06321f331735417dd149d649b8e26de71a63ff2bb26a31c38cbf66a4f0314b77

Then check it, because a citation you cannot follow is just a confident-looking string:

bimq cite model.ifc 31kamnSrrNbf3eF0_vhXrJ
31kamnSrrNbf3eF0_vhXrJ  (IfcGloballyUniqueId)
office.ifc:304  #297

#297= IFCDOOR('31kamnSrrNbf3eF0_vhXrJ',#5,'Door-301',$,$,$,$,'D301',2100.0,900.0,.DOOR.,.SINGLE_SWING_LEFT.,$);

Why

The current instinct is to dump IFC text into a context window. That fails immediately at real model sizes, and it fails quietly: a 300 MB model is roughly 95% geometry, so what fits in the window is a truncated arbitrary slice, and the model answers from it anyway. The failure looks like a fluent paragraph about a door that does not exist.

bimq inverts it. The model stays on disk. Queries are structured, the answers are small, and every row carries the id and line it came from — so a claim can be checked against the file instead of trusted.

Three properties hold for every answer:

Bounded. A TOML policy file says what is readable — which files, which queries, which types, which storeys, which properties. The engine reduces the model to the visible set before the query runs, so a query primitive cannot reach what the policy hides even by accident.

Deterministic. Same model, same query, same bytes. Every answer carries a digest you can pin in a test. Element order, group order and float rounding are all fixed; the read block size and the file's name do not change a finding.

Cited. Every row carries {id, id_kind, source, ref, line}. bimq cite resolves it back to the original statement. The test-suite re-reads the recorded line for every element of every fixture and fails if the id is not there.

Related MCP server: artagon-vault-mcp

Install

pip install bimq

Or run it from a clone with no install at all — there is nothing to build:

python -m bimq describe tests/fixtures/office.ifc

Use it as an MCP server

{
  "mcpServers": {
    "bimq": {
      "command": "bimq",
      "args": ["serve", "/srv/bim/tower.ifc", "-p", "/srv/bim/policy.toml"]
    }
  }
}

Every query primitive becomes a bim_* tool, all annotated readOnlyHint, plus bim_cite. Omit the model path to let each call name its own file — then allow_sources is what stands between a path argument and your filesystem.

The server tells the agent how to behave on initialize: call bim_model_summary first, quote a GlobalId for anything you assert, treat truncated as "there are more", and read notes — because no results and no data recorded are different findings and only the notes distinguish them.

A policy refusal comes back as a successful tool result carrying policy_denied and the rule that fired, not as a protocol error. An agent that receives a protocol error retries; an agent told "this policy does not expose costs" reports the limit and moves on.

Query primitives

Primitive

Answers

model_summary

schema, units, storeys, entity types, property-set names

spatial_tree

project → site → building → storey → space

elements_by_type

elements of a type, subtypes included

elements_by_property

property comparison; the fire-door workhorse

elements_missing_property

data completeness: who has no value for this field

elements_missing_material

no material through any of IFC's five ways of saying so

spaces_by_area

rooms inside an area range, always in m²

property_values

distinct values with counts — run this before guessing names

quantity_rollup

totals grouped by type, storey or PredefinedType

element_detail

expand specific GlobalIds to every pset and quantity

bimq queries prints their parameters. List queries return compact rows on purpose; element_detail is the drill-down, and keeping those separate is what stops a query from becoming the context dump it replaced.

Aggregates report their own coverage. A roll-up over 200 walls where 160 carry no quantity says so in summary and notes, because a total over 40 of 200 is not a total.

Policy

name = "consultant-readonly"

[allow_sources]
roots = ["/srv/bim"]
max_bytes = 536870912

[allow_queries]
queries = ["model_summary", "spatial_tree", "elements_by_type", "elements_by_property"]

[scope_storeys]
names = ["Level 2", "Level 3"]
include_unplaced = false

[allow_types]
types = ["IfcBuiltElement", "IfcSpace", "IfcBuildingStorey"]

[deny_properties]
properties = ["*Cost*", "Pset_Tender.*"]

[redact_properties]
properties = ["*.Owner*", "*SerialNumber*"]
placeholder = "[redacted]"

[max_results]
limit = 200
bimq policy check policy.toml   # validate before shipping
bimq rules                      # every rule, with an example

Notes on the design:

  • An unknown table is a hard error, not a warning. A file whose job is to withhold data must not fail open because of a typo.

  • deny and redact are different tools. A denied property is gone; a redacted one is present with a placeholder. The distinction matters to an agent: redaction says this exists and you are not being shown it, so the agent reports a gap instead of concluding nobody entered the data.

  • Denial covers the query side too. You cannot filter on a denied property, because op=gt value=1000 repeated a few times reconstructs it.

  • Withholding is reported, never silent. Answers carry policy.elements_withheld and a note. Truncation sets truncated: true.

  • Every answer is capped even with no policy at all. "Unlimited" is not a sane default for something feeding a context window.

Source formats

Format

Notes

IFC-SPF (.ifc, .ifczip)

IFC2X3 / IFC4 / IFC4X3, streaming reader, no dependencies

gbXML (.gbxml)

energy models; ids are stamped gbXMLId, never confused with GlobalIds

Wanted, one per PR: Revit export (pyRevit/Dynamo JSON), Speckle stream, IFC-JSON, COBie. See CONTRIBUTING.md.

How the IFC reader stays small

bimq/sources/spf.py is a complete ISO 10303-21 reader in under 400 lines. The parts that matter:

  • The file is scanned in 4 MB blocks, so a 300 MB model is never one string. A block boundary can land inside a string literal, so the scanner explicitly matches unterminated literals and carries them forward. Tested at block sizes down to one byte, where the result must still be byte-identical.

  • A ; inside 'a;b' does not end a statement, '' is an escaped quote, and \X2\...\X0\ decodes to UTF-16 — so Phòng họp survives the round trip.

  • Comments appear between statements, inside parameter lists, and around section markers. All three are handled; the reported line still points at the entity.

  • Geometry is never loaded. An instance is kept only if its first attribute is a syntactically valid GlobalId — making it an IfcRoot subtype — or if it is one of ~30 unrooted carriers of property, quantity, material or unit data. The test is applied to the raw text before tokenising, which is where the parse time on a real file actually goes.

Check the throughput claim yourself without needing a model of your own — this writes a file shaped like a real export (a modest element count buried in geometry), parses it, and reports:

$ bimq bench --synthetic 20000
synthetic model: 20000 elements among 820006 instances
tmp6l05ix9x.ifc: 32.2 MiB, 20001 elements
parse: 1.71 s  ·  18.8 MiB/s  ·  11,680 elements/s
peak rss: 107 MiB  (3.3x file size)

820,006 instances go in; 20,001 elements stay resident. That ratio is the whole argument — resident size tracks how many things the building has, not how many points were needed to draw them.

Model files are treated as untrusted input. The gbXML reader refuses entity declarations outright, so a file cannot carry a billion-laughs expansion or an external entity pointing at /etc/passwd.

Units

Every number bimq returns is SI: metres, m², m³. A model authored in millimetres with areas in square metres (what Revit exports) and one authored in feet with areas in square feet both answer spaces_by_area max_m2=8 correctly. IfcConversionBasedUnit chains are resolved, not guessed.

Try it

The fixtures are synthetic — stated plainly, because a fixture pretending to be a real project is one nobody can check. What makes them useful is that the defects are deliberate and enumerated: a wall with no material, a fire door with no rating, a room below 8 m², a room with no area quantity at all, a door whose rating is inherited from its type, and a Vietnamese room name written with \X2\ escapes.

python scripts/make_fixture.py tests/fixtures

bimq describe tests/fixtures/office.ifc
bimq query elements_missing_material tests/fixtures/office.ifc type=IfcWall
bimq query spaces_by_area tests/fixtures/office.ifc max_m2=8
bimq query property_values tests/fixtures/office.ifc type=IfcDoor property=FireRating
bimq query spaces_by_area tests/fixtures/legacy-imperial.ifc max_m2=8   # authored in feet
bimq query spaces_by_area tests/fixtures/clinic.gbxml max_m2=8          # gbXML, same primitive

Development

make test        # the suite
make fixtures    # regenerate fixtures (byte-identical; CI checks this)
make bench       # parse throughput on a fixture

License

MIT

Available Tools

11 tools
bim_citeQuote the source for a GlobalIdA
Read-only

Return the original file text behind a GlobalId: the STEP line that declares it, verbatim. Use it to verify a claim before repeating it, and when a reviewer asks where a number came from.

NameRequiredDescriptionDefault
idYesGlobalId from a previous result.
max_linesNoCap on quoted lines.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only and closed-world behavior. The description adds useful behavioral context by saying the return is the verbatim original STEP line, which matters because there is no output schema. It does not mention missing-ID errors or truncation/line-cap behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with the purpose front-loaded and no wasted wording. Every phrase contributes either the tool's output or its intended use.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only two-parameter tool, the description covers purpose, return value, and usage well enough to call it correctly. Minor gaps remain around truncation/max_lines behavior and not-found cases, though the schema documents `max_lines`.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already documented. The description reinforces that `id` is a GlobalId but adds no syntax, format, or `max_lines` details beyond the schema, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

It states a specific verb and resource: return the original file text behind a GlobalId, specifically the STEP line that declares it verbatim. This clearly distinguishes it from sibling BIM query/aggregation tools as a provenance/citation lookup.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance: verify a claim before repeating it, and when a reviewer asks where a number came from. It does not name alternatives or state when not to use it, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bim_element_detailElement detail by GlobalIdA
Read-only

The drill-down half of the loop: list queries return compact rows, and this expands named GlobalIds into every property set, quantity and material.

Ids that are not returned are reported in not_found, which covers both "no such element" and "hidden by policy" — deliberately without distinguishing them, so the response does not leak the shape of what is filtered out.

NameRequiredDescriptionDefault
idsYesGlobalIds to expand.
max_idsNoRefuse more than this many ids at once.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only/open-world safety profile, but the description goes further by disclosing how unresolved ids surface in `not_found` and that 'no such element' and 'hidden by policy' are deliberately conflated to avoid leaking filtered shape. That is genuinely non-obvious behavioral context an agent could not infer from annotations or schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short paragraphs, front-loaded with the core action followed by the error-semantics detail. The em-dash clause about not leaking filtered shape is slightly ornate but still load-bearing information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description must convey what comes back — and it does: full property sets, quantities, materials, plus the `not_found` bucket. With only two well-documented parameters, an agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both `ids` and `max_ids` are already documented, and the description adds little parameter-level detail beyond calling them 'named GlobalIds'. Baseline 3 is appropriate when the schema carries the semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb ('expands') plus resource ('named GlobalIds into every property set, quantity and material'), and it explicitly frames itself as the drill-down counterpart to the compact list queries, which cleanly separates it from siblings like bim_elements_by_type and bim_property_values.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'drill-down half of the loop' framing tells the agent this follows a list query, which is clear usage context. It stops short of naming a specific sibling or stating exclusions (e.g. when to prefer bim_property_values instead), so it falls just below the top score.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bim_elements_by_propertyElements by property valueA
Read-only

Find elements whose property matches a condition, e.g. fire-rated doors on level 3: type=IfcDoor, storey=Level 3, property=FireRating, op=exists.

pset is optional and usually best left out: the same field lands in Pset_DoorCommon on one exporter and a bespoke set on another, so by default every property set on the element is searched. The matched set and value are returned alongside each hit, so the answer says where it came from.

NameRequiredDescriptionDefault
opNoComparison operator.exists
psetNoRestrict to this property set. Omit to search all.
typeNoEntity type, e.g. IfcDoor. Subtypes included by default.
valueNoValue to compare against (ignored by exists/missing).
storeyNoStorey name or GlobalId. Substring match on the name.
propertyYesProperty name, e.g. FireRating.
name_containsNoCase-insensitive substring of the element name.
predefined_typeNoPredefinedType / surfaceType value, e.g. FIRE_RATED.
include_subtypesNoMatch subtypes of `type`.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only, closed-world safety profile, and the description adds real context beyond them: that all property sets are searched by default due to exporter inconsistency, and that the matched set and value are returned with each hit. It does not discuss result limits or ordering, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the example, followed by a short paragraph on the one non-obvious parameter decision. Every sentence carries information; nothing is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 9 parameters, no output schema, and a rich schema, the description covers the trickiest decision (pset) and hints at the return payload. It stops short of describing the full result shape or caps, which matters because there is no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds genuine meaning: it justifies the `pset` default and shows a multi-parameter combination in the example. The `op` semantics are only illustrated via `exists`, not fully explained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (find) and resource (elements matching a property condition), then anchors it with a concrete example (fire-rated doors on level 3). An agent can distinguish this from bim_elements_by_type or bim_elements_missing_property based on the property-condition framing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The worked example implicitly shows when this tool is appropriate, and it gives clear guidance to omit `pset` by default. However it never explicitly contrasts itself with siblings like bim_elements_by_type or bim_elements_missing_property, leaving the agent to infer the boundary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bim_elements_by_typeElements by typeA
Read-only

List elements of an IFC type, optionally narrowed by storey, name or PredefinedType. Subtypes are included by default, so IfcBuiltElement returns walls, slabs, doors and the rest. Returns one compact row per element with its GlobalId citation.

NameRequiredDescriptionDefault
typeNoEntity type, e.g. IfcDoor. Subtypes included by default.
storeyNoStorey name or GlobalId. Substring match on the name.
name_containsNoCase-insensitive substring of the element name.
predefined_typeNoPredefinedType / surfaceType value, e.g. FIRE_RATED.
include_subtypesNoMatch subtypes of `type`.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (readOnlyHint) and closed-world scope, so the description is free to add value — and it does: subtype inclusion is the default and expands the result set, which is a real behavioral trait an agent could get wrong. It also discloses the return shape ("one compact row per element with its GlobalId citation"), which is useful with no output schema present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the operation, then the subtype caveat, then the return shape. Nothing is padding and the most error-prone behavior (subtype expansion) lands early.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully characterizes the response as compact rows carrying GlobalId citations. For a read-only filter tool with fully documented params this is close to complete; only the interaction with sibling tools is left unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all five parameters are already documented — including the include_subtypes default that the description restates. The description adds no format or edge-case detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("List elements of an IFC type") plus its filter scope, and the subtype note makes the semantics concrete with an example (`IfcBuiltElement` returns walls, slabs, doors). It separates itself from bim_elements_by_property by being type-driven, but never names a sibling to make the distinction explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the phrase "optionally narrowed by storey, name or PredefinedType", which hints at the type-first lookup pattern. There is no explicit when-to-use vs. bim_elements_by_property / bim_element_detail guidance and no stated exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bim_elements_missing_materialElements with no material assignedA
Read-only

Elements that no IfcRelAssociatesMaterial reaches — through a plain material, a material list, a layer set, a profile set or a constituent set, all of which are resolved before the check. Restrict with type to ask the question that actually matters, e.g. only IfcWall and IfcSlab.

NameRequiredDescriptionDefault
typeNoEntity type, e.g. IfcDoor. Subtypes included by default.
storeyNoStorey name or GlobalId. Substring match on the name.
name_containsNoCase-insensitive substring of the element name.
predefined_typeNoPredefinedType / surfaceType value, e.g. FIRE_RATED.
include_subtypesNoMatch subtypes of `type`.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. Beyond that, the description discloses non-obvious internal behavior: plain material, material list, layer set, profile set and constituent set associations are all resolved before the check, which tells the agent it will not get false positives from layered or constituent-based assignments.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the qualifying condition, and the enumeration of material association kinds is dense but earns its place by defining the predicate. Slightly wordy for what could be a single clause, but no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, no-output-schema query tool with five optional filters, the description supplies the semantic definition an agent needs and points at the most useful filter. It omits return shape (element list contents) and any result-size limits, which is a modest gap given there is no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five filters are already documented in the schema, and the description only elaborates on `type` (its role in scoping the query) with an example. That is a genuine but small increment over structured data, matching the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific resource (elements unreachable by IfcRelAssociatesMaterial) and defines the exact predicate that makes an element qualify, which goes well beyond restating the title. It does not explicitly contrast itself with the near-identical sibling bim_elements_missing_property, so an agent must infer that this is the material-specific variant.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Restrict with `type` to ask the question that actually matters, e.g. only IfcWall and IfcSlab" gives concrete usage advice on narrowing scope. However, it never says when to choose this tool over bim_elements_missing_property or how to combine it with storey/name filters, leaving alternatives unaddressed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bim_elements_missing_propertyElements missing a required propertyA
Read-only

The inverse of elements_by_property, and the one most model-audit questions reduce to: which elements of this type have no value for this field? An empty string counts as missing by default, because exporters write one for "not filled in" as often as they omit the property entirely.

NameRequiredDescriptionDefault
psetNoRequire it in this property set specifically.
typeNoEntity type, e.g. IfcDoor. Subtypes included by default.
storeyNoStorey name or GlobalId. Substring match on the name.
propertyYesProperty name that ought to be present.
name_containsNoCase-insensitive substring of the element name.
predefined_typeNoPredefinedType / surfaceType value, e.g. FIRE_RATED.
include_subtypesNoMatch subtypes of `type`.
empty_counts_as_missingNoTreat '' as missing.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds real semantic context beyond the schema: why the empty-string default exists (exporters write '' for "not filled in"), which tells the agent how matching actually behaves. It does not describe return shape or result volume, keeping it below 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the inverse-of-sibling framing followed by the rationale for the default. The clause about exporters is not filler – it justifies a behavioral default the agent might otherwise override.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 8 parameters, full schema coverage and no output schema, the description covers the key conceptual gap (what "missing" means). It stops short of saying what comes back – a list of elements, a count, or grouped results – which an agent would want for an audit query.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all eight parameters are already documented, establishing a baseline of 3. The description only reinforces the property/type pairing in prose and adds no syntax, format, or interaction detail (e.g. how pset and property combine) beyond what the schema states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific operation (find elements with no value for a given field) and explicitly frames itself as the inverse of a named sibling, bim_elements_by_property. An agent can distinguish it from that sibling and from bim_elements_by_type without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear use case ("the one most model-audit questions reduce to") and names the complementary tool it inverts, which routes selection. It does not state explicit exclusions or when to prefer a different audit tool such as bim_property_values, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bim_model_summaryModel summaryA
Read-only

Schema, authoring application, units, storeys, and the element counts by type — of the visible model, after policy. Cheap, bounded, and the right first call: it tells an agent which types and property sets exist before it starts guessing names at them.

NameRequiredDescriptionDefault
top_psetsNoHow many property-set names to list.
top_typesNoHow many entity types to list.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds genuinely useful context beyond them: results reflect the *visible* model 'after policy' (i.e., filtered by access policy), and the call is 'cheap, bounded'. That policy-filtering nuance is exactly the kind of behavioral trait annotations cannot express.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the returned contents and then the usage recommendation; no filler. The phrase 'cheap, bounded' is slightly marketing-flavored but still earns its place as cost guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, but the description explicitly enumerates the return contents, and the policy-filtering caveat plus boundedness tells the agent what to expect. Nothing essential for calling this tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so top_psets and top_types are already documented with defaults. The description adds no additional meaning about these parameters, which is acceptable at the baseline when the schema carries the load.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description enumerates exactly what the tool returns (schema, authoring application, units, storeys, element counts by type) and explicitly positions itself as the discovery/first-call tool versus the more targeted siblings like bim_elements_by_type or bim_property_values. An agent can tell what this does and why it differs from the other bim_* tools without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear when-to-use signal ('the right first call... before it starts guessing names at them'), which is strong positive guidance. It does not name a when-not case or name specific sibling alternatives to avoid, so it falls just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bim_property_valuesDistinct property valuesA
Read-only

What values does this field actually take? Run this before elements_by_property rather than guessing: it is how you learn that the model spells fire ratings "EI60", "60 min" and "60" in three different property sets, which no amount of schema documentation will tell you.

Returns each distinct value with a count and up to three example GlobalIds.

NameRequiredDescriptionDefault
psetNoRestrict to this property set.
typeNoEntity type, e.g. IfcDoor. Subtypes included by default.
storeyNoStorey name or GlobalId. Substring match on the name.
propertyYesProperty name to tabulate.
name_containsNoCase-insensitive substring of the element name.
include_missingNoInclude a row for elements with no value.
predefined_typeNoPredefinedType / surfaceType value, e.g. FIRE_RATED.
include_subtypesNoMatch subtypes of `type`.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint/openWorldHint=false; the description adds genuinely non-obvious behavior — that real models spell the same concept inconsistently across property sets, which is exactly why the tool exists. It also discloses the return shape (each distinct value, a count, up to three example GlobalIds). It doesn't discuss cost/performance on large models, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the motivating question, then the sequencing instruction, then the return shape — each sentence carries distinct information. The fire-rating example is concrete and earns its space as the justification for existence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description supplies the return format (value + count + sample GlobalIds) and the core motivation, which is enough to call it correctly. It doesn't cover interaction between flags like include_missing/include_subtypes or behavior on very large models, but nothing critical is missing for a read-only tabulation tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and all eight parameters are documented there (pset, type, storey, property, name_contains, include_missing, predefined_type, include_subtypes). The description adds no parameter-level meaning beyond 'this field', so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a concrete question the tool answers ('What values does this field actually take?') and names the resource (distinct property values with counts and sample GlobalIds). It explicitly distinguishes itself from the sibling bim_elements_by_property, so an agent can route without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly prescribes sequencing: 'Run this before elements_by_property rather than guessing.' That is a clear when-to-use plus a named alternative. It stops short of stating when *not* to use it (e.g., for absent values, where bim_elements_missing_property may fit), so it is strong but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bim_quantity_rollupQuantity roll-upA
Read-only

Total a named quantity (NetSideArea, GrossVolume, Length, ...) over a selection, grouped by type, storey or PredefinedType. Lengths, areas and volumes are already converted to m, m2 and m3.

Every group reports without_quantity next to count. A total computed over 40 of 200 walls is not a total, and the caller is told so rather than left to assume the model was complete.

NameRequiredDescriptionDefault
typeNoEntity type, e.g. IfcDoor. Subtypes included by default.
storeyNoStorey name or GlobalId. Substring match on the name.
group_byNoHow to group the totals.type
quantityYesQuantity name, e.g. NetSideArea.
name_containsNoCase-insensitive substring of the element name.
predefined_typeNoPredefinedType / surfaceType value, e.g. FIRE_RATED.
include_subtypesNoMatch subtypes of `type`.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint, openWorldHint=false), and the description adds genuinely non-obvious behavior: unit normalization to m/m2/m3 and, crucially, that each group reports `without_quantity` alongside `count` so incomplete totals are self-evident. It does not say what happens when the named quantity is absent everywhere or on error, keeping it below a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Opens with the operation and grouping before any caveat, which is the right ordering. The second paragraph's aphorism about 40 of 200 walls is slightly editorial but does justify the `without_quantity` field, so it mostly earns its space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-value burden and does so for the main fields (group key, count, without_quantity). It stops short of describing the shape of group labels or behavior on unknown quantity names, but an agent has enough to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so every parameter is already documented in the schema, and the description adds only the example quantity names and the unit-conversion note. Baseline 3 is appropriate since the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Total a named quantity ... over a selection') plus the grouping axis, which is more precise than any sibling like bim_model_summary or bim_property_values. An agent can tell this is the aggregation tool versus the listing/detail tools without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use it (you want a rolled-up total rather than per-element values) and names the grouping options, but never states exclusions or points to an alternative such as bim_property_values for distinct values or bim_elements_by_type for per-element listings. Usage is inferable rather than directed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bim_spaces_by_areaSpaces by floor areaA
Read-only

Spaces whose floor area falls inside a range, e.g. "rooms below the 8 m2 minimum". Areas are reported in square metres after unit conversion, so the threshold means the same thing on a model authored in millimetres and one authored in feet.

Quantity names are tried in order: the explicit quantity if given, then NetFloorArea, GrossFloorArea, Area. Spaces carrying none of them are reported in notes rather than silently dropped — "no answer" and "no data" are different findings.

NameRequiredDescriptionDefault
typeNoEntity type, e.g. IfcDoor. Subtypes included by default.
max_m2NoOnly spaces with area <= this, in m2.
min_m2NoOnly spaces with area >= this, in m2.
storeyNoStorey name or GlobalId. Substring match on the name.
quantityNoQuantity name to prefer, e.g. NetFloorArea.
name_containsNoCase-insensitive substring of the element name.
predefined_typeNoPredefinedType / surfaceType value, e.g. FIRE_RATED.
include_subtypesNoMatch subtypes of `type`.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint=true, openWorldHint=false), yet the description adds real behavior: areas are normalized to square metres after unit conversion, and spaces lacking any area quantity land in `notes` instead of being silently dropped. That 'no answer vs. no data' distinction is exactly the kind of context an agent cannot infer from annotations, though result ordering and any result caps remain unstated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short paragraphs: purpose first, then unit semantics, then quantity resolution. Every sentence carries information an agent would otherwise have to guess, and nothing is repeated from the schema or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With eight optional parameters and no output schema, the description covers the highest-risk ambiguities: unit normalization and where unmeasured spaces end up. Minor gaps remain — the defaults for include_subtypes and the interaction between `type` and `storey` filtering are left entirely to the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline would be 3, but the description goes beyond it by explaining that min/max thresholds are applied post-unit-conversion and by spelling out the resolution order for `quantity` (explicit, then NetFloorArea, GrossFloorArea, Area). That fallback chain is not derivable from the schema's one-line parameter description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Spaces whose floor area falls inside a range') plus a concrete example ('rooms below the 8 m2 minimum'). The area-threshold framing cleanly separates it from siblings like bim_quantity_rollup and bim_elements_by_type, which do not filter on area ranges.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The example use case makes the intended scenario concrete, and the quantity fallback paragraph tells the agent how the tool behaves when the caller is unsure which quantity to name. It does not, however, explicitly name an alternative sibling or state when-not to use it (e.g. vs. bim_quantity_rollup for aggregated totals).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bim_spatial_treeSpatial structureA
Read-only

The containment hierarchy, which is the map an agent needs before it can ask anything storey-shaped: it turns "level 3" into a GlobalId. Element counts are counts of visible elements, so a policy that scopes the model to two storeys shows zero elsewhere rather than hinting at what it is hiding.

NameRequiredDescriptionDefault
max_depthNoStop descending after this many levels.
with_element_idsNoInclude the GlobalId of every element.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond readOnlyHint=true / openWorldHint=false, the description discloses a genuinely non-obvious behavior: element counts reflect only *visible* elements, so policy-scoped models report zero rather than revealing hidden content. That caveat prevents a real misinterpretation of zero counts. It stops short of describing depth defaults or output shape in detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly packed sentences with no wasted words; the identity of the tool comes first and the important visibility caveat follows. Every clause carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does the necessary work of characterizing the return value as a hierarchy with level names, GlobalIds, and element counts, plus the visibility caveat. It could be slightly more explicit about hierarchy shape (storeys vs. spaces) but is sufficient to call correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters (max_depth, with_element_ids) are documented in the schema, so the baseline is 3. The description's mention of GlobalIds loosely gestures at with_element_ids but adds no semantics about max_depth or what depth means in this hierarchy.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description identifies the tool as returning the containment hierarchy and explains concretely that it 'turns "level 3" into a GlobalId', which tells an agent exactly what resource is produced. It lacks a crisp verb phrase ('return/describe') but the outcome is unambiguous and clearly distinct from siblings like bim_model_summary or bim_elements_by_type.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It implies a sequencing rule ('the map an agent needs before it can ask anything storey-shaped'), which is useful guidance but purely implicit. No sibling is named as an alternative, and no when-not-to-use condition is stated, so the agent must infer the routing from the phrasing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 11 tool updatesv0.1.0
    • First observedbim_cite
    • First observedbim_element_detail
    • First observedbim_elements_by_property
    • First observedbim_elements_by_type
    • First observedbim_elements_missing_material
    • First observedbim_elements_missing_property
    • First observedbim_model_summary
    • First observedbim_property_values
    • First observedbim_quantity_rollup
    • First observedbim_spaces_by_area
    • First observedbim_spatial_tree

TDQS

A4.2/5.0

Scored across 11 tools

Disambiguation5/5

Each tool maps to a distinct IFC query or audit operation: model discovery, typed/property selection, missing-data filters, detail expansion, aggregation, spatial lookup, and raw citation. The element-query family shares a resource but the filters and inverses are clearly separated, so misselection risk is low.

Naming Consistency5/5

All 11 names use a uniform snake_case `bim_` prefix and predictable resource/action phrasing such as `elements_by_*`, `missing_*`, and `*_rollup`. The singular `bim_element_detail` versus plural `bim_elements_*` reads naturally rather than inconsistently.

Tool Count5/5

11 tools fit the scope of an IFC/BIM inspection server: a small discovery set, a coherent element-query family, and specialized aggregation, spatial, and citation tools. There is no obvious filler or missing basic operation that would require extra tools.

Completeness4/5

The surface covers discovery, filtering, missing-data audits, quantity aggregation, spatial containment, and source citation, which is strong for a read-only BIM query server. Minor gaps remain around reverse material queries and richer relationship/containment queries, but most audit workflows are covered or workable through detail expansion.

Maintenance

ActivityInactive
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables AI agents to load, query, and analyze IFC building model files, including spatial structures, elements, properties, materials, and geometry.
    20
    1
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Read-only MCP server for querying an evidence-aware knowledge vault with temporal and provenance-aware data, supporting agent memory and semantic graph projections.
    -
  • A
    license
    A
    quality
    D
    maintenance
    An MCP server that lets users query, validate, convert, and compare IFC/BIM files using natural language. Runs fully locally and integrates with AI agents like Claude.
    8
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Open-source MCP server for Autodesk Revit 2022 to 2027: read, audit and edit live models with 89 tools, one Undo entry per change, and a workstation read-only lock.
    89
    9
    MIT