klipper-manager

SKILL.md

Skill: klipper-manager

Klipper Manager — Full AI-Driven Printer Configuration & Diagnostics

Manages any Klipper printer via Moonraker API: reads and edits printer.cfg, runs diagnostics, executes calibration sequences, monitors live status, and fixes issues with full config-awareness.


Activation

When the user asks to:

  • Connect to / manage a Klipper printer
  • Read, change, or fix any printer.cfg setting
  • Diagnose a Klipper error or warning
  • Run calibration (bed mesh, probe, PID, resonances, pressure advance, axis twist, screws, etc.)
  • Monitor temperatures, positions, or print status
  • Send GCode commands
  • Restart firmware or Klipper

Always start by reading state/printer_context.json — if it exists, greet the user with a summary of the known printer. If it is missing or the user provides a new IP, run Phase 1.


Phase 1: Printer Discovery

Step 1 — Connect to Moonraker

Ask for the printer IP if not already known. Then verify connectivity:

curl -s "http://<IP>:7125/printer/info"

Expected response contains: state, hostname, software_version, config_file.

If state is not "ready", report it and ask the user to resolve before continuing.

Step 2 — Fetch printer.cfg

curl -s "http://<IP>:7125/server/files/config/printer.cfg"

Also fetch any included files referenced with [include ...]:

curl -s "http://<IP>:7125/server/files/config/<included_file>"

