orca-slicer-mcp
Allows sending G-code to a Creality printer via SSH and its web UI, including uploading and starting print jobs.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@orca-slicer-mcp Slice model.stl to output.gcode"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
orca-slicer-mcp
An MCP server that drives OrcaSlicer headlessly on a private Xvfb
display, so an agent can import a model, slice it, and export G-code without a
physical screen.
It exists because OrcaSlicer has no scripting API for slicing profiles the way
its GUI does. Rather than click buttons by screen coordinate (fragile across
versions and resolutions), this server drives OrcaSlicer through its
single-instance IPC channel: a short-lived orca-slicer <arg> process
forwards its argument over DBus to the already-running GUI. Model paths load
via Plater::load_files; a small source patch adds an
orca-cmd:export:<path> command that slices the current plate and writes the
G-code straight to a file. No coordinate clicking, no file-chooser scripting.
Requirements
System binaries on PATH:
orca-slicer2.4.2, patched (see "OrcaSlicer patch" below)Xvfbopenboxxdotoolscrot
Python deps are declared in pyproject.toml (mcp, Pillow).
uv venv .venv
uv pip install --python .venv/bin/python -e .Related MCP server: Klipper MCP Server
OrcaSlicer patch
The DBus-command tools require a patched OrcaSlicer: patches/orca-mcp.patch
adds one IPC command, orca-cmd:export:<path>, that slices the current plate
and exports the G-code to <path> with no file dialog. It touches four files
(InstanceCheck.{hpp,cpp}, Plater.{hpp,cpp}): a new
EVT_EXPORT_GCODE_OTHER_INSTANCE event, its parsing in
OtherInstanceMessageHandler::handle_message, and Plater::export_gcode_to(),
which reuses the existing slice+export path (priv::export_gcode with
FORCE_EXPORT).
Apply it in the AUR PKGBUILD (portable, survives OrcaSlicer updates): add
orca-mcp.patch to source=()/sha256sums=() and
prepare() {
cd "$srcdir/OrcaSlicer-${pkgver}"
patch -p1 < "$srcdir/orca-mcp.patch"
}then rebuild with makepkg. The patch applies cleanly with patch -p1 against
the v2.4.2 source tree.
Single-instance IPC is only active when app.single_instance is true in
~/.config/OrcaSlicer/OrcaSlicer.conf; start_session sets this automatically
before launching. (The --single-instance CLI flag is not used - it is not
a valid OrcaSlicer 2.4.x option and is rejected by read_cli() before the IPC
code runs.)
Running
.venv/bin/orca-slicer-mcp # stdio MCP serverRegister it with your MCP client, e.g. for Claude Code:
claude mcp add orca-slicer -- /home/USER/forge/orca-slicer-mcp/.venv/bin/orca-slicer-mcpTools
Tool | Purpose |
| Launch Xvfb + openbox + OrcaSlicer; enable single-instance IPC; dismiss first-run/crash dialogs. Call first. |
| Terminate OrcaSlicer, openbox and Xvfb. |
| Report running state and current windows. |
| Return the current screen as a PNG image. |
| Load STL/OBJ/3MF/STEP/AMF/SVG into the running instance via single-instance IPC ( |
| Slice the current plate and export G-code to |
| Convenience: import + export. |
| Ship a local G-code to the Creality printer and start it (see Printing). |
| Low-level primitives for dialogs not yet covered by the high-level tools. |
Printing (Creality K1 Max)
print_gcode(gcode_path, start=True) closes the loop: it takes a G-code file
this server just exported and gets it printing without you walking to the
machine.
The printer's own web UI does expose starting a print, but only as a right-click/tap context-menu item per file — easy to miss and awkward on a phone. This tool drives the exact same two web actions programmatically:
upload —
POST /upload/<name>(multipart, fieldfile), andstart — a WebSocket
seton/wsapiwithopGcodeFile: "printprt:<gcode_dir>/<name>".
It reaches the Creality web UI through the docker container that serves it,
bypassing the public oauth2-proxy gate — the local side only runs scp and
ssh <host>; the HTTP upload and WebSocket start execute on the docker host
(see creality_print_remote.py), the only machine on the printer's LAN.
Configuration (environment variables):
Variable | Default | Meaning |
|
| SSH alias of the host running the Creality docker stack. |
|
| Docker container serving the web UI; talked to directly, bypassing oauth2-proxy. |
|
| Upload directory on the printer, used to build the |
Requires on the docker host: docker, curl, and Python with
websocket-client. Pass start=False to stage a file without printing.
Why each moving part exists (hard-won lessons)
These are baked into session.py; do not "simplify" them away:
A window manager is mandatory. Without one there is no
_NET_ACTIVE_WINDOW; focus and window management silently misbehave.openboxis launched with a bundledopenbox-rc.xmlthat makes every window undecorated and maximized.Commands travel over single-instance IPC, not the CLI action API. A second
orca-slicer <arg>process passes CLI validation (the arg is a plain positional, not an option), reachesinstance_check, and — becauseapp.single_instanceis enabled — forwards the whole command line over DBus to the running instance, then exits.--single-instancemust not be passed: it is not a valid 2.4.x option andread_cli()rejects it beforeinstance_checkruns, so the sender would error out or spawn a second GUI.app.single_instancemust betruebefore launch. It lives nested under the"app"object inOrcaSlicer.conf(not at the top level);start()sets it and OrcaSlicer preserves it across runs.Export completion is detected by the G-code file on disk, not by any GUI signal:
export_gcodepolls until the file stops growing across several samples (so a mid-write stall cannot yield a truncated read).Dialogs block the main window. The first-run SSL-certificate dialog, the update-check dialog, and — after any unclean exit — the crash "Restore" dialog all prevent the main window from being created.
start()interleaves dismissing them with waiting for the main window, in one loop.The main window's title varies ("Unnamed Window", "*Untitled", a project name), so it is detected by size (>=90% of screen width), not by title.
Every
xdotool/scrotcall has a timeout. A single blocked call (e.g. if the X server dies) would otherwise freeze every polling loop.Long-lived processes are owned by the server. They are spawned with
start_new_session=Trueand held by theOrcaSessionobject; launching them from an ephemeral shell that then exits would kill them.
Testing
.venv/bin/python test_e2e.pyRuns the full import -> export against a sample STL on a fresh Xvfb and asserts a non-trivial G-code is produced.
Available Tools
12 toolsclickA
Click at absolute screen coordinates (button 1=left, 3=right).
Inputs: x (required), y (required), button. Returns: result
export_gcodeA
Slice the current plate and export G-code to an absolute path.
Sends a single orca-cmd:export:<path> command over the single-instance
DBus channel. Inside OrcaSlicer this slices the current plate and writes the
G-code straight to (Plater::export_gcode_to), bypassing the file
dialog entirely. Completion is detected by the G-code file appearing on
disk. Returns a summary parsed from the generated G-code header.
Inputs: path (required), timeout. Returns: result
import_modelA
Import a model (STL/OBJ/3MF/STEP/AMF/SVG) into the running instance.
Delivers the file path to the already-running OrcaSlicer over the
single-instance DBus channel (orca-slicer <path> with single-instance
mode enabled in the app config), which routes it to Plater::load_files - no
coordinate clicking. Waits until a top-level window title reflects the
loaded model.
Inputs: path (required). Returns: result
press_keyA
Send a key or chord in xdotool syntax (e.g. 'ctrl+i', 'Return', 'Escape').
Inputs: keys (required). Returns: result
print_gcodeA
Send a local .gcode file to the Creality printer and start printing it.
Reaches the printer's web UI through the docker container on the configured SSH host, bypassing the public oauth2-proxy gate, and drives the same two web actions a human would: upload the file, then start the print.
Set start=False to upload only and leave the file staged on the printer.
Configuration (environment variables): CREALITY_SSH_HOST (default t580), CREALITY_PROXY_CONTAINER (default creality-proxy), CREALITY_GCODE_DIR (default /usr/data/printer_data/gcodes).
Inputs: gcode_path (required), start. Returns: result
process_modelA
Convenience: import a model then slice + export G-code in one call.
Inputs: stl_path (required), gcode_path (required). Returns: result
screenshotA
Capture the current OrcaSlicer screen and return it as a PNG image.
Inputs: no named parameters.
session_statusA
Report whether a session is running and list its top-level windows.
Inputs: no named parameters. Returns: result
start_sessionA
Start a private Xvfb display with openbox and launch OrcaSlicer on it.
Must be called before any other tool. Dismisses the first-run SSL and update dialogs. Returns a status string.
Inputs: width, height, display. Returns: result
stop_sessionA
Terminate OrcaSlicer, openbox and Xvfb, freeing the display.
Inputs: no named parameters. Returns: result
type_textC
Type literal text into the focused widget.
Inputs: text (required). Returns: result
zoomC
Zoom the 3D view. Positive steps zoom in, negative out, over (x,y).
When x/y are left at -1 the screen centre of the active session is used.
Inputs: steps (required), x, y. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 12 tools
Each tool has a distinct purpose: UI actions (click, press_key, type_text), file operations (export_gcode, import_model, process_model), session management (start/stop_session, session_status), printer control (print_gcode), view manipulation (zoom), and capture (screenshot). No overlapping functionality.
Most tools follow a verb_noun pattern (e.g., import_model, start_session). However, 'screenshot' is a noun, 'zoom' is a single verb, and 'session_status' uses noun_noun, introducing a few inconsistencies.
12 tools cover the core workflow (session lifecycle, model import, slicing, printing, UI interaction) without being excessive. Each tool justifies its existence for automating OrcaSlicer.
The set covers major workflows but lacks direct tools for model editing (e.g., scale, rotate) and printer status. However, UI tools like click and press_key can compensate, and the core slice-and-print path is complete.
Maintenance
Related MCP Connectors
MCP server for Hailuo (MiniMax) AI video generation
MCP server for Qwen Image 3 AI image generation
MCP server for OpenAI API (chat completions, image generation, embeddings) via AceDataCloud
MCP server for Grok Imagine AI video generation
Related MCP Servers
- AlicenseBqualityBmaintenanceEnables interaction with 3D printer management systems through an MCP server, supporting STL file manipulation, slicing, and control of printers like OctoPrint, Klipper, Duet, and more.309,585 npm261GPL 2.0
- FlicenseNot gradedqualityCmaintenanceAn MCP server that enables AI assistants to control and monitor Klipper 3D printers via the Moonraker API. It supports comprehensive printer management, including G-code execution, toolchanger operations, and real-time status monitoring.29-
- AlicenseNot gradedqualityCmaintenanceMCP server for generating print-ready 3D models from text descriptions via a multi-agent pipeline, enabling AI assistants to create and optimize STL files.1MIT
- AlicenseAqualityAmaintenanceMCP server that lets Claude drive a real, running OrcaSlicer: load models, arrange the plate, tune settings, slice, and read results back.661,944 PyPI99AGPL 3.0