bambu-mcp
README.md
# bambu-mcp
[](https://github.com/JacobJBurrell/bambu-mcp/actions/workflows/tests.yml)
[](LICENSE)
An MCP server that lets Claude (or any MCP client) monitor and control a Bambu Lab 3D printer over your local network.
> **Unofficial.** This project is not made by, affiliated with, or endorsed by Bambu Lab. "Bambu Lab" and its product names are trademarks of their owner.
>
> **It controls a machine that heats and moves.** It needs the printer's Developer Mode, and you use it at your own risk. Read [docs/SAFETY.md](docs/SAFETY.md) first.
## Status
- **Tested on a real printer:** Bambu Lab H2C, firmware 01.02.00.00. Status, camera, homing and jogging, nozzle switching, the hotend rack (including Read All), temperatures (nozzles, bed, chamber), fans, air management, lights, speed, every Print Option and AMS tag reading all worked.
- **Not yet tested on a real printer:**
- starting, pausing, resuming and stopping a print
- deleting files
- calibration
- filament load, unload and extrude
- **Other 13 models:** built from Bambu's published specs and Bambu Studio's source, and tested only against a simulated printer. Reports from real printers are welcome; see [CONTRIBUTING.md](CONTRIBUTING.md).
- **LAN only.** There is no cloud support: Developer Mode, which LAN control needs on current firmware, disconnects the printer from Bambu Cloud and Bambu Handy.
## What it looks like
Ask your MCP client things like:
- "What's my printer doing?"
- "Show me the camera."
- "What filament is in the AMS?"
- "Preheat the bed to 60."
Read requests run straight away. Anything that changes the printer is a dry run first: the tool shows exactly what it would send, and only acts when called again with `confirm=true`.
## Supported printers
Set `BAMBU_MODEL` to one of these names. The default is `H2C`.
`get_status` warns if the printer reports a different model.
| `BAMBU_MODEL` | Nozzles | Max nozzle / bed / chamber (°C) | Camera | Unverified fields |
|---|---|---|---|---|
| `H2C` | 2 + 6-hotend rack | 350 / 120 / 65 heated | RTSPS | none (tested live) |
| `H2D` | 2 | 350 / 120 / 65 heated | RTSPS | — |
| `H2DPRO` | 2 | 350 / 120 / 65 heated | RTSPS | all physical limits (no spec page; H2D values used) |
| `H2S` | 1 | 350 / 120 / 65 heated | RTSPS | — |
| `H3C` | 1 + tool changer | 350 / 120 / 65 heated | RTSPS | nozzle count, tool changer, rack size, lights |
| `X2D` | 2 | 300 / 120 / 65 heated | RTSPS | tool changer, lights |
| `X1C` | 1 | 300 / 110 / sensor only | RTSPS | bed limit, build volume, product name |
| `X1E` | 1 | 320 / 110 / 60 heated | RTSPS | bed limit, build volume, product name |
| `P2S` | 1 | 300 / 110 / sensor only | RTSPS | — |
| `P1S` | 1 | 300 / 100 / none | JPEG port 6000 | nozzle and bed limits, build volume |
| `P1P` | 1 | 300 / 100 / none | JPEG port 6000 | nozzle and bed limits, build volume, fans |
| `A1` | 1 | 300 / 100 / none | JPEG port 6000 | lights |
| `A1MINI` | 1 | 300 / 80 / none | JPEG port 6000 | lights |
| `A2L` | 1 | 300 / 80 / none | JPEG port 6000 | lights |
`gcode_file_prefix`, the path used to print plain `.gcode` files, is unverified on every model. Use sliced `.gcode.3mf` files.
Where an official figure couldn't be confirmed, the profile uses the lower, safer value and marks it `unverified`.
Each profile file cites its sources: bambulab.com spec pages (read 2026-11-10) and the ha-bambulab integration for protocol details.
Aliases `X1`, `A1 mini` and `H2D-Pro` also work.
## 1. Prepare the printer
1. **Enable LAN Only Mode** on the printer touchscreen (Settings > Network / WLAN).
2. **Enable Developer Mode** (it appears once LAN Only Mode is on).
Current firmware has *Authorization Control*, which blocks third-party LAN commands unless Developer Mode is on.
Developer Mode disconnects the printer from Bambu Cloud.
See [Bambu's guide](https://wiki.bambulab.com/en/knowledge-sharing/enable-developer-mode).
3. **Note the Access Code** from the same network screen. It changes when you toggle LAN Only Mode.
4. **Note the printer's IP address** and **serial number** (Settings > Device).
Give the printer a DHCP reservation in your router so its IP doesn't change.
5. **For camera snapshots:** enable *LAN Mode Liveview* (Settings > General; the label varies by firmware).
Also install ffmpeg (`winget install Gyan.FFmpeg`).
## 2. Install
You need Python 3.11 or newer and git.
```powershell
git clone https://github.com/JacobJBurrell/bambu-mcp.git
cd bambu-mcp
python -m venv .venv
.venv\Scripts\pip install -e ".[dev]"
.venv\Scripts\python -m pytest # no printer needed
```
On Linux or macOS, use `.venv/bin/pip` and `.venv/bin/python` instead.
Two Windows notes:
- Clone into a **short path** (for example `C:\dev\bambu-mcp`). Windows' 260-character path limit breaks compiled packages inside deeply nested folders.
- On Windows-on-ARM, use an x64 Python. `cryptography`, which `mcp` needs, has no native ARM64 build.
## 3. Configure credentials
The server reads only environment variables. Never put them in code.
| Variable | Value |
|---|---|
| `BAMBU_IP` | Printer IP, e.g. `192.168.1.50` |
| `BAMBU_SERIAL` | Printer serial number |
| `BAMBU_ACCESS_CODE` | LAN access code |
| `BAMBU_MODEL` | Optional, default `H2C` (see the table above) |
To set them once for your Windows user (then restart your MCP client):
```powershell
setx BAMBU_IP "192.168.1.50"
setx BAMBU_SERIAL "YOUR_SERIAL"
```
For the access code, run this script. It asks for the code without showing it as you type:
```powershell
powershell -ExecutionPolicy Bypass -File scripts\set_access_code.ps1
```
## 4. Connect to Claude
Use the full path to the Python inside the project's `.venv`. The examples assume the project is at `C:\dev\bambu-mcp`; change the path to match yours.
**Claude Code:**
```powershell
claude mcp add bambu --scope user -- C:\dev\bambu-mcp\.venv\Scripts\python.exe -m bambu_mcp
```
**Claude Desktop:** add this to `%APPDATA%\Claude\claude_desktop_config.json`:
```json
{
"mcpServers": {
"bambu": {
"command": "C:\\dev\\bambu-mcp\\.venv\\Scripts\\python.exe",
"args": ["-m", "bambu_mcp"]
}
}
}
```
If you didn't use `setx`, add an `"env": {"BAMBU_IP": "...", ...}` block to the config.
That stores the code in plain text in that file.
## 5. Live read-only check
This sends **no** control commands:
```powershell
.venv\Scripts\python scripts\live_readonly_check.py
```
It runs `get_status`, `get_ams_status`, `list_sd_files` and a camera snapshot, saved to `live_snapshot.jpg`.
## Tools
**Read tools (run immediately):**
| Tool | What it returns |
|---|---|
| `get_status` | State, progress, layer, time left, temperatures for every nozzle plus bed and chamber, active nozzle, whether axes are homed, hotends and rack position, fan percentages, lights, HMS errors with Bambu's message text |
| `get_ams_status` | Each AMS unit's humidity and temperature, plus every slot's type, colour and % left |
| `get_print_options` | Every Print Option as Bambu Studio shows it, the air management mode, and options this printer doesn't support |
| `list_sd_files` | Files on the printer storage (`/`, `/cache`, `/timelapse`) |
| `get_camera_snapshot` | One JPEG from the chamber camera |
| `get_printer_profile` | Model limits and capabilities, including unverified fields |
| `get_print_history` | Reports that history needs the cloud, which this server doesn't use |
**Control tools.** Each is a **dry run unless `confirm=true`**:
| Bambu Studio control | Tool |
|---|---|
| Nozzle (left/right), bed and chamber temperature | `set_temperature` |
| Home, XY and bed jog | `home_axes`, `move_axis` |
| Left / Right nozzle | `select_extruder` |
| Extruder up / down | `extrude` |
| Fans and Air Management (cooling / heating) | `set_fan`, `set_air_mode` |
| Speed and Lamp | `set_print_speed`, `set_light` |
| Print Options dialog | `set_print_option` |
| Calibration dialog | `start_calibration` |
| Hotends tab (Row A, Row B, home, Read All) | `hotend_rack` |
| Filament load / unload (per nozzle), tag re-read | `load_filament`, `unload_filament`, `read_ams_rfid` |
| Print, pause, resume, stop | `start_print`, `pause_print`, `resume_print`, `stop_print` |
| Storage | `delete_file` |
| Raw G-code | `send_gcode` |
Printer Parts (nozzle type, diameter, flow) is read-only in Bambu Studio too; `get_status` reports it under `hotends`.
## Safety rules
[docs/SAFETY.md](docs/SAFETY.md) lists the rule behind every tool, where it comes from, and whether it was tested on a real H2C.
- Without `confirm=true`, a control tool returns exactly what it *would* send (MQTT JSON and file operations) and sends nothing.
- These checks are refused even with `confirm=true`:
- moving an axis or switching nozzles before all axes are homed
- temperatures above the model maximum, or heaters the model doesn't have (for example, the chamber on an A1)
- extruding with the nozzle below 170 °C
- moves longer than the axis
- homing, moving, nozzle switching, rack moves, calibration, filament changes or a new print while a print is running
- a second mechanical job while the hotend rack is moving or a nozzle switch is in progress
- options or hardware the printer reports it doesn't have
- `send_gcode` bypasses all limits and is marked destructive.
- The access code and serial are never logged, and are redacted from error messages.
- Printers use self-signed TLS certificates, so certificate verification is off (LAN only).
## Layout
```
src/bambu_mcp/
server.py MCP tool definitions only (no model logic)
printer.py Operations: profile + transport + safety gate
safety.py Confirmation gate and hard limits
commands.py MQTT payload builders
status.py Report parsing (packed H2 temps, HMS, AMS, fans, rack)
options.py Print Options and capability bits
hms.py Readable HMS error text from Bambu's lookup service (cached)
models/ One profile per printer, shared values in _common.py; registry and detection in __init__.py
transport/lan.py MQTT 8883 + FTPS 990 + camera (RTSPS via ffmpeg, or JPEG on port 6000)
transport/cloud.py Placeholder (cloud skipped)
tests/ Mocked MQTT broker, FTPS and camera socket; synthetic report fixtures
scripts/ set_access_code.ps1, live_readonly_check.py, live_*_test.py (send real commands), mcp_call.py
docs/SAFETY.md Rule, source and live-test status for every tool
```
To add a model, create `models/<model>.py` with a `PrinterProfile` and register it in `models/__init__.py`.
## Known limits
- See **Status** above for what has and hasn't run on a real printer.
- AMS drying is not implemented.
- The camera on P1/A1/A2 printers (JPEG on port 6000) has only been tested against a simulated printer.
- Printing plain `.gcode` files is unverified. Use sliced `.gcode.3mf` files.
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md). Security reports: [SECURITY.md](SECURITY.md).
## Credits
Protocol details were learned from these open-source projects and from Bambu's own documentation:
- [Bambu Studio](https://github.com/bambulab/BambuStudio) (command formats and safety rules)
- [ha-bambulab](https://github.com/greghesp/ha-bambulab) (status parsing, camera, FTP)
- [OpenBambuAPI](https://github.com/Doridian/OpenBambuAPI) (MQTT, FTP and camera documentation)
- [Bambu Lab Wiki](https://wiki.bambulab.com)
## License
[MIT](LICENSE)
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo recent community issues