Showcase · D2 · 3D printer

A 3D printer, designed, verified and run by an AI agent in Polykrom.

The second rung of the ladder: a CoreXY printer in the style of a Voron Trident, from an empty design to a machine that draws a test square layer by layer. An AI agent was given six plain-language briefs and nothing but Polykrom's tools. It built the frame, the belt-driven XY motion and a three-screw Z axis from library parts and 27 printed parts, found how far each axis can travel, redesigned three printed parts to reach the build volume it was asked for, and ran a print study keyed only on the motors.

The printer in Polykrom's colours: a black 2020 frame, lime printed brackets and mounts, the bed partway down
Loading the printer (3 MB of meshes)…
step 0A 0°B 0°X 0Y 0tip 0 above the bed

Live: the URDF Polykrom exported from the agent's design, driven by its print study's recorded joint values. Motors A and B turn, the gantry and toolhead follow through the CoreXY links, and the bed drops 0.2 mm after each layer. The belts are hidden because they don't move with the machine (below). Drag to orbit, scroll to zoom.

252 × 272 × 284
mm build volume, against 250³
40.000 mm
along X only for A = B = 360°
8.000 mm
of bed travel per Z motor turn
0.2 · 0.4 · 0.6
mm test layers, 100.000 mm sides
287
parts, 9.48 kg
1 h 48 min
agent time, $27.85

How it was built

Each stage was one request to Claude Code running headless, with Polykrom's MCP server (polykrom-cli mcp --headless) as its only tool, starting from the design the stage before had saved. Times, costs and tool calls are from the agent's run records.

StageWhat the agent didTimeCostCallsErrors
1. Frame and bedA 400 × 400 × 450 mm frame of 2020 extrusion, eight printed corner brackets, four feet and the pixel-p badge, held by 36 M5 screws, most of them in T-nuts it modelled itself (the library has none); a 300 × 300 × 8 mm aluminium bed with a black print surface.11.7 min$4.09772
2. XY motionMGN12 rails and carriages, the gantry and toolhead, two NEMA17 motors on printed mounts, idlers on stacked 625 bearings and two GT2 belts. CoreXY links X = (A + B) / 2 and Y = (A − B) / 2, checked by driving the motors.22.2 min$8.481162
3. Z axisThree NEMA17 motors on printed mounts, couplers, T8 lead screws and nuts, printed bed brackets. The bed rides joint Z, driven by Zmotor through the 8 mm lead; the other two screws follow it 1 : 1.15.1 min$4.12636
4. VerifySwept each axis to its first contact and set the limits. X reached only 225 mm, so it reworked the gantry joiners and the carriage plate to reach 252; a Corners study to the build volume's eight corners then found the shroud hitting two corner brackets, so it reworked those too. BOM and mass.18.9 min$4.63893
5. PrintA 240-step Print study keyed only on A, B and Zmotor, with the motor angles worked out from the CoreXY relations: a 100 mm square, three layers, 0.2 mm apart. Traced the tip, checked for collisions, exported the GIF.12.4 min$2.36483
6. ShowcasePosed the machine, rendered it, exported the BOM, and checked that all 293 bodies still had their colours.27.6 min$4.17926
Total1 h 48 min$27.8548522

Errors are tool calls that came back with an error; the agent recovered from each one and reported what it worked around.

The briefs, word for word

1. Frame and bedthe brief

