Skip to main content

Python client and MCP server for Elegoo Centauri Carbon 3D printers

Project description

pycentauri

Python client, CLI, and MCP server for the Elegoo Centauri Carbon 3D printer.

pycentauri speaks the printer's native SDCP v3 protocol over its local WebSocket (port 3030) — no cloud account required. It exposes five surfaces:

  1. An async Python library for direct integration.
  2. A centauri CLI for quick status checks, snapshots, and control.
  3. An MCP server so AI agents (Claude Code, Claude Desktop, Cursor, any MCP-compatible client) can monitor and drive the printer as a tool.
  4. An HTTP + SSE server for dashboards, reverse-proxy integration, and anything that wants a plain REST API.
  5. A built-in web UI (dark theme, mobile-friendly) served at /ui/ by the HTTP server — live webcam, progress, temperatures, and control.

Status: alpha. The protocol has been reverse-engineered from the official elegoo-link C++ SDK and the CentauriLink project. It works against the original Centauri Carbon on current firmware. The newer Centauri Carbon 2 (which uses MQTT) is not supported.

Install

pip install pycentauri                    # library + CLI
pip install "pycentauri[mcp]"             # + MCP server
pip install "pycentauri[server]"          # + HTTP REST/SSE server
pip install "pycentauri[mcp,server]"      # everything

Quick start — CLI

# Find printers on your LAN
centauri discover

# One-shot status (pretty or JSON)
centauri status --host 192.168.1.209
centauri status --host 192.168.1.209 --json

# Stream live status updates
centauri watch --host 192.168.1.209

# Grab a webcam snapshot
centauri snapshot --host 192.168.1.209 shot.jpg

# Files on the printer
centauri files --host 192.168.1.209

# Control actions require --enable-control
centauri print start cube.gcode --host 192.168.1.209 --enable-control
centauri print pause              --host 192.168.1.209 --enable-control
centauri print resume             --host 192.168.1.209 --enable-control
centauri print stop               --host 192.168.1.209 --enable-control

The host can also come from PYCENTAURI_HOST or ~/.config/pycentauri/config.toml.

Quick start — Python

import asyncio
from pycentauri import Printer

async def main():
    async with await Printer.connect("192.168.1.209") as printer:
        status = await printer.status()
        print(status.state, status.progress, status.temp_nozzle)

        jpeg = await printer.snapshot()
        with open("shot.jpg", "wb") as f:
            f.write(jpeg)

        async for update in printer.watch():
            print(update.state, update.progress)

asyncio.run(main())

Quick start — HTTP server

# Read-only, bound to loopback so only this box can hit it:
centauri server --host 192.168.1.209 --port 8787

# Read + write, bound to all interfaces (put a reverse proxy in front):
centauri server --host 192.168.1.209 --bind 0.0.0.0 --port 8787 --enable-control
Method Path Notes
GET / Redirects to /ui/
GET /ui/ Built-in web dashboard
GET /api/info Health + version (JSON)
GET /status Latest status push (cached; updates every ~5s)
GET /attributes Printer attributes
GET /snapshot image/jpeg response
GET /stream MJPEG stream proxied from the printer (embeds in <img>)
GET /discover LAN scan
GET /events/status Server-Sent Events stream of pushes
POST /print/start Body: {"filename": "cube.gcode"}. Requires --enable-control.
POST /print/{pause,resume,stop} Requires --enable-control.

The server holds a single long-lived WebSocket to the printer and reuses it for every request — no per-request reconnect, and it won't bump into the firmware's 5-slot limit.

Quick start — MCP

Register the server with your agent. With Claude Code:

claude mcp add pycentauri -- python -m pycentauri.mcp
# or, with control actions enabled (gives the agent start/pause/stop/upload):
claude mcp add pycentauri -- python -m pycentauri.mcp --enable-control

Set PYCENTAURI_HOST in your MCP server env so the agent can't target an arbitrary IP. The server exposes these tools:

Tool Always available Description
get_status yes State, temperatures, progress, elapsed/remaining
get_attributes yes Model, firmware, mainboard ID
list_files yes Files stored on the printer
get_snapshot yes Webcam frame as MCP Image content
discover_printers yes LAN scan
start_print only with --enable-control Starts a print
pause_print only with --enable-control Pauses the current print
resume_print only with --enable-control Resumes a paused print
stop_print only with --enable-control Stops the current print
upload_file only with --enable-control Uploads a file to the printer

Safety

Control actions are gated behind an explicit enable_control=True (library) or --enable-control flag (CLI / MCP). Destructive MCP tools are not even registered when the flag is off, so an LLM never sees them. Still: leaving a printer running unattended with write-capable agents is your responsibility.

Known firmware quirks

  • 5 concurrent WebSocket connections max. The printer's SDCP server accepts up to 5 open WebSockets on port 3030; the 6th returns HTTP 500 with body "too many client". Slots release immediately when a connection closes — the CLI and MCP server each open/close one per invocation, so this is almost never a problem in practice.
  • Paused / errored states don't auto-push Attributes. The printer only sends its Attributes frame spontaneously while idle or printing. In paused and errored states it stays silent until asked. Since every SDCP command needs the printer's MainboardID, the client takes care of this by pre-seeding the mainboard ID from a UDP discovery on every connect (as of v0.1.1). If you call Printer.connect() directly without discovery, pass mainboard_id= yourself.

Credits & licensing

  • Protocol reference: elegoo-link (Apache-2.0) and CentauriLink.
  • pycentauri is licensed under Apache-2.0. See LICENSE.
  • Not affiliated with or endorsed by Elegoo.

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

pycentauri-0.3.1.tar.gz (43.8 kB view details)

Uploaded Source

Built Distribution

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

pycentauri-0.3.1-py3-none-any.whl (43.3 kB view details)

Uploaded Python 3

File details

Details for the file pycentauri-0.3.1.tar.gz.

File metadata

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

File hashes

Hashes for pycentauri-0.3.1.tar.gz
Algorithm Hash digest
SHA256 0b4e52bc5ea2a30fa0896ce9a239e86af8f90784d052f85728f8f8a8c7e80bb7
MD5 f947f05f2ec5a1d6949558e6fd63864b
BLAKE2b-256 e52a0d8d7899eb51b66d44f5887260f0575964b4f2e52c309e574827e6adad17

See more details on using hashes here.

Provenance

The following attestation bundles were made for pycentauri-0.3.1.tar.gz:

Publisher: publish.yml on bjan/pycentauri

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

File details

Details for the file pycentauri-0.3.1-py3-none-any.whl.

File metadata

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

File hashes

Hashes for pycentauri-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 32270f2ecdc14a5f4329d4899e8639fe24034ea5af163f1c037f5e6afa689423
MD5 6a9276c3ee463ca41fd1baf5ad14a44d
BLAKE2b-256 12d45835893af7c52e7d11017234c997e402b589760a614b7dc9d046769b3bab

See more details on using hashes here.

Provenance

The following attestation bundles were made for pycentauri-0.3.1-py3-none-any.whl:

Publisher: publish.yml on bjan/pycentauri

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