Skip to main content

Moonraker MCP server for E3CNC UI — exposes printer state, G-code, history, and system info as MCP tools

Project description

Moonraker MCP

A Moonraker component and MCP (Model Context Protocol) server for the E3CNC UI project.

What's inside

This package contains two things:

Component Purpose
CNC agent (cnc_agent.py) Moonraker component registered under [cnc_agent] — owns spindle, coolant, units, WCS, jog, and settings state. Vended into moonraker/moonraker/components/ during install.
MCP server (mcp_server.py) A standalone stdio-based MCP server that exposes Moonraker's API as MCP tools for AI agents.

CNC Agent

The CNC agent owns CNC-specific state that Klipper does not model:

  • spindle state and control (state, rpm, override)
  • coolant state and control (flood, mist)
  • units tracking (G20/G21)
  • active work coordinate system (G54..G59, G53) and per-WCS offsets
  • safe jog / set-zero / WCS-select command endpoints
  • CNC dashboard settings persistence (separate from Mainsail's settings)
  • machine profile loading for capability/safety/frontend feature gating

It registers HTTP endpoints under /server/cnc/*:

Endpoint Methods Description
/server/cnc/state GET Full agent state snapshot
/server/cnc/spindle GET, POST Read or control spindle (M3/M4/M5)
/server/cnc/coolant GET, POST Read or control coolant (M7/M8/M9)
/server/cnc/units GET, POST Read or set units (G20/G21)
/server/cnc/wcs GET Query WCS offsets from Klipper
/server/cnc/wcs/select POST Select active WCS (G54–G59)
/server/cnc/wcs/set-zero POST Set work zero at current position (G10 L20)
/server/cnc/jog POST Execute a guarded jog move
/server/cnc/settings GET, POST Read or persist CNC dashboard settings

Read-only Klipper machine state is not re-exposed — the frontend reads it directly from Mainsail's existing websocket store subscription.

MCP Server

The MCP server connects to a running Moonraker instance and exposes 13 tools that AI agents can call.

13 Exposed MCP Tools

Tool Moonraker Endpoint What it does
moonraker_server_info GET /server/info Moonraker version, loaded components
moonraker_server_config GET /server/config Parsed moonraker.conf
moonraker_printer_info GET /printer/info Klippy host info
moonraker_printer_objects_list GET /printer/objects/list Loaded Klipper objects
moonraker_query_printer_objects POST /printer/objects/query Query printer object state
moonraker_gcode_help GET /printer/gcode/help Supported G-code commands
moonraker_send_gcode POST /printer/gcode/script Send G-code to Klipper
moonraker_job_queue_status GET /server/job_queue/status Job queue state
moonraker_history_list GET /server/history/list Print history (filterable)
moonraker_webcams_list GET /server/webcams/list Configured webcams
moonraker_system_info GET /machine/system_info Host OS and service info
moonraker_proc_stats GET /machine/proc_stats Process statistics
moonraker_request Generic Raw request to any Moonraker endpoint

Running the MCP server

Option A — install from PyPI (recommended):

pip install moonraker-mcp
moonraker-mcp

Option B — install from source:

cd E3CNC/moonraker-mcp
pip install -e .
moonraker-mcp

Option C — run directly (no install):

cd E3CNC/moonraker-mcp
PYTHONPATH=src python -m moonraker_mcp.mcp_server

Environment variables

Env Var Default Purpose
MOONRAKER_URL http://127.0.0.1:7125 Moonraker API base URL
MOONRAKER_API_KEY (none) API key if Moonraker auth is configured
MOONRAKER_TIMEOUT 15 Request timeout in seconds

Connecting to AI Agents

The MCP server uses stdio transport — it communicates via stdin/stdout. Register it in your AI agent's MCP configuration.

Claude Desktop

Add to claude_desktop_config.json (typically at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "moonraker": {
      "command": "moonraker-mcp",
      "args": [],
      "env": {
        "MOONRAKER_URL": "http://192.168.1.100:7125"
      }
    }
  }
}

If you didn't pip install -e ., use the full Python path:

{
  "mcpServers": {
    "moonraker": {
      "command": "/usr/bin/python3",
      "args": ["-m", "moonraker_mcp.mcp_server"],
      "env": {
        "MOONRAKER_URL": "http://192.168.1.100:7125"
      }
    }
  }
}

Cursor

Go to Settings → MCP → Add New MCP Server and fill in:

  • Name: moonraker
  • Type: command
  • Command: moonraker-mcp
  • Env (optional): MOONRAKER_URL=http://192.168.1.100:7125

Or add to .cursor/mcp.json in your project:

{
  "mcpServers": {
    "moonraker": {
      "command": "moonraker-mcp",
      "args": [],
      "env": {
        "MOONRAKER_URL": "http://192.168.1.100:7125"
      }
    }
  }
}

VS Code (Continue extension)

Add to ~/.continue/config.json:

{
  "experimental": {
    "mcpServers": [
      {
        "name": "moonraker",
        "command": "moonraker-mcp",
        "env": {
          "MOONRAKER_URL": "http://192.168.1.100:7125"
        }
      }
    ]
  }
}

Windsurf

Add to your Windsurf MCP config:

{
  "mcpServers": {
    "moonraker": {
      "command": "moonraker-mcp",
      "env": {
        "MOONRAKER_URL": "http://192.168.1.100:7125"
      }
    }
  }
}

Any MCP-compatible agent

The pattern is always the same: register a subprocess that runs moonraker-mcp (or python -m moonraker_mcp.mcp_server) with MOONRAKER_URL set to your printer's Moonraker address.

Example AI prompts

Once connected, an AI agent can use the tools. Some examples:

"What's the printer status?" → calls moonraker_printer_info + moonraker_query_printer_objects

"Home all axes" → calls moonraker_send_gcode({ "script": "G28" })

"Set spindle to 12000 RPM clockwise" → calls moonraker_send_gcode({ "script": "M3 S12000" })

"Show the last 10 print jobs" → calls moonraker_history_list({ "limit": 10 })

"What webcams are configured?" → calls moonraker_webcams_list

"List all loaded Klipper objects" → calls moonraker_printer_objects_list

Network notes

  • The MCP server runs on the same machine as the AI agent (your dev machine). It connects to Moonraker over HTTP.
  • If Moonraker is on a different machine (the printer), set MOONRAKER_URL to the printer's IP (e.g. http://192.168.1.100:7125).
  • Make sure your dev machine's IP is in Moonraker's trusted_clients list (in moonraker.conf).

Installing the CNC Agent on a Printer

Ansible playbook (recommended)

cd ~/E3CNC_UI
ansible-playbook ansible/playbooks/install.yml

This vendors the CNC agent into Moonraker, configures [cnc_agent] and [cnc_metadata] sections, deploys the WCS plugin and macros, builds the frontend, and restarts services.

Legacy bash script

cd ~/E3CNC_UI
./scripts/install_to_moonraker.sh

Updating via Moonraker Update Manager

The Ansible install and bash script both register an [update_manager E3CNC_UI] entry in moonraker.conf. After a git pull, the post_update_script automatically:

  1. Downloads the latest pre-built frontend (avoids running vite build on the printer)
  2. Re-vendors the CNC agent files into moonraker/components/
  3. Re-deploys the metadata extractor, WCS plugin, and macros
  4. Restarts Moonraker

Clicking Update in Mainsail's Machine → Update Manager panel is all you need.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

moonraker_mcp-0.1.1.tar.gz (17.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

moonraker_mcp-0.1.1-py3-none-any.whl (13.2 kB view details)

Uploaded Python 3

File details

Details for the file moonraker_mcp-0.1.1.tar.gz.

File metadata

  • Download URL: moonraker_mcp-0.1.1.tar.gz
  • Upload date:
  • Size: 17.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for moonraker_mcp-0.1.1.tar.gz
Algorithm Hash digest
SHA256 464bd575552a433a1ae93a3f3ac11e59a896615e4fe2a60a6714974fb0e10d39
MD5 3ae57e8b09e55b600545a577cab97e3d
BLAKE2b-256 316036707289202cddc8f43fa7ed05559bd12afd62f6c2f3068d866a0cd86c48

See more details on using hashes here.

Provenance

The following attestation bundles were made for moonraker_mcp-0.1.1.tar.gz:

Publisher: publish-moonraker-mcp.yml on E3CNC/E3CNC_UI

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moonraker_mcp-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: moonraker_mcp-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 13.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for moonraker_mcp-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7cc572206583d05324215bb23607790c3088e91b66f76b8c57539961aa46d09b
MD5 930f2c5dfa3252eabcd4bb479b5d75b8
BLAKE2b-256 1f471e812ae72d012e2959865a563cd91919c3db37513aa8c39bca6e714ef694

See more details on using hashes here.

Provenance

The following attestation bundles were made for moonraker_mcp-0.1.1-py3-none-any.whl:

Publisher: publish-moonraker-mcp.yml on E3CNC/E3CNC_UI

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page