PlanPilotMCP
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| FREECAD_MCP_PORT | No | Port for the FreeCAD bridge (default 9876). | 9876 |
| FREECAD_MCP_TOKEN | No | Optional token to authenticate with the bridge. Must match the bridge's token if set. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| pingA | Check the link to the open FreeCAD: returns its version and active document. |
| create_rectangleA | Draw a 2D rectangle in the open FreeCAD (XY plane, all values in mm). (x, y) is the lower-left corner; width x height default to 10000 x 8000 mm. |
| create_wall_2dA | Draw one straight wall as a closed outline on layer 'murs' (mm). start/end are [x, y] points on the wall AXIS. Default thickness 200 mm. merge (default true): a wall that overlaps or touches other closed walls on 'murs' is fused with them into one clean outline (no doubled lines at corners and T junctions). Do it BEFORE placing doors/windows: a wall already cut open by a door is not merged. Returns the 4 corners, length, thickness and the resulting outline name(s). |
| create_partition_2dA | Draw one interior partition on layer 'cloisons' (mm). start/end are [x, y] points on the partition AXIS. Default thickness 100 mm. merge (default true): fused with the touching partitions into one outline, like create_wall_2d. |
| merge_wallsA | Fuse the closed wall outlines that overlap or touch into clean outlines (no doubled lines),
on layers 'murs' and 'cloisons' (or the given |
| create_wall_loopA | Draw a closed run of walls (e.g. a house perimeter) with clean mitered corners. points: polygon vertices [[x, y], ...] in mm, in order. alignment says where the points lie: "outer" (outside face - use this for "house 12 x 8 m"), "center" (wall axis) or "inner" (inside face). Draws the outer and inner outlines on layer 'murs' and returns axis_points (wall centre line: place doors/windows on it), plus the interior bounds and area (mm2). |
| create_door_2dA | Cut a door opening in the wall and draw the classic door: jambs, open leaf, swing arc.
The door is one block ("Porte"): move/copy/delete it as a single object. It is also a BIM object:
it keeps a mark (P1, P2... numbered per level unless position: [x, y] centre of the opening ON THE WALL AXIS (mm). width: default 900 mm. orientation: direction of the WALL, "horizontal" (along x) or "vertical" (along y). wall_thickness: thickness of the wall/partition crossed (default 200 = wall; use 100 for a partition). hinge: "start" (lower x/y end of the opening) or "end". swing: side the door opens to: north/south for a horizontal wall, east/west for a vertical one (default north / east). Warns if no wall was found at the position. |
| create_window_2dA | Cut a window opening in the wall and draw the 2D window (jambs, frame and glazing lines).
A BIM object like the door: mark (F1, F2...), position: [x, y] centre of the window ON THE WALL AXIS (mm). width: default 1200 mm. orientation: direction of the WALL, "horizontal" or "vertical". wall_thickness: thickness of the wall crossed (default 200). Warns if no wall was found there. |
| create_lineA | Draw a straight line between two [x, y] points (mm), optionally on a named layer. |
| create_polylineA | Draw a polyline through [[x, y], ...] points (mm); closed=True joins last to first. |
| create_circleC | Draw a circle (mm). |
| create_arcB | Draw a counter-clockwise arc from start_angle to end_angle (degrees, 0 = +x axis). |
| get_documentA | Active document: name, file, unit (mm), object count, layers and overall bounds. |
| get_objectsA | List drawing objects (name, label, type, layer, visible, bounds), optionally filtered by layer or type (Wire, Rectangle, Circle, Block). visible_only=true leaves out hidden objects and layers. Door/window blocks appear as one 'Block' object. |
| get_selected_objectsB | Objects currently selected by the user in FreeCAD. |
| get_object_geometryA | Exact geometry of one object: points/length/area (polyline), center/radius/angles (arc, circle) or components (block), in global mm coordinates. |
| get_layersB | Layers with object count, visibility, line width, colour and style. |
| get_boundsA | Bounding box of the whole drawing (or one layer): x/y min/max, width, height (mm). visible_only=true ignores hidden layers and objects. |
| move_objectA | Move objects by (dx, dy) mm. A door/window block moves as one, but the hole it cut in the wall stays where it was. |
| rotate_objectA | Rotate objects counter-clockwise by angle degrees around center (default: centre of the objects). |
| copy_objectA | Copy objects |
| delete_objectC | Delete objects (a block is deleted with its parts). |
| mirrorB | Mirror objects across the line through axis_start and axis_end ([x, y] mm). |
| offsetA | Create a parallel copy at |
| set_geometryA | Redefine an object's geometry. Polyline: points (+closed). Rectangle: x, y, width, height. Circle/arc: center, radius (+start_angle and end_angle for an arc). Not for blocks. |
| trimB | Trim a straight line: remove the part of |
| extendC | Extend a straight line (end = "start", "end" or "nearest") until it meets |
| create_layerB | Create a layer. Standard names (murs, cloisons, ouvertures, mobilier, cotations, textes, hachures) have default styles. line_color is [r, g, b] in 0..1; draw_style is Solid, Dashed, Dotted or Dashdot. |
| set_layerB | Put objects on a layer (created if needed). |
| set_visibilityC | Show or hide a layer. |
| set_line_widthA | Set the line width of a layer OR of objects (give exactly one of layer / names). |
| set_line_styleA | Set Solid, Dashed, Dotted or Dashdot on a layer OR on objects (exactly one of layer / names). |
| dimension_horizontalB | Horizontal dimension between two [x, y] points (mm). offset: distance of the dimension line from the points, > 0 above, < 0 below (default 600 at 1:50, i.e. 12 mm on paper). One 'Cote' block on layer 'cotations'. |
| dimension_verticalC | Vertical dimension between two points. offset > 0 puts the line to the right, < 0 to the left. |
| dimension_alignedB | Dimension of the true distance p1-p2, line parallel to it (offset > 0 = left of p1->p2). |
| dimension_linearC | Horizontal or vertical dimension, picked from the points (or direction="horizontal"/"vertical"). |
| dimension_angleB | Angle at |
| dimension_chainB | A chain of consecutive dimensions plus the overall dimension on a second line.
axis="horizontal": coordinates are x values measured along the face at y=edge; the line is
|
| dimension_exteriorB | Automatic exterior dimensions on the 4 sides of the walls (layer 'murs'): a chain through corners, door/window openings on that face and partitions meeting it, plus the overall dimension. Draw walls, partitions, doors and windows first. Returns the stops per side. |
| dimension_roomB | Clear interior width and depth of a room, drawn inside it along its bottom and left sides. points: the room's clear corners (wall FACES, not axes). Uses the bounding box. |
| create_textA | Single-line text (real vector geometry, prints in PDF). position = anchor on the baseline, align = left/center/right, angle in degrees. height = capital height in mm (default 2.5 mm on paper = 125 at 1:50). Layer 'textes' by default. |
| create_noteC | Multi-line note: |
| create_room_labelA | Room name with its area (e.g. "36,10 m2") centred in the room, as one block on layer 'textes'.
Give |
| get_textsA | All texts of the drawing (room names, areas, dimension values, notes) with position, height, layer and the block that holds them. |
| update_textA | Change the string of an existing text (name from get_texts), keeping its anchor and alignment. |
| create_hatchA | Hatch an area with parallel lines, as one block "Hachure" on layer 'hachures' (mm). points: the outline [[x, y], ...]. holes: outlines to leave empty, e.g. for a wall ring give the OUTER outline as points and the INNER outline as holes (both from create_wall_loop). pattern: "lines" or "cross" (second set at +90 degrees). angle in degrees (default 45). spacing: mm between lines; default 3 mm on paper = 3 x scale (scale = print denominator). Lines align on the world origin, so neighbouring hatches of the same angle/spacing match. avoid_openings (default true): no hatch inside the doors and windows already drawn. Hatch AFTER placing them; a door added or moved later does not clear the existing hatch. |
| create_stairA | Draw a stair on the active level as one block "Escalier" on layer 'escaliers' (mm): treads,
riser lines, walking line with arrow, and the cut line at 1.2 m. |
| create_stairs_3dA | Build the 3D steps of every stair of the active level (solid blocks from the floor up to each tread), standing on the level's floor. Replaces the previous ones of that level. |
| create_fillA | Solid fill (poché) of an area, as one block on layer 'poche' (mm): what a plan shows for concrete or masonry cut by the section plane. points = outline, holes = outlines left empty (walls: outer outline as points, inner as holes). tone "black" (solid) or "grey" (lighter). scale = print scale denominator (the fill is drawn with pen-thick lines so it prints solid on the sheet and in the PDF). avoid_openings (default true): doors and windows already drawn stay empty. |
| fill_wallsA | Fill (or hatch) the walls of the active level in one call: the wall outlines of layers 'murs' and
'cloisons' (or |
| create_walls_3dA | Extrude the 2D walls (layer 'murs', and 'cloisons' unless partitions=false) into solids of the given height (mm), from z=0. The doors and windows drawn in 2D are cut through: doors from the floor to door_height, windows from window_sill to window_sill + window_height. Replaces the previous 3D walls. Returns the volume (m3) and z range of each solid. |
| create_slabA | Floor slab under the house: |
| create_roofA | Roof over the walls (outline from the walls, or |
| clear_3dA | Delete the 3D volumes (walls, slab, roof) of one level, or of all levels. The 2D plan is untouched. |
| set_propertiesA | Change the BIM properties of a door/window block (mark, height, sill [windows], material, description) or of a room label (name, usage, floor_finish, description). Heights and sills in mm. After changing a height or sill, call create_walls_3d again to update the 3D. |
| set_wall_typeA | Describe the walls of a layer for the schedules and the IFC export: type name, material, fire rating (e.g. "REI 60"), finish, load_bearing. Defaults: murs = Mur, Maçonnerie, load-bearing; cloisons = Cloison, Plâtre. Only the given fields change. |
| get_wall_typesB | The wall type (name, material, fire rating...) of the 'murs' and 'cloisons' layers. |
| get_scheduleA | A quantity schedule of the building, read from the plan of every level (or one |
| export_scheduleA | Save a schedule as a CSV file (semicolon-separated, opens in Excel/LibreOffice). Default path: next to the FreeCAD document. An explicit path must be in the document folder, ~/Documents or $FREECAD_MCP_EXPORT_DIR; an existing file is only replaced with overwrite=true. |
| export_ifcA | Export the building to an IFC4 file (BIM): one storey per level, walls with their openings, doors and windows (mark, height, material) filling those openings, slabs, spaces (rooms with area and usage) and optionally a roof over the top level. Default path: next to the FreeCAD document. Path rules and overwrite as export_schedule. |
| create_levelA | Add a level (storey), e.g. name="R+1". elevation = floor level in mm (default: on top of the previous level); height = floor to floor. On an existing name, changes its elevation/height. activate=true switches to it (an empty plan). |
| set_active_levelA | Switch the drawing to a level: only its plan is shown, and new objects belong to it. |
| get_levelsA | The levels (name, elevation, height) and which one is active. |
| copy_levelA | Create a level as a copy of |
| set_viewA | Turn the FreeCAD 3D view like the navigation cube: top (plan view, the default), front, rear, left, right, bottom or isometric. rotation = extra turn in degrees in the screen plane (positive = the drawing turns counter-clockwise, i.e. to the left). fit=True also zooms to show the whole drawing. This only moves the camera; the drawing itself is unchanged. |
| create_drawing_pageA | Create a sheet: size A4/A3/A2/A1, landscape or portrait, print scale ("1:50"), with a French title block (cartouche) filled from projet, adresse, client (maitre d'ouvrage), titre (plan title), dessine, date (default today), numero, indice. Then call add_plan_view. Create the plan's dimensions and texts with scale= so they are readable on paper. |
| get_sheetC | The sheet's format, scale, title block fields and plan placement (fits / overlaps warnings). |
| set_page_sizeB | Change the sheet format (A4, A3, A2, A1); the plan is re-placed automatically. |
| set_orientationA | Switch the sheet to "landscape" or "portrait"; the plan is re-placed automatically. |
| set_scaleB | Change the print scale ("1:50", "1:100"...). The result warns if the plan no longer fits or if the dimensions/texts are too small to read at that scale. |
| add_plan_viewA | Put the drawing (all visible layers, or only |
| position_viewA | Move the plan so its centre is at (x, y) mm from the sheet's bottom-left corner. |
| add_title_blockA | Add the title block (cartouche) to a sheet created without one, and fill the given fields. |
| update_title_blockC | Change fields of the sheet's title block (only the given ones). |
| export_pdfA | Export the sheet to a PDF (vector, at print size). Default path: next to the saved FreeCAD file, else in ~/Documents. Path rules and overwrite as export_schedule. Returns the file path. |
| export_svgB | Export the sheet to an SVG file. Default path as export_pdf. |
| export_dxfA | Export a DXF. mode="model" (default): the plan at 1:1 in mm with its layers (murs, cloisons, ouvertures, cotations, textes...) and real editable texts, no sheet needed: use it to work in a CAD program. mode="sheet": the TechDraw page as drawn on paper (scaled). Path rules and overwrite as export_schedule. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 77 tools
Most tools target a distinct resource and action, but there are overlapping clusters: seven dimension tools, three fill/hatch tools, and three wall creation tools. The detailed descriptions disambiguate them, though an agent could still misselect between dimension_variant or fill_walls vs create_hatch.
All tools use a consistent verb_noun snake_case pattern, including dimensional variants (dimension_vertical, dimension_aligned) and level/export names. The few single-verb tools (mirror, offset, trim, extend) are conventional imperative commands and do not break the pattern.
77 tools is far beyond the well-scoped 3-15 range and the 25+ threshold, making the surface heavy. The broad architectural/BIM domain justifies some size, but this is still an extreme count that risks overwhelming agents and consuming context.
The tool surface covers the full lifecycle for the domain: create/get/update/delete for objects and levels, walls, doors/windows, stairs, 3D extrusion, schedules, and many export formats. Minor gaps exist (no delete_level, no door/window width update), but these can be worked around with existing tools.