vcad.
Back to AI & Automation
AI & Automation

Loon for AI Agents

Practical patterns for AI agents generating Loon geometry programs

This guide covers practical patterns for AI agents writing Loon — vcad's Lisp-inspired geometry language. For the complete syntax reference, see Loon Language Docs. For a tutorial introduction, see Loon Language.

Loon vs VCode

vcad has two compact formats. Loon uses S-expression syntax with square brackets ([cube 50 30 5]), let bindings, and pipe. VCode is a separate line-based opcode format (C 50 30 5, Y 5 10) used for IR serialization. The create_cad_loon MCP tool accepts Loon, not VCode. If you are seeing single-letter opcodes, you are looking at VCode.

Structure of a Loon Program

A Loon program is a sequence of expressions evaluated top to bottom. The core pattern is: define named geometry with let, then declare visible outputs with root.

; 1. Optional custom materials
[material "purple" 0.5 0.2 0.8 0 0.5]

; 2. Build geometry with let bindings
[let plate [cube 100 60 5]]
[let hole [cylinder 2.75 10]]
[let drilled [difference plate [translate 50 30 0 hole]]]

; 3. Declare scene roots
[root drilled "aluminum"]

Built-in materials (aluminum, steel, abs-black, abs-white, etc.) are available without declaration.

Pattern: Named Assembly with let

Use let bindings to give names to intermediate results. This produces a readable sequence that mirrors a machining plan and makes debugging easier — if a dimension is wrong, you can identify which binding to adjust.

; Mounting bracket
[let base [cube 80 60 8]]
[let rib [translate 0 25 8 [cube 80 10 30]]]
[let bracket [union base rib]]

; Drill pattern
[let hole [cylinder 3.0 15]]
[let h1 [translate 15 30 0 hole]]
[let h2 [translate 65 30 0 hole]]
[let drilled [difference bracket [union h1 h2]]]

[let result [fillet 2 drilled]]
[root result "aluminum"]

Guideline: Name every significant intermediate result. Avoid deeply nested expressions with more than 2-3 levels — use let to flatten them.

Pattern: pipe for Sequential Operations

When a single body passes through a chain of transforms and features, pipe is more readable than nested let bindings or deep nesting.

[pipe
  [cube 50 50 30]
  [fillet 3]
  [shell 2]
  [translate -25 -25 0]]
[root _ "abs-white"]

Each step receives the previous result as its last argument. The special variable _ refers to the most recent pipe result.

Guideline: Use pipe for linear chains of 3+ operations on a single body. Use let when you need to reference intermediate results more than once (e.g., subtracting the same hole template from multiple positions).

Pattern: Reusable Tool Bodies

Define a "tool" shape once with let, then position it multiple times for repeated operations like holes or slots.

[let plate [cube 100 60 5]]
[let hole [cylinder 2.75 10]]

[let h1 [translate 10 10 0 hole]]
[let h2 [translate 90 10 0 hole]]
[let h3 [translate 10 50 0 hole]]
[let h4 [translate 90 50 0 hole]]

[let drilled [difference plate [union h1 [union h2 [union h3 h4]]]]]
[root drilled "aluminum"]

For regular arrays of holes, prefer patterns over manual placement:

[let plate [cube 100 60 5]]
[let bolt-hole [translate 40 0 -1 [cylinder 3 7]]]
[let pattern [circular-pattern 0 0 0 0 0 1 6 360 bolt-hole]]
[let result [difference plate pattern]]
[root result "steel"]

Pattern: Sketch and Extrude

For profiles that go beyond box/cylinder primitives, define a 2D sketch and extrude it.

[let profile [sketch xy
  [line 0 0 30 0]
  [line 30 0 30 5]
  [line 5 5 5 20]
  [line 5 20 0 20]
  [line 0 20 0 0]
end]]

[let bracket [extrude 0 0 15 profile]]
[root bracket "aluminum"]

Sketch planes: xy (horizontal), xz (front), yz (side). The profile must form a closed loop — the last point must connect back to the first.

Pattern: Multi-Part Scenes

Multiple root directives create multi-part documents. Each root gets its own material.

[let base [cube 100 100 10]]
[let pillar [translate 40 40 10 [cylinder 10 50]]]

[root base "steel"]
[root pillar "aluminum"]

Common Mistakes

Wrong: VCode opcodes in Loon source. The create_cad_loon tool expects S-expression syntax, not VCode opcodes.

; WRONG — this is VCode, not Loon
C 50 30 5
Y 3 10
T 1 25 15 0
D 0 2
; CORRECT — Loon syntax
[let plate [cube 50 30 5]]
[let hole [translate 25 15 0 [cylinder 3 10]]]
[root [difference plate hole] "aluminum"]

Wrong: Open sketches. Sketch profiles must close. An open profile causes an error during extrusion.

Wrong: Forward references. let bindings are evaluated in order. A binding cannot reference a name defined later in the file.

Workflow Integration

The standard MCP workflow with Loon:

  1. Generatecreate_cad_loon with the Loon source
  2. Verifyinspect_cad to check volume, bounding box, center of mass
  3. Iterate — Adjust dimensions in the Loon source if inspection reveals problems
  4. Exportexport_cad to STL or GLB, or open_in_browser for a shareable link
{
  "source": "[let plate [cube 50 30 5]]\n[root plate \"aluminum\"]",
  "format": "vcode"
}

The format parameter controls the output representation: "vcode" (default) returns the compact VCode serialization, "json" returns the full JSON IR. Both can be passed to downstream tools.

For the complete language specification, see the Loon Language Docs. For the create_cad_loon parameter reference, see create_cad_loon.