bambu-printer-mcp 1.1.13 → 1.1.15
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/CONTRIBUTORS.md +2 -2
- package/README.md +20 -4
- package/dist/bambu-connect.d.ts +7 -0
- package/dist/bambu-connect.js +77 -0
- package/dist/bambu-native.d.ts +66 -0
- package/dist/bambu-native.js +609 -0
- package/dist/index.js +457 -33
- package/dist/printers/bambu.d.ts +17 -14
- package/dist/printers/bambu.js +124 -65
- package/native/bambu-native-print.cpp +758 -0
- package/package.json +7 -3
- package/scripts/build-bambu-native.zsh +33 -0
- package/src/bambu-connect.ts +100 -0
- package/src/bambu-native.ts +722 -0
- package/src/index.ts +527 -66
- package/src/printers/bambu.ts +110 -61
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bambu-printer-mcp",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.15",
|
|
4
4
|
"description": "MCP server for Bambu Lab 3D printers with STL manipulation, slicing, and print management",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"test": "npm run build && node --test tests/*.test.mjs tests/**/*.test.mjs",
|
|
17
17
|
"package:mcpb": "npm run build && node scripts/package-mcpb.mjs",
|
|
18
18
|
"version": "node scripts/sync-manifest-version.mjs",
|
|
19
|
-
"postinstall": "node scripts/install-patches.mjs"
|
|
19
|
+
"postinstall": "node scripts/install-patches.mjs",
|
|
20
|
+
"build:native": "scripts/build-bambu-native.zsh"
|
|
20
21
|
},
|
|
21
22
|
"bin": {
|
|
22
23
|
"bambu-printer-mcp": "dist/index.js"
|
|
@@ -28,7 +29,10 @@
|
|
|
28
29
|
"scripts/install-patches.mjs",
|
|
29
30
|
"README.md",
|
|
30
31
|
"CONTRIBUTORS.md",
|
|
31
|
-
"LICENSE"
|
|
32
|
+
"LICENSE",
|
|
33
|
+
"native/*.cpp",
|
|
34
|
+
"native/*.h",
|
|
35
|
+
"scripts/build-bambu-native.zsh"
|
|
32
36
|
],
|
|
33
37
|
"keywords": [
|
|
34
38
|
"mcp",
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/bin/zsh
|
|
2
|
+
|
|
3
|
+
# Build the optional macOS adapter that calls Bambu Studio's installed
|
|
4
|
+
# networking plug-in at runtime. The plug-in itself is not bundled here.
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
if [[ "$(uname -s)" != "Darwin" ]]; then
|
|
8
|
+
print -u2 "The Bambu native helper currently supports macOS only."
|
|
9
|
+
exit 1
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
SCRIPT_DIR="${0:A:h}"
|
|
13
|
+
PROJECT_ROOT="${SCRIPT_DIR:h}"
|
|
14
|
+
CXX_BIN="${CXX:-clang++}"
|
|
15
|
+
OUTPUT="${PROJECT_ROOT}/native/bambu-native-print"
|
|
16
|
+
SOURCE="${PROJECT_ROOT}/native/bambu-native-print.cpp"
|
|
17
|
+
|
|
18
|
+
if ! command -v "$CXX_BIN" >/dev/null 2>&1; then
|
|
19
|
+
print -u2 "C++ compiler not found: $CXX_BIN"
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
"$CXX_BIN" \
|
|
24
|
+
-std=c++17 \
|
|
25
|
+
-O2 \
|
|
26
|
+
-Wall \
|
|
27
|
+
-Wextra \
|
|
28
|
+
-o "$OUTPUT" \
|
|
29
|
+
"$SOURCE" \
|
|
30
|
+
-ldl
|
|
31
|
+
|
|
32
|
+
chmod 755 "$OUTPUT"
|
|
33
|
+
print "Built $OUTPUT"
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { execFile } from "node:child_process";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
const BAMBU_CONNECT_APP_PATH = "/Applications/Bambu Connect.app";
|
|
8
|
+
const BAMBU_CONNECT_SCHEME = "bambu-connect://import-file";
|
|
9
|
+
|
|
10
|
+
export type BambuConnectImportOptions = {
|
|
11
|
+
filePath: string;
|
|
12
|
+
name?: string;
|
|
13
|
+
version?: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
function resolveImportFilePath(rawPath: string): string {
|
|
17
|
+
const trimmed = rawPath.trim();
|
|
18
|
+
if (!trimmed) {
|
|
19
|
+
throw new Error("file_path is required.");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const filePath = path.resolve(trimmed);
|
|
23
|
+
if (!/\.(?:gcode|3mf)$/i.test(filePath)) {
|
|
24
|
+
throw new Error("Bambu Connect import accepts a .gcode or .3mf file.");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let stat: fs.Stats;
|
|
28
|
+
try {
|
|
29
|
+
stat = fs.statSync(filePath);
|
|
30
|
+
fs.accessSync(filePath, fs.constants.R_OK);
|
|
31
|
+
} catch {
|
|
32
|
+
throw new Error(`Bambu Connect import file is not readable: ${filePath}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!stat.isFile()) {
|
|
36
|
+
throw new Error(`Bambu Connect import path is not a regular file: ${filePath}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return filePath;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function defaultImportName(filePath: string): string {
|
|
43
|
+
const name = path.basename(filePath)
|
|
44
|
+
.replace(/\.gcode\.3mf$/i, "")
|
|
45
|
+
.replace(/\.3mf$/i, "")
|
|
46
|
+
.replace(/\.gcode$/i, "")
|
|
47
|
+
.trim();
|
|
48
|
+
return name || "Bambu print";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function buildBambuConnectImportUrl(options: BambuConnectImportOptions): string {
|
|
52
|
+
const filePath = resolveImportFilePath(options.filePath);
|
|
53
|
+
const name = options.name?.trim() || defaultImportName(filePath);
|
|
54
|
+
const version = options.version?.trim() || "1.0.0";
|
|
55
|
+
if (!version) {
|
|
56
|
+
throw new Error("version must not be empty.");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const url = new URL(BAMBU_CONNECT_SCHEME);
|
|
60
|
+
url.searchParams.set("path", filePath);
|
|
61
|
+
url.searchParams.set("name", name);
|
|
62
|
+
url.searchParams.set("version", version);
|
|
63
|
+
return url.toString();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function importFileViaBambuConnect(
|
|
67
|
+
options: BambuConnectImportOptions
|
|
68
|
+
): Promise<Record<string, unknown>> {
|
|
69
|
+
if (process.platform !== "darwin") {
|
|
70
|
+
throw new Error("Bambu Connect URL handoff is currently supported only on macOS.");
|
|
71
|
+
}
|
|
72
|
+
if (!fs.existsSync(BAMBU_CONNECT_APP_PATH)) {
|
|
73
|
+
throw new Error(`Bambu Connect is not installed at ${BAMBU_CONNECT_APP_PATH}.`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const filePath = resolveImportFilePath(options.filePath);
|
|
77
|
+
const name = options.name?.trim() || defaultImportName(filePath);
|
|
78
|
+
const version = options.version?.trim() || "1.0.0";
|
|
79
|
+
const url = buildBambuConnectImportUrl({ filePath, name, version });
|
|
80
|
+
const { stdout, stderr } = await execFileAsync(
|
|
81
|
+
"/usr/bin/open",
|
|
82
|
+
["-a", BAMBU_CONNECT_APP_PATH, url],
|
|
83
|
+
{ encoding: "utf8", timeout: 30_000 }
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
status: "handoff_ready",
|
|
88
|
+
app: "Bambu Connect",
|
|
89
|
+
app_path: BAMBU_CONNECT_APP_PATH,
|
|
90
|
+
route: BAMBU_CONNECT_SCHEME,
|
|
91
|
+
file_path: filePath,
|
|
92
|
+
project_name: name,
|
|
93
|
+
version,
|
|
94
|
+
opened: true,
|
|
95
|
+
url,
|
|
96
|
+
stdout: String(stdout || "").trim() || undefined,
|
|
97
|
+
stderr: String(stderr || "").trim() || undefined,
|
|
98
|
+
note: "The file was handed to Bambu Connect. Review the selected printer and plate there, then start printing from Bambu Connect when ready; this handoff does not start a print by itself.",
|
|
99
|
+
};
|
|
100
|
+
}
|