bambu-printer-mcp 1.1.5 → 1.1.6
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 +3 -3
- package/dist/index.js +52 -24
- package/package.json +1 -1
- package/src/index.ts +108 -24
package/README.md
CHANGED
|
@@ -771,7 +771,7 @@ Two transports are wired in, picked by `bambu_model`:
|
|
|
771
771
|
- **TCP-on-6000** for **A1, A1 mini, P1S, P1P**. Native protocol per [OpenBambuAPI/video.md](https://github.com/Doridian/OpenBambuAPI/blob/main/video.md): TLS on port 6000, 80-byte auth packet (`bblp` + access token), repeating 16-byte frame header + JPEG payload.
|
|
772
772
|
- **RTSP** for **X1, X1 Carbon, X1E, P2S** and **H2, H2S, H2D, H2C, H2D Pro**. Shells out to ffmpeg with `rtsps://bblp:<token>@<host>:322/streaming/live/1 -frames:v 1`. The H2 series wasn't documented in OpenBambuAPI's `video.md` but its firmware uses the same RTSP endpoint as X1 (verified live against an H2S, 2026-04-27).
|
|
773
773
|
|
|
774
|
-
**Requires ffmpeg in PATH** for the RTSP path. Install with `brew install ffmpeg` on macOS.
|
|
774
|
+
**Requires ffmpeg in PATH** for the RTSP path. Install with `brew install ffmpeg` on macOS. Configure a trusted custom binary with the server-side `FFMPEG_PATH` environment variable, or set `MCP_ALLOW_EXECUTABLE_ARG=1` before using the `ffmpeg_path` tool argument. The TCP-on-6000 path uses native Node TLS and does not require ffmpeg.
|
|
775
775
|
|
|
776
776
|
```json
|
|
777
777
|
{
|
|
@@ -1191,7 +1191,7 @@ Slice an STL or 3MF file using an external slicer and return the path to the out
|
|
|
1191
1191
|
|
|
1192
1192
|
`slicer_type` options: `bambustudio`, `orcaslicer`, `prusaslicer`, `cura`, `slic3r`. When omitted, the value from the `SLICER_TYPE` environment variable is used (default: `bambustudio`).
|
|
1193
1193
|
|
|
1194
|
-
`slicer_path` and `slicer_profile` fall back to the `SLICER_PATH` and `SLICER_PROFILE` environment variables when omitted.
|
|
1194
|
+
`slicer_path` and `slicer_profile` fall back to the `SLICER_PATH` and `SLICER_PROFILE` environment variables when omitted. Per-call `slicer_path` overrides require `MCP_ALLOW_EXECUTABLE_ARG=1`.
|
|
1195
1195
|
|
|
1196
1196
|
You can provide either `template_3mf_path` or `template_name` when you want to slice from a saved template. `template_name` resolves through the local template registry directory configured for the server.
|
|
1197
1197
|
|
|
@@ -1257,7 +1257,7 @@ Send a set of named edit operations (remesh, boolean, decimate, etc.) to a Blend
|
|
|
1257
1257
|
|
|
1258
1258
|
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.
|
|
1259
1259
|
|
|
1260
|
-
When `execute` is `true`, the server invokes the configured bridge command with the payload as a JSON-encoded environment variable (`MCP_BLENDER_PAYLOAD`).
|
|
1260
|
+
When `execute` is `true`, the server invokes the configured bridge command with the payload as a JSON-encoded environment variable (`MCP_BLENDER_PAYLOAD`). Configure it with `BLENDER_MCP_BRIDGE_COMMAND`; per-call `bridge_command` overrides require `MCP_ALLOW_EXECUTABLE_ARG=1`.
|
|
1261
1261
|
|
|
1262
1262
|
```json
|
|
1263
1263
|
{
|
package/dist/index.js
CHANGED
|
@@ -498,6 +498,9 @@ function readRuntimeConfig() {
|
|
|
498
498
|
enableJsonResponse: parseBooleanEnv(process.env.MCP_HTTP_JSON_RESPONSE, true),
|
|
499
499
|
allowedOrigins: parseCsvEnv(process.env.MCP_HTTP_ALLOWED_ORIGINS),
|
|
500
500
|
blenderBridgeCommand: process.env.BLENDER_MCP_BRIDGE_COMMAND?.trim() || undefined,
|
|
501
|
+
ffmpegPath: process.env.FFMPEG_PATH?.trim() || undefined,
|
|
502
|
+
allowExecutableArg: parseBooleanEnv(process.env.MCP_ALLOW_EXECUTABLE_ARG, false),
|
|
503
|
+
allowBridgeCommandArg: parseBooleanEnv(process.env.MCP_ALLOW_BRIDGE_COMMAND_ARG, false),
|
|
501
504
|
};
|
|
502
505
|
}
|
|
503
506
|
function expandUserPath(rawPath) {
|
|
@@ -821,17 +824,44 @@ class BambuPrinterMCPServer {
|
|
|
821
824
|
throw elicitError;
|
|
822
825
|
}
|
|
823
826
|
}
|
|
824
|
-
bridgeOptionsFromArgs(args) {
|
|
827
|
+
bridgeOptionsFromArgs(args, toolName) {
|
|
825
828
|
return {
|
|
826
|
-
bridgeCommand: args?.bridge_command
|
|
829
|
+
bridgeCommand: this.resolveExecutableSelectorArg(args?.bridge_command, toolName, "bridge_command", true),
|
|
827
830
|
configDir: args?.bambu_network_config_dir !== undefined ? String(args.bambu_network_config_dir) : undefined,
|
|
828
831
|
countryCode: args?.country_code !== undefined ? String(args.country_code) : undefined,
|
|
829
832
|
userInfo: args?.user_info !== undefined ? String(args.user_info) : undefined,
|
|
830
833
|
timeoutMs: args?.timeout_ms !== undefined ? Number(args.timeout_ms) : undefined,
|
|
831
834
|
};
|
|
832
835
|
}
|
|
836
|
+
resolveExecutableSelectorArg(rawValue, toolName, argumentName, allowLegacyBridgeArg = false) {
|
|
837
|
+
if (rawValue === undefined) {
|
|
838
|
+
return undefined;
|
|
839
|
+
}
|
|
840
|
+
const value = String(rawValue);
|
|
841
|
+
if (value.length === 0) {
|
|
842
|
+
return undefined;
|
|
843
|
+
}
|
|
844
|
+
const isAllowed = this.runtimeConfig.allowExecutableArg ||
|
|
845
|
+
(allowLegacyBridgeArg && this.runtimeConfig.allowBridgeCommandArg);
|
|
846
|
+
if (!isAllowed) {
|
|
847
|
+
throw new Error(`${toolName}: the ${argumentName} argument cannot select an executable by default. ` +
|
|
848
|
+
"Executable paths and commands are read from server environment configuration. Set " +
|
|
849
|
+
`MCP_ALLOW_EXECUTABLE_ARG=1 to accept ${argumentName} for process execution.`);
|
|
850
|
+
}
|
|
851
|
+
return value;
|
|
852
|
+
}
|
|
853
|
+
resolveSlicerConfigFromArgs(args, toolName) {
|
|
854
|
+
const config = resolveSlicerConfig(args);
|
|
855
|
+
if (args?.slicer_path !== undefined) {
|
|
856
|
+
const resolvedSlicerPath = this.resolveExecutableSelectorArg(args.slicer_path, toolName, "slicer_path");
|
|
857
|
+
if (resolvedSlicerPath !== undefined) {
|
|
858
|
+
config.slicerPath = resolvedSlicerPath;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
return config;
|
|
862
|
+
}
|
|
833
863
|
async ensurePrintableThreeMFPath(args, printModel, printPreset, bedType) {
|
|
834
|
-
const { slicerType, slicerPath, slicerProfile } =
|
|
864
|
+
const { slicerType, slicerPath, slicerProfile } = this.resolveSlicerConfigFromArgs(args, "print_3mf_bambu_network");
|
|
835
865
|
let threeMFPath = String(args.three_mf_path);
|
|
836
866
|
const JSZip = (await import('jszip')).default;
|
|
837
867
|
const zipData = fs.readFileSync(threeMFPath);
|
|
@@ -993,7 +1023,7 @@ class BambuPrinterMCPServer {
|
|
|
993
1023
|
task_ext_change_assist: args?.external_change_assist !== undefined ? Boolean(args.external_change_assist) : false,
|
|
994
1024
|
try_emmc_print: args?.try_emmc_print !== undefined ? Boolean(args.try_emmc_print) : false,
|
|
995
1025
|
};
|
|
996
|
-
const bridgeResult = await this.bambuNetwork.callWithAgent(bridgeMethod, { client_job_id: clientJobId, params }, this.bridgeOptionsFromArgs(args));
|
|
1026
|
+
const bridgeResult = await this.bambuNetwork.callWithAgent(bridgeMethod, { client_job_id: clientJobId, params }, this.bridgeOptionsFromArgs(args, "print_3mf_bambu_network"));
|
|
997
1027
|
if (typeof bridgeResult === "object" && bridgeResult !== null && bridgeResult.ok === false) {
|
|
998
1028
|
throw new Error(`FULU BambuNetwork bridge method ${bridgeMethod} failed: ${String(bridgeResult.error || "unknown bridge error")}`);
|
|
999
1029
|
}
|
|
@@ -1484,7 +1514,7 @@ class BambuPrinterMCPServer {
|
|
|
1484
1514
|
enum: SLICER_SCHEMA_VALUES,
|
|
1485
1515
|
description: "Type of slicer to use. Bambu-compatible choices (bambustudio, orcaslicer, orcaslicer-bambulab) export sliced 3MF; aliases such as fulu-orca and orca-studio are accepted."
|
|
1486
1516
|
},
|
|
1487
|
-
slicer_path: { type: "string", description: "Path to the slicer executable (default: value from env)" },
|
|
1517
|
+
slicer_path: { type: "string", description: "Path to the slicer executable (default: value from env). Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
1488
1518
|
slicer_profile: { type: "string", description: "Explicit slicer profile/config file. Overrides the named template only when provided in the tool call." },
|
|
1489
1519
|
nozzle_diameter: { type: "string", description: "Nozzle diameter in mm (default: 0.4)" },
|
|
1490
1520
|
bed_type: {
|
|
@@ -1530,7 +1560,7 @@ class BambuPrinterMCPServer {
|
|
|
1530
1560
|
enum: SLICER_SCHEMA_VALUES,
|
|
1531
1561
|
description: "Type of slicer to use. Bambu-compatible choices (bambustudio, orcaslicer, orcaslicer-bambulab) export sliced 3MF; aliases such as fulu-orca and orca-studio are accepted."
|
|
1532
1562
|
},
|
|
1533
|
-
slicer_path: { type: "string", description: "Path to the slicer executable (default: value from env)" },
|
|
1563
|
+
slicer_path: { type: "string", description: "Path to the slicer executable (default: value from env). Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
1534
1564
|
slicer_profile: { type: "string", description: "Path to the slicer profile/config file (optional, overrides bambu_model preset)" },
|
|
1535
1565
|
template_3mf_path: { type: "string", description: "Optional template 3MF whose embedded Bambu slicer settings should be reused when slicing a new STL or 3MF." },
|
|
1536
1566
|
template_name: { type: "string", description: "Optional named template from the local registry. Resolves to template_3mf_path automatically." },
|
|
@@ -1584,7 +1614,7 @@ class BambuPrinterMCPServer {
|
|
|
1584
1614
|
type: "object",
|
|
1585
1615
|
properties: {
|
|
1586
1616
|
connect: { type: "boolean", description: "When true, start the bridge command and run a handshake plus agent initialization probe." },
|
|
1587
|
-
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND." },
|
|
1617
|
+
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND. Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
1588
1618
|
bambu_network_config_dir: { type: "string", description: "Config/log directory used by the BambuNetwork agent; defaults to BAMBU_NETWORK_CONFIG_DIR or a user config directory." },
|
|
1589
1619
|
country_code: { type: "string", description: "BambuNetwork country code, such as US, used by the agent during startup." },
|
|
1590
1620
|
user_info: { type: "string", description: "Optional BambuNetwork user_info JSON string to pass to net.change_user after the agent starts." },
|
|
@@ -1601,7 +1631,7 @@ class BambuPrinterMCPServer {
|
|
|
1601
1631
|
method: { type: "string", description: "FULU bridge method name, for example bridge.handshake, net.is_user_login, or net.get_user_selected_machine." },
|
|
1602
1632
|
payload: { type: "object", description: "JSON payload passed to the bridge method." },
|
|
1603
1633
|
with_agent: { type: "boolean", description: "When true, initialize a BambuNetwork agent and add its agent id to the payload before calling the method." },
|
|
1604
|
-
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND." },
|
|
1634
|
+
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND. Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
1605
1635
|
bambu_network_config_dir: { type: "string", description: "Config/log directory used by the BambuNetwork agent; defaults to BAMBU_NETWORK_CONFIG_DIR or a user config directory." },
|
|
1606
1636
|
country_code: { type: "string", description: "BambuNetwork country code, such as US, used by the agent during startup." },
|
|
1607
1637
|
user_info: { type: "string", description: "Optional BambuNetwork user_info JSON string to pass to net.change_user after the agent starts." },
|
|
@@ -1637,13 +1667,13 @@ class BambuPrinterMCPServer {
|
|
|
1637
1667
|
preset_name: { type: "string", description: "Optional preset name sent in FULU PrintParams; defaults to project plus one-based plate index." },
|
|
1638
1668
|
task_name: { type: "string", description: "Optional BambuNetwork task name; defaults to the project name." },
|
|
1639
1669
|
config_filename: { type: "string", description: "Optional config 3MF path for cloud print; defaults to the same 3MF path." },
|
|
1640
|
-
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND." },
|
|
1670
|
+
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND. Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
1641
1671
|
bambu_network_config_dir: { type: "string", description: "Config/log directory used by the BambuNetwork agent; defaults to BAMBU_NETWORK_CONFIG_DIR or a user config directory." },
|
|
1642
1672
|
country_code: { type: "string", description: "BambuNetwork country code, such as US, used by the agent during startup." },
|
|
1643
1673
|
user_info: { type: "string", description: "Optional BambuNetwork user_info JSON string to pass to net.change_user after the agent starts." },
|
|
1644
1674
|
timeout_ms: { type: "number", description: "Bridge request timeout in milliseconds." },
|
|
1645
1675
|
slicer_type: { type: "string", enum: SLICER_SCHEMA_VALUES, description: "Slicer to use only if auto-slicing an unsliced 3MF; use orcaslicer-bambulab for FULU's fork." },
|
|
1646
|
-
slicer_path: { type: "string", description: "Path to the slicer executable for auto-slicing; defaults to value from env or a platform default." },
|
|
1676
|
+
slicer_path: { type: "string", description: "Path to the slicer executable for auto-slicing; defaults to value from env or a platform default. Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
1647
1677
|
slicer_profile: { type: "string", description: "Path to an optional slicer profile/config file for auto-slicing." },
|
|
1648
1678
|
nozzle_diameter: { type: "string", description: "Nozzle diameter in mm for auto-slicing (default: 0.4)." },
|
|
1649
1679
|
use_ams: { type: "boolean", description: "Whether to use the AMS; defaults to auto-detect from the 3MF mapping." },
|
|
@@ -1679,7 +1709,7 @@ class BambuPrinterMCPServer {
|
|
|
1679
1709
|
timeout_ms: { type: "number", description: "Max ms to wait for a full frame (default 8000). Camera may take a few seconds on cold start." },
|
|
1680
1710
|
bambu_model: { type: "string", description: "Printer model. Used to route to the correct protocol or fail fast on unsupported models. Defaults to BAMBU_MODEL." },
|
|
1681
1711
|
experimental: { type: "boolean", description: "Deprecated and ignored. Earlier this flag let callers probe H2 series via the A1/P1 TCP-on-6000 path; live testing on an H2S confirmed H2 uses RTSP instead, so the flag has no effect now." },
|
|
1682
|
-
ffmpeg_path: { type: "string", description: "Override path to the ffmpeg binary used by the RTSP path. Defaults to ffmpeg via $PATH. Required only for the RTSP transport (X1, P2S, H2 series)." },
|
|
1712
|
+
ffmpeg_path: { type: "string", description: "Override path to the ffmpeg binary used by the RTSP path. Defaults to FFMPEG_PATH or ffmpeg via $PATH. Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1. Required only for the RTSP transport (X1, P2S, H2 series)." },
|
|
1683
1713
|
host: { type: "string", description: "Hostname or IP of the printer (default: value from env)" },
|
|
1684
1714
|
bambu_serial: { type: "string", description: "Serial number (default: value from env)" },
|
|
1685
1715
|
bambu_token: { type: "string", description: "Access token (default: value from env)" }
|
|
@@ -1997,7 +2027,7 @@ class BambuPrinterMCPServer {
|
|
|
1997
2027
|
bambu_network_method: { type: "string", enum: BAMBU_NETWORK_PRINT_METHODS, description: "FULU print method when connection_mode is bambu_network; defaults to start_print for cloud and start_local_print for lan." },
|
|
1998
2028
|
dev_id: { type: "string", description: "Bambu device id for FULU BambuNetwork printing; defaults to BAMBU_DEV_ID or BAMBU_SERIAL." },
|
|
1999
2029
|
dev_ip: { type: "string", description: "Printer IP address for FULU BambuNetwork LAN/local print methods; defaults to host when provided." },
|
|
2000
|
-
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND." },
|
|
2030
|
+
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND. Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
2001
2031
|
bambu_network_config_dir: { type: "string", description: "Config/log directory used by the FULU BambuNetwork agent." },
|
|
2002
2032
|
country_code: { type: "string", description: "BambuNetwork country code, such as US, used by the FULU bridge agent." },
|
|
2003
2033
|
user_info: { type: "string", description: "Optional BambuNetwork user_info JSON string passed to net.change_user for the FULU bridge." },
|
|
@@ -2015,7 +2045,7 @@ class BambuPrinterMCPServer {
|
|
|
2015
2045
|
enum: SLICER_SCHEMA_VALUES,
|
|
2016
2046
|
description: "Slicer to use only if auto-slicing an unsliced 3MF. Bambu-compatible slicer aliases such as fulu-orca and orca-studio are accepted."
|
|
2017
2047
|
},
|
|
2018
|
-
slicer_path: { type: "string", description: "Path to the slicer executable for auto-slicing (default: value from env or a platform default)" },
|
|
2048
|
+
slicer_path: { type: "string", description: "Path to the slicer executable for auto-slicing (default: value from env or a platform default). Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
2019
2049
|
use_ams: { type: "boolean", description: "Whether to use the AMS (default: auto-detect from 3MF)" },
|
|
2020
2050
|
ams_mapping: {
|
|
2021
2051
|
type: "array",
|
|
@@ -2122,7 +2152,7 @@ class BambuPrinterMCPServer {
|
|
|
2122
2152
|
description: "Ordered edit operations for Blender (e.g. remesh, boolean, decimate)",
|
|
2123
2153
|
items: { type: "string" }
|
|
2124
2154
|
},
|
|
2125
|
-
bridge_command: { type: "string", description: "Override command for invoking Blender MCP bridge" },
|
|
2155
|
+
bridge_command: { type: "string", description: "Override command for invoking Blender MCP bridge. Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
2126
2156
|
execute: { type: "boolean", description: "Execute bridge command (true) or return payload only (false)" }
|
|
2127
2157
|
},
|
|
2128
2158
|
required: ["stl_path", "operations"]
|
|
@@ -2195,7 +2225,7 @@ class BambuPrinterMCPServer {
|
|
|
2195
2225
|
break;
|
|
2196
2226
|
case "bambu_network_bridge_status": {
|
|
2197
2227
|
const bridgeArgs = args;
|
|
2198
|
-
const options = this.bridgeOptionsFromArgs(bridgeArgs);
|
|
2228
|
+
const options = this.bridgeOptionsFromArgs(bridgeArgs, "bambu_network_bridge_status");
|
|
2199
2229
|
result = this.bambuNetwork.getStatus(options);
|
|
2200
2230
|
if (Boolean(bridgeArgs?.connect)) {
|
|
2201
2231
|
const probe = await this.bambuNetwork.ensureAgent(options);
|
|
@@ -2216,7 +2246,7 @@ class BambuPrinterMCPServer {
|
|
|
2216
2246
|
const payload = bridgeArgs.payload && typeof bridgeArgs.payload === "object"
|
|
2217
2247
|
? bridgeArgs.payload
|
|
2218
2248
|
: {};
|
|
2219
|
-
const options = this.bridgeOptionsFromArgs(bridgeArgs);
|
|
2249
|
+
const options = this.bridgeOptionsFromArgs(bridgeArgs, "bambu_network_call");
|
|
2220
2250
|
result = bridgeArgs.with_agent === false
|
|
2221
2251
|
? await this.bambuNetwork.request(String(bridgeArgs.method), payload, options)
|
|
2222
2252
|
: await this.bambuNetwork.callWithAgent(String(bridgeArgs.method), payload, options);
|
|
@@ -2233,7 +2263,7 @@ class BambuPrinterMCPServer {
|
|
|
2233
2263
|
timeoutMs: args?.timeout_ms !== undefined ? Number(args.timeout_ms) : undefined,
|
|
2234
2264
|
bambuModel: snapshotModel ? String(snapshotModel) : undefined,
|
|
2235
2265
|
experimental: Boolean(args?.experimental),
|
|
2236
|
-
ffmpegPath: args?.ffmpeg_path
|
|
2266
|
+
ffmpegPath: this.resolveExecutableSelectorArg(args?.ffmpeg_path, "camera_snapshot", "ffmpeg_path") ?? this.runtimeConfig.ffmpegPath,
|
|
2237
2267
|
});
|
|
2238
2268
|
break;
|
|
2239
2269
|
}
|
|
@@ -2380,7 +2410,7 @@ class BambuPrinterMCPServer {
|
|
|
2380
2410
|
if (!args?.template_name) {
|
|
2381
2411
|
throw new Error("Missing required parameter: template_name");
|
|
2382
2412
|
}
|
|
2383
|
-
const { slicerType, slicerPath, slicerProfile } =
|
|
2413
|
+
const { slicerType, slicerPath, slicerProfile } = this.resolveSlicerConfigFromArgs(args, "slice_with_template");
|
|
2384
2414
|
const sliceModel = await this.resolveBambuModel(args?.bambu_model);
|
|
2385
2415
|
const nozzleDiam = String(args?.nozzle_diameter || DEFAULT_NOZZLE_DIAMETER);
|
|
2386
2416
|
const activeSlicerProfile = await resolveTemplateFirstSlicerProfilePath(args, slicerProfile || undefined, resolveTemplatePathFromName(["json", "config", "3mf"]) || explicitTemplatePath || undefined, TEMP_DIR);
|
|
@@ -2456,7 +2486,7 @@ class BambuPrinterMCPServer {
|
|
|
2456
2486
|
if (!args?.stl_path) {
|
|
2457
2487
|
throw new Error("Missing required parameter: stl_path");
|
|
2458
2488
|
}
|
|
2459
|
-
const { slicerType, slicerPath, slicerProfile } =
|
|
2489
|
+
const { slicerType, slicerPath, slicerProfile } = this.resolveSlicerConfigFromArgs(args, "slice_stl");
|
|
2460
2490
|
const sliceModel = await this.resolveBambuModel(args?.bambu_model);
|
|
2461
2491
|
const nozzleDiam = String(args?.nozzle_diameter || DEFAULT_NOZZLE_DIAMETER);
|
|
2462
2492
|
const activeSlicerProfile = await resolveSlicerProfilePath(slicerProfile || undefined, resolveTemplatePathFromName(["json", "config", "3mf"]) || explicitTemplatePath || undefined, TEMP_DIR);
|
|
@@ -2541,7 +2571,7 @@ class BambuPrinterMCPServer {
|
|
|
2541
2571
|
if (!bambuSerial || !bambuToken) {
|
|
2542
2572
|
throw new Error("Bambu serial number and access token are required for print_3mf.");
|
|
2543
2573
|
}
|
|
2544
|
-
const { slicerType, slicerPath, slicerProfile } =
|
|
2574
|
+
const { slicerType, slicerPath, slicerProfile } = this.resolveSlicerConfigFromArgs(args, "print_3mf");
|
|
2545
2575
|
const printModel = await this.resolveBambuModel(args?.bambu_model);
|
|
2546
2576
|
const printBedType = resolveBedType(args?.bed_type);
|
|
2547
2577
|
const printNozzle = String(args?.nozzle_diameter || DEFAULT_NOZZLE_DIAMETER);
|
|
@@ -2689,7 +2719,7 @@ class BambuPrinterMCPServer {
|
|
|
2689
2719
|
if (!bambuSerial || !bambuToken) {
|
|
2690
2720
|
throw new Error("Bambu serial number and access token are required for print_collar_charm.");
|
|
2691
2721
|
}
|
|
2692
|
-
const { slicerType, slicerPath, slicerProfile } =
|
|
2722
|
+
const { slicerType, slicerPath, slicerProfile } = this.resolveSlicerConfigFromArgs(args, "print_collar_charm");
|
|
2693
2723
|
const printModel = await this.resolveBambuModel(args?.bambu_model);
|
|
2694
2724
|
const printBedType = resolveBedType(args?.bed_type);
|
|
2695
2725
|
const printNozzle = String(args?.nozzle_diameter || DEFAULT_NOZZLE_DIAMETER);
|
|
@@ -2761,9 +2791,7 @@ class BambuPrinterMCPServer {
|
|
|
2761
2791
|
stlPath: String(args.stl_path),
|
|
2762
2792
|
operations: args.operations.map((entry) => String(entry)),
|
|
2763
2793
|
execute: Boolean(args.execute ?? false),
|
|
2764
|
-
bridgeCommand: args.bridge_command
|
|
2765
|
-
? String(args.bridge_command)
|
|
2766
|
-
: this.runtimeConfig.blenderBridgeCommand,
|
|
2794
|
+
bridgeCommand: this.resolveExecutableSelectorArg(args.bridge_command, "blender_mcp_edit_model", "bridge_command", true) ?? this.runtimeConfig.blenderBridgeCommand,
|
|
2767
2795
|
});
|
|
2768
2796
|
break;
|
|
2769
2797
|
default:
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -601,6 +601,9 @@ type RuntimeConfig = {
|
|
|
601
601
|
enableJsonResponse: boolean;
|
|
602
602
|
allowedOrigins: Set<string>;
|
|
603
603
|
blenderBridgeCommand?: string;
|
|
604
|
+
ffmpegPath?: string;
|
|
605
|
+
allowExecutableArg: boolean;
|
|
606
|
+
allowBridgeCommandArg: boolean;
|
|
604
607
|
};
|
|
605
608
|
|
|
606
609
|
function parseBooleanEnv(rawValue: string | undefined, fallback: boolean): boolean {
|
|
@@ -698,6 +701,9 @@ function readRuntimeConfig(): RuntimeConfig {
|
|
|
698
701
|
enableJsonResponse: parseBooleanEnv(process.env.MCP_HTTP_JSON_RESPONSE, true),
|
|
699
702
|
allowedOrigins: parseCsvEnv(process.env.MCP_HTTP_ALLOWED_ORIGINS),
|
|
700
703
|
blenderBridgeCommand: process.env.BLENDER_MCP_BRIDGE_COMMAND?.trim() || undefined,
|
|
704
|
+
ffmpegPath: process.env.FFMPEG_PATH?.trim() || undefined,
|
|
705
|
+
allowExecutableArg: parseBooleanEnv(process.env.MCP_ALLOW_EXECUTABLE_ARG, false),
|
|
706
|
+
allowBridgeCommandArg: parseBooleanEnv(process.env.MCP_ALLOW_BRIDGE_COMMAND_ARG, false),
|
|
701
707
|
};
|
|
702
708
|
}
|
|
703
709
|
|
|
@@ -1113,9 +1119,17 @@ class BambuPrinterMCPServer {
|
|
|
1113
1119
|
}
|
|
1114
1120
|
}
|
|
1115
1121
|
|
|
1116
|
-
private bridgeOptionsFromArgs(
|
|
1122
|
+
private bridgeOptionsFromArgs(
|
|
1123
|
+
args: Record<string, any> | undefined,
|
|
1124
|
+
toolName: string
|
|
1125
|
+
): BambuNetworkBridgeOptions {
|
|
1117
1126
|
return {
|
|
1118
|
-
bridgeCommand:
|
|
1127
|
+
bridgeCommand: this.resolveExecutableSelectorArg(
|
|
1128
|
+
args?.bridge_command,
|
|
1129
|
+
toolName,
|
|
1130
|
+
"bridge_command",
|
|
1131
|
+
true
|
|
1132
|
+
),
|
|
1119
1133
|
configDir: args?.bambu_network_config_dir !== undefined ? String(args.bambu_network_config_dir) : undefined,
|
|
1120
1134
|
countryCode: args?.country_code !== undefined ? String(args.country_code) : undefined,
|
|
1121
1135
|
userInfo: args?.user_info !== undefined ? String(args.user_info) : undefined,
|
|
@@ -1123,13 +1137,61 @@ class BambuPrinterMCPServer {
|
|
|
1123
1137
|
};
|
|
1124
1138
|
}
|
|
1125
1139
|
|
|
1140
|
+
private resolveExecutableSelectorArg(
|
|
1141
|
+
rawValue: unknown,
|
|
1142
|
+
toolName: string,
|
|
1143
|
+
argumentName: string,
|
|
1144
|
+
allowLegacyBridgeArg = false
|
|
1145
|
+
): string | undefined {
|
|
1146
|
+
if (rawValue === undefined) {
|
|
1147
|
+
return undefined;
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
const value = String(rawValue);
|
|
1151
|
+
if (value.length === 0) {
|
|
1152
|
+
return undefined;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
const isAllowed =
|
|
1156
|
+
this.runtimeConfig.allowExecutableArg ||
|
|
1157
|
+
(allowLegacyBridgeArg && this.runtimeConfig.allowBridgeCommandArg);
|
|
1158
|
+
if (!isAllowed) {
|
|
1159
|
+
throw new Error(
|
|
1160
|
+
`${toolName}: the ${argumentName} argument cannot select an executable by default. ` +
|
|
1161
|
+
"Executable paths and commands are read from server environment configuration. Set " +
|
|
1162
|
+
`MCP_ALLOW_EXECUTABLE_ARG=1 to accept ${argumentName} for process execution.`
|
|
1163
|
+
);
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
return value;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
private resolveSlicerConfigFromArgs(
|
|
1170
|
+
args: Record<string, unknown> | undefined,
|
|
1171
|
+
toolName: string
|
|
1172
|
+
): ReturnType<typeof resolveSlicerConfig> {
|
|
1173
|
+
const config = resolveSlicerConfig(args);
|
|
1174
|
+
if (args?.slicer_path !== undefined) {
|
|
1175
|
+
const resolvedSlicerPath = this.resolveExecutableSelectorArg(
|
|
1176
|
+
args.slicer_path,
|
|
1177
|
+
toolName,
|
|
1178
|
+
"slicer_path"
|
|
1179
|
+
);
|
|
1180
|
+
if (resolvedSlicerPath !== undefined) {
|
|
1181
|
+
config.slicerPath = resolvedSlicerPath;
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
return config;
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1126
1187
|
private async ensurePrintableThreeMFPath(
|
|
1127
1188
|
args: Record<string, any>,
|
|
1128
1189
|
printModel: string,
|
|
1129
1190
|
printPreset: string | undefined,
|
|
1130
1191
|
bedType?: string
|
|
1131
1192
|
): Promise<{ threeMFPath: string; autoSliced: boolean }> {
|
|
1132
|
-
const { slicerType, slicerPath, slicerProfile } =
|
|
1193
|
+
const { slicerType, slicerPath, slicerProfile } =
|
|
1194
|
+
this.resolveSlicerConfigFromArgs(args, "print_3mf_bambu_network");
|
|
1133
1195
|
let threeMFPath = String(args.three_mf_path);
|
|
1134
1196
|
|
|
1135
1197
|
const JSZip = (await import('jszip')).default;
|
|
@@ -1366,7 +1428,7 @@ class BambuPrinterMCPServer {
|
|
|
1366
1428
|
const bridgeResult = await this.bambuNetwork.callWithAgent(
|
|
1367
1429
|
bridgeMethod,
|
|
1368
1430
|
{ client_job_id: clientJobId, params },
|
|
1369
|
-
this.bridgeOptionsFromArgs(args)
|
|
1431
|
+
this.bridgeOptionsFromArgs(args, "print_3mf_bambu_network")
|
|
1370
1432
|
);
|
|
1371
1433
|
|
|
1372
1434
|
if (typeof bridgeResult === "object" && bridgeResult !== null && (bridgeResult as { ok?: unknown }).ok === false) {
|
|
@@ -1949,7 +2011,7 @@ class BambuPrinterMCPServer {
|
|
|
1949
2011
|
enum: SLICER_SCHEMA_VALUES,
|
|
1950
2012
|
description: "Type of slicer to use. Bambu-compatible choices (bambustudio, orcaslicer, orcaslicer-bambulab) export sliced 3MF; aliases such as fulu-orca and orca-studio are accepted."
|
|
1951
2013
|
},
|
|
1952
|
-
slicer_path: { type: "string", description: "Path to the slicer executable (default: value from env)" },
|
|
2014
|
+
slicer_path: { type: "string", description: "Path to the slicer executable (default: value from env). Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
1953
2015
|
slicer_profile: { type: "string", description: "Explicit slicer profile/config file. Overrides the named template only when provided in the tool call." },
|
|
1954
2016
|
nozzle_diameter: { type: "string", description: "Nozzle diameter in mm (default: 0.4)" },
|
|
1955
2017
|
bed_type: {
|
|
@@ -1995,7 +2057,7 @@ class BambuPrinterMCPServer {
|
|
|
1995
2057
|
enum: SLICER_SCHEMA_VALUES,
|
|
1996
2058
|
description: "Type of slicer to use. Bambu-compatible choices (bambustudio, orcaslicer, orcaslicer-bambulab) export sliced 3MF; aliases such as fulu-orca and orca-studio are accepted."
|
|
1997
2059
|
},
|
|
1998
|
-
slicer_path: { type: "string", description: "Path to the slicer executable (default: value from env)" },
|
|
2060
|
+
slicer_path: { type: "string", description: "Path to the slicer executable (default: value from env). Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
1999
2061
|
slicer_profile: { type: "string", description: "Path to the slicer profile/config file (optional, overrides bambu_model preset)" },
|
|
2000
2062
|
template_3mf_path: { type: "string", description: "Optional template 3MF whose embedded Bambu slicer settings should be reused when slicing a new STL or 3MF." },
|
|
2001
2063
|
template_name: { type: "string", description: "Optional named template from the local registry. Resolves to template_3mf_path automatically." },
|
|
@@ -2049,7 +2111,7 @@ class BambuPrinterMCPServer {
|
|
|
2049
2111
|
type: "object",
|
|
2050
2112
|
properties: {
|
|
2051
2113
|
connect: { type: "boolean", description: "When true, start the bridge command and run a handshake plus agent initialization probe." },
|
|
2052
|
-
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND." },
|
|
2114
|
+
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND. Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
2053
2115
|
bambu_network_config_dir: { type: "string", description: "Config/log directory used by the BambuNetwork agent; defaults to BAMBU_NETWORK_CONFIG_DIR or a user config directory." },
|
|
2054
2116
|
country_code: { type: "string", description: "BambuNetwork country code, such as US, used by the agent during startup." },
|
|
2055
2117
|
user_info: { type: "string", description: "Optional BambuNetwork user_info JSON string to pass to net.change_user after the agent starts." },
|
|
@@ -2066,7 +2128,7 @@ class BambuPrinterMCPServer {
|
|
|
2066
2128
|
method: { type: "string", description: "FULU bridge method name, for example bridge.handshake, net.is_user_login, or net.get_user_selected_machine." },
|
|
2067
2129
|
payload: { type: "object", description: "JSON payload passed to the bridge method." },
|
|
2068
2130
|
with_agent: { type: "boolean", description: "When true, initialize a BambuNetwork agent and add its agent id to the payload before calling the method." },
|
|
2069
|
-
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND." },
|
|
2131
|
+
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND. Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
2070
2132
|
bambu_network_config_dir: { type: "string", description: "Config/log directory used by the BambuNetwork agent; defaults to BAMBU_NETWORK_CONFIG_DIR or a user config directory." },
|
|
2071
2133
|
country_code: { type: "string", description: "BambuNetwork country code, such as US, used by the agent during startup." },
|
|
2072
2134
|
user_info: { type: "string", description: "Optional BambuNetwork user_info JSON string to pass to net.change_user after the agent starts." },
|
|
@@ -2102,13 +2164,13 @@ class BambuPrinterMCPServer {
|
|
|
2102
2164
|
preset_name: { type: "string", description: "Optional preset name sent in FULU PrintParams; defaults to project plus one-based plate index." },
|
|
2103
2165
|
task_name: { type: "string", description: "Optional BambuNetwork task name; defaults to the project name." },
|
|
2104
2166
|
config_filename: { type: "string", description: "Optional config 3MF path for cloud print; defaults to the same 3MF path." },
|
|
2105
|
-
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND." },
|
|
2167
|
+
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND. Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
2106
2168
|
bambu_network_config_dir: { type: "string", description: "Config/log directory used by the BambuNetwork agent; defaults to BAMBU_NETWORK_CONFIG_DIR or a user config directory." },
|
|
2107
2169
|
country_code: { type: "string", description: "BambuNetwork country code, such as US, used by the agent during startup." },
|
|
2108
2170
|
user_info: { type: "string", description: "Optional BambuNetwork user_info JSON string to pass to net.change_user after the agent starts." },
|
|
2109
2171
|
timeout_ms: { type: "number", description: "Bridge request timeout in milliseconds." },
|
|
2110
2172
|
slicer_type: { type: "string", enum: SLICER_SCHEMA_VALUES, description: "Slicer to use only if auto-slicing an unsliced 3MF; use orcaslicer-bambulab for FULU's fork." },
|
|
2111
|
-
slicer_path: { type: "string", description: "Path to the slicer executable for auto-slicing; defaults to value from env or a platform default." },
|
|
2173
|
+
slicer_path: { type: "string", description: "Path to the slicer executable for auto-slicing; defaults to value from env or a platform default. Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
2112
2174
|
slicer_profile: { type: "string", description: "Path to an optional slicer profile/config file for auto-slicing." },
|
|
2113
2175
|
nozzle_diameter: { type: "string", description: "Nozzle diameter in mm for auto-slicing (default: 0.4)." },
|
|
2114
2176
|
use_ams: { type: "boolean", description: "Whether to use the AMS; defaults to auto-detect from the 3MF mapping." },
|
|
@@ -2144,7 +2206,7 @@ class BambuPrinterMCPServer {
|
|
|
2144
2206
|
timeout_ms: { type: "number", description: "Max ms to wait for a full frame (default 8000). Camera may take a few seconds on cold start." },
|
|
2145
2207
|
bambu_model: { type: "string", description: "Printer model. Used to route to the correct protocol or fail fast on unsupported models. Defaults to BAMBU_MODEL." },
|
|
2146
2208
|
experimental: { type: "boolean", description: "Deprecated and ignored. Earlier this flag let callers probe H2 series via the A1/P1 TCP-on-6000 path; live testing on an H2S confirmed H2 uses RTSP instead, so the flag has no effect now." },
|
|
2147
|
-
ffmpeg_path: { type: "string", description: "Override path to the ffmpeg binary used by the RTSP path. Defaults to ffmpeg via $PATH. Required only for the RTSP transport (X1, P2S, H2 series)." },
|
|
2209
|
+
ffmpeg_path: { type: "string", description: "Override path to the ffmpeg binary used by the RTSP path. Defaults to FFMPEG_PATH or ffmpeg via $PATH. Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1. Required only for the RTSP transport (X1, P2S, H2 series)." },
|
|
2148
2210
|
host: { type: "string", description: "Hostname or IP of the printer (default: value from env)" },
|
|
2149
2211
|
bambu_serial: { type: "string", description: "Serial number (default: value from env)" },
|
|
2150
2212
|
bambu_token: { type: "string", description: "Access token (default: value from env)" }
|
|
@@ -2462,7 +2524,7 @@ class BambuPrinterMCPServer {
|
|
|
2462
2524
|
bambu_network_method: { type: "string", enum: BAMBU_NETWORK_PRINT_METHODS, description: "FULU print method when connection_mode is bambu_network; defaults to start_print for cloud and start_local_print for lan." },
|
|
2463
2525
|
dev_id: { type: "string", description: "Bambu device id for FULU BambuNetwork printing; defaults to BAMBU_DEV_ID or BAMBU_SERIAL." },
|
|
2464
2526
|
dev_ip: { type: "string", description: "Printer IP address for FULU BambuNetwork LAN/local print methods; defaults to host when provided." },
|
|
2465
|
-
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND." },
|
|
2527
|
+
bridge_command: { type: "string", description: "Override command for the FULU bridge host or macOS/WSL wrapper; defaults to BAMBU_NETWORK_BRIDGE_COMMAND. Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
2466
2528
|
bambu_network_config_dir: { type: "string", description: "Config/log directory used by the FULU BambuNetwork agent." },
|
|
2467
2529
|
country_code: { type: "string", description: "BambuNetwork country code, such as US, used by the FULU bridge agent." },
|
|
2468
2530
|
user_info: { type: "string", description: "Optional BambuNetwork user_info JSON string passed to net.change_user for the FULU bridge." },
|
|
@@ -2480,7 +2542,7 @@ class BambuPrinterMCPServer {
|
|
|
2480
2542
|
enum: SLICER_SCHEMA_VALUES,
|
|
2481
2543
|
description: "Slicer to use only if auto-slicing an unsliced 3MF. Bambu-compatible slicer aliases such as fulu-orca and orca-studio are accepted."
|
|
2482
2544
|
},
|
|
2483
|
-
slicer_path: { type: "string", description: "Path to the slicer executable for auto-slicing (default: value from env or a platform default)" },
|
|
2545
|
+
slicer_path: { type: "string", description: "Path to the slicer executable for auto-slicing (default: value from env or a platform default). Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
2484
2546
|
use_ams: { type: "boolean", description: "Whether to use the AMS (default: auto-detect from 3MF)" },
|
|
2485
2547
|
ams_mapping: {
|
|
2486
2548
|
type: "array",
|
|
@@ -2587,7 +2649,7 @@ class BambuPrinterMCPServer {
|
|
|
2587
2649
|
description: "Ordered edit operations for Blender (e.g. remesh, boolean, decimate)",
|
|
2588
2650
|
items: { type: "string" }
|
|
2589
2651
|
},
|
|
2590
|
-
bridge_command: { type: "string", description: "Override command for invoking Blender MCP bridge" },
|
|
2652
|
+
bridge_command: { type: "string", description: "Override command for invoking Blender MCP bridge. Per-call overrides require MCP_ALLOW_EXECUTABLE_ARG=1." },
|
|
2591
2653
|
execute: { type: "boolean", description: "Execute bridge command (true) or return payload only (false)" }
|
|
2592
2654
|
},
|
|
2593
2655
|
required: ["stl_path", "operations"]
|
|
@@ -2696,7 +2758,10 @@ class BambuPrinterMCPServer {
|
|
|
2696
2758
|
|
|
2697
2759
|
case "bambu_network_bridge_status": {
|
|
2698
2760
|
const bridgeArgs = args as Record<string, any> | undefined;
|
|
2699
|
-
const options = this.bridgeOptionsFromArgs(
|
|
2761
|
+
const options = this.bridgeOptionsFromArgs(
|
|
2762
|
+
bridgeArgs,
|
|
2763
|
+
"bambu_network_bridge_status"
|
|
2764
|
+
);
|
|
2700
2765
|
result = this.bambuNetwork.getStatus(options);
|
|
2701
2766
|
if (Boolean(bridgeArgs?.connect)) {
|
|
2702
2767
|
const probe = await this.bambuNetwork.ensureAgent(options);
|
|
@@ -2718,7 +2783,7 @@ class BambuPrinterMCPServer {
|
|
|
2718
2783
|
const payload = bridgeArgs.payload && typeof bridgeArgs.payload === "object"
|
|
2719
2784
|
? bridgeArgs.payload as Record<string, unknown>
|
|
2720
2785
|
: {};
|
|
2721
|
-
const options = this.bridgeOptionsFromArgs(bridgeArgs);
|
|
2786
|
+
const options = this.bridgeOptionsFromArgs(bridgeArgs, "bambu_network_call");
|
|
2722
2787
|
result = bridgeArgs.with_agent === false
|
|
2723
2788
|
? await this.bambuNetwork.request(String(bridgeArgs.method), payload, options)
|
|
2724
2789
|
: await this.bambuNetwork.callWithAgent(String(bridgeArgs.method), payload, options);
|
|
@@ -2737,7 +2802,11 @@ class BambuPrinterMCPServer {
|
|
|
2737
2802
|
timeoutMs: args?.timeout_ms !== undefined ? Number(args.timeout_ms) : undefined,
|
|
2738
2803
|
bambuModel: snapshotModel ? String(snapshotModel) : undefined,
|
|
2739
2804
|
experimental: Boolean(args?.experimental),
|
|
2740
|
-
ffmpegPath:
|
|
2805
|
+
ffmpegPath: this.resolveExecutableSelectorArg(
|
|
2806
|
+
args?.ffmpeg_path,
|
|
2807
|
+
"camera_snapshot",
|
|
2808
|
+
"ffmpeg_path"
|
|
2809
|
+
) ?? this.runtimeConfig.ffmpegPath,
|
|
2741
2810
|
});
|
|
2742
2811
|
break;
|
|
2743
2812
|
}
|
|
@@ -2959,7 +3028,10 @@ class BambuPrinterMCPServer {
|
|
|
2959
3028
|
if (!args?.template_name) {
|
|
2960
3029
|
throw new Error("Missing required parameter: template_name");
|
|
2961
3030
|
}
|
|
2962
|
-
const { slicerType, slicerPath, slicerProfile } =
|
|
3031
|
+
const { slicerType, slicerPath, slicerProfile } = this.resolveSlicerConfigFromArgs(
|
|
3032
|
+
args as Record<string, unknown> | undefined,
|
|
3033
|
+
"slice_with_template"
|
|
3034
|
+
);
|
|
2963
3035
|
const sliceModel = await this.resolveBambuModel(args?.bambu_model as string | undefined);
|
|
2964
3036
|
const nozzleDiam = String(args?.nozzle_diameter || DEFAULT_NOZZLE_DIAMETER);
|
|
2965
3037
|
const activeSlicerProfile = await resolveTemplateFirstSlicerProfilePath(
|
|
@@ -3041,7 +3113,10 @@ class BambuPrinterMCPServer {
|
|
|
3041
3113
|
if (!args?.stl_path) {
|
|
3042
3114
|
throw new Error("Missing required parameter: stl_path");
|
|
3043
3115
|
}
|
|
3044
|
-
const { slicerType, slicerPath, slicerProfile } =
|
|
3116
|
+
const { slicerType, slicerPath, slicerProfile } = this.resolveSlicerConfigFromArgs(
|
|
3117
|
+
args as Record<string, unknown> | undefined,
|
|
3118
|
+
"slice_stl"
|
|
3119
|
+
);
|
|
3045
3120
|
const sliceModel = await this.resolveBambuModel(args?.bambu_model as string | undefined);
|
|
3046
3121
|
const nozzleDiam = String(args?.nozzle_diameter || DEFAULT_NOZZLE_DIAMETER);
|
|
3047
3122
|
const activeSlicerProfile = await resolveSlicerProfilePath(
|
|
@@ -3131,7 +3206,10 @@ class BambuPrinterMCPServer {
|
|
|
3131
3206
|
throw new Error("Bambu serial number and access token are required for print_3mf.");
|
|
3132
3207
|
}
|
|
3133
3208
|
|
|
3134
|
-
const { slicerType, slicerPath, slicerProfile } =
|
|
3209
|
+
const { slicerType, slicerPath, slicerProfile } = this.resolveSlicerConfigFromArgs(
|
|
3210
|
+
args as Record<string, unknown> | undefined,
|
|
3211
|
+
"print_3mf"
|
|
3212
|
+
);
|
|
3135
3213
|
const printModel = await this.resolveBambuModel(args?.bambu_model as string | undefined);
|
|
3136
3214
|
const printBedType = resolveBedType(args?.bed_type as string | undefined);
|
|
3137
3215
|
const printNozzle = String(args?.nozzle_diameter || DEFAULT_NOZZLE_DIAMETER);
|
|
@@ -3320,7 +3398,10 @@ class BambuPrinterMCPServer {
|
|
|
3320
3398
|
throw new Error("Bambu serial number and access token are required for print_collar_charm.");
|
|
3321
3399
|
}
|
|
3322
3400
|
|
|
3323
|
-
const { slicerType, slicerPath, slicerProfile } =
|
|
3401
|
+
const { slicerType, slicerPath, slicerProfile } = this.resolveSlicerConfigFromArgs(
|
|
3402
|
+
args as Record<string, unknown> | undefined,
|
|
3403
|
+
"print_collar_charm"
|
|
3404
|
+
);
|
|
3324
3405
|
const printModel = await this.resolveBambuModel(args?.bambu_model as string | undefined);
|
|
3325
3406
|
const printBedType = resolveBedType(args?.bed_type as string | undefined);
|
|
3326
3407
|
const printNozzle = String(args?.nozzle_diameter || DEFAULT_NOZZLE_DIAMETER);
|
|
@@ -3423,9 +3504,12 @@ class BambuPrinterMCPServer {
|
|
|
3423
3504
|
stlPath: String(args.stl_path),
|
|
3424
3505
|
operations: args.operations.map((entry: any) => String(entry)),
|
|
3425
3506
|
execute: Boolean(args.execute ?? false),
|
|
3426
|
-
bridgeCommand:
|
|
3427
|
-
|
|
3428
|
-
|
|
3507
|
+
bridgeCommand: this.resolveExecutableSelectorArg(
|
|
3508
|
+
args.bridge_command,
|
|
3509
|
+
"blender_mcp_edit_model",
|
|
3510
|
+
"bridge_command",
|
|
3511
|
+
true
|
|
3512
|
+
) ?? this.runtimeConfig.blenderBridgeCommand,
|
|
3429
3513
|
});
|
|
3430
3514
|
break;
|
|
3431
3515
|
|