bambu-printer-mcp 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,31 +1,279 @@
1
1
  # bambu-printer-mcp
2
2
 
3
- MCP server for Bambu Lab 3D printers. Provides STL manipulation, BambuStudio slicing, and direct printer control over MQTT/FTP.
3
+ [![npm version](https://img.shields.io/npm/v/bambu-printer-mcp.svg)](https://www.npmjs.com/package/bambu-printer-mcp)
4
+ [![License: GPL-2.0](https://img.shields.io/badge/License-GPL%20v2-blue.svg)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0%2B-blue)](https://www.typescriptlang.org/)
6
+ [![Node.js Version](https://img.shields.io/badge/node-%3E%3D%2018.0.0-green.svg)](https://nodejs.org/en/download/)
7
+ [![GitHub stars](https://img.shields.io/github/stars/DMontgomery40/bambu-printer-mcp.svg?style=social&label=Star)](https://github.com/DMontgomery40/bambu-printer-mcp)
8
+ [![Downloads](https://img.shields.io/npm/dm/bambu-printer-mcp.svg)](https://www.npmjs.com/package/bambu-printer-mcp)
4
9
 
5
- Stripped-down, Bambu-focused fork of [mcp-3D-printer-server](https://github.com/DMontgomery40/mcp-3D-printer-server).
10
+ A Bambu Lab-focused MCP server for controlling Bambu printers, manipulating STL files, and managing end-to-end 3MF print workflows from Claude Desktop, Claude Code, or any MCP-compatible client.
11
+
12
+ This is a stripped-down, Bambu-only fork of [mcp-3D-printer-server](https://github.com/DMontgomery40/mcp-3D-printer-server). All OctoPrint, Klipper, Duet, Repetier, Prusa Connect, and Creality Cloud support has been removed. What remains is a focused, correct implementation for Bambu Lab hardware -- with two protocol-level bugs fixed that exist in the parent project.
13
+
14
+ <details>
15
+ <summary><strong>Click to expand Table of Contents</strong></summary>
16
+
17
+ ## Table of Contents
18
+
19
+ - [Description](#description)
20
+ - [Features](#features)
21
+ - [Installation](#installation)
22
+ - [Prerequisites](#prerequisites)
23
+ - [Run without installing (npx)](#run-without-installing-npx)
24
+ - [Install globally from npm](#install-globally-from-npm)
25
+ - [Install from source](#install-from-source)
26
+ - [Configuration](#configuration)
27
+ - [Environment variables reference](#environment-variables-reference)
28
+ - [Usage with Claude Desktop](#usage-with-claude-desktop)
29
+ - [Usage with Claude Code](#usage-with-claude-code)
30
+ - [Enabling Developer Mode (Required)](#enabling-developer-mode-required)
31
+ - [Finding Your Bambu Printer's Serial Number and Access Token](#finding-your-bambu-printers-serial-number-and-access-token)
32
+ - [AMS (Automatic Material System) Setup](#ams-automatic-material-system-setup)
33
+ - [Bambu Communication Notes (MQTT and FTP)](#bambu-communication-notes-mqtt-and-ftp)
34
+ - [What this fork fixes](#what-this-fork-fixes)
35
+ - [Available Tools](#available-tools)
36
+ - [STL Manipulation Tools](#stl-manipulation-tools)
37
+ - [Printer Control Tools](#printer-control-tools)
38
+ - [Slicing Tools](#slicing-tools)
39
+ - [Advanced Tools](#advanced-tools)
40
+ - [Available Resources](#available-resources)
41
+ - [Example Commands for Claude](#example-commands-for-claude)
42
+ - [Bambu Lab Printer Limitations](#bambu-lab-printer-limitations)
43
+ - [General Limitations and Considerations](#general-limitations-and-considerations)
44
+ - [Memory usage](#memory-usage)
45
+ - [STL manipulation limitations](#stl-manipulation-limitations)
46
+ - [Performance considerations](#performance-considerations)
47
+ - [License](#license)
48
+
49
+ </details>
50
+
51
+ ---
52
+
53
+ ## Description
54
+
55
+ `bambu-printer-mcp` is a Model Context Protocol server that gives Claude (or any MCP client) direct control over Bambu Lab 3D printers. It handles the full workflow: manipulate an STL, auto-slice it with BambuStudio if needed, upload the resulting 3MF over FTPS, and start the print via an MQTT `project_file` command -- all without leaving your conversation.
56
+
57
+ **What this is not.** This package intentionally supports only Bambu Lab printers. It does not include adapters for OctoPrint, Klipper (Moonraker), Duet, Repetier, Prusa Connect, or Creality Cloud. If you need multi-printer support, use the parent project [mcp-3D-printer-server](https://github.com/DMontgomery40/mcp-3D-printer-server) instead.
58
+
59
+ **Why a separate package?** The parent project carries all printer adapters in a single binary. When working exclusively with Bambu hardware, that breadth adds noise and includes code paths with known Bambu-specific bugs. This fork strips the project to its Bambu core and applies two targeted protocol fixes described in [Bambu Communication Notes](#bambu-communication-notes-mqtt-and-ftp).
60
+
61
+ **Note on resource usage.** STL manipulation loads entire mesh geometry into memory. For large or complex STL files (greater than 10 MB), these operations can be memory-intensive. See [General Limitations and Considerations](#general-limitations-and-considerations) for details.
62
+
63
+ ---
6
64
 
7
65
  ## Features
8
66
 
9
- - **Printer control**: status, cancel, temperature, file management via MQTT (bambu-node)
10
- - **Print 3MF**: upload via FTP, send `project_file` command with proper AMS mapping
11
- - **Auto-slice**: unsliced 3MF files are automatically sliced with BambuStudio CLI
12
- - **STL tools**: scale, rotate, extend base, merge vertices, center, lay flat, info
13
- - **Blender bridge**: optional integration for advanced model edits
14
- - **Transports**: stdio and Streamable HTTP
67
+ - Get detailed printer status: temperatures (nozzle, bed, chamber), print progress, current layer, time remaining, and live AMS slot data
68
+ - List, upload, and manage files on the printer's SD card via FTPS
69
+ - Upload and print `.3mf` files with full plate selection and calibration flag control
70
+ - Automatic slicing: pass an unsliced 3MF to `print_3mf` and the server will slice it with BambuStudio CLI (or another configured slicer) before uploading
71
+ - Parse AMS mapping from the 3MF's embedded slicer config (`Metadata/project_settings.config`) and send it correctly formatted per the OpenBambuAPI spec
72
+ - Cancel in-progress print jobs via MQTT
73
+ - Set nozzle and bed temperature via G-code dispatch over MQTT
74
+ - Start G-code files already stored on the printer
75
+ - STL manipulation: scale, rotate, extend base, merge vertices, center at origin, lay flat, and inspect model info
76
+ - Slice STL or 3MF files using BambuStudio, OrcaSlicer, PrusaSlicer, Cura, or Slic3r
77
+ - Optional Blender MCP bridge for advanced mesh operations
78
+ - Dual transport: stdio (default, for Claude Desktop / Claude Code) and Streamable HTTP
79
+
80
+ ---
15
81
 
16
- ## Quick Start
82
+ ## Installation
83
+
84
+ ### Prerequisites
85
+
86
+ - Node.js 18 or higher
87
+ - npm
88
+
89
+ ### Run without installing (npx)
90
+
91
+ The fastest way to get started. No global install required:
17
92
 
18
93
  ```bash
19
94
  npx bambu-printer-mcp
20
95
  ```
21
96
 
22
- Or install globally:
97
+ Set environment variables inline or via a `.env` file in your working directory (see [Configuration](#configuration)).
98
+
99
+ ### Install globally from npm
23
100
 
24
101
  ```bash
25
102
  npm install -g bambu-printer-mcp
26
103
  ```
27
104
 
28
- ### Claude Desktop config
105
+ After installation, the `bambu-printer-mcp` command is available in your PATH.
106
+
107
+ ### Install from source
108
+
109
+ ```bash
110
+ git clone https://github.com/DMontgomery40/bambu-printer-mcp.git
111
+ cd bambu-printer-mcp
112
+ npm install
113
+ npm run build
114
+ npm link
115
+ ```
116
+
117
+ `npm link` makes the `bambu-printer-mcp` binary available globally without publishing to npm.
118
+
119
+ ---
120
+
121
+ ## Configuration
122
+
123
+ Create a `.env` file in the directory where you run the server, or pass environment variables directly in your MCP client config. All printer connection variables can also be passed as tool arguments on a per-call basis, which is useful when working with multiple printers.
124
+
125
+ ```env
126
+ # --- Bambu printer connection (required for all printer tools) ---
127
+ PRINTER_HOST=192.168.1.100 # IP address of your Bambu printer on the local network
128
+ BAMBU_SERIAL=01P00A123456789 # Printer serial number (see Finding Your Serial Number below)
129
+ BAMBU_TOKEN=your_access_token # LAN access token from printer touchscreen
130
+
131
+ # --- Printer model (CRITICAL for safe operation) ---
132
+ BAMBU_MODEL=p1s # Your printer model: p1s, p1p, x1c, x1e, a1, a1mini, h2d
133
+ BED_TYPE=textured_plate # Bed plate type: textured_plate, cool_plate, engineering_plate, hot_plate
134
+ NOZZLE_DIAMETER=0.4 # Nozzle diameter in mm (default: 0.4)
135
+
136
+ # --- Slicer configuration (required for slice_stl and print_3mf auto-slice) ---
137
+ SLICER_TYPE=bambustudio # Options: bambustudio, prusaslicer, orcaslicer, cura, slic3r
138
+ SLICER_PATH=/Applications/BambuStudio.app/Contents/MacOS/BambuStudio
139
+ # Default on macOS. Adjust for your OS and install path.
140
+ SLICER_PROFILE= # Optional: path to a slicer profile/config file
141
+
142
+ # --- Temporary file directory ---
143
+ TEMP_DIR=/tmp/bambu-mcp-temp # Directory for intermediate files. Created automatically if absent.
144
+
145
+ # --- MCP transport ---
146
+ MCP_TRANSPORT=stdio # Options: stdio (default), streamable-http
147
+
148
+ # --- Streamable HTTP transport (only used when MCP_TRANSPORT=streamable-http) ---
149
+ MCP_HTTP_HOST=127.0.0.1
150
+ MCP_HTTP_PORT=3000
151
+ MCP_HTTP_PATH=/mcp
152
+ MCP_HTTP_STATEFUL=true
153
+ MCP_HTTP_JSON_RESPONSE=true
154
+ MCP_HTTP_ALLOWED_ORIGINS=http://localhost
155
+
156
+ # --- Optional Blender MCP bridge ---
157
+ BLENDER_MCP_BRIDGE_COMMAND= # Shell command to invoke your Blender MCP bridge executable
158
+ ```
159
+
160
+ ### Environment variables reference
161
+
162
+ | Variable | Default | Required | Description |
163
+ |---|---|---|---|
164
+ | `PRINTER_HOST` | `localhost` | Yes | IP address of the Bambu printer |
165
+ | `BAMBU_SERIAL` | | Yes | Printer serial number |
166
+ | `BAMBU_TOKEN` | | Yes | LAN access token |
167
+ | `BAMBU_MODEL` | | **Yes** | Printer model: `p1s`, `p1p`, `x1c`, `x1e`, `a1`, `a1mini`, `h2d`. **Required for safe operation** -- determines the correct G-code generation. If omitted and the MCP client supports elicitation, the server will ask you interactively. |
168
+ | `BED_TYPE` | `textured_plate` | No | Bed plate type: `textured_plate`, `cool_plate`, `engineering_plate`, `hot_plate` |
169
+ | `NOZZLE_DIAMETER` | `0.4` | No | Nozzle diameter in mm. Used to select the correct BambuStudio machine preset. |
170
+ | `SLICER_TYPE` | `bambustudio` | No | Slicer to use for slicing operations |
171
+ | `SLICER_PATH` | BambuStudio macOS path | No | Full path to the slicer executable |
172
+ | `SLICER_PROFILE` | | No | Path to a slicer profile or config file |
173
+ | `TEMP_DIR` | `./temp` | No | Directory for intermediate files |
174
+ | `MCP_TRANSPORT` | `stdio` | No | Transport mode: `stdio` or `streamable-http` |
175
+ | `MCP_HTTP_HOST` | `127.0.0.1` | No | HTTP bind address (HTTP transport only) |
176
+ | `MCP_HTTP_PORT` | `3000` | No | HTTP port (HTTP transport only) |
177
+ | `MCP_HTTP_PATH` | `/mcp` | No | HTTP endpoint path (HTTP transport only) |
178
+ | `MCP_HTTP_STATEFUL` | `true` | No | Enable stateful HTTP sessions |
179
+ | `MCP_HTTP_JSON_RESPONSE` | `true` | No | Return structured JSON alongside text responses |
180
+ | `MCP_HTTP_ALLOWED_ORIGINS` | | No | Comma-separated list of allowed CORS origins |
181
+ | `BLENDER_MCP_BRIDGE_COMMAND` | | No | Command to invoke Blender MCP bridge |
182
+
183
+ ---
184
+
185
+ ## Usage with Claude Desktop
186
+
187
+ Edit your Claude Desktop configuration file. On macOS this is at `~/Library/Application Support/Claude/claude_desktop_config.json`. On Windows it is at `%APPDATA%\Claude\claude_desktop_config.json`.
188
+
189
+ **Using npx (recommended -- always runs the latest version):**
190
+
191
+ ```json
192
+ {
193
+ "mcpServers": {
194
+ "bambu-printer": {
195
+ "command": "npx",
196
+ "args": ["-y", "bambu-printer-mcp"],
197
+ "env": {
198
+ "PRINTER_HOST": "192.168.1.100",
199
+ "BAMBU_SERIAL": "01P00A123456789",
200
+ "BAMBU_TOKEN": "your_access_token",
201
+ "BAMBU_MODEL": "p1s"
202
+ }
203
+ }
204
+ }
205
+ }
206
+ ```
207
+
208
+ **Using a globally installed binary:**
209
+
210
+ ```json
211
+ {
212
+ "mcpServers": {
213
+ "bambu-printer": {
214
+ "command": "bambu-printer-mcp",
215
+ "env": {
216
+ "PRINTER_HOST": "192.168.1.100",
217
+ "BAMBU_SERIAL": "01P00A123456789",
218
+ "BAMBU_TOKEN": "your_access_token",
219
+ "BAMBU_MODEL": "p1s"
220
+ }
221
+ }
222
+ }
223
+ }
224
+ ```
225
+
226
+ **With slicer configured (for auto-slice and print_3mf workflows):**
227
+
228
+ ```json
229
+ {
230
+ "mcpServers": {
231
+ "bambu-printer": {
232
+ "command": "npx",
233
+ "args": ["-y", "bambu-printer-mcp"],
234
+ "env": {
235
+ "PRINTER_HOST": "192.168.1.100",
236
+ "BAMBU_SERIAL": "01P00A123456789",
237
+ "BAMBU_TOKEN": "your_access_token",
238
+ "BAMBU_MODEL": "p1s",
239
+ "SLICER_TYPE": "bambustudio",
240
+ "SLICER_PATH": "/Applications/BambuStudio.app/Contents/MacOS/BambuStudio"
241
+ }
242
+ }
243
+ }
244
+ }
245
+ ```
246
+
247
+ After editing the file, restart Claude Desktop. You should see the bambu-printer tools appear in the tool list when you open a new conversation.
248
+
249
+ ---
250
+
251
+ ## Usage with Claude Code
252
+
253
+ In Claude Code, MCP servers are configured in your project's `.mcp.json` file or in your global Claude Code settings at `~/.claude/settings.json`.
254
+
255
+ **Project-level configuration (`.mcp.json` in your project root):**
256
+
257
+ ```json
258
+ {
259
+ "mcpServers": {
260
+ "bambu-printer": {
261
+ "command": "npx",
262
+ "args": ["-y", "bambu-printer-mcp"],
263
+ "env": {
264
+ "PRINTER_HOST": "192.168.1.100",
265
+ "BAMBU_SERIAL": "01P00A123456789",
266
+ "BAMBU_TOKEN": "your_access_token",
267
+ "BAMBU_MODEL": "p1s",
268
+ "SLICER_TYPE": "bambustudio",
269
+ "SLICER_PATH": "/Applications/BambuStudio.app/Contents/MacOS/BambuStudio"
270
+ }
271
+ }
272
+ }
273
+ }
274
+ ```
275
+
276
+ **Global configuration (`~/.claude/settings.json`):**
29
277
 
30
278
  ```json
31
279
  {
@@ -35,51 +283,641 @@ npm install -g bambu-printer-mcp
35
283
  "args": ["-y", "bambu-printer-mcp"],
36
284
  "env": {
37
285
  "PRINTER_HOST": "192.168.1.100",
38
- "BAMBU_SERIAL": "your_serial",
39
- "BAMBU_TOKEN": "your_token"
286
+ "BAMBU_SERIAL": "01P00A123456789",
287
+ "BAMBU_TOKEN": "your_access_token",
288
+ "BAMBU_MODEL": "p1s"
40
289
  }
41
290
  }
42
291
  }
43
292
  }
44
293
  ```
45
294
 
46
- ## Environment Variables
295
+ ---
296
+
297
+ ## Enabling Developer Mode (Required)
298
+
299
+ This MCP server communicates directly with your printer over your local network using MQTT and FTPS. For this to work, **Developer Mode** must be enabled on the printer. Without it, the printer will reject third-party LAN connections even if you have the correct access code.
300
+
301
+ Developer Mode is available on the following firmware versions and later:
302
+
303
+ | Series | Minimum Firmware |
304
+ |--------|-----------------|
305
+ | P1 Series (P1P, P1S) | `01.08.02.00` |
306
+ | X1 Series (X1C, X1E) | `01.08.03.00` |
307
+ | A1 Series (A1, A1 Mini) | `01.05.00.00` |
308
+ | H2D | `01.01.00.01` |
309
+
310
+ If your firmware is older than these versions, update through Bambu Studio or the Bambu Handy app before proceeding.
311
+
312
+ ### Step 1: Navigate to Network Settings
313
+
314
+ On the printer's touchscreen, go to **Settings**, then select the **Network** (WLAN) page. You should see your WiFi network name, IP address, and the LAN Only Mode toggle.
315
+
316
+ <p align="center">
317
+ <img src="docs/images/p1s-network-settings.jpeg" width="400" alt="P1S network settings screen showing WLAN, LAN Only Mode, IP address, and Access Code" />
318
+ </p>
319
+
320
+ ### Step 2: Enable LAN Only Mode
321
+
322
+ Toggle **LAN Only Mode** to **ON**. This enables direct local network communication protocols (MQTT on port 8883 and FTPS on port 990) that this server requires.
323
+
324
+ **Important:** Enabling LAN Only Mode disconnects the printer from Bambu Lab's cloud services. The Bambu Handy mobile app will stop working while this mode is active. Bambu Studio and OrcaSlicer can still connect over LAN.
325
+
326
+ ### Step 3: Enable Developer Mode
327
+
328
+ Once LAN Only Mode is on, a **Developer Mode** option appears in the same settings menu. Toggle it **ON**. This allows third-party clients (like this MCP server) to authenticate and send commands over MQTT.
329
+
330
+ ### Step 4: Note the Access Code
331
+
332
+ The **Access Code** displayed on the network settings screen is your LAN access token. You will need this value for the `BAMBU_TOKEN` environment variable.
333
+
334
+ <p align="center">
335
+ <img src="docs/images/p1s-access-code.jpeg" width="400" alt="P1S network settings showing the Access Code field" />
336
+ </p>
337
+
338
+ The access code can be refreshed by tapping the circular arrow icon next to it. If you refresh it, any existing connections using the old code will be disconnected and you will need to update your configuration with the new code.
339
+
340
+ ---
341
+
342
+ ## Finding Your Bambu Printer's Serial Number and Access Token
343
+
344
+ Two values are required to connect directly to a Bambu Lab printer over your local network: the printer's serial number and its LAN access token (the Access Code from Developer Mode setup above).
345
+
346
+ ### Serial number
347
+
348
+ The serial number is printed on a sticker on the back or underside of the printer. It typically follows one of these formats:
349
+
350
+ - P1 Series: begins with `01P`
351
+ - X1 Series: begins with `01X`
352
+ - A1 Series: begins with `01A`
353
+
354
+ You can also find it on the printer's touchscreen. Navigate to **Settings** and select the **Device Info** page:
355
+
356
+ <p align="center">
357
+ <img src="docs/images/p1s-device-info.jpeg" width="400" alt="P1S device info screen showing model name, serial number, AMS serial, and printing time" />
358
+ </p>
359
+
360
+ The **Printer** line shows your serial number. In Bambu Studio, you can also find it under Device > Device Management in the printer information panel.
361
+
362
+ ### LAN access token
363
+
364
+ The access token is the **Access Code** shown on the printer's network settings screen. It is separate from your Bambu Cloud account password. If you followed the [Developer Mode setup](#enabling-developer-mode-required) above, you already have this value.
365
+
366
+ **P1 Series (P1P, P1S):**
367
+ 1. On the printer touchscreen, go to Settings.
368
+ 2. Select the Network / WLAN page.
369
+ 3. The Access Code is displayed at the bottom of the screen.
370
+
371
+ **X1 Series (X1C, X1E):**
372
+ 1. On the printer touchscreen, go to Settings.
373
+ 2. Select Network.
374
+ 3. Enable LAN Only Mode and Developer Mode if not already on.
375
+ 4. The Access Code appears on this screen.
376
+
377
+ **A1 and A1 Mini:**
378
+ 1. Open the Bambu Handy app on your phone.
379
+ 2. Connect to your printer.
380
+ 3. Navigate to Settings > Network.
381
+ 4. The Access Code is shown here.
382
+
383
+ Your printer must also be logged into a Bambu Cloud account for LAN mode to function. You can verify this on the cloud/account settings screen:
384
+
385
+ <p align="center">
386
+ <img src="docs/images/p1s-cloud-account.jpeg" width="400" alt="P1S cloud account screen showing logged-in user with Logout button" />
387
+ </p>
388
+
389
+ **Troubleshooting:** If the LAN Only Mode or Developer Mode options are not visible, your printer firmware is likely outdated. Update to the latest firmware version through Bambu Studio or the Bambu Handy app and try again.
390
+
391
+ ---
392
+
393
+ ## AMS (Automatic Material System) Setup
394
+
395
+ The Bambu AMS is a multi-spool feeder that lets you assign different filaments to different parts of a multi-color or multi-material print. This section explains how AMS slot mapping works with this MCP server.
396
+
397
+ ### How AMS slots work
398
+
399
+ The AMS has 4 slots per unit, numbered 0 through 3. If you have multiple AMS units chained together, the second unit's slots are 4 through 7, and so on. When you slice a model in Bambu Studio or OrcaSlicer, each color/material in the print is assigned to a specific AMS slot.
400
+
401
+ ### Automatic AMS mapping from the 3MF
402
+
403
+ When you slice a model in Bambu Studio, the slicer embeds AMS mapping information inside the 3MF file at `Metadata/project_settings.config`. The `print_3mf` tool reads this file automatically and extracts the correct mapping. In most cases, you do not need to specify `ams_mapping` manually -- the tool handles it.
404
+
405
+ ### Manual AMS mapping
406
+
407
+ If you need to override the embedded mapping (for example, you swapped filament positions since slicing), pass the `ams_mapping` array to `print_3mf`:
408
+
409
+ ```json
410
+ {
411
+ "three_mf_path": "/path/to/model.3mf",
412
+ "ams_mapping": [0, 2],
413
+ "use_ams": true
414
+ }
415
+ ```
416
+
417
+ Each element in the array corresponds to a filament slot used in the print file, in the order they appear in the slicer. The value is the physical AMS slot number (0-based) where that filament is currently loaded. In the example above, the first filament in the print uses AMS slot 0, and the second uses AMS slot 2.
418
+
419
+ The server pads this array to the 5 elements required by the printer's MQTT protocol. An `ams_mapping` of `[0, 2]` becomes `[0, 2, -1, -1, -1]` on the wire, where `-1` indicates unused positions.
420
+
421
+ ### Single-material prints
422
+
423
+ For a single-material print (the most common case), the default mapping is `[-1, -1, -1, -1, 0]`, which tells the printer to pull filament from AMS slot 0. If your filament is in a different slot, specify it:
424
+
425
+ ```json
426
+ {
427
+ "three_mf_path": "/path/to/model.3mf",
428
+ "ams_mapping": [2]
429
+ }
430
+ ```
431
+
432
+ This tells the printer to use AMS slot 2 for the single filament in the print.
433
+
434
+ ### Printing without AMS
435
+
436
+ If you are using the direct-feed spool holder (no AMS attached) or want to bypass the AMS entirely, set `use_ams` to `false`:
437
+
438
+ ```json
439
+ {
440
+ "three_mf_path": "/path/to/model.3mf",
441
+ "use_ams": false
442
+ }
443
+ ```
444
+
445
+ ### Checking AMS status
446
+
447
+ Use `get_printer_status` to see which filaments are currently loaded in each AMS slot, including material type and color data reported by the printer:
448
+
449
+ ```
450
+ "What filaments are loaded in my AMS right now?"
451
+ ```
452
+
453
+ The `ams` field in the status response contains the raw AMS data from the printer, including tray information for each slot.
454
+
455
+ ---
456
+
457
+ ## Bambu Communication Notes (MQTT and FTP)
458
+
459
+ Bambu Lab printers do not use a conventional REST API. Instead, they expose two local protocols that this server uses directly:
460
+
461
+ **MQTT (port 8883, TLS):** All printer commands and state reports flow over an MQTT broker running on the printer itself. The broker requires your serial number as the client ID and your access token as the password. Commands like starting a print, cancelling a job, and dispatching G-code lines are all MQTT publishes to the device topic. Status data is received by subscribing to the printer's report topic and requesting a `push_all` refresh. This implementation is based on community reverse engineering documented in the [OpenBambuAPI](https://github.com/Doridian/OpenBambuAPI) project.
462
+
463
+ **FTPS (port 990, implicit TLS):** File operations (upload and directory listing) use FTPS. The printer's SD card is accessible as a filesystem with directories including `cache/` (for 3MF and G-code print files), `timelapse/`, and `logs/`. Authentication uses the username `bblp` and your access token as the password.
464
+
465
+ ### What this fork fixes
466
+
467
+ The parent project (`mcp-3D-printer-server`) contains two Bambu-specific protocol bugs that this fork corrects.
468
+
469
+ **Bug 1: FTP double-path error in bambu-js.**
470
+
471
+ The `bambu-js` library's `sendFile` method has a path construction bug. It calls `ensureDir` to change the working directory into the target directory (e.g., `/cache`), and then calls `uploadFrom` with the full relative path including the directory prefix (e.g., `cache/file.3mf`). The result is that the file lands at the wrong path on the printer (e.g., `/cache/cache/file.3mf` instead of `/cache/file.3mf`), and the subsequent print command fails because it references a file that does not exist at the expected path.
472
+
473
+ This fork bypasses `bambu-js` for all uploads and uses `basic-ftp` directly. The upload function (`ftpUpload`) connects to the printer, resolves the absolute remote path, changes to the correct directory with `ensureDir`, and then uploads using only the basename -- avoiding the double-path construction entirely.
474
+
475
+ ```typescript
476
+ // From src/printers/bambu.ts
477
+ private async ftpUpload(host, token, localPath, remotePath): Promise<void> {
478
+ const client = new FTPClient(15_000);
479
+ await client.access({ host, port: 990, user: "bblp", password: token,
480
+ secure: "implicit", secureOptions: { rejectUnauthorized: false } });
481
+ const absoluteRemote = remotePath.startsWith("/") ? remotePath : `/${remotePath}`;
482
+ const remoteDir = path.posix.dirname(absoluteRemote);
483
+ await client.ensureDir(remoteDir);
484
+ // basename only -- no double-path
485
+ await client.uploadFrom(localPath, path.posix.basename(absoluteRemote));
486
+ client.close();
487
+ }
488
+ ```
489
+
490
+ **Bug 2: AMS mapping format in the project_file MQTT command.**
491
+
492
+ The `bambu-js` library's project file command hardcodes `use_ams: true` and does not support the `ams_mapping` field at all. Separately, the parent project constructs the mapping as a simple array of slot indices (e.g., `[0, 2]`), which does not match the OpenBambuAPI specification.
493
+
494
+ According to the OpenBambuAPI spec, `ams_mapping` must be a 5-element array where each position corresponds to a filament color slot in the print file. Unused positions must be padded with `-1`. For example, a print using only AMS slot 0 sends `[-1, -1, -1, -1, 0]`.
495
+
496
+ This fork sends the `project_file` command directly via `bambu-node` (bypassing `bambu-js` entirely for print initiation) and constructs the `ams_mapping` array correctly:
497
+
498
+ ```typescript
499
+ // From src/printers/bambu.ts
500
+ let amsMapping: number[];
501
+ if (options.amsMapping && options.amsMapping.length > 0) {
502
+ amsMapping = Array.from({ length: 5 }, (_, i) =>
503
+ i < options.amsMapping!.length ? options.amsMapping![i] : -1
504
+ );
505
+ } else {
506
+ amsMapping = [-1, -1, -1, -1, 0]; // default: slot 0 only
507
+ }
508
+ ```
509
+
510
+ The command payload also includes all required fields per the OpenBambuAPI spec: `param` (the internal gcode path within the 3MF), `url` (the sdcard path), `md5` (computed from the plate's embedded gcode), and all calibration flags.
47
511
 
48
- | Variable | Default | Description |
49
- |----------|---------|-------------|
50
- | `PRINTER_HOST` | `localhost` | Printer IP address |
51
- | `BAMBU_SERIAL` | | Printer serial number |
52
- | `BAMBU_TOKEN` | | Printer access token |
53
- | `SLICER_PATH` | BambuStudio macOS path | Path to slicer executable |
54
- | `SLICER_PROFILE` | | Path to slicer profile |
55
- | `MCP_TRANSPORT` | `stdio` | `stdio` or `streamable-http` |
512
+ ---
56
513
 
57
- ## Tools
514
+ ## Available Tools
58
515
 
59
- ### Printer
60
- - `get_printer_status` - Temperatures, print progress, AMS status
61
- - `print_3mf` - Upload and print a 3MF file (auto-slices if needed)
62
- - `cancel_print` - Cancel current print
63
- - `set_temperature` - Set bed/nozzle temperature
64
- - `start_print_job` - Start a gcode file already on the printer
65
- - `upload_file` / `upload_gcode` - Upload files to printer
66
- - `list_printer_files` - List files on printer SD card
516
+ <details>
517
+ <summary><strong>Click to expand STL Manipulation Tools</strong></summary>
67
518
 
68
- ### STL Manipulation
69
- - `get_stl_info` - Bounding box, face count, dimensions
70
- - `scale_stl` - Scale by X/Y/Z factors
71
- - `rotate_stl` - Rotate by X/Y/Z angles
72
- - `extend_stl_base` - Extend the base of a model
73
- - `merge_vertices` - Merge close vertices
74
- - `center_model` - Center at origin
75
- - `lay_flat` - Orient largest face down
519
+ ### STL Manipulation Tools
76
520
 
77
- ### Slicing
78
- - `slice_stl` - Slice STL/3MF with BambuStudio (or PrusaSlicer, OrcaSlicer, Cura)
521
+ All STL tools load the full mesh geometry into memory. For files larger than 10 MB, monitor memory usage and prefer testing on smaller files first.
79
522
 
80
- ### Advanced
81
- - `blender_mcp_edit_model` - Bridge to Blender MCP for advanced edits
523
+ #### get_stl_info
524
+
525
+ Inspect an STL file without modifying it. Returns bounding box dimensions, face count, vertex count, and model center.
526
+
527
+ ```json
528
+ {
529
+ "stl_path": "/path/to/model.stl"
530
+ }
531
+ ```
532
+
533
+ #### scale_stl
534
+
535
+ Scale an STL model along individual axes. Omit any axis to leave it unchanged (defaults to 1.0).
536
+
537
+ ```json
538
+ {
539
+ "stl_path": "/path/to/model.stl",
540
+ "scale_x": 1.5,
541
+ "scale_y": 1.5,
542
+ "scale_z": 1.0
543
+ }
544
+ ```
545
+
546
+ For uniform scaling, set all three axes to the same value:
547
+
548
+ ```json
549
+ {
550
+ "stl_path": "/path/to/model.stl",
551
+ "scale_x": 2.0,
552
+ "scale_y": 2.0,
553
+ "scale_z": 2.0
554
+ }
555
+ ```
556
+
557
+ #### rotate_stl
558
+
559
+ Rotate an STL model around one or more axes. Angles are in degrees. Omitted axes default to 0.
560
+
561
+ ```json
562
+ {
563
+ "stl_path": "/path/to/model.stl",
564
+ "angle_x": 0,
565
+ "angle_y": 0,
566
+ "angle_z": 90
567
+ }
568
+ ```
569
+
570
+ #### extend_stl_base
571
+
572
+ Add solid geometry underneath the model to increase its base height. Useful for improving bed adhesion on models with a small or unstable footprint.
573
+
574
+ ```json
575
+ {
576
+ "stl_path": "/path/to/model.stl",
577
+ "extension_height": 3.0
578
+ }
579
+ ```
580
+
581
+ `extension_height` is in millimeters.
582
+
583
+ #### merge_vertices
584
+
585
+ Merge vertices that are closer together than the specified tolerance. This can close small gaps in a mesh and slightly reduce file size. Useful as a cleanup step before slicing.
586
+
587
+ ```json
588
+ {
589
+ "stl_path": "/path/to/model.stl",
590
+ "tolerance": 0.01
591
+ }
592
+ ```
593
+
594
+ `tolerance` is in millimeters and defaults to 0.01 if omitted.
595
+
596
+ #### center_model
597
+
598
+ Translate the model so the center of its bounding box sits at the world origin (0, 0, 0). Useful before applying transformations or exporting for use in another tool.
599
+
600
+ ```json
601
+ {
602
+ "stl_path": "/path/to/model.stl"
603
+ }
604
+ ```
605
+
606
+ #### lay_flat
607
+
608
+ Identify the largest flat surface on the model and rotate the model so that face is oriented downward on the XY plane (Z = 0). This is a common preparation step before slicing to minimize the need for supports.
609
+
610
+ ```json
611
+ {
612
+ "stl_path": "/path/to/model.stl"
613
+ }
614
+ ```
615
+
616
+ Note: this works best on models with a clearly dominant flat face. Results on organic or rounded shapes may be unpredictable.
617
+
618
+ </details>
619
+
620
+ <details>
621
+ <summary><strong>Click to expand Printer Control Tools</strong></summary>
622
+
623
+ ### Printer Control Tools
624
+
625
+ All printer tools accept optional `host`, `bambu_serial`, and `bambu_token` arguments. If omitted, values fall back to the environment variables `PRINTER_HOST`, `BAMBU_SERIAL`, and `BAMBU_TOKEN`. Passing them explicitly is useful when working with more than one printer.
626
+
627
+ #### get_printer_status
628
+
629
+ Retrieve current printer state including temperatures, print progress, layer count, time remaining, and AMS slot data. Internally sends a `push_all` MQTT command to force a fresh status report before reading cached state.
630
+
631
+ ```json
632
+ {
633
+ "host": "192.168.1.100",
634
+ "bambu_serial": "01P00A123456789",
635
+ "bambu_token": "your_access_token"
636
+ }
637
+ ```
638
+
639
+ Returns a structured object with fields including `status` (gcode_state string), `temperatures.nozzle`, `temperatures.bed`, `temperatures.chamber`, `print.progress`, `print.currentLayer`, `print.totalLayers`, `print.timeRemaining`, and `ams` (raw AMS data from the printer).
640
+
641
+ #### list_printer_files
642
+
643
+ List files stored on the printer's SD card. Scans the `cache/`, `timelapse/`, and `logs/` directories and returns both a flat list and a directory-grouped breakdown.
644
+
645
+ ```json
646
+ {
647
+ "host": "192.168.1.100",
648
+ "bambu_serial": "01P00A123456789",
649
+ "bambu_token": "your_access_token"
650
+ }
651
+ ```
652
+
653
+ #### upload_gcode
654
+
655
+ Write G-code content from a string directly to the printer's `cache/` directory. The content is written to a temporary file and uploaded via FTPS.
656
+
657
+ ```json
658
+ {
659
+ "filename": "calibration.gcode",
660
+ "gcode": "G28\nM104 S210\nG1 X100 Y100 Z10 F3000\n",
661
+ "host": "192.168.1.100",
662
+ "bambu_serial": "01P00A123456789",
663
+ "bambu_token": "your_access_token"
664
+ }
665
+ ```
666
+
667
+ #### upload_file
668
+
669
+ Upload a local file (G-code or 3MF) to the printer. If `print` is `true` and the file is a `.gcode` file, `start_print_job` is called automatically after a successful upload. For `.3mf` files, upload completes normally but you must use `print_3mf` to initiate the print (which handles plate selection and metadata).
670
+
671
+ ```json
672
+ {
673
+ "file_path": "/Users/yourname/Downloads/part.3mf",
674
+ "filename": "part.3mf",
675
+ "print": false,
676
+ "host": "192.168.1.100",
677
+ "bambu_serial": "01P00A123456789",
678
+ "bambu_token": "your_access_token"
679
+ }
680
+ ```
681
+
682
+ #### start_print_job
683
+
684
+ Start printing a `.gcode` file that is already on the printer's SD card. Do not use this for `.3mf` files -- use `print_3mf` instead, which handles the `project_file` MQTT command with proper metadata.
685
+
686
+ ```json
687
+ {
688
+ "filename": "cache/calibration.gcode",
689
+ "host": "192.168.1.100",
690
+ "bambu_serial": "01P00A123456789",
691
+ "bambu_token": "your_access_token"
692
+ }
693
+ ```
694
+
695
+ If `filename` does not include a directory prefix, the server prepends `cache/` automatically.
696
+
697
+ #### cancel_print
698
+
699
+ Cancel the currently running print job. Sends an `UpdateState` MQTT command with `state: "stop"`.
700
+
701
+ ```json
702
+ {
703
+ "host": "192.168.1.100",
704
+ "bambu_serial": "01P00A123456789",
705
+ "bambu_token": "your_access_token"
706
+ }
707
+ ```
708
+
709
+ #### set_temperature
710
+
711
+ Set the target temperature for the bed or nozzle. Dispatches an M140 (bed) or M104 (nozzle) G-code command via MQTT. Valid range is 0 to 300 degrees Celsius. Accepted values for `component` are `bed`, `nozzle`, `extruder`, `tool`, and `tool0`.
712
+
713
+ ```json
714
+ {
715
+ "component": "nozzle",
716
+ "temperature": 220,
717
+ "host": "192.168.1.100",
718
+ "bambu_serial": "01P00A123456789",
719
+ "bambu_token": "your_access_token"
720
+ }
721
+ ```
722
+
723
+ #### print_3mf
724
+
725
+ The primary tool for starting a Bambu print. This tool handles the complete workflow:
726
+
727
+ 1. Checks whether the 3MF contains embedded G-code (`Metadata/plate_<n>.gcode` entries).
728
+ 2. If no G-code is found, automatically slices the file using the configured slicer before proceeding.
729
+ 3. Parses the sliced 3MF to extract the correct plate file and compute its MD5 hash.
730
+ 4. Also parses `Metadata/project_settings.config` to read AMS mapping embedded by Bambu Studio.
731
+ 5. Uploads the 3MF to the printer's `cache/` directory via FTPS using `basic-ftp` directly (avoiding the bambu-js double-path bug).
732
+ 6. Sends a `project_file` MQTT command with the plate path, MD5, AMS mapping (formatted as a 5-element array per the OpenBambuAPI spec), and calibration flags.
733
+
734
+ ```json
735
+ {
736
+ "three_mf_path": "/Users/yourname/Downloads/bracket.3mf",
737
+ "bambu_model": "p1s",
738
+ "bed_type": "textured_plate",
739
+ "host": "192.168.1.100",
740
+ "bambu_serial": "01P00A123456789",
741
+ "bambu_token": "your_access_token",
742
+ "bed_leveling": true,
743
+ "flow_calibration": true,
744
+ "vibration_calibration": true,
745
+ "timelapse": false,
746
+ "use_ams": true,
747
+ "ams_mapping": [0, 1]
748
+ }
749
+ ```
750
+
751
+ `bambu_model` is **required** -- it ensures the slicer generates G-code for the correct printer. Using the wrong model can cause the bed to crash into the nozzle. If `bambu_model` is not provided in the tool call and `BAMBU_MODEL` is not set in the environment, the server will ask you interactively via MCP elicitation (if your client supports it) or return a clear error.
752
+
753
+ `bed_type` defaults to `textured_plate` if omitted. AMS mapping from the 3MF's slicer config is used automatically when present; the `ams_mapping` argument overrides it. Setting `use_ams: false` disables AMS entirely regardless of other mapping values.
754
+
755
+ Layer height, nozzle temperature, and other slicer parameters cannot be overridden via this tool -- they are baked into the 3MF's G-code at slice time. Apply those settings in your slicer before generating the 3MF.
756
+
757
+ </details>
758
+
759
+ <details>
760
+ <summary><strong>Click to expand Slicing Tools</strong></summary>
761
+
762
+ ### Slicing Tools
763
+
764
+ #### slice_stl
765
+
766
+ Slice an STL or 3MF file using an external slicer and return the path to the output file. The output is a sliced 3MF (for BambuStudio and OrcaSlicer) or a G-code file (for PrusaSlicer, Cura, Slic3r).
767
+
768
+ ```json
769
+ {
770
+ "stl_path": "/path/to/model.stl",
771
+ "slicer_type": "bambustudio",
772
+ "slicer_path": "/Applications/BambuStudio.app/Contents/MacOS/BambuStudio",
773
+ "slicer_profile": "/path/to/profile.ini"
774
+ }
775
+ ```
776
+
777
+ `slicer_type` options: `bambustudio`, `orcaslicer`, `prusaslicer`, `cura`, `slic3r`. When omitted, the value from the `SLICER_TYPE` environment variable is used (default: `bambustudio`).
778
+
779
+ `slicer_path` and `slicer_profile` fall back to the `SLICER_PATH` and `SLICER_PROFILE` environment variables when omitted.
780
+
781
+ For printing on a Bambu printer, the recommended workflow is: slice with `bambustudio` to get a sliced 3MF, then pass that output path to `print_3mf`.
782
+
783
+ </details>
784
+
785
+ <details>
786
+ <summary><strong>Click to expand Advanced Tools</strong></summary>
787
+
788
+ ### Advanced Tools
789
+
790
+ #### blender_mcp_edit_model
791
+
792
+ Send a set of named edit operations (remesh, boolean, decimate, etc.) to a Blender MCP bridge command for advanced mesh work that goes beyond what the built-in STL tools support.
793
+
794
+ When `execute` is `false` (the default), the tool returns the payload that would be sent without running anything -- useful for previewing what would be dispatched.
795
+
796
+ When `execute` is `true`, the server invokes the configured bridge command with the payload as a JSON-encoded environment variable (`MCP_BLENDER_PAYLOAD`). The bridge command must be set via the `BLENDER_MCP_BRIDGE_COMMAND` environment variable or passed inline as `bridge_command`.
797
+
798
+ ```json
799
+ {
800
+ "stl_path": "/path/to/model.stl",
801
+ "operations": ["remesh", "decimate:0.5", "boolean_union:/path/to/other.stl"],
802
+ "execute": false
803
+ }
804
+ ```
805
+
806
+ ```json
807
+ {
808
+ "stl_path": "/path/to/model.stl",
809
+ "operations": ["remesh"],
810
+ "bridge_command": "/usr/local/bin/blender-mcp-bridge",
811
+ "execute": true
812
+ }
813
+ ```
814
+
815
+ </details>
816
+
817
+ ---
818
+
819
+ ## Available Resources
820
+
821
+ Resources follow the MCP resource protocol and can be read by calling `ReadResource` with a URI. The server also lists them via `ListResources`.
822
+
823
+ ### Printer resources
824
+
825
+ - `printer://{host}/status` -- Current printer status. Equivalent to calling `get_printer_status`. Returns a JSON object with temperature, progress, layer, AMS, and raw state data.
826
+
827
+ - `printer://{host}/files` -- File listing for the printer's SD card. Equivalent to calling `list_printer_files`. Returns files grouped by directory.
828
+
829
+ **Example:** To read the status of the default printer, use URI `printer://192.168.1.100/status`. The host segment must match a configured printer IP; the server uses `PRINTER_HOST` if the default URI template is used.
830
+
831
+ ---
832
+
833
+ ## Example Commands for Claude
834
+
835
+ After connecting the MCP server in Claude Desktop or Claude Code, you can ask Claude to perform these operations directly in conversation.
836
+
837
+ ### Printer status and control
838
+
839
+ - "What is the current status of my Bambu printer?"
840
+ - "What temperature is the bed at right now?"
841
+ - "Show me the files on my printer's SD card."
842
+ - "Cancel the current print job."
843
+ - "Set the nozzle temperature to 220 degrees."
844
+ - "Set the bed to 65 degrees."
845
+
846
+ ### Printing 3MF files
847
+
848
+ - "Print the file at ~/Downloads/bracket.3mf on my Bambu printer."
849
+ - "Upload bracket.3mf to the printer and start printing with AMS slots 0 and 1."
850
+ - "Print my_model.3mf with bed leveling enabled and vibration calibration off."
851
+ - "Upload this 3MF without printing it yet."
852
+ - "Slice model.stl with BambuStudio and then print the result."
853
+
854
+ ### STL manipulation
855
+
856
+ - "What are the dimensions of this STL file?"
857
+ - "Scale model.stl to twice its current size."
858
+ - "Scale this model so it is 150% as wide but stays the same height."
859
+ - "Rotate this STL 90 degrees around the Z axis."
860
+ - "Extend the base of this model by 3mm so it sticks to the bed better."
861
+ - "Center this model at the origin."
862
+ - "Orient this model so its largest flat face is on the bottom."
863
+ - "Merge any near-duplicate vertices in this STL to clean it up."
864
+
865
+ ### Combined workflows
866
+
867
+ - "Rotate model.stl 45 degrees around Z, extend the base by 2mm, then print it on my Bambu P1S."
868
+ - "Take this unsliced 3MF, slice it with BambuStudio, and print the result."
869
+ - "Scale this part to 80% of its size, lay it flat, and start a print."
870
+
871
+ ---
872
+
873
+ ## Bambu Lab Printer Limitations
874
+
875
+ Understanding these constraints will help you avoid frustrating errors and set appropriate expectations.
876
+
877
+ 1. **Printable 3MF required for print_3mf.** The `print_3mf` tool expects a sliced 3MF containing at least one `Metadata/plate_<n>.gcode` entry. If you pass an unsliced 3MF (one exported from a CAD tool without slicing), the server will attempt to auto-slice it using the configured slicer. If auto-slicing fails, the tool errors out rather than sending an incomplete command to the printer.
878
+
879
+ 2. **Layer height, temperature, and slicer settings are baked in.** The `project_file` MQTT command tells the printer which plate to run. It does not support overriding layer height, temperature targets, infill percentage, or other slicing parameters at print time. These must be set in your slicer before generating the 3MF.
880
+
881
+ 3. **G-code and 3MF jobs use different command paths.** `start_print_job` sends a `GCodeFileCommand` over MQTT and is intended only for plain G-code files stored in the `cache/` directory. `.3mf` files must go through `print_3mf`, which sends the `project_file` command with plate selection, MD5 verification, and AMS mapping. Mixing these up will result in the printer either ignoring the command or displaying an error.
882
+
883
+ 4. **Temperature commands depend on printer state.** `set_temperature` dispatches M104 or M140 G-code via MQTT. Whether the printer accepts these commands depends on its current firmware version and operational state. Some printer states (such as the idle screen with AMS management open) may ignore or queue the commands.
884
+
885
+ 5. **Real-time status has latency.** `get_printer_status` sends a `push_all` MQTT request and waits up to 1.5 seconds for a response before reading cached state. If the printer is not responding quickly (busy, sleeping, or transitioning states), you may see slightly stale data. There is no persistent event subscription in this server -- each status call is a fresh request.
886
+
887
+ 6. **LAN mode required.** All operations require the printer to be on the same local network as the machine running this server. Cloud-only or remote access setups are not supported. If your printer is connected only via Bambu Cloud and LAN mode is disabled, connection will fail.
888
+
889
+ 7. **Self-signed TLS certificate.** The printer's FTPS server uses a self-signed certificate. The `basic-ftp` client is configured with `rejectUnauthorized: false` to accept it. This is standard for local network Bambu connections but assumes a trusted local network environment.
890
+
891
+ ---
892
+
893
+ ## General Limitations and Considerations
894
+
895
+ ### Memory usage
896
+
897
+ STL manipulation tools load the entire mesh into memory as Three.js geometry. For large files:
898
+
899
+ - Files over 10 MB can consume several hundred MB of RAM during processing.
900
+ - Running multiple operations sequentially on large files may cause memory to accumulate between garbage collection cycles.
901
+ - If you encounter out-of-memory errors, try splitting large operations or working with smaller/simplified meshes.
902
+ - The server has no built-in memory cap. On constrained systems, set the `TEMP_DIR` to a fast local path and avoid processing multiple large files concurrently.
903
+
904
+ ### STL manipulation limitations
905
+
906
+ - `lay_flat` identifies the largest flat face by analyzing surface normals. It works reliably on mechanical parts with clear flat faces and less reliably on organic or curved models where no single dominant face exists.
907
+ - `extend_stl_base` adds a new rectangular solid beneath the model. For models with complex or non-planar undersides, the result may include gaps or intersections at the join. Review the modified STL before printing.
908
+ - `merge_vertices` uses a distance tolerance to identify near-duplicate vertices. Setting the tolerance too high can alter model geometry. The default of 0.01 mm is safe for most models.
909
+ - Non-manifold meshes (meshes with holes, overlapping faces, or internal geometry) may produce unpredictable results for any transformation operation. Use a mesh repair tool (Meshmixer, PrusaSlicer's repair function, or Bambu Studio's repair option) before working with problematic files.
910
+
911
+ ### Performance considerations
912
+
913
+ - Slicing with BambuStudio CLI can take 30 seconds to several minutes depending on model complexity, layer height, and your system's CPU. The `slice_stl` call is synchronous and will block until the slicer process completes.
914
+ - FTPS uploads for large 3MF files (multi-plate prints, high-detail models) may take 15 to 60 seconds depending on your local network speed.
915
+ - MQTT connections are pooled by `host + serial` key. The first call to any printer tool in a session establishes the MQTT connection; subsequent calls reuse it. If the connection drops (printer power cycled, network interruption), the next call will reconnect automatically.
916
+
917
+ ---
82
918
 
83
919
  ## License
84
920
 
85
- GPL-2.0
921
+ GPL-2.0. See [LICENSE](./LICENSE) for the full text.
922
+
923
+ This project is a fork of [mcp-3D-printer-server](https://github.com/DMontgomery40/mcp-3D-printer-server) by David Montgomery, also GPL-2.0.