Archicad-MCP
Connects an MCP client to Archicad 29/30 for QA, model inspection and editing, element creation, viewing, issues, publishing, Teamwork, schedules, library-part learning, and raw API access.
List running Archicad instances, project/model info, summaries, and current selection.
Run QA rules and audits, verify IFC readiness, highlight failures, and create issues from failures.
Find elements by criteria, search property/attribute definitions, read element data, list attributes, and find collisions.
Edit element data, modify/move/delete elements, apply favourites, and edit attributes, property definitions, classifications, and import definitions.
Create many element types, including walls, slabs, doors/windows, zones, stairs, dimensions, MEP, 2D elements, markers, swept beams, road markings, and road arrows.
Show/select/clear/highlight elements and capture the Archicad window as an image.
Manage issues and BCF import/export, export IFC, run publisher sets, and save the project.
Reserve/release Teamwork elements and object sets.
Read, edit, and validate exported schedule scheme XML.
Learn, preview, record, and list learned library parts for placement guidance.
Discover, describe, and execute official/Tapir read and write API commands through a gateway.
Install Tapir and update the extension.
Use safe defaults: many writes are dry-run first, and delete/move/save/API-write/Teamwork actions are confirmation-gated.
Provides tools for querying, editing, and creating elements in a running Archicad instance, plus delivery-readiness QA via YAML rules and access to the full Archicad JSON API.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Archicad-MCP Run the office rules QA audit on the open model"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Archicad MCP
Connects Claude, ChatGPT or any MCP client to a running Archicad 29 (30 works too) on macOS and Windows. You ask in plain language; the server does it through Archicad's JSON API and the Tapir add-on.
Check a model against office standards. YAML rules run against the open model: pass or fail, a score, and the failing elements, highlighted or turned into issues.
Find, read and change elements. Criteria queries, properties, classifications, GDL and IFC data, favourites, attributes, clash checks.
Create elements. Walls, slabs, columns, doors and windows, zones, stairs, dimensions and 40-odd more types.
Everything else. About 800 official and Tapir commands through one gateway.
Save before reading properties. Archicad 29 can crash on a property read,
even of one element, taking unsaved work with it. The server cannot prevent it.
Ask the client to run save_project first, and see
Known issues.
Install
Claude Desktop: download the bundle for your platform from the latest release and drag it into Settings > Extensions. It carries its own Python, so there is nothing else to install.
Platform | File |
Windows |
|
macOS (Apple silicon) |
|
To update, ask Claude to update the extension: it downloads the newest release, checks it and opens Claude Desktop's install dialog.
Claude Code (needs uv):
uv tool install archicad-mcp-server
claude mcp add archicad -- archicad-mcp --mode fullTapir: most tools need the Tapir add-on in Archicad. Ask the client to
install Tapir, or run archicad-mcp install-tapir. It puts the pinned Tapir
2.0.0 into Archicad's Add-Ons folder, checked by sha256, and never replaces an
existing one unless told to. Restart Archicad afterwards.
Intel Macs, a hand-written Claude Desktop config, ChatGPT, Codex and all the settings: Install.
Related MCP server: Automatización MCP — Navisworks Manage 2025
Check it works
With Archicad open, ask the client to list Archicad instances. It shows the port, Archicad version, open project and Tapir version, and what to install when something is missing. If the client shows no tools at all, see Check it works.
What you can ask
Area | Tools |
QA |
|
Find and read |
|
Change |
|
Create |
|
Look |
|
Issues and output | Issue Manager and BCF, |
Teamwork |
|
Schedules |
|
Library parts | mesh models (OBJ, 3DS) to GDL objects: |
Gateway |
|
Every tool in detail, with what it checks and what it needs: Tools.
Safe by default. Changes to elements, data and definitions are a dry run
first, showing current and new values. Delete and move also need confirm=true.
Elements Archicad would refuse (another view's, a hidden or locked layer, a
hotlinked module, not reserved in Teamwork) are skipped with the reason, never
unlocked. A commit reads back what it wrote and reports what did not land.
Office rules
Rules are YAML files in a folder you point the server at (the extension's
Office rules folder setting, or ARCHICAD_MCP_RULES_DIR):
- id: walls-fire-rating
type: property-required
property: "OFFICE/Fire Rating"
applies_to: { element_type: Wall }
severity: errorEight rule types are built in, and custom checks go in Python beside the YAML. Keep real office standards outside this repository. See Writing rules.
Docs
Install: every install route, Tapir, configuration
Tools: every tool, what it checks and what it needs
API dashboard: every reachable command, and which have a tool
Development: tests, Tapir, bundles, releasing
Privacy
The server runs on your machine and talks only to Archicad on 127.0.0.1. There
is no telemetry and no backend. What it reads goes to the MCP client that asked,
normally Claude, under that client's privacy terms. See PRIVACY.md.
License
MIT. See LICENSE.
Available Tools
56 toolsadd_issue_commentComment on an issueADestructive
Add a text comment to an existing issue, addressed by its id (requires the Tapir add-on).
Inputs: comment (required), issue_id (required), port. Returns: object
apply_favoritesApply favoritesADestructive
Make existing elements match a favourite (Tapir), the office standard in one step. Without favorite it changes nothing and lists the favourites that fit the given elements' types (all types when no guids either). DRY-RUN BY DEFAULT: lists the elements it would change, skips with the reason those of another type than the favourite's or that Archicad would refuse (another view's, hidden or locked layer, not reserved in Teamwork, inside a hotlinked module, locked), and warns what the favourite takes over besides materials and pens: a wall's height, top link, reference line and structure, a column's height and top link, a door's or window's library part, size and sill, and every element's layer; for other types it says what was not checked live. Plan positions stay. Stairs, railings and curtain walls get only their own settings, not their parts'. keep (default ["id"]) writes each element's own Element ID back after the favourite, and "layer" its own layer. From Tapir 1.7.3 Tapir keeps them itself, and keep also takes "width", "height" and "sillHeight" (doors, windows), "referenceLineLocation" (walls) and "height", "topOffset" and "relativeTopStory" (walls, columns; keep the three together), so e.g. only the library part or the wall type changes; on older Tapir use modify_elements for heights and sizes. On Tapir 1.7.3 the dry run also names the favourite's library part, marker and folder (favorite_settings), and on a Tapir newer than 1.8.0 and Archicad 29 its layer and Element ID as well. settings, classifications, categories and properties choose what the favourite applies; classifications are added per system and property values overwrite. Pass dry_run=false to apply: returns applied, changed (per element current and new of every field the favourite changed, read back), unchanged, failed grouped by reason, and restored for keep. Classifications, categories and properties are not read back. to_defaults=true with no guids sets the favourite's tool defaults instead.
Inputs: keep, port, guids, dry_run, +6 more. Returns: object
attach_elements_to_issueAttach elements to an issueADestructive
Attach elements to an existing issue as highlights (requires the Tapir add-on).
Inputs: guids (required), issue_id (required), port. Returns: object
audit_delivery_readinessAudit delivery readinessARead-only
Run all loaded QA rules (optionally only those tagged with 'ruleset') against the open model. Returns a scored verdict.
Inputs: port, ruleset. Returns: object
capture_windowCapture the Archicad windowARead-only
See what the current Archicad window shows (floor plan, section, 3D, layout ...) as an image, to check a result by eye: which way a placed object faces, which way a door opens, whether walls meet. Call show_elements first to bring the elements into view. entire_drawing=true covers the whole drawing of a 2D window instead of the current zoom. Images larger than 1568 pixels are scaled down (scaled_from gives the original size). Needs Tapir 1.7.2. Reads only.
Inputs: port, entire_drawing.
clear_selectionClear current selectionB
Deselect everything in the Archicad window.
Inputs: port. Returns: object
create_elementsCreate elementsADestructive
Create elements of any type Tapir can create. element_type: model wall, beam, column, slab, roof, shell, morph, mesh, stair, railing, railing_polyline, zone, curtain_wall, grid_element, object, lamp; hosted door, window (in a wall), skylight (in a roof or shell), opening; MEP mep_route, mep_element, mep_flexible_segment, mep_take_off (Archicad 28+), electrical_panel, electrical_device, electrical_circuit (Archicad 30); markers section, elevation, interior_elevation, detail_marker, worksheet_marker; hotlink_instance; 2D line, arc, circle, polyline, spline, hatch, hotspot, text, label, keynote_label; dimension, level_dimension, wall_thickness_dimension, section_dimension; drawing (on a layout). Plurals and Tapir command names work too. Items use Tapir's field names and units (metres, radians): call with items=[] to get the item schema for a type, with notes on what the schema leaves out (which heights are absolute, which side a wall's body, a door's swing and a stair's flight lie on). DRY-RUN BY DEFAULT: every item is validated against the schema (any problem: nothing is sent, problems listed by item index and field), a favoriteName and a libraryPartName must exist (closest names suggested), and hosts (a door's wall, the elements a dimension measures, a label's parent) must exist, be the right type and be editable; items failing those are skipped with the reason and the rest go ahead. Most types take the Element ID as 'id' from Tapir 1.7.3 (doors, windows, openings, roofs and morphs do not); on an older Tapir such an item is skipped. Warns when the active window is wrong for the type, when an object or lamp has no dimensions (it would take the tool's current size, not the library part's), when it sends offset or useFixedAngle (Archicad discards them), when a door or window has no sillHeight (it would take the tool's sill), when one placed by libraryPartName leaves the Door or Window tool holding that part, when an absolute height lies off the story floorIndex names, when a stair's flights overlap, and, after the create, when a stair runs past its baseline. Learn a part once with learn_library_part before placing it by placement; a learned part is then placed with no samples. An object, lamp, door or window of such a part may give placement instead: an object's footprint centre, size (length along the head, width across it) and head direction (the head is the end that goes against the wall: a bed's pillow end, a chair's or sofa's back), for coordinates, angle, reflected and dimensions; a door's or window's hinge_near and opens_toward points, for reflected and oSide, and leaves (a recorded leaf state, written right after the create). On a part learned with a Tapir newer than 1.8.0, an object's size may be left out, as may a door's or window's width and height, which then take the part's own. items=[] shows its placement_schema; 'placements' lists what each one derived, and for a door or window the hinge and swing it read. Reading a sketch: choose the part from what it draws, the lines dividing a window give its sashes and the arcs give which sash or leaf opens and where it is hinged; prefer the plain generic part ("Window", "Door", "Double Window") when the sketch says no more. Width is a check: a window about 1.2 m wide is a single or a double window, never a multi-sash one; when the count and the width disagree, ask. A bed's head is the end with the pillows, or with the duvet's turned-back edge; when the sketch shows neither, ask. After placing, look (capture_window) and correct with modify_elements before reporting done. Pass dry_run=false to create: returns created GUIDs, plus Tapir's per-item errors grouped with item indices and by_index (item index -> GUID) when not every item was created, and 'placed_not_set' for an element placed whose leaves Archicad refused. On a Tapir newer than 1.8.0, database ({"guid": ...}, from GetDatabaseIdFromNavigatorItemId) puts lines, arcs, circles, polylines, splines, hatches, hotspots, texts or labels into that layout's, section's or other view's database instead of the active window's.
Inputs: items (required), element_type (required), port, dry_run, +1 more. Returns: object
create_issueCreate an issueADestructive
Create a new issue in the open project and return its id (requires the Tapir add-on).
Inputs: name (required), port. Returns: object
create_issues_from_failuresCreate issues from rule failuresADestructive
Create an Archicad issue from a rule's failures and attach the failing elements (requires Tapir add-on).
Inputs: rule_id (required), port. Returns: object
create_road_arrowCreate Road ArrowADestructive
Place Road Arrows (straight, left, right, combined, roundabout, sorting, split, lane ending, wrong way, cycle and garage arrows) as the 'Road Arrow' library part at stations along a lane axis, and drape them onto Meshes and Slabs. The axis comes from source_guid (a Morph line, Polyline, Line or Arc) or points [{x, y, z}] in metres, drawn in the direction of travel. arrow is a name, for example '5411 Straight' or '5443 Split, left and right', any case. stations is metres along the axis, a number or a list, default [0]: one arrow at each, with its anchor ('tail', 'centre' or 'tip') on the station and offset metres to the right. The size is size ('5.00 m'), speed_kmh (30, 50, 90 or more picks 3.00, 5.00, 7.50 or 12.00 m) or custom_length and custom_width. drape_on lists Mesh and Slab GUIDs: the arrow's height points follow the surface, the paint never sinks below it, and points are added until it is within drape_tolerance (metres); lift raises it. Without drape_on, height, slope_percent and cross_fall set the height. update_guid rewrites one placed arrow in place, keeping its settings unless given. DRY-RUN BY DEFAULT: reports each arrow's position, direction, height points, drape deviations, stretches off the surface and warnings. Pass dry_run=false to place or update.
Inputs: lift, port, size, arrow, +18 more. Returns: object
create_road_markingCreate Road MarkingADestructive
Place a Road Marking (lane lines, zebra crossings, stop and give way lines, bus and taxi stops, BUS and TAXI lettering) or a Road Parking (parking rows, disabled, taxi and EV bays) as the 'Road Marking' or 'Road Parking' library part, and drape it onto Meshes and Slabs. A parking preset name places a Road Parking; any other name, 'Custom' or none places a Road Marking; update_guid takes the element's own part, and a name of the other part is refused. The path comes from source_guid (a Morph line, Polyline, Line or Arc) or points [{x, y, z}] in metres. marking is a preset name, for example '5121 Broken divider, in settlements', 'Parking 60 degrees', '5352-1 Disabled bays, shared zone' or '5333-2 Bus stop on the carriageway', or 'Custom'. stripes changes stripes: {"1": {on, offset, width, dash, gap, angle, shape}}; a Road Parking takes only width, dash, gap and angle on stripe 1 and on for 2 and 3 ({"3": {"on": true}} is its kerb line); bays sets {layout, depth} and, on a Road Parking, {width, zone_width, zone_first, symbol}, on a Road Marking {bar_width}; lettering (Road Marking only) sets {text, length, width, gap, offset, align, shift, repeat}. Offsets, bays and the word lie to the right looking from the first point to the last. drape_on lists Mesh and Slab GUIDs: the cross fall follows the surface, the paint never sinks below it, and nodes are added until the marking is within drape_tolerance (metres) of it along the path; lift raises it. update_guid rewrites a placed marking, keeping its settings unless given; with drape_on and no source it drapes the marking's own path. DRY-RUN BY DEFAULT: reports nodes, the marking's reach, drape deviations, stretches off the surface and warnings. Pass dry_run=false to place or update.
Inputs: bays, lift, port, points, +17 more. Returns: object
create_swept_beamCreate Swept BeamADestructive
Place a Swept Beam: a sloped, curved beam with a Profile Manager profile or a rectangle, as the 'Swept Beam' library part. The path comes from source_guid (a Morph line, Polyline, Line or Arc) or from points [{x, y, z}] in metres. Flat sources take start_height (metres above the source) and slope_percent; morph lines and points keep their own heights. profile is {"attribute": ""} or {"rectangle": {"width", "height", "building_material"}} (default 0.2 x 0.2 rectangle). update_guid rewrites the path of an existing Swept Beam, keeping its GUID; its profile, offsets, flip and end cuts stay unless given, its segment profiles stay while the node count does, and node roll resets to 0. End cuts in degrees: cut_start_plan and cut_end_plan turn a cut counter-clockwise from square in plan (-80 to 80); cut_start_tilt and cut_end_tilt lean the top of the face out past the end (-85 to 85, 0 is square to the beam, the beam's slope there gives a vertical face). ref_line ('left face', 'centre', 'right face', looking from the first point to the last) puts that face of the beam on the path; ref_offset (metres) moves the beam that far away from it (with centre, to the right). DRY-RUN BY DEFAULT: reports nodes, arcs, the maximum deviation from the source and warnings. Pass dry_run=false to place or update.
Inputs: flip, port, points, dry_run, +14 more. Returns: object
delete_elementsDelete elementsADestructive
Delete elements. IRREVERSIBLE. Refuses without confirm=true. Archicad deletes only elements in the database of the active window and still answers success for the rest (a floor-plan label cannot be deleted while a Layout is active), so elements it would refuse (another view's, on a hidden or locked layer, not reserved in Teamwork, inside a hotlinked module, locked, or not found) are not sent, and the rest are read back afterwards. Returns requested; deleted, the count that is really gone; not_deleted grouped by reason with the GUIDs; active_window when anything was refused up front; and stopped if the delete command itself errored.
Inputs: guids (required), port, confirm. Returns: object
describe_api_commandDescribe an API commandARead-only
Full description and input schema for one API command. Call before execute_read_api_command or execute_write_api_command.
Inputs: name (required). Returns: object
edit_attributesEdit attributesADestructive
Create, modify, delete and replace attributes (layers, layer combinations, lines, fills, zone categories, pen tables, profiles, building materials, composites, surfaces) and set attribute property values (Tapir). DRY-RUN BY DEFAULT; pass dry_run=false to commit. Each change has one action key whose value is the type: {"create": "Layer", "name": "X", } makes a new one and NEVER overwrites (an existing name is skipped, with what would change and the modify to send instead); {"modify": "Composite", "attribute": "", } changes an existing one (name renames; fields not given keep their value, including what Tapir's own overwrite would drop: a composite's useWith, a building material's texts); {"modify": ..., "properties": {"Group/Name": "value"}} sets property values; {"delete": "Fill", "attribute": ...} deletes; {"replace": "Fill", "attribute": ..., "with": ...} (fills, lines, surfaces, building materials, a Tapir newer than 1.8.0, Archicad 27) rewrites every reference across the project and deletes it, and its dry run lists what uses it (uses). Fields use Tapir's names and units (metres, radians, pen numbers); a field holding another attribute (buildingMaterialId, lineTypeId, fillId, cutFillIndex, a layer combination's layers[].attributeId) takes its name. changes=[] lists every type's fields; list_attributes(details=true) shows current values in the same form. The dry run shows current -> new and skips with the reason anything Archicad or Tapir would refuse or silently get wrong: misspelt enums, unknown references, Archicad's own index 1 attributes, a layer delete while elements are on the layer (it would delete them) or without the floor plan active. In Teamwork the attribute type's set must be reserved (reserve_elements object_sets). Attribute writes cannot be undone, except a replace, which is one undo step per type. A commit returns applied (read back), not_applied, failed (grouped) and stopped.
Inputs: changes (required), port, dry_run. Returns: object
edit_classificationsEdit classificationsADestructive
Edit classification systems and items in place. DRY-RUN BY DEFAULT; pass dry_run=false to commit. Items: {"item": "System/Code", "code"?, "name"?, "description"?}. Systems: {"system": "Name", "name"?, "description"?, "source"?, "version"?, "date"? (YYYY-MM-DD)}. Items keep their GUID, so classified elements and property availability stay attached. Moving an item to another parent is not supported. In a Teamwork project the Classifications set must be reserved first (reserve_elements object_sets).
Inputs: changes (required), port, dry_run. Returns: object
edit_property_definitionsEdit property definitionsADestructive
Edit custom property DEFINITIONS in place (not element values): name, description, group, default value or expressions, availability, enum options. DRY-RUN BY DEFAULT: returns each property's before/after and warnings; pass dry_run=false to commit. Address properties as 'Group/Name' (search_definitions) or GUID; availability entries as 'System/Code', with '/' for the item and everything below it; enum options by their text (or GUID when two options share a text). Example change: {"property": "Office/Status", "name": "Approval", "availability": {"add": ["Uniclass/Ss_25/"]}, "enum": {"rename": {"Old": "New"}, "remove": ["X"], "add": ["Y"], "order": [...]}, "default": "New"}. GUIDs are kept, so element values survive everything except removing an option (those elements show ) or availability. In a Teamwork project the Properties set must be reserved first (reserve_elements object_sets). Needs the Tapir build with UpdateClassificationItems.
Inputs: changes (required), port, dry_run. Returns: object
edit_schedule_schemeEdit a schedule schemeADestructive
Apply a YAML scheme spec to an exported schedule scheme XML: set the columns and their order, retarget bindings, rename the scheme. DRY-RUN BY DEFAULT: returns the before and after column lists and writes nothing until dry_run=false. Never overwrites the input; writes to 'output' or to .edited.xml beside it. Import the result via Document > Schedules > Scheme Settings > Import. Criteria are preserved, not yet editable. A spec that binds every property by GUID needs no Archicad connection and runs fully offline; a spec that binds a property by a 'Group/Name' string needs Archicad open so the name can be resolved.
Inputs: path (required), spec_path (required), port, output, +2 more. Returns: object
execute_read_api_commandRun a read-only API commandARead-only
Run one read-only Archicad API command by name and return its result. Covers the official Archicad JSON API (https://archicadapi.graphisoft.com/JSONInterfaceDocumentation/) and the Tapir add-on (https://github.com/ENZYME-APD/tapir-archicad-automation). Reads only: a command that changes the project is refused here and belongs to execute_write_api_command. Params are validated against the bundled schema where available. Prefer the dedicated tools when one exists.
Inputs: name (required), port, params. Returns: object
execute_write_api_commandRun a write API commandADestructive
Run one Archicad API command that changes the project. Covers the official Archicad JSON API (https://archicadapi.graphisoft.com/JSONInterfaceDocumentation/) and the Tapir add-on (https://github.com/ENZYME-APD/tapir-archicad-automation). IRREVERSIBLE for many commands, and reaches DeleteElements and QuitArchicad among others. Refuses without confirm=true; the refusal echoes the command and params it would have run. Params are validated against the bundled schema where available. Prefer the dedicated tools when one exists.
Inputs: name (required), port, params, confirm. Returns: object
export_ifcExport IFCADestructive
Save the project as an IFC file, the step after verify_ifc_export_readiness. DRY-RUN BY DEFAULT: returns the translator, path, file type and scope, and lists every translator; pass dry_run=false to write. path: absolute, ending in .ifc or .ifczip. translator: a name from the project's IFC translators (default: the preview translator). scope: EntireProject, VisibleElementsOnAllStories (default), AllElementsOnCurrentStory, VisibleElementsOnCurrentStory or SelectedElementsOnly. Refuses to replace an existing file unless overwrite=true. Archicad exports from the floor plan or the 3D window, so from any other window it first brings the floor plan to the front and leaves it there. The commit checks the file and returns its size. Never opens or merges IFC. Needs Tapir 1.6.0.
Inputs: path (required), port, scope, dry_run, +2 more. Returns: object
export_issues_bcfExport issues to BCFADestructive
Export every issue in the project to a BCF file at the given path, aligned to the survey point. Overwrites the file if it exists (requires the Tapir add-on).
Inputs: bcf_path (required), port. Returns: object
find_collisionsFind collisionsARead-only
Find clashes: which elements of one group collide with which elements of another (Tapir). The first group is guids plus every element of element_types; the second is against_guids plus against_types, and without it the first group is checked against itself. Element types are Archicad's names (Wall, Beam, Column, Slab, Object, Morph, ...); for property criteria call find_elements first and pass its GUIDs. volume_tolerance (m3, default 0.001) is the overlap volume below which a clash is ignored; surface_tolerance (m2) also reports touching faces over that area. Returns each pair with both elements' type and ID, the first one's story, and kind (body, clearance for MEP clearance zones, or both), counts by type pair, and 'elements', every GUID in a pair, to pass to show_elements. Archicad does not count elements its own junctions clean up (crossing walls); the volume check sees only closed bodies, so an open surface (a Morph surface) clashes only with surface_tolerance set; building materials set not to take part in collision detection are left out. No pairs is not proof that nothing overlaps. A whole-model check can take a while. Reads only.
Inputs: port, guids, against_guids, against_types, +3 more. Returns: object
find_elementsFind elements by criteriaARead-only
Find elements matching criteria groups. Groups combine with OR; inside a group the comparisons combine with logical_operator 'and' (default) or 'or'. Each group may restrict element types (is / is_not) and lists comparisons of {property, operator, value}; the schema enumerates the element types and the 22 operators, and each field documents its values and units. Call search_definitions to find a property's exact address. An element with no usable value matches no binary operator. Returns GUIDs, counts, how many elements had properties read, and 'coverage' ('whole-plan' with Tapir, 'model-elements-only' without: then 2D elements are invisible and 0 is not proof of absence). 'not_read' lists the properties nothing could read on some elements, with the reason (the official API refuses them, and Tapir 2.0.0 or newer was not there or did not answer); such a pair matches no operator, so check it before trusting a count. Property comparisons read values in the server (no API filters by property); a read spanning more than the element ceiling is refused, so narrow with element_types, story or classification first.
Inputs: groups (required), port, selection_only. Returns: object
get_element_dataRead element dataARead-only
Read type, layer and requested values of the given elements. properties takes addresses: a property ('Group/Name', a built-in name or a property GUID, as search_definitions gives it); 'classification:' (the item ID); 'gdl:' (a GDL parameter of an object, lamp, door, window or other library part element); 'marker:' (a door's or window's marker parameter, Tapir 1.7.1); 'ifc:.' (an IFC property). Lengths in metres, angles in radians, attribute-typed GDL parameters as attribute indexes. 'gdl:', 'marker:', 'ifc:' and 'classification:' read every value, with display names in 'labels'; at most 20 elements per wildcard call. What could not be read for an element (a kind, a property or the layer) is named in its 'unreadable' with the reason; a property the official API refuses (on 2D elements and sub-elements, and definitions it does not support) is read through Tapir 2.0.0 or newer. include_classifications adds every system's item GUID.
Inputs: guids (required), port, properties, include_classifications. Returns: object
get_model_summarySummarize model contentsARead-only
Aggregate element counts. by_type is always returned (cheap and safe). Set include_layer_story=true to also break down by layer and story, which reads a property across every element and is refused on very large models (can crash Archicad). Counts only, never element data. 'coverage' says what element_count spans: 'whole-plan' with the Tapir add-on, 'model-elements-only' without it (then it is NOT a project total). 'owned_parts' counts apart the GDL parts of stairs and other elements that Archicad types Object.
Inputs: port, include_layer_story. Returns: object
get_project_infoGet project infoBRead-only
Project info: Archicad version, project name, stories, hotlinks, geolocation presence (Tapir enriches).
Inputs: port. Returns: object
get_selectionRead current selectionARead-only
Return the GUIDs of the elements currently selected in Archicad, and 'coverage': 'whole-plan' when read through the Tapir add-on, 'model-elements-only' without it (then selected markers, 2D elements and native MEP routes are left out, and an empty list is not proof that nothing is selected).
Inputs: port. Returns: object
highlight_failuresHighlight failing elementsB
Highlight the elements failing a rule in the Archicad window and zoom to them (zoom=false to leave the view). Highlights every story at once. A rule with no failures removes the highlight. show_elements opens the right story or view and selects; show_elements with guids=[] removes the highlight. Requires the Tapir add-on.
Inputs: rule_id (required), port, zoom. Returns: object
import_definitionsImport definitions XMLADestructive
Import a Property Manager (kind='property') or Classification Manager (kind='classification') XML file. DRY-RUN BY DEFAULT: lists what is new and what collides with existing names, and what the conflict policy does. conflict: property append|replace|skip; classification merge|replace|skip (item_conflict replace|skip). Commit returns what was created and removed.
Inputs: kind (required), conflict (required), xml_path (required), port, +2 more. Returns: object
import_issues_bcfImport issues from BCFADestructive
Import issues into the project from a BCF file, aligned to the survey point (requires the Tapir add-on).
Inputs: bcf_path (required), port. Returns: object
install_tapirInstall the Tapir add-onADestructive
Install the pinned Tapir add-on (2.0.0) into Archicad's Add-Ons folder. Dry run by default: it finds every Archicad on this computer, downloads and checks the file (sha256) and says what it would do. confirm=true writes. Never replaces an existing Tapir unless replace_existing=true, and then moves the old copy to a backup folder; a custom Tapir build loses its own commands when replaced. archicad_version limits it to one version. On macOS a protected Add-Ons folder brings up the system password dialog; on Windows it returns the command to run from an administrator terminal. Archicad must be restarted afterwards. Needs no running Archicad.
Inputs: confirm, archicad_version, replace_existing. Returns: object
learn_library_partLearn a library partADestructive
Learn a library part once, before placing it by placement; a learned part is then placed with no samples. Places samples of the part named name (kind: object, lamp, door or window) in a row just past the right edge of the model, on the story the floor plan shows, measures their footprints, shows them in one floor plan image, deletes every sample again in the same call and stores the measurement. The reply lists 'samples' left to right as the image shows them, the first sample's GDL parameters, warnings, and 'next', the fields still to give record_library_part. variants: optional sets of GDL parameter values (parameter name to value), each placed as one more sample, such as a leaf or one of a window's sashes opened. On a Tapir newer than 1.8.0 samples are placed at the part's own size and 1.5 times it, and the record keeps its own size. On Tapir 1.8.0 and older a door or window placed by part name, as its samples are, has GDL parameters that can be neither read nor written, and the Door or Window tool keeps that fault for later openings, so a door's or window's samples show no parameters and a placement's leaves end in placed_not_set; the same part placed from a favourite has them. When a window's capture shows no opening lines, the view settings hide them: ask the user to show them, then learn the window again, before recording hinge and swing. A part whose plan size does not follow its own A and B gets no footprint (the reply's note says so) and is placed by coordinates. Lengths are metres. The floor plan must be the active window, with its view not rotated. It zooms the plan to the samples and leaves it zoomed, since Tapir cannot set the zoom back; on Tapir 1.8.0 and older a door or window learned may leave the Door or Window tool holding the part. Needs Tapir 1.7.2.
Inputs: kind (required), name (required), port, variants.
list_api_commandsList API commandsARead-only
Catalog of ALL available Archicad API commands (official JSON API + Tapir). Filter by group, or by access='read' / 'write' to see which of the two execute tools runs a given command.
Inputs: group, access. Returns: object
list_attributesList attributesARead-only
List attributes by type: Layer, LayerCombination, Line, Fill, ZoneCategory, PenTable, Profile, BuildingMaterial, Composite, Surface (plurals work). Names only by default. details=true returns each attribute's settings (Tapir): a composite's skins and separators, a building material's fills and physical values, a layer combination's layer states, a pen table's pens, ... with references to other attributes shown by name, in the vocabulary edit_attributes takes. names= picks attributes; otherwise details are paged (limit, offset; next_offset when more remain).
Inputs: attribute_type (required), port, limit, names, +2 more. Returns: object
list_instancesList Archicad instancesARead-only
List running Archicad instances: port, version, open project, Tapir add-on availability. Call this first.
Inputs: no named parameters. Returns: object
list_issuesList issuesARead-only
List the issues in the open project, with their ids (requires the Tapir add-on).
Inputs: port. Returns: object
list_library_part_recordsList learned library partsARead-only
List the learned library parts, all or only those in names, each with its stored fields and 'missing', the fields still needed before it can be placed from. 'not_recorded' names any part asked for that has no record. Also returns the path of the records file. Reads only that local file and needs no Archicad.
Inputs: names. Returns: object
list_rulesList QA rulesARead-only
List loaded QA rules (id, type, severity, tags) and any rule-file load errors.
Inputs: no named parameters. Returns: object
modify_elementsModify elementsADestructive
Change existing elements. DRY-RUN BY DEFAULT: returns per element the current and new value of every field, plus skipped elements with the reason and warnings; pass dry_run=false to commit. Each change is {"guid", ...fields}. Any element: story (index, ground floor 0, or a story name; the element keeps its height above the story and moves with it unless keep_elevation=true), layer (name), draw_order (1 to 14, 0 = the type's default), id (the Element ID; Tapir 1.7.3 and newer, otherwise set_element_data General_ElementID). Walls, beams, slabs, columns, windows, doors, morphs, multi-plane roofs, meshes, objects, lamps, texts and labels also take the fields of Tapir's Modify command by its own names (describe_api_command ModifyWalls lists them), e.g. height, thickness, sillHeight, lightIsOn. On a Tapir newer than 1.8.0 so do stairs (ModifyStairs), railings (ModifyRailings), sections and elevations (ModifySections) and detail and worksheet markers (ModifyDetailMarkers); on those last two the reference ID shown in the marker is reference_id, as id stays the Element ID. Attribute fields (buildingMaterialId, compositeId, profileId, surfaceId, lineTypeId, sectionFillId, ...) take a name. Lengths in metres, angles in radians, text sizes in mm. Partial coordinates, dimensions and visibility are completed from the current values. Elements Archicad would refuse (another view's, hidden or locked layer, not reserved in Teamwork, inside a hotlinked module, locked) are skipped with the reason, never unlocked. A placed object, lamp, door or window of a part learned with learn_library_part may take placement, as create_elements does (its items=[] shows the placement_schema), in place of the fields it works out: an object or lamp keeps its story and elevation (center takes x and y only), a door or window its wall and centerOffset; leaves are written after the commit, and 'placed_not_set' names an element whose leaves were not set. A placement that cannot be worked out makes the whole call an error naming the change. After a placement, look (capture_window) and correct with this tool before reporting done; create_elements has the rules for reading a sketch. A commit reads the elements back: 'modified' counts what landed, 'failed' groups Archicad's refusals, 'not_applied' lists fields Archicad answered success for but did not change.
Inputs: changes (required), port, dry_run. Returns: object
move_elementsMove elementsADestructive
Move elements by a vector {x,y,z} in meters. Refuses without confirm=true. Archicad changes only elements in the database of the active window, so elements it would refuse (another view's, on a hidden or locked layer, not reserved in Teamwork, inside a hotlinked module, locked, or not found) are not sent. Returns requested; moved, counted from Archicad's per-element results; not_moved grouped by reason with the GUIDs; and active_window when anything was refused up front.
Inputs: guids (required), vector (required), port, confirm. Returns: object
preview_library_partsPreview library partsARead-only
Draw the 2D symbols of up to 8 library parts in one image, with nothing placed, to choose between candidates before learning one (a Tapir newer than 1.8.0). Each cell is numbered and has its own scale, with a red cross at the insertion point; 'parts' gives each part's number, default size (a, b, height) and extent in metres, and 'not_drawn' why a name could not be drawn, with the closest names. It shows the default parameters, and only lines, arcs and polygons, so no texts or hotspots. It does not replace learn_library_part or the look after placing.
Inputs: names (required), port.
publishRun a publisher setCDestructive
Fire an Archicad publisher set by name (Tapir). On a Tapir newer than 1.8.0 an unknown name is refused with the project's sets.
Inputs: publisher_set_name (required), port. Returns: object
read_schedule_schemeRead a schedule schemeARead-only
Describe an exported Archicad schedule scheme XML: its criteria and its ordered columns, with what each column binds to. Schedules have no API, so export the scheme first via Document > Schedules > Scheme Settings > Export and pass the file path. Reads the file only, never Archicad.
Inputs: path (required). Returns: object
record_library_partRecord a learned library partA
Record what you judged from learn_library_part's image, in the part's stored record. Objects and lamps: head ('+x', '-x', '+y' or '-y', the part's own axis its head points along), one_sided (true or false) and height (metres). The head is the end that goes against the wall: a bed's pillow end, a chair's or sofa's back, not its front. A bed's head is the end with the pillows, or with the duvet's turned-back edge; when the image shows neither, ask. Doors and windows (learned with refSide false): combos, which maps a flag pair (reflected then oSide, t for true and f for false: 'ff', 'tf', 'ft' or 'tt') to [hinge, swing], hinge 'begin' or 'end' of the wall's own direction and swing 'left' or 'right' of it; leaves (a whole number, at least 1); and leaf_states, which maps a state name to GDL parameter values. The lines dividing a window give its sashes, the arcs give which sash or leaf opens and where it is hinged. combos and leaf_states merge by key: recording a key again replaces it, and removing one takes forget and a new learn; every other field replaces its value. One refused value saves nothing. Returns the record and 'missing', the fields still needed before the part can be placed from it. forget=true removes the part's record, which can be learned again, and takes no other field. The part must have been learned first. Writes only the MCP's own learned-parts file, never the model, and needs no Archicad.
Inputs: name (required), head, combos, forget, +4 more. Returns: object
release_elementsRelease Teamwork elements and setsA
Release elements, and non-element object sets, from your Teamwork workspace (Tapir). CONFIRM-GATED: without confirm=true it reports would_release (the ones actually in your workspace), not_mine and not_found. With confirm=true releases them and reports released and still_mine. Unsent changes on a released element are not lost by this call; TeamworkSend is the gateway's job. object_sets takes the names reserve_elements takes; releasing a set sends that set's changes to the server first (Archicad does that as part of the release).
Inputs: port, guids, confirm, object_sets. Returns: object
reserve_elementsReserve Teamwork elements and setsA
Reserve elements, and non-element object sets, in a Teamwork project so you can edit them (Tapir). CONFIRM-GATED: without confirm=true it only reports what it can learn without touching the server: not_found, already_mine, and would_attempt. On Tapir 1.7.3 it also reads who holds an element (held_by_others, with the user's name); on older Tapir that is only learned by attempting, because Archicad exposes no read for it. With confirm=true returns reserved, reserved_by_others (with the user's name), already_mine, not_found, and indirectly_reserved: elements Archicad pulled into your workspace that you did not ask for, such as a door's wall. object_sets reserves what attribute, property and classification edits need: an attribute type (Layers, Composites, Fills, Lines, PenTables, Profiles, BuildingMaterials, Surfaces, ZoneCategories), Properties or Classifications, or any Archicad set name (Favorites, ProjectInfo, ...); needs Tapir 1.7.1. Each set's entry says status, held_by and outcome (would_reserve, already_mine, held_by_others, reserved, failed); for sets the dry run does know who holds them. A reservation is visible to every teammate and blocks their edits until released.
Inputs: port, guids, confirm, object_sets. Returns: object
run_ruleRun one QA ruleARead-only
Run one QA rule by id. Returns a verdict: pass/fail, failure count, failing element GUIDs.
Inputs: rule_id (required), port. Returns: object
save_projectSave the projectADestructive
Save the open project to its own file, as File > Save (Tapir). CONFIRM-GATED: without confirm=true it only reports what it would save. Call it before the reads that can crash Archicad 29 and lose unsaved work: property reads in get_element_data, set_element_data, find_elements with property comparisons, audit_delivery_readiness, run_rule, verify_ifc_export_readiness, get_model_summary with include_layer_story, modify_elements, and moving or deleting a locked element. A project never saved, or made in an older Archicad, needs File > Save As in Archicad; this tool does no Save As and says why a save was refused. On Teamwork it saves your local copy and never sends. file_updated says whether the file on disk changed.
Inputs: port, confirm. Returns: object
search_definitionsSearch property and attribute definitionsARead-only
Fuzzy search over property and attribute definitions, so a caller does not need to know the exact 'Group/Name'. Matches names, groups and enum values; case- and accent-insensitive. kind: 'property', 'attribute' (layers, fills, surfaces, composites, profiles, pen tables, ...) or 'any'. alternatives: up to 6 synonyms or translations searched too (useful on non-English projects). editable_only: keep only properties whose value can be written on at least one element type; check it before set_element_data. Each property match carries 'property', the exact address find_elements, get_element_data, set_element_data and rules accept, plus value_type, measure_type (Length/Area/Volume/Angle values are in m, m2, m3, radian), collection, editable, expression_based and enum_values. Results are ranked: whole-word matches first, then word starts, then substrings; a query word under 4 letters must start a word. total_matches counts everything; pass next_offset as offset to page past limit. Reads definitions only, never property values.
Inputs: query (required), kind, port, limit, +3 more. Returns: object
set_element_dataWrite element dataADestructive
Write element data. DRY-RUN BY DEFAULT: returns planned changes (current -> new) without touching the model; pass dry_run=false to commit. A change is {guid, property, value}; property takes the addresses get_element_data reads (a property, 'classification:', 'gdl:', 'marker:', 'ifc:.'), so one call can mix kinds. Classification values are an item ID or GUID, null unclassifies. GDL and marker values in metres and radians, an array as the whole list in its own shape (rows for two dimensions; array writes need Tapir 1.7.2), an attribute parameter by index or name. IFC values are text, a number or true/false, with an optional ifc_type (IfcLabel for text by default); Tapir writes IFC properties only in Archicad 27 and older. A commit sends classifications first and reads every change back: 'applied' counts what reads as sent; 'not_applied', changes Archicad answered success for but kept or replaced (a GDL Parameter Script can); 'failed', Archicad's refusals grouped by code and message with a count and sample GUIDs; 'skipped', changes not sent, with the reason (value type, enum, unknown parameter, a property the official API cannot read, or an element Archicad would refuse: in another view's database than the active window's, on a hidden or locked layer, inside a hotlinked module, locked with Edit > Locking, or not reserved in Teamwork); 'not_sent' and 'stopped' if a batch was refused outright after earlier batches landed; 'unconfirmed' if the read after the write failed. run_parameter_script=true (Tapir 1.7.3) runs the Parameter Script of every element whose GDL write went through, before the read back, so parameters that depend on the written ones update as they would after an edit in the settings dialog; 'parameter_script' reports the run. Off by default: a part's script can reset what was just written.
Inputs: changes (required), port, dry_run, run_parameter_script. Returns: object
set_selectionReplace current selectionA
Replace the current selection with the given element GUIDs. Whatever the user had selected by hand is deselected. The selection is read back afterwards. Returns requested; selected, the count Archicad really selected (it answers success and still leaves some unselected: section Objects, railing sub-elements, elevation marker parts, or GUIDs not in the plan); not_selected with those GUIDs when any; and the coverage of the read, as get_selection.
Inputs: guids (required), port. Returns: object
show_elementsShow elements in ArchicadA
Show elements to the user in Archicad: open the story or view that holds them (a section, elevation, detail, worksheet or layout when they are not on the floor plan), select them, highlight them and zoom to them. When they span several stories or views, the one holding the most is shown and the rest are listed (on_other_stories, in_other_views) for another call; with the 3D window in front, floor plan elements are shown there across every story. selected counts what Archicad really selected (not_selectable lists the rest). highlight=false removes any earlier highlight; guids=[] removes the highlight and, with select, the selection, and changes nothing else. in_3d=true (a Tapir newer than 1.8.0) opens the 3D window on just the floor plan's elements among them, as Show Selection in 3D does, so they always become the selection; there guids=[] shows everything, as Show All in 3D does. Changes only what is on screen, never the project.
Inputs: guids (required), port, zoom, in_3d, +2 more. Returns: object
update_extensionUpdate this extensionADestructive
Update this extension to the newest release. Dry run by default: it compares the installed version with the latest release on GitHub and says what it would do. confirm=true downloads the bundle for this computer, checks its sha256 and opens it, so Claude Desktop shows its own install dialog; nothing is installed until the user accepts there. Never downgrades. Reaches GitHub only when called. A server not installed as a Claude Desktop bundle gets the upgrade command instead. Needs no running Archicad.
Inputs: confirm. Returns: object
validate_schedule_schemeValidate a schedule schemeARead-only
Check an exported schedule scheme against the open project: do its property bindings still exist, and does any column caption disagree with what it is bound to. Reads property definitions only, not values, so it does not risk the property-read crash.
Inputs: path (required), port. Returns: object
verify_ifc_export_readinessVerify IFC export readinessARead-only
Run only the IFC-related QA rules to check IFC export readiness. Requires the Tapir add-on for IFC data.
Inputs: port. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 56 tools
Most tools have clearly distinct purposes (element CRUD, selection, attributes, properties, classifications, issues, BCF, QA rules, collisions, schedules), and the descriptions explain boundaries well, including when to prefer dedicated tools over the generic API escape hatches. Some overlap remains: create_elements can create any type while create_swept_beam/create_road_marking/create_road_arrow specialize in single library parts, show_elements also selects and highlights (overlapping highlight_failures and set_selection), and read/write API command tools shadow the dedicated surface.
All names are snake_case and almost uniformly verb_noun (list_issues, create_issue, get_element_data, modify_elements, delete_elements, run_rule, export_ifc). The few exceptions like 'publish' are still verb-first and unambiguous, so the set reads predictably.
56 tools is heavy for an agent to navigate, though the Archicad domain is genuinely enormous and each tool maps to a real subdomain. The count could be reduced by folding the three specialized creation tools into create_elements, merging selection tools, and trimming the generic API escape hatches, so the set is over-fragmented rather than fundamentally mismatched.
Coverage is unusually broad: element lifecycle, attributes, property/classification definitions and values, schedules (read/validate/edit XML), issues and BCF, QA rules, collisions, selection, view capture, library-part learning, Teamwork reservation, IFC export and publishing. Gaps exist around issue update/delete, layout/sheet and publisher-set management, undo, and story management, but generic tools and the API escape hatches let agents work around most of them.
Maintenance
Related MCP Connectors
MCP server giving Claude AI access to 22+ NYC public-record databases for real estate due diligence
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
Augments MCP Server - A comprehensive framework documentation provider for Claude Code
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Related MCP Servers
- AlicenseAqualityBmaintenanceMCP server for Archicad automation, enabling AI assistants to run Python scripts against running Archicad instances via the Tapir JSON API for complex workflows.4121 PyPI6MIT
- FlicenseNot gradedqualityCmaintenanceMCP server to control Autodesk Navisworks Manage 2025 from Claude via natural language, enabling model inspection, property search, selection sets, and clash detection.-
- AlicenseAqualityBmaintenanceMCP server that lets Claude manage an ISO 19650 / TCVN 14177 Common Data Environment on Autodesk Construction Cloud — projects, CDE folder trees, permissions, files, document status and naming compliance.451MIT
- AlicenseAqualityDmaintenanceA local MCP server giving Claude access to Trimble Connect, with 40 tools for projects, folder trees, files, versions, members, groups, and permissions via the Core API v2.40MIT