Start a new design: the frame and bed of a CoreXY 3D printer in the style of a Voron Trident (the XY gantry fixed at the top, the bed moving down on three lead screws). Frame: 2020 extrusions from the library (parts.insert family extrusion, size 2020): four vertical posts 450 mm long at the corners of a 400 x 400 mm footprint (outer faces flush with it), and eight horizontal members between the posts at the bottom and at the top (360 mm). Hold the corners together with 3D-printed corner brackets: at each of the eight corners a printed bracket that wraps the joint, each with M5 socket head cap screws (library) through it into the extrusions' slots or core. Four printed feet under the posts. Give the front a logo: Polykrom's pixel p, a printed badge made of 5 mm square cells, 6 cells tall, rows from the top '#####.', '##..##', '##..##', '#####.', '##....', '##....' (# is a cell), standing out 3 mm, mounted on the front of the top front extrusion, centred. Ground the frame (a grounded component named Frame holding its extrusions, brackets, feet, screws and the badge, or grounded subcomponents rigidly joined). Bed: an aluminium plate 300 x 300 x 8 in a component named Bed, centred, its top 380 mm above the frame's bottom, with a 1 mm black print surface on top. Report the frame's outer dimensions, its mass, a cut list, and how many brackets and screws you used.

2. XY motionthe brief

Open s1_frame.polykrom (a CoreXY printer frame with its bed). Add the XY motion, every part held: Y: an MGN12 rail 400 long on top of each of the two top extrusions that run along Y (left and right; extend them to the frame's outer edge if needed), fastened with M3 screws through its holes, each with an MGN12H carriage. Gantry: a 2020 extrusion along X joined to the two Y carriages by printed gantry joiners (one on each carriage, screwed to the carriage's M3 holes and to the extrusion), in a component named Gantry with those carriages and joiners; a slider joint named Y between the Frame and the Gantry, axis +Y. X: an MGN12 rail 350 long screwed to the gantry's front face, an MGN12H carriage on it, and a printed X-carriage plate on that carrying the toolhead: a printed shroud about 55 x 45 x 60, an aluminium heater block and a brass nozzle (a cone about 10 mm ending in a point), all in a component named Toolhead; a slider joint named X between the Gantry and the Toolhead, axis +X. Motors: two NEMA17-48 steppers at the two rear top corners on printed motor mounts (each mount screwed to the frame, the motor screwed to the mount with four M3 screws into its tapped holes), shafts vertical, a GT2 20T-5 pulley on each shaft; revolute joints named A (rear left) and B (rear right) about their shafts. Belts and idlers: idlers of stacked 625 bearings (library) on M5 screws in printed idler mounts at the two front top corners and at both ends of the gantry, and the two GT2 belts as thin solids (6 mm wide, 1.4 mm thick) along the CoreXY path at two heights, from each motor's pulley round the idlers to the X carriage: the belts are part of the picture, not of the kinematics. CoreXY: motion links that follow two joints (joint.motion_link with `also`): X follows (A + B) / 2 and Y follows (A - B) / 2, in mm of belt per degree (parts.library gt2_pulley: belt_mm_per_deg). Verify by driving: A = B = 360 deg moves the toolhead along X only, A = -B = 360 deg along Y only. Report what you measured, then put the joints back to 0, and check that nothing overlaps (inspect.interference) except fasteners in their holes.

3. Z axisthe brief

Open s2_xy.polykrom (a CoreXY printer with its XY motion). Add the Z axis, every part held: three NEMA17-40 steppers under the bed at its front left, front right and rear centre, each on a printed Z motor mount screwed to a bottom extrusion, shaft up; a shaft coupler (an aluminium cylinder 20 mm across, 25 long) joining each motor shaft to a T8 lead screw 400 long; a T8 lead nut on each screw, screwed into a printed bed bracket that carries the bed (the brackets fastened to the bed). The bed moves on a slider joint named Z between the Frame and the Bed (axis +Z), driven by a revolute joint named Zmotor (the front left motor) through joint.screw with the T8's lead (8 mm per turn); the other two motors and their screws turn with it (motion links). Verify: one turn of Zmotor moves the bed 8 mm and turns all three screws. Check that nothing overlaps except fasteners in their holes, and report the masses of the printed parts together.

4. Verify it as a machinethe brief

Open s3_z.polykrom (a complete CoreXY printer: gantry on joint Y, toolhead on joint X, motors A and B driving X and Y through CoreXY motion links, the bed on joint Z driven by Zmotor through lead screws). Verify it as a machine. 1. Travel: with joint sweeps (sweep a motor where a joint follows it), find how far X, Y and Z can go both ways before anything collides or a carriage would leave its rail, and set the joints' limits to that range. 2. Build volume: the box the nozzle tip can reach above the bed's print surface (X x Y x Z ranges); is it at least 250 x 250 x 250 mm? If not, change the design until it is, and say what you changed. 3. Collisions: a motion study named Corners keyed on A, B and Zmotor that takes the nozzle to the eight corners of the build volume; check it for interference and fix anything that collides. 4. The bill of materials (assembly.bom) by part and quantity, the total mass, the printed parts' mass, and the centre of mass.

5. Make it printthe brief

Open s4_verify.polykrom (a verified CoreXY 3D printer: A and B are the XY motors, Zmotor the bed's lead screws; X and Y follow A and B through CoreXY links). Make it print: a motion study named Print of 240 steps, keyed only on A, B and Zmotor (never on X or Y directly), in which the nozzle draws a 100 mm square centred on the bed three times, the first layer with the tip 0.2 mm above the print surface and each next layer 0.2 mm higher. Work out the motor angles for each corner from the CoreXY relations. Check it for interference. Trace the nozzle tip's path and report the square's side lengths and the corners' heights above the print surface. Export the animation as a GIF to corexy-print.gif (900 x 600), and give the motor angles you used for the first layer's corners.

6. Showcasethe brief

Open s5_print.polykrom (the finished CoreXY printer, in Polykrom's colours: black frame, lime printed parts, the pixel p badge on the front). Make its showcase pictures: put the joints at a pose that shows the machine well (the toolhead off centre, the bed partway down); render it in the render workspace (render.preflight, render.start, render.status until done, render.export) to printer-render.png at 1600 x 1000 from a three-quarter front view that shows the badge, and export the bill of materials as CSV to printer-bom.csv. Report the render's settings and the BOM's line count. Check before you finish that every part still has its colour.

every briefended with

Units are millimetres and degrees; Z is up. Work only through the Polykrom tools. Standard hardware comes from the parts library: parts.library lists the families (extrusion, stepper, gt2_pulley, linear_rail, linear_carriage, lead_screw, lead_nut, bearing, socket_head_cap_screw, hex_nut, washer...), with their dimensions. Everything has to make physical sense: every part is held by something (a bracket, a fastener, a joint), nothing floats and nothing overlaps another part except fasteners in their holes; parts that a real printer would 3D-print (brackets, mounts, joiners, the toolhead shroud) are modelled as their own components in PLA. Colours, Polykrom's: the aluminium frame anodised black (#111111), every printed part lime (#CCFF00), the bed's print surface black, metal hardware left as metal (appearance.assign). When the stage is done and you have verified it, save the design to <the stage’s file> and reply with a short report: what you did, the numbers you verified, and anything that did not work or that you had to work around.

Measured, not claimed

Every number here was measured on the model by Polykrom's tools: by driving joints, sweeping them to contact, tracing the nozzle and checking for interference. We then re-measured the test print from the exported URDF with this page's own viewer code.

The print

The Print study as Polykrom's headless renderer exported it. The motors are keyed, never X or Y directly: for each corner the agent solved A = 9 (X + Y) and B = 9 (X − Y) in degrees, and Zmotor lowers the bed 0.2 mm between layers. 121 frames, every second step (the export stops at 124 frames at 900 × 600). The agent hid the belts while recording.

First layer corner (X, Y)ABZmotor
(−50, −50) start−900°0°81°
(+50, −50)0°+900°81°
(+50, +50)+900°0°81°
(−50, +50)0°−900°81°

Zmotor 81° puts the tip 0.2 mm above the print surface; the second and third layers run at 72° and 63°.

Bill of materials

287 parts on 47 lines, from assembly.bom. Standard parts come from Polykrom's library with their part numbers. The rest were modelled for this printer and have no part number yet; the printed ones are PLA.

From the library

PartQty
2020 extrusion, 450 mm (posts)4
2020 extrusion, 360 mm (top and bottom)8
2020 extrusion, 395 mm (gantry)1
MGN12 rail, 400 mm2
MGN12 rail, 350 mm1
MGN12H carriage3
NEMA17-48 stepper (A, B)2
NEMA17-40 stepper (Z)3
GT2 pulley 20T-52
625 bearing (idlers)16
T8 lead screw, 400 mm3
T8 flanged nut3
ISO 4762 M3 × 8 · × 10 · × 1666 · 24 · 8
ISO 4762 M5 × 10 · × 16 · × 25 · × 3540 · 6 · 8 · 4

Made for this printer

PartQty
Corner bracket8
Foot4
Pixel-p badge1
Gantry joiner, left and right2
XY motor mount, A and B2
Front idler mount, left and right2
X carriage plate1
Hotend shroud1
Z motor mount3
Bed bracket3
Bed: aluminium plate with print surface1
Shaft coupler, Ø20 × 253
Heater block and nozzle1 + 1
GT2 belts (one body)1
M5 T-nut: slot · top38 · 8
M3 nut strip: X · Y1 · 2

27 printed parts of 17 designs, 1,363 g of PLA. Every left/right or per-motor variant is its own line in the CSV.

Where Polykrom fell short

A whole machine finds what a robot arm didn't. The ticked item was fixed while the printer was being built; the others are open issues.

Fastener seating

Seating a screw in a hole picked the wrong part.

In the Z stage, five tries at seating M3 screws in a printed motor mount failed with "no cylindrical face there": the stepper's shaft reaches up past the mount, so the stepper's bounding box held the mount's holes and won. The agent placed the screws by position with hand-made rigid joints. Fixed: the host is now the part that has a hole at the pick, on its wall or centred on one of its ends. → #134, fixed in #137

Belts

The belts don't follow the machine.

Each GT2 belt is a fixed solid drawn for one pose, so away from it every sweep and study shows the belts up to about 10 mm inside the joiners and carriage. The agent left them out of every motion check, hid them for the GIF and redrew them for the showcase pose; the saved belts fit only that pose, and the viewer above hides them. A belt routed over its pulleys, with its length measured, would move with the joints and check itself. → #139

Render limits

The renderer refused the whole printer.

Its preview mode stops at 262,144 triangles, and the printer has about 350,000, so the agent hid 113 parts the camera couldn't see. A 128-million pixel-work cap then made it pull the camera back to 1,950 mm, so the machine fills half the frame. The GIF export stops at 124 frames. polykrom-cli snapshot draws the whole machine; the picture behind the 3D view is one. → #140

The agent's render: the whole printer, small in the middle of a pale frame
The agent's render, as it came out.
Interference budget

The whole-printer collision check over the print stopped early.

Checking every part over the 240-step print study ran out of its budget after 10 samples, and a larger time budget made no difference. The agent split the check by hand into three groups (toolhead against bed, the bed's side, gantry and toolhead against the frame) to get a verdict. → #141

Copied screws

Screws placed as copies aren't recognised as fasteners.

A copy of a library screw isn't recognised as a fastener, so its thread engagement counts as a clash: 53 overlaps at the showcase pose, 28 in the first stage. The agent showed the overlaps match a seated screw's (5.8298 mm³ for the rails' M3 × 8 screws, copy or not) and rebuilt the first stage's copies as separate parts. → #142

Joints after a redesign

Joints on a redesigned face were dropped silently.

When the agent shortened the corner brackets' gussets, eight M5 screws seated on a face that no longer existed lost their joints without a warning: they and their T-nuts floated until the next stage noticed and re-seated them by hand. → #143

Stepper masses

Library steppers weigh what aluminium blocks of their shape would.

A NEMA17-40 comes out at 191.8 g against about 280 g for a real one, so the printer's 9,477 g and its centre of mass are short of the five real motors' weight. Standard parts need their datasheet masses. → #144

Take it apart yourself

The agent's design as it left it after the showcase stage (the belts fit that pose: toolhead at X 70, Y 40, bed 140 mm down), the bill of materials and the print study's joint values.