Common includes to auto-fetch: mainsail.cfg, macros/*.cfg, KAMP/*.cfg.

Step 3 — Parse and Inventory Config

Parse ALL sections from the fetched config. Extract and store in state/printer_context.json:

{
  "version": 1,
  "updated": "ISO-8601",
  "moonraker_url": "http://<IP>:7125",
  "klipper_version": "v0.13.x",
  "hostname": "mainsailos",
  "config_file": "/home/pi/printer_data/config/printer.cfg",

  "kinematics": "cartesian | corexy | corexz | delta | ...",
  "build_volume": {"x": 235, "y": 235, "z": 250},

  "steppers": {
    "stepper_x": {"position_max": 246, "position_min": 0, "rotation_distance": 40, "microsteps": 16},
    "stepper_y": {"position_max": 235, "position_min": 0},
    "stepper_z": {"position_max": 250, "position_min": -2}
  },

  "probe": {
    "type": "bltouch | probe | smart_effector | probe_eddy_current | none",
    "x_offset": -62,
    "y_offset": -12,
    "z_offset": 3.439
  },

  "bed_mesh": {
    "mesh_min": [60, 30],
    "mesh_max": [170, 220],
    "probe_count": [5, 5]
  },

  "axis_twist_compensation": {
    "calibrate_start_x": 20,
    "calibrate_end_x": 183,
    "calibrate_y": 117.5
  },

  "safe_z_home": {
    "home_xy_position": [108.5, 117.5]
  },

  "extruder": {
    "nozzle_diameter": 0.4,
    "rotation_distance": 7.687,
    "pressure_advance": null
  },

  "tmc_drivers": {
    "stepper_x": {"driver": "tmc2209", "run_current": 0.750, "stealthchop_threshold": 999999},
    "stepper_y": {"driver": "tmc2209", "run_current": 0.750, "stealthchop_threshold": 999999},
    "stepper_z": {"driver": "tmc2209", "run_current": 0.580, "stealthchop_threshold": 0},
    "extruder": {"driver": "tmc2209", "run_current": 0.580, "stealthchop_threshold": 0}
  },

  "input_shaper": {
    "x": {"type": "3hump_ei", "freq": 66.2},
    "y": {"type": "ei", "freq": 45.0}
  },

  "printer_limits": {
    "max_velocity": 300,
    "max_accel": 7000,
    "max_z_velocity": 15,
    "max_z_accel": 100
  },

  "installed_sections": [],
  "save_config_block": {},

  "known_issues": [],
  "last_diagnostic": null
}

Step 4 — Run Auto-Diagnostic

After parsing, always run the full diagnostic (see Phase 3) and report any issues found.

Step 5 — Present Summary

Show the user a table:

Printer    : mainsailos (Klipper v0.13.x)
Kinematics : Cartesian  |  Build: 246 × 235 × 250 mm
Probe      : BLTouch    |  x_offset: -62  y_offset: -12  z_offset: 3.439
Sections   : [printer] [extruder] [heater_bed] [bltouch] [bed_mesh] [axis_twist_compensation]
             [input_shaper] [firmware_retraction] [safe_z_home] [screws_tilt_adjust] ...
Issues     : (list any found by diagnostic, or "None detected")

Phase 2: Configuration Management

Reading a Setting

To read any setting, look up the parsed printer_context.json or re-fetch the file:

curl -s "http://<IP>:7125/server/files/config/printer.cfg"

Editing a Setting

Workflow for every config change:

  1. Fetch the CURRENT file (never edit a stale copy)
  2. Make the targeted change
  3. Validate the change (see Phase 3 validation rules)
  4. Save to a temp file C:/Users/<user>/Documents/printer_fix.cfg
  5. Upload via Moonraker:
    curl -s -X POST "http://<IP>:7125/server/files/upload" \
      -F "root=config" \
      -F "file=@C:/Users/<user>/Documents/printer_fix.cfg;filename=printer.cfg"
    
  6. Firmware restart to apply:
    curl -s -X POST "http://<IP>:7125/printer/firmware_restart"
    
  7. Wait 5 seconds, verify state: ready:
    curl -s "http://<IP>:7125/printer/info"
    
  8. Update state/printer_context.json
  9. Clean up temp file

CRITICAL: Never edit the SAVE_CONFIG block by hand. Only Klipper's SAVE_CONFIG command should modify that block. When uploading a modified config, preserve the entire #*# <--- SAVE_CONFIG ---> block exactly as-is unless explicitly removing stale calibration data.

Multiple Config Files

If the printer uses [include] sections, list all config files:

curl -s "http://<IP>:7125/server/files/list?root=config"

Fetch and edit the correct file — do not modify printer.cfg when the target section lives in an included file.


Phase 3: Diagnostics & Validation

Auto-Diagnostic Checklist

Run this every time a config is loaded or after any change. Check ALL rules:

1. Probe Offset Bounds

For every calibration section that uses probe coordinates, the nozzle must stay within [position_min, position_max] accounting for probe offsets.

Section Coord params Nozzle position formula
[axis_twist_compensation] calibrate_start_x, calibrate_end_x, calibrate_y nozzle_x = coord_x - probe.x_offset; nozzle_y = coord_y - probe.y_offset
[bed_mesh] mesh_min, mesh_max nozzle_x = mesh_x - probe.x_offset; nozzle_y = mesh_y - probe.y_offset
[screws_tilt_adjust] screw1..N (x,y) nozzle_x = screw_x - probe.x_offset; nozzle_y = screw_y - probe.y_offset
[safe_z_home] home_xy_position These are NOZZLE coords directly (no offset subtraction needed)
[delta_calibrate] radius probe must land within radius from center accounting for offset

Validate for each axis:

nozzle_x >= stepper_x.position_min  AND  nozzle_x <= stepper_x.position_max
nozzle_y >= stepper_y.position_min  AND  nozzle_y <= stepper_y.position_max

Fix formula:

max_coord_x = stepper_x.position_max + probe.x_offset   (when x_offset is negative)
min_coord_x = stepper_x.position_min - probe.x_offset   (when x_offset is positive)

2. Bed Mesh Bounds

mesh_min and mesh_max must be within the reachable probe area:

mesh_min.x >= stepper_x.position_min - probe.x_offset
mesh_max.x <= stepper_x.position_max + probe.x_offset  (when x_offset < 0)
mesh_min.y >= stepper_y.position_min - probe.y_offset
mesh_max.y <= stepper_y.position_max + probe.y_offset  (when y_offset < 0)

3. Safe Z Home Position

home_xy_position must be reachable for the NOZZLE:

home_xy.x >= stepper_x.position_min AND home_xy.x <= stepper_x.position_max
home_xy.y >= stepper_y.position_min AND home_xy.y <= stepper_y.position_max

Also validate that at the home position, the PROBE is over the bed (not hanging off the edge).

4. SAVE_CONFIG / Calibration Consistency

After a config change, check if saved calibration data in #*# SAVE_CONFIG is still valid:

  • If axis_twist_compensation bounds changed → old z_compensations / compensation_start_x / compensation_end_x may be stale → warn user to re-run AXIS_TWIST_COMPENSATION_CALIBRATE
  • If bltouch.z_offset or probe.z_offset was manually changed → warn that PROBE_CALIBRATE should be re-run
  • If bed_mesh bounds changed → existing mesh profiles may be out of bounds → warn to re-run BED_MESH_CALIBRATE

5. TMC Driver Warnings

  • stealthchop_threshold: 999999 on extruder with pressure advance → warn (reduced torque, but often acceptable)
  • hold_current configured → warn (can cause vibration, Klipper docs recommend omitting)
  • run_current > rated motor current × 0.85 → warn (thermal risk)
  • interpolate: True with high-precision requirements → note positional deviation (~0.006mm at 16 microsteps)

6. Input Shaper

  • shaper_type: 3hump_ei or 2hump_ei → complex resonance signature → recommend belt tension check
  • No [input_shaper] section → recommend running SHAPER_CALIBRATE
  • Shaper frequency < 20Hz → likely miscalibrated or very heavy toolhead

7. Pressure Advance

  • pressure_advance not set (0 or absent) in [extruder] → recommend calibration
  • pressure_advance > 1.0 → unusually high, check rotation_distance and extruder type

8. Rotation Distance Sanity

For extruder:

  • Direct drive: rotation_distance should be 4–10 (typical 7–8 for BMG-style)
  • Bowden: rotation_distance should be 20–40

For motion axes:

  • GT2 belt, 20-tooth pulley: rotation_distance = 40
  • GT2 belt, 16-tooth pulley: rotation_distance = 32
  • T8 leadscrew (2mm pitch, 4 starts): rotation_distance = 8
  • T8 leadscrew (2mm pitch, 1 start): rotation_distance = 2

9. PID Tuning

  • control: watermark → old method, recommend PID calibration
  • pid_Kp, pid_Ki, pid_Kd absent → heater has no PID, may be unstable

10. Missing Recommended Sections

Flag as warnings (not errors):

  • No [exclude_object] → object cancellation unavailable
  • No [firmware_retraction] → runtime retraction tuning unavailable
  • No [gcode_arcs] → arc support unavailable
  • No [respond] → macro feedback may be silent
  • No [pause_resume] → pause/cancel prints may not work

Phase 4: Live Status Monitoring

Query Printer Objects

Klipper exposes live state via Moonraker's objects API:

# Query everything
curl -s "http://<IP>:7125/printer/objects/query?toolhead&extruder&heater_bed&bed_mesh&probe&print_stats"

# Query specific fields
curl -s "http://<IP>:7125/printer/objects/query?toolhead=position,max_velocity,max_accel&extruder=temperature,target,pressure_advance"

Key objects and fields:

Object Key fields
toolhead position, homed_axes, max_velocity, max_accel, stalls
extruder temperature, target, pressure_advance, can_extrude
heater_bed temperature, target, power
probe or bltouch last_query, last_probe_position
bed_mesh profile_name, mesh_min, mesh_max, probed_matrix
print_stats state, filename, total_duration, filament_used
idle_timeout state, printing_time
motion_report live_position, live_velocity
firmware_retraction retract_length, retract_speed
input_shaper (queried from configfile)
tmc2209 stepper_x run_current, hold_current, drv_status, temperature
configfile save_config_pending, settings.<section>.<key>
webhooks state, state_message
system_stats sysload, cputime, memavail

Send GCode

curl -s -X POST "http://<IP>:7125/printer/gcode/script" \
  -H "Content-Type: application/json" \
  -d '{"script": "QUERY_ENDSTOPS"}'

Query Endstops

curl -s "http://<IP>:7125/printer/query_endstops/status"

Phase 5: Calibration Sequences

Probe Z-Offset (PROBE_CALIBRATE)

  1. Verify printer is homed: send G28
  2. Start calibration: PROBE_CALIBRATE
  3. Guide user through paper test at nozzle
  4. Accept: TESTZ Z=-0.1 (adjust in steps)
  5. Finalize: ACCEPT
  6. Save: SAVE_CONFIG (triggers firmware restart automatically)

Bed Mesh Calibration

  1. Home all axes: G28
  2. Optional: heat bed to print temp first
  3. Run: BED_MESH_CALIBRATE
  4. Save profile: BED_MESH_PROFILE SAVE=default
  5. Save to config: SAVE_CONFIG

Axis Twist Compensation

Before running, always validate calibrate_end_x:

max_safe_end_x = stepper_x.position_max + probe.x_offset

If calibrate_end_x > max_safe_end_x → fix it first (see Phase 2 edit workflow)

Then:

  1. Home: G28
  2. Run: AXIS_TWIST_COMPENSATION_CALIBRATE
  3. Follow prompts for paper test at each probe point
  4. Save: SAVE_CONFIG

PID Tuning

Hotend:

PID_CALIBRATE HEATER=extruder TARGET=200
SAVE_CONFIG

Bed:

PID_CALIBRATE HEATER=heater_bed TARGET=60
SAVE_CONFIG

Pressure Advance

Method 1 — Tuning tower (manual):

SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=1 ACCEL=500
TUNING_TOWER COMMAND=SET_PRESSURE_ADVANCE PARAMETER=ADVANCE START=0 FACTOR=.005

Print a tuning tower model. Measure optimal layer. Calculate: PA = START + FACTOR × best_layer_height_mm

Method 2 — Set directly after finding value:

SET_PRESSURE_ADVANCE ADVANCE=0.04

Then add to [extruder] in config and SAVE_CONFIG.

Resonance / Input Shaper Calibration

  1. Verify [adxl345] or other accelerometer configured
  2. Home: G28
  3. Test accelerometer: ACCELEROMETER_QUERY
  4. Measure noise baseline: MEASURE_AXES_NOISE
  5. Calibrate X: SHAPER_CALIBRATE AXIS=X
  6. Calibrate Y: SHAPER_CALIBRATE AXIS=Y
  7. Review results and apply recommended shaper
  8. SAVE_CONFIG

Screws Tilt Adjust

  1. Home: G28
  2. Run: SCREWS_TILT_CALCULATE
  3. Read output — each screw shows turn direction (CW/CCW) and amount (HH:MM)
  4. Re-run until all screws show < 0:05 deviation

TMC Driver Diagnostics

Dump driver state:

DUMP_TMC STEPPER=stepper_x
DUMP_TMC STEPPER=stepper_y
DUMP_TMC STEPPER=stepper_z
DUMP_TMC STEPPER=extruder

Adjust current at runtime (test only — add to config to persist):

SET_TMC_CURRENT STEPPER=stepper_x CURRENT=0.8 HOLDCURRENT=0.5

Phase 6: Troubleshooting

Use references/troubleshooting.md for the full error → cause → fix database.

Workflow for any error message the user pastes:

  1. Extract the error pattern (error type + coordinates/values if present)
  2. Match against known patterns in the troubleshooting reference
  3. Pull the relevant config sections from printer_context.json
  4. Compute the specific fix values using the validation formulas
  5. Present the diagnosis with the exact lines to change
  6. Offer to apply the fix automatically (Phase 2 edit workflow)

Common error patterns (quick reference):

Error Cause Fix
Move out of range: X Y Z [step] Nozzle would exceed axis limit; often probe offset not accounted in calibration coords Reduce calibrate_end_x / mesh_max by abs(probe.x_offset)
Must home axis first Axes not homed before move command Run G28
Endstop stepper_x still triggered Endstop stuck or wiring fault Check QUERY_ENDSTOPS, check endstop pin polarity
Unable to read tmc uart ... IFCNT TMC UART comms failure Check motor power and UART wiring; power cycle
TMC reports error: ... OvertempError TMC driver too hot Reduce run_current, improve cooling
TMC reports error: ShortToGND Shorted motor wire Check motor wiring
TMC reports error: Undervoltage PSU voltage dip Check PSU and wiring connections
Heater extruder not heating at expected rate PID tuning needed or heater/sensor issue Run PID_CALIBRATE HEATER=extruder TARGET=200
Probe triggered prior to movement BLTouch in wrong state or z_offset too high Run BLTOUCH_DEBUG COMMAND=reset then re-home
Timeout on connect Moonraker not running or wrong IP Verify printer IP and that Moonraker is running
Lost communication with MCU USB disconnect or firmware crash Run FIRMWARE_RESTART; check USB cable

Phase 7: Config Section Reference

Use references/config_sections.md for the complete parameter reference.

Key sections and their most commonly tuned parameters:

[printer]

kinematics: cartesian          # cartesian|corexy|corexz|delta|deltesian|polar
max_velocity: 300              # mm/s — runtime tunable via SET_VELOCITY_LIMIT
max_accel: 7000                # mm/s² — runtime tunable
max_z_velocity: 15             # mm/s (cartesian only)
max_z_accel: 100               # mm/s² (cartesian only)
minimum_cruise_ratio: 0.5      # 0.0–1.0, reduces top speed of short moves
square_corner_velocity: 5.0    # mm/s, higher = less deceleration at corners

[stepper_x/y/z]

rotation_distance: 40          # mm per full motor rotation
microsteps: 16                 # 8|16|32|64|128
position_min: 0                # soft limit minimum
position_max: 246              # soft limit maximum — CRITICAL for range checks
position_endstop: 0            # endstop position (must match position_min or position_max)
homing_speed: 80               # mm/s

[extruder]

rotation_distance: 7.687       # mm per motor rotation (direct drive ~7-8, bowden ~20-40)
nozzle_diameter: 0.400
pressure_advance: 0.04         # 0 = disabled; typical range 0.02–0.12 for direct
pressure_advance_smooth_time: 0.04
max_extrude_cross_section: 5   # max mm² cross section (4 × nozzle_diameter² is safe default)

[bltouch] / [probe]

x_offset: -62                  # probe X position relative to nozzle (negative = left of nozzle)
y_offset: -12                  # probe Y position relative to nozzle (negative = in front)
# z_offset: stored in SAVE_CONFIG block
samples: 3                     # number of probe samples
samples_result: median         # average|median
sample_retract_dist: 5.0
samples_tolerance: 0.01        # max deviation between samples (mm)
samples_tolerance_retries: 3

[bed_mesh]

mesh_min: 60, 30               # PROBE coordinates (not nozzle!)
mesh_max: 170, 220             # PROBE coordinates
probe_count: 5, 5              # grid points per axis
algorithm: bicubic             # lagrange (≤3×3) | bicubic (≥4×4 recommended)
fade_start: 1                  # mm height to start fading mesh correction
fade_end: 10                   # mm height where mesh correction reaches zero (0=disabled)

[axis_twist_compensation]

calibrate_start_x: 20         # PROBE X coordinate — nozzle = start_x - x_offset
calibrate_end_x: 183          # PROBE X coordinate — nozzle = end_x - x_offset
calibrate_y: 117.5            # PROBE Y coordinate — nozzle = calibrate_y - y_offset
# Rule: nozzle must be within [position_min, position_max]
# Formula: calibrate_end_x <= position_max + x_offset  (when x_offset < 0)

[safe_z_home]

home_xy_position: 108.5, 117.5  # NOZZLE position for Z homing (not probe!)
speed: 120
z_hop: 10
z_hop_speed: 5

[tmc2209 stepper_x]

run_current: 0.750             # Amps RMS — start at 70% rated current
hold_current: 0.500            # Optional — Klipper docs recommend omitting
stealthchop_threshold: 999999  # 999999=always stealthChop; 0=always spreadCycle
interpolate: True              # micro-step interpolation (small positional error)
driver_SGTHRS: 255             # stallGuard threshold for sensorless homing (if used)

[input_shaper]

shaper_type_x: 3hump_ei        # mzv|ei|2hump_ei|3hump_ei|zv|zvd
shaper_freq_x: 66.2            # Hz — from SHAPER_CALIBRATE
shaper_type_y: ei
shaper_freq_y: 45.0

[firmware_retraction]

retract_length: 0.5            # mm — direct drive: 0.4–1.0; bowden: 4–7
retract_speed: 60              # mm/s
unretract_extra_length: 0
unretract_speed: 60

Moonraker API Quick Reference

Base URL: http://<IP>:7125

Method Endpoint Purpose
GET /printer/info Klipper state, version, hostname
GET /server/files/config/printer.cfg Read printer.cfg
GET /server/files/list?root=config List all config files
POST /server/files/upload (multipart) Upload/overwrite a config file
POST /printer/firmware_restart Firmware restart (apply config changes)
POST /printer/gcode/script Send GCode command (JSON body: {"script":"..."})
GET /printer/objects/list List all queryable printer objects
GET /printer/objects/query?<obj>=<fields> Query live printer state
GET /printer/query_endstops/status Endstop states
POST /printer/gcode/script {"script":"SAVE_CONFIG"} Persist calibration data
GET /server/info Moonraker version, registered components
POST /machine/reboot Reboot the host (Pi)
POST /machine/shutdown Shutdown the host

File Upload (curl)

curl -X POST "http://<IP>:7125/server/files/upload" \
  -F "root=config" \
  -F "file=@/path/to/printer.cfg;filename=printer.cfg"

GCode Send (curl)

curl -X POST "http://<IP>:7125/printer/gcode/script" \
  -H "Content-Type: application/json" \
  -d '{"script": "G28"}'

Object Query (curl)

curl "http://<IP>:7125/printer/objects/query?extruder&heater_bed&toolhead"

Platform Notes

The AI performs all config fetching, parsing, and editing inline using curl (available on both Windows and Linux) and direct text analysis. The scripts in scripts/ are provided as reference implementations and work on Linux/macOS (require python3). On Windows, the AI executes the equivalent logic directly — do not rely on the shell scripts.

When running on the Klipper host directly (via SSH), the scripts work without modification.


File Structure

klipper-manager/
├── SKILL.md                         # This file
├── references/
│   ├── config_sections.md           # Full parameter reference for all config sections
│   ├── gcodes.md                    # All supported G-codes and extended commands
│   ├── troubleshooting.md           # Error patterns → causes → fixes
│   └── moonraker_api.md             # Full Moonraker API reference
├── scripts/
│   ├── fetch_config.sh              # Fetch printer.cfg from Moonraker
│   ├── upload_config.sh             # Upload modified config
│   ├── send_gcode.sh                # Send a GCode command
│   ├── query_status.sh              # Query printer status objects
│   └── diagnose.sh                  # Full diagnostic run
└── state/
    └── printer_context.json         # Persisted printer state (auto-created)

Base directory: file:///C:/Users/santi/.config/opencode/skills/klipper-manager

Weekly Installs
5
First Seen
3 days ago
Installed on
opencode5
gemini-cli5
github-copilot5
codex5
kimi-cli5
amp5