Reviving a 4-Year-Old Ender 3 V2 with Klipper, Mainsail and Claude Code
My Ender 3 V2 hadn’t printed anything since late 2021. It was running OctoPrint on Raspbian Buster with Klipper v0.10.0 — a setup that was solid at the time but completely outdated by 2026 standards. Python 3.7, no security patches, and a dead WiFi connection. Time to bring it back.
What made this project different: I did the entire migration through Claude Code, an AI coding assistant that can SSH into machines, read configs, write files, and execute commands. No manual terminal sessions, no copy-pasting from forum posts. Just a conversation.
The Starting Point
The printer was running:
- OctoPi (Raspbian Buster) with the OctoKlipper plugin
- Klipper v0.10.0 on an STM32F103 MCU
- Python 3.7 — already deprecated, with OctoPrint 1.12+ dropping support entirely
- A 3.5” SPI touchscreen connected via GPIO (unused)
- Direct drive mod, 0.6mm nozzle, input shaper tuned
The Pi 3 couldn’t even connect to WiFi anymore — the network had been switched to WPA3-only, and the Pi 3’s BCM43430 chip only supports WPA2.
Step 1: Backup Everything
Before touching anything, Claude Code SSH’d into the old Pi and backed up every important file:
# OctoPrint config, users, printer profiles
~/.octoprint/config.yaml
~/.octoprint/users.yaml
~/.octoprint/printerProfiles/_default.profile
# Klipper config and firmware build settings
~/printer.cfg
~/klipper/.config
The backup included PID-tuned values for the hotend and bed, input shaper frequencies, and the Klipper make menuconfig settings — all things that would be painful to redo from scratch.
Step 2: Flash MainsailOS
OctoPrint served well for years, but for a Klipper printer in 2026, Mainsail is the better choice. It was built specifically for Klipper — native config editing, exclude object support, bed mesh visualization, and a fraction of OctoPrint’s resource usage.
I flashed MainsailOS (Bookworm, Python 3.11) onto the same SD card. The new stack:
- Klipper v0.13.0 (host)
- Moonraker (API server)
- Mainsail (web UI)
- KlipperScreen (touchscreen UI)
Step 3: Fix WiFi
Claude Code diagnosed the WiFi issue in seconds — scanned available networks, identified that the primary SSID was WPA3-only (which the Pi 3’s Broadcom chip can’t handle), and switched the connection to a WPA2/WPA3 mixed-mode SSID on the same router. One nmcli command and the Pi was back online wirelessly. A good reminder that WPA3-only networks silently break older devices.
Step 4: Migrate the Config
The old printer.cfg was adapted for MainsailOS:
[include mainsail.cfg]
[exclude_object]
[mcu]
serial: /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0
restart_method: command
[input_shaper]
shaper_freq_x: 36.36
shaper_freq_y: 42.1
shaper_type: mzv
Key changes: added [include mainsail.cfg] for the Mainsail macros, added [exclude_object] for mid-print object cancellation, and removed the OctoPrint-specific virtual serial path.
Step 5: Flash the MCU Firmware
This was the trickiest part. Klipper strictly enforces version matching between host and MCU — v0.13.0 on the Pi refused to talk to v0.10.0 on the STM32F103.
Claude Code built the firmware on the Pi, tried the SPI SD card flash script (which failed due to the Creality bootloader’s SDIO quirks), and ultimately we went the manual route: copy firmware.bin to the printer’s SD card, power cycle with USB disconnected.
The Creality bootloader is notoriously picky:
- The filename must be different from the last flash
- USB must be disconnected during boot (otherwise the host grabs the serial port before the bootloader runs)
- A full power cycle is required (not just a switch toggle)
After the second attempt with USB disconnected, the MCU reported v0.13.0. Done.
Step 6: KlipperScreen on the 3.5” Display
The Pi had a generic 3.5” SPI display (ILI9486 + XPT2046 touch controller) sitting on top of it. I’d bought it years ago to use with OctoPrint but never got it working — the last time I tried, the screen stayed black and I gave up. Claude Code:
- Added the
piscreenoverlay to/boot/firmware/config.txt - Installed KlipperScreen via its install script
- Configured X11 to render on the SPI display instead of HDMI
# /etc/X11/xorg.conf.d/99-spi-display.conf
Section "Device"
Identifier "SPI Display"
Driver "modesetting"
Option "kmsdev" "/dev/dri/card0"
EndSection
After a reboot, the touchscreen showed Mainsail’s main menu with temperature readouts and print controls.
Step 7: Tune OrcaSlicer
The stock Creality Ender 3 V2 profile in OrcaSlicer ships with conservative settings — 500 mm/s² acceleration and 25 mm/s outer wall speed. With input shaper tuned and Klipper’s motion planning, the printer can do much more.
The tuned profile bumps acceleration to 2500 mm/s² and adjusts speeds to stay within the stock hotend’s volumetric flow limit (~10 mm³/s):
| Setting | Stock | Tuned |
|---|---|---|
| Acceleration | 500 mm/s² | 2500 mm/s² |
| Outer wall speed | 25 mm/s | 55 mm/s |
| Inner wall speed | 40 mm/s | 90 mm/s |
| Infill speed | 50 mm/s | 110 mm/s |
| Travel speed | 150 mm/s | 200 mm/s |
The acceleration change alone cuts 20-30% off print times without visible quality loss.
The Claude Code Workflow
What struck me most about this project was the workflow. Every step — backup, config migration, firmware build, WiFi diagnostics, display setup, slicer tuning — happened through a conversation. Claude Code SSH’d into both the old and new Pi, read configs, wrote files, diagnosed errors, and adapted when things didn’t work (like the bootloader refusing to flash).
Some highlights:
- WiFi diagnostics: scanned networks, identified the WPA3 incompatibility, reconfigured NetworkManager
- Firmware flash: built Klipper, attempted SPI flash, fell back to manual SD card method when the Creality bootloader was stubborn
- Display setup: probed DRM devices, configured X11 to use the SPI framebuffer, got KlipperScreen rendering on the right output
- Slicer profiles: reviewed the stock OrcaSlicer config and created a tuned profile based on the printer’s actual capabilities
It felt less like using a tool and more like pair-programming with someone who happens to know Klipper, Linux networking, X11 display configuration, and slicer settings.
What’s Next
The printer is running, but there’s more to do:
- Pressure advance calibration — currently at 0, should be ~0.04 for direct drive PLA
- Moonraker Telegram bot — notifications when prints finish or fail
- BLTouch/CRTouch — automatic bed mesh compensation instead of manual leveling
- High-flow hotend — the stock hotend is the speed bottleneck now, not the motion system
A printer that sat unused for four years is now running a modern stack, faster than it ever was. Not bad for an afternoon’s work.

The first print off the revived setup. Oh, and the 3D model itself? Also generated with AI. But that’s a story for the next post.
The views and opinions expressed here are my own and do not reflect those of my employer.