lambdacad-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| BRICS_MCP_IN | No | Bridge input file path | /tmp/mcp_bricscad.in |
| BRICS_COMPACT | No | Set to 1 to expose only 14 essential tools (~1k schema tokens instead of ~7k) for clients that inject every schema | off |
| BRICS_DISPLAY | No | X display where BricsCAD runs (e.g. :77 for a nested Xephyr) | $DISPLAY |
| BRICS_MCP_OUT | No | Bridge output file path | /tmp/mcp_bricscad.out |
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": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| draw_batchA | Execute many drawing ops in ONE call - ALWAYS prefer this over single tools for 3+ entities. Each op is {"type":...} + params (optional "layer"). Types: line(x1,y1,x2,y2) circle(cx,cy,radius) arc(cx,cy,radius,start_angle,end_angle) rectangle(x1,y1,x2,y2) polyline(points,closed) point(x,y) text(x,y,text,height,rotation) mtext(x,y,text,width,height) ellipse(cx,cy,major_dx,major_dy,ratio) layer(name,color: set current) center_mark(x,y,size) bolt_circle(cx,cy,pcd,hole_dia,count) hatch(points,pattern,scale,angle) dim_linear/dim_aligned(x1,y1,x2,y2,line_x,line_y[,snap]) polygon(cx,cy,sides,radius) slot(x1,y1,x2,y2,width) rounded_rect(x1,y1,x2,y2,radius) symbol(symbol,x,y[,rotation,scale_denominator,layer]: a library symbol by the name a designer uses). Returns OK n= h=. |
| draw_lineA | Line from (x1,y1) to (x2,y2). |
| draw_circleC | Circle at (cx,cy) with radius. |
| draw_arcC | Arc: center, radius, start/end angles in degrees (CCW). |
| draw_ellipseB | Ellipse: center (cx,cy), major-axis endpoint (major_dx,major_dy) relative to center, ratio=minor/major. |
| draw_rectangleA | Rectangle (closed polyline) between opposite corners. |
| draw_polylineB | Polyline through [[x,y],...]; closed=true to close it. |
| draw_pointC | Point at (x,y). |
| draw_textC | Single-line text at (x,y); rotation in degrees. |
| draw_mtextB | Multiline text; (x,y)=top-left corner, width=wrap width. |
| bolt_circleC | N holes on a pitch-circle diameter (pcd), positions computed server-side; one call. |
| center_markC | Center-mark cross at (x,y). |
| hatch_polygonC | Fill a closed polygon with a real HATCH entity (pattern ANSI31, SOLID, ...). |
| polygonA | Regular polygon: center, number of sides, circumscribed radius, rotation degrees. |
| slotA | Slot/obround (asola, oblong hole): rounded-end slot between the two arc centers, given width. Use this for slots - NOT a rectangle. |
| rounded_rectC | Rectangle with rounded corners (raccordato), single polyline. |
| draw_splineB | Smooth spline through the given points [[x,y],...]. |
| draw_xlineA | Infinite construction line through (x,y) at angle degrees. |
| draw_donutB | Donut (filled ring; inner_dia=0 gives a filled dot). |
| chamfer_polylineA | Chamfer (bevel) ALL corners of a polyline with equal distances. |
| hatch_circleB | Hatch a circular area (creates the circle boundary + HATCH). |
| offset_entityB | Offset a curve by distance toward the side of point (toward_x,toward_y). CAD does the math. |
| fillet_polylineB | Fillet (round) ALL corners of a polyline with the given radius. CAD does the math. |
| mirror_entitiesA | Mirror entities across the axis (x1,y1)-(x2,y2). Draw half, mirror the rest. handles=['selection'] uses the GUI selection. |
| array_rectC | Rectangular array of entities: rows x cols with spacings. handles=['selection'] uses the GUI selection. |
| array_polarA | Polar array: copy entities count times around (cx,cy) over angle degrees. handles=['selection'] uses the GUI selection. |
| get_extentsA | Bounding box of the whole drawing or of one layer: cheap spatial check, no screenshot. |
| entity_lengthB | Length (and area if closed) of a curve: line, arc, circle, polyline, spline. |
| check_intersectionC | Do two entities intersect/overlap? Returns intersection points. The anti-collision check. |
| solid_volumeC | Volume and centroid of a 3D solid. |
| entity_pointsB | Key points of an entity (ends/mid/center/radius/vertices): connect geometry without math. |
| create_layerA | Create a layer with ACI color (1=red 2=yellow 3=green 4=cyan 5=blue 6=magenta 7=white) and optional lineweight in MM (0.13/0.25/0.35/0.50/0.70/1.00 - snapped to the nearest legal one). |
| set_current_layerA | Set current layer (created with color and optional lineweight in MM if missing). Line weight is what separates a drawing from a sketch: walls 0.50, visible edges 0.35, dimensions/hatching 0.18. |
| set_current_colorA | Set current entity color (ACI code; 256=ByLayer). |
| list_layersB | List layers with colors. |
| insert_blockB | Insert a block (or .dwg file) at (x,y); rotation in degrees. |
| create_blockA | Define a reusable block from existing entities (they become the definition; re-place with insert_block). |
| text_styleA | Create/set a text style with a font (e.g. isocpeur.ttf for ISO drawings) and make it current. |
| list_blocksA | List block definitions in the drawing. |
| list_symbolsA | What the symbol library offers: block name, Italian and English description, category and real size. Filter by category (unita/distribuzione/canali/terminali/regolazione/accessori) or leave empty for all. Use this before insert_symbol when you do not know what exists. |
| insert_symbolA | Place a library symbol by NAME OR BY WHAT YOU CALL IT: 'bocchetta di ripresa', 'recuperatore', 'sifone' all resolve through the library's synonym dictionary. Layer and scale come from the library index, so the symbol lands coloured and sized correctly without anyone remembering the convention (symbols are drawn for the index's reference scale; pass scale_denominator=100 for a 1:100 plan). Loads the block from the library DWG if the drawing does not have it yet. Use list_symbols to see what exists. |
| erase_lastA | Delete the last created entity. |
| erase_entityB | Delete an entity by handle, or handle='selection' for the user's GUI selection. |
| move_allA | Move ALL entities by (dx,dy). |
| move_entityA | Move entity by (dx,dy); handle='selection' moves the user's GUI selection. |
| copy_entityB | Copy entity with offset (dx,dy); handle='selection' copies the user's GUI selection. |
| rotate_entityA | Rotate one entity (or 'selection') around a base point by angle degrees (CCW). Turns around Z only - for any other axis use rotate_3d. |
| move_3dA | Move an entity in 3D by (dx,dy,dz); handle='selection' moves the user's GUI selection. move_entity only shifts in the XY plane. |
| rotate_3dA | Rotate entities around ANY axis: the line (x1,y1,z1)->(x2,y2,z2), by angle degrees (right-hand rule). This is how you swing a part about a hinge - rotate_entity can only turn around Z. |
| scale_entityB | Scale one entity (or 'selection') from a base point by factor. |
| set_entity_propsB | Change properties of an entity (or 'selection'): layer, color (ACI, 256=ByLayer), linetype. |
| explode_entityB | Explode a block/polyline/dimension into its components. |
| join_entitiesA | Join touching lines/arcs/polylines into one polyline (first handle = source). |
| break_entityA | Break an entity between two points (opens a gap; same point twice = split only). |
| rotate_allA | Rotate ALL entities around a base point by angle degrees (CCW). |
| scale_allB | Scale ALL entities from a base point by factor. |
| dim_linearA | Linear (horiz/vert) dimension between two points; (line_x,line_y)=dimension line position. Measures your EXACT coordinates: snap=True instead lets running object snap pull the ends onto nearby geometry (handy to dimension existing entities, but it can silently measure the wrong distance). |
| dim_alignedA | Aligned (parallel) dimension between two points; (line_x,line_y)=dimension line position. Exact coordinates unless snap=True (see dim_linear). |
| dim_radiusA | Radius dimension (R...) on a circle/arc by handle; angle=where it points (deg), offset=leader length factor. |
| dim_diameterB | Diameter dimension (D...) on a circle/arc by handle. |
| dim_angularC | Angular dimension: vertex + a point on each side + dimension arc position. |
| undoA | Undo the last N operations (a whole draw_batch counts as ONE). |
| redoB | Redo the last undone operation. |
| get_selectionA | What the user has currently selected in the GUI (count, handles, types, layers). Enables 'do X on what I selected'. |
| select_byA | Select+highlight entities by type and/or layer (wildcards ok: layer='MUR*'). Returns handles; user SEES the selection. |
| select_windowA | Select+highlight by rectangular area: crossing=false only fully-inside, true also touching. Optional type/layer filter. |
| drawing_infoA | Total entity count (OK n=). |
| get_entity_countsA | Instant census: entity count per type (cheap; call this FIRST to understand a drawing). |
| layer_infoA | Per-layer report: object count, color, linetype, frozen/locked. |
| list_entitiesA | List entities (type, handle, layer), paginated; optional type/layer filter (wildcards ok). Use get_entity_counts first on big drawings. |
| get_entityC | Raw DXF data of an entity by handle. |
| get_variableA | Read a system variable (e.g. CLAYER, DIMSCALE). |
| set_linetypeA | Assign a linetype to a layer: CENTER (chain, for axes), HIDDEN, DASHED, PHANTOM, CONTINUOUS. Loads it if missing; ltscale>0 sets global linetype scale. |
| set_dim_styleB | Appearance of NEW dimensions: text height, arrow size, decimal places, overall scale. |
| leaderA | Leader arrow: points at (x,y) [the feature], text lands at (end_x,end_y). For callouts like '4x D10'. |
| hatch_islandsA | HATCH the outer closed polygon SKIPPING the island polygons (hatch around holes). outer=[[x,y],...], islands=[[[x,y],...],...]. |
| trim_entityC | Trim: remove the portion of the entity at pick point, cut by the cutting entity. |
| extend_entityC | Extend: lengthen the entity (picked near the end to extend) until the boundary entity. |
| zoom_extentsA | Zoom to drawing extents. |
| zoom_windowB | Zoom to a rectangular window. |
| regenB | Regenerate the view. |
| save_as_dwgA | Save the drawing as DWG (2018) to path. Says so explicitly if the drawing is open read-only - typically a stale .dwl lock file left by a crash, which otherwise fails with nothing but 'Function cancelled'. |
| export_pdfA | Export the current view to PDF, fitted to the page. For a sheet at a real scale use export_sheet_pdf instead. |
| render_viewA | Render the drawing to a clean PNG (no UI chrome) for visual inspection. Pass a window (x1,y1,x2,y2) to frame a region; omit for current view. |
| export_dxfA | Export the drawing as ASCII DXF to path. |
| solid_boxA | 3D solid box: base corner (x,y,z), sizes dx,dy,dz (dz along Z). |
| solid_cylinderB | 3D solid cylinder: base center (cx,cy,z), radius, height along Z. |
| solid_sphereC | 3D solid sphere: center (cx,cy,z), radius. |
| solid_coneA | 3D solid cone: base center (cx,cy,z), base radius, height along Z. |
| solid_wedgeB | 3D solid wedge (ramp): base corner (x,y,z), sizes dx,dy,dz. |
| solid_torusC | 3D solid torus: center (cx,cy,z), ring radius, tube radius. |
| sweep_profileB | Sweep a closed 2D profile along a path curve -> 3D solid (pipes, rails, gaskets). |
| slice_solidB | Slice a 3D solid with a vertical plane through 2 points; keep='both' or a point-side 'x,y'. |
| extrude_profileA | Extrude a CLOSED 2D profile (polyline/circle) into a 3D solid, height along Z. The 2D->3D bridge. |
| revolve_profileA | Revolve a CLOSED 2D profile around axis (x1,y1)-(x2,y2) by angle degrees (turned parts). |
| bool_unionC | Union 3D solids into one. |
| bool_subtractA | Subtract solids from solids (holes, pockets). keep = the part, subtract = the tools. |
| fillet_solidA | Round edges of a 3D solid: edges = [[x,y,z], ...], ONE point lying ON each edge to round. Printed parts need this - a sharp inside corner is where the part cracks. The edge nearest the camera wins, so set the view (view_3d) when the target is hidden behind the part. Check the result with solid_volume. |
| chamfer_solidA | Chamfer edges of a 3D solid: edges = [[x,y,z], ...], ONE point lying ON each edge to cut. A 45 deg chamfer prints without support where a fillet would need it. The edge nearest the camera wins, so set the view (view_3d) when the target is hidden behind the part. Check with solid_volume - the chamfer runs out where it meets another edge, so expect slightly less removed than distance^2/2 * length. |
| export_stlA | Export 3D solids to STL - the file a slicer needs to actually 3D print the part. handles=None exports EVERY 3D solid in the drawing; pass handles to export one part per file. quality low/medium/high/default sets the tessellation: use high for anything curved, low leaves visible facets. to_origin parks the part on the origin before writing (STL keeps world coordinates, so a part modelled far from 0,0 would otherwise land metres away in the slicer) and puts it back afterwards. |
| bool_intersectC | Keep only the intersection of 3D solids. |
| boolean_verifiedA | Boolean that MEASURES what it did: volume before and after, and the change checked against expected_change (mm3, worked out from the shape you meant to remove or add). Catches the two failures a plain boolean reports as success: a cut that lands SHORT (the tool solid did not fully span the part, so volume drops and it looks fine - the leftover is a sliver you find in the slicer) and a cut that misses altogether (change exactly 0). Also encodes the trap that the result KEEPS the target's handle: SUBTRACT/UNION/INTERSECT write into the first solid instead of making a new entity, so (entlast) after a boolean belongs to somebody else. |
| assembly_placeA | Place a COPY of a master part into the assembly, posed and registered. The master stays where it is; the copy is moved so its bounding-box anchor ('min' = the lowest corner, natural for putting a part ON something at height z; 'center') lands at (x,y,z), then rotated rot_z degrees about that point. The instance is recorded under |
| assembly_listA | The assembly manifest: every placed instance with its pose, and whether its solid still exists in the drawing (an instance whose solid was consumed or erased is reported, not hidden - a manifest that cannot drift silently is the point of having one). |
| assembly_clearA | Remove instances from the assembly - their copied solids are erased from the drawing and their entries leave the manifest. names=None clears the whole assembly. Masters are never touched. |
| contact_reportA | Who touches whom in the assembly - and who touches NOTHING. For every pair of instances: bounding boxes first (cheap), then a real intersection on throwaway copies for the pairs whose boxes come within |
| hole_reportA | Probe every hole of a part and say which are actually OPEN. holes=[{name,x,y,z,axis,r,len}]: a probe cylinder (radius r SMALLER than the hole's, length len) is grown from (x,y,z) along axis X/Y/Z and intersected with a throwaway copy of the part - material found means the hole is blocked, and the volume says by how much. Born from a part that reached a printable state with four screw holes silently filled by an earlier union: a drawing lies about its holes unless something physically probes them. All probes run in one round-trip; the part is never modified. |
| graph_buildA | Read the 2D geometry as a CONNECTIVITY GRAPH and cache it: curves whose ends meet (within tol) become one node, so the drawing can be asked questions instead of read. Reports separate networks, junctions, total length, and the open ends - and for every open end checks whether it actually lands on another curve (a T-junction, fine) or on nothing (a real break, which on a schematic is the defect you were looking for). tol=None (the default) makes the joining tolerance EMERGE from this drawing's own endpoint distances by the max-jump rule, and the report states the value used - pass a number only to override what the drawing says. window=[x1,y1,x2,y2] limits it to one drawing area, layer to one layer. Lengths are exact (arcs and bulges included), in drawing units. |
| graph_traceA | Follow the network from a point through the graph_build cache: how many curves hang together with it, their total length (a take-off), and the open ends inside that network. Answers 'what is downstream of here' and 'is this the same run as that' without reading the drawing. Rebuild with graph_build if the drawing changed - this reads the cached index, and says so if it cannot find one. |
| overhang_reportA | Will this part print without supports, and which way up is best? Reads the STL mesh (no CAD needed) and measures the area that overhangs past limit_deg from the build plate, how much of that is flat ceiling (the bridges), the worst angle and the height where the trouble starts - then scores all six axis orientations so you can see whether simply flipping the part removes the problem. Areas are mm2. build_dir is the direction layers stack in ('z+' means the part prints as it is modelled, 'z-' upside down). Note this measures FACES, not spans: a flat ceiling area of zero means nothing bridges, but a large one does not say whether it is one wide bridge or many narrow ones. |
| view_3dA | 3D view: direction iso/iso2/top/front/back/left/right; shade wireframe/hidden/flat/gouraud. Zooms extents. |
| flatshot_viewA | Auto-generate a 2D drawing view (block) of ALL 3D solids, projected from direction (front/top/right/left/back/iso), lower-left corner placed at (x,y). Model in 3D, get the 2D view for free. Returns block handle+size. |
| view_planA | Back to flat 2D view (top, wireframe, zoom extents). Use after 3D work. |
| purge_drawingA | Purge unused layers, blocks, linetypes, styles from the drawing. |
| run_commandA | Run any BricsCAD command; tokens list, "" = Enter. The command name is checked to exist before anything is sent. Prefer dedicated tools when they exist. |
| run_lispA | Eval AutoLISP code (multi-line and multiple expressions OK); set (setq MCPRES ...) to return data. |
| list_documentsB | Every drawing open in the CAD, marking the one the tools are acting on, with entity count, unsaved changes and read-only state. |
| use_documentA | Choose which open drawing the tools act on (match on file name or any part of the path). Everything after this call lands there. |
| save_drawingA | Save the active drawing where it already lives. Confirmed by DBMOD returning to 0, which is the only thing that proves a write happened. |
| create_sheetA | Create/reset a paper-space sheet (layout) of size A4..A0 ready to plot 1:1: margins zeroed so paper mm = sheet mm, plot rotation cleared, auto-viewport removed. Returns the MEASURED sheet size. |
| add_viewportA | Put a window onto the model on a sheet: rectangle (x1,y1)-(x2,y2) in SHEET mm, at 1:scale, centred on model point (center_x,center_y). Returns the scale MEASURED back off the viewport. |
| fit_viewportA | Fit the model into a region of a sheet: measures what is drawn, picks the largest STANDARD scale that fits, then sizes the viewport to the drawing instead of to the region. Returns the scale it chose and why. |
| title_blockA | Draw the border and an ISO 7200 title block (180x40, bottom right) on a sheet, in SHEET mm. Reads the sheet size itself; returns the measured border. |
| export_sheet_pdfA | Export a sheet to PDF AT ITS SCALE (unlike export_pdf, which fits the drawing to the page). Verifies by measuring the page of the PDF it produced. |
| memory_enableA | Turn ON the drawing's autonomous memory journal. Registers a database reactor inside the CAD that appends every entity event (add / erase / undo-resurrect / modify) to a journal file beside the drawing - including changes the USER makes by hand in the GUI while no tool is running. Survives across sessions: call it once per CAD start. Then use tag_entity to give entities semantic roles and world_report to read the drawing's state and evolution. |
| memory_disableA | Turn the drawing's memory journal OFF, cleanly. Flushes whatever the reactor still holds in its queue, removes every lambdacad memory reactor application-wide (also the strays another drawing may have left behind), and stops bracketing tool evaluations. Tags and journal files stay on disk untouched. |
| tag_entityA | Give an entity a semantic ROLE in the drawing's memory. The role is what the geometry cannot say: "muro-nord", "asta-principale", "staffa-v2". Refuses dead handles - a memory that tags ghosts lies from day one. Tags live beside the drawing and survive sessions; world_report revalidates them against the live drawing every time it answers. |
| world_reportA | What is in this drawing, what changed, and is the memory still true. Reads the semantic tags and the autonomous journal, then REVALIDATES every tagged handle against the live drawing (entget - the only liveness test that survives entdel) in one round-trip. Reports: roles alive and dead, events since the last report (including manual GUI edits the reactor journaled), and untagged newcomers worth naming. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| traps | Hard-won failure modes of driving this CAD: read before a long session. |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Psalmustrack/lambdacad-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server