carbonctl is an MCP server for my Elegoo Centauri Carbon 3D printer. An AI assistant can check on a print, look through the camera, read the print history, and pause, resume, or stop a print. It can’t do anything else to the printer.
Problem
I wanted to ask an assistant “is the print OK?” from anywhere, and let it stop a failing print. An assistant with direct access to real hardware needs limits that live in code, not in a prompt.
Work
flowchart LR A[MCP client<br/>Claude, agents] -->|loopback HTTP| C[carbonctl] C -->|WebSocket, SDCP| P[Printer] C -->|MJPEG| K[Camera] C -->|HTTP| H[Print history]
- Allowlist, not denylist. Only pause, stop, and resume can reach the printer. Every other command is rejected in one place.
- No one-shot stop. A stop needs a single-use token tied to the current print and valid for five minutes, followed by a human approval through MCP elicitation. A stale token, or one for a different print, fails.
- Loopback only. The server refuses to listen anywhere but localhost.
- Locked-down NixOS module. Runs as a sandboxed service that can reach only the printer and local clients. It runs on
europabehind my sign-in gate.
Stack
Go, MCP (streamable HTTP), SDCP over WebSocket, NixOS module.
Status
Active, and in daily use from my agents.
Lessons
- Put the safety checks in the server, where the model can’t argue its way past them.
- Two-step confirmation with a human in the loop costs little and removes the scariest failure.