mcp-3d-printer-server 0.1.0 → 0.2.2

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.
@@ -1,66 +0,0 @@
1
- import { PrinterImplementation } from "../types.js";
2
- import fs from "fs";
3
- import FormData from "form-data";
4
- export class DuetImplementation extends PrinterImplementation {
5
- async getStatus(host, port, apiKey) {
6
- const url = `http://${host}:${port}/machine/status`;
7
- const response = await this.apiClient.get(url);
8
- return response.data;
9
- }
10
- async getFiles(host, port, apiKey) {
11
- const url = `http://${host}:${port}/machine/file-list`;
12
- const response = await this.apiClient.get(url);
13
- return response.data;
14
- }
15
- async getFile(host, port, apiKey, filename) {
16
- const url = `http://${host}:${port}/machine/file/${encodeURIComponent(filename)}`;
17
- const response = await this.apiClient.get(url);
18
- return response.data;
19
- }
20
- async uploadFile(host, port, apiKey, filePath, filename, print) {
21
- const url = `http://${host}:${port}/machine/file-upload`;
22
- const formData = new FormData();
23
- formData.append("file", fs.createReadStream(filePath));
24
- formData.append("filename", filename);
25
- const response = await this.apiClient.post(url, formData, {
26
- headers: {
27
- ...formData.getHeaders()
28
- }
29
- });
30
- if (print && response.data.err === 0) {
31
- await this.startJob(host, port, apiKey, filename);
32
- }
33
- return response.data;
34
- }
35
- async startJob(host, port, apiKey, filename) {
36
- const url = `http://${host}:${port}/machine/code`;
37
- const response = await this.apiClient.post(url, {
38
- code: `M32 "${filename}"`
39
- });
40
- return response.data;
41
- }
42
- async cancelJob(host, port, apiKey) {
43
- const url = `http://${host}:${port}/machine/code`;
44
- const response = await this.apiClient.post(url, {
45
- code: "M0"
46
- });
47
- return response.data;
48
- }
49
- async setTemperature(host, port, apiKey, component, temperature) {
50
- const url = `http://${host}:${port}/machine/code`;
51
- let gcode;
52
- if (component === "bed") {
53
- gcode = `M140 S${temperature}`;
54
- }
55
- else if (component === "extruder") {
56
- gcode = `M104 S${temperature}`;
57
- }
58
- else {
59
- throw new Error(`Unsupported component: ${component}`);
60
- }
61
- const response = await this.apiClient.post(url, {
62
- code: gcode
63
- });
64
- return response.data;
65
- }
66
- }
@@ -1,10 +0,0 @@
1
- import { PrinterImplementation } from "../types.js";
2
- export declare class KlipperImplementation extends PrinterImplementation {
3
- getStatus(host: string, port: string, apiKey: string): Promise<any>;
4
- getFiles(host: string, port: string, apiKey: string): Promise<any>;
5
- getFile(host: string, port: string, apiKey: string, filename: string): Promise<any>;
6
- uploadFile(host: string, port: string, apiKey: string, filePath: string, filename: string, print: boolean): Promise<any>;
7
- startJob(host: string, port: string, apiKey: string, filename: string): Promise<any>;
8
- cancelJob(host: string, port: string, apiKey: string): Promise<any>;
9
- setTemperature(host: string, port: string, apiKey: string, component: string, temperature: number): Promise<any>;
10
- }
@@ -1,62 +0,0 @@
1
- import { PrinterImplementation } from "../types.js";
2
- import fs from "fs";
3
- import FormData from "form-data";
4
- export class KlipperImplementation extends PrinterImplementation {
5
- async getStatus(host, port, apiKey) {
6
- const url = `http://${host}:${port}/printer/info`;
7
- const response = await this.apiClient.get(url);
8
- return response.data;
9
- }
10
- async getFiles(host, port, apiKey) {
11
- const url = `http://${host}:${port}/server/files/list`;
12
- const response = await this.apiClient.get(url);
13
- return response.data;
14
- }
15
- async getFile(host, port, apiKey, filename) {
16
- const url = `http://${host}:${port}/server/files/metadata?filename=${encodeURIComponent(filename)}`;
17
- const response = await this.apiClient.get(url);
18
- return response.data;
19
- }
20
- async uploadFile(host, port, apiKey, filePath, filename, print) {
21
- const url = `http://${host}:${port}/server/files/upload`;
22
- const formData = new FormData();
23
- formData.append("file", fs.createReadStream(filePath));
24
- formData.append("filename", filename);
25
- const response = await this.apiClient.post(url, formData, {
26
- headers: {
27
- ...formData.getHeaders()
28
- }
29
- });
30
- if (print && response.data.result === "success") {
31
- await this.startJob(host, port, apiKey, filename);
32
- }
33
- return response.data;
34
- }
35
- async startJob(host, port, apiKey, filename) {
36
- const url = `http://${host}:${port}/printer/print/start`;
37
- const response = await this.apiClient.post(url, { filename });
38
- return response.data;
39
- }
40
- async cancelJob(host, port, apiKey) {
41
- const url = `http://${host}:${port}/printer/print/cancel`;
42
- const response = await this.apiClient.post(url, null);
43
- return response.data;
44
- }
45
- async setTemperature(host, port, apiKey, component, temperature) {
46
- const url = `http://${host}:${port}/printer/gcode/script`;
47
- let gcode;
48
- if (component === "bed") {
49
- gcode = `SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=${temperature}`;
50
- }
51
- else if (component === "extruder") {
52
- gcode = `SET_HEATER_TEMPERATURE HEATER=extruder TARGET=${temperature}`;
53
- }
54
- else {
55
- throw new Error(`Unsupported component: ${component}`);
56
- }
57
- const response = await this.apiClient.post(url, {
58
- script: gcode
59
- });
60
- return response.data;
61
- }
62
- }
@@ -1,10 +0,0 @@
1
- import { PrinterImplementation } from "../types.js";
2
- export declare class OctoPrintImplementation extends PrinterImplementation {
3
- getStatus(host: string, port: string, apiKey: string): Promise<any>;
4
- getFiles(host: string, port: string, apiKey: string): Promise<any>;
5
- getFile(host: string, port: string, apiKey: string, filename: string): Promise<any>;
6
- uploadFile(host: string, port: string, apiKey: string, filePath: string, filename: string, print: boolean): Promise<any>;
7
- startJob(host: string, port: string, apiKey: string, filename: string): Promise<any>;
8
- cancelJob(host: string, port: string, apiKey: string): Promise<any>;
9
- setTemperature(host: string, port: string, apiKey: string, component: string, temperature: number): Promise<any>;
10
- }
@@ -1,97 +0,0 @@
1
- import { PrinterImplementation } from "../types.js";
2
- import fs from "fs";
3
- import FormData from "form-data";
4
- export class OctoPrintImplementation extends PrinterImplementation {
5
- async getStatus(host, port, apiKey) {
6
- const url = `http://${host}:${port}/api/printer`;
7
- const response = await this.apiClient.get(url, {
8
- headers: {
9
- "X-Api-Key": apiKey
10
- }
11
- });
12
- return response.data;
13
- }
14
- async getFiles(host, port, apiKey) {
15
- const url = `http://${host}:${port}/api/files`;
16
- const response = await this.apiClient.get(url, {
17
- headers: {
18
- "X-Api-Key": apiKey
19
- }
20
- });
21
- return response.data;
22
- }
23
- async getFile(host, port, apiKey, filename) {
24
- const url = `http://${host}:${port}/api/files/local/${filename}`;
25
- const response = await this.apiClient.get(url, {
26
- headers: {
27
- "X-Api-Key": apiKey
28
- }
29
- });
30
- return response.data;
31
- }
32
- async uploadFile(host, port, apiKey, filePath, filename, print) {
33
- const url = `http://${host}:${port}/api/files/local`;
34
- const formData = new FormData();
35
- formData.append("file", fs.createReadStream(filePath));
36
- formData.append("filename", filename);
37
- if (print) {
38
- formData.append("print", "true");
39
- }
40
- const response = await this.apiClient.post(url, formData, {
41
- headers: {
42
- "X-Api-Key": apiKey,
43
- ...formData.getHeaders()
44
- }
45
- });
46
- return response.data;
47
- }
48
- async startJob(host, port, apiKey, filename) {
49
- const url = `http://${host}:${port}/api/files/local/${filename}`;
50
- const response = await this.apiClient.post(url, {
51
- command: "select",
52
- print: true
53
- }, {
54
- headers: {
55
- "X-Api-Key": apiKey,
56
- "Content-Type": "application/json"
57
- }
58
- });
59
- return response.data;
60
- }
61
- async cancelJob(host, port, apiKey) {
62
- const url = `http://${host}:${port}/api/job`;
63
- const response = await this.apiClient.post(url, {
64
- command: "cancel"
65
- }, {
66
- headers: {
67
- "X-Api-Key": apiKey,
68
- "Content-Type": "application/json"
69
- }
70
- });
71
- return response.data;
72
- }
73
- async setTemperature(host, port, apiKey, component, temperature) {
74
- let url = `http://${host}:${port}/api/printer/tool`;
75
- const data = {};
76
- if (component === "bed") {
77
- data.command = "target";
78
- data.target = temperature;
79
- url = `http://${host}:${port}/api/printer/bed`;
80
- }
81
- else if (component.startsWith("extruder")) {
82
- data.command = "target";
83
- data.targets = {};
84
- data.targets[component] = temperature;
85
- }
86
- else {
87
- throw new Error(`Unsupported component: ${component}`);
88
- }
89
- const response = await this.apiClient.post(url, data, {
90
- headers: {
91
- "X-Api-Key": apiKey,
92
- "Content-Type": "application/json"
93
- }
94
- });
95
- return response.data;
96
- }
97
- }
@@ -1,9 +0,0 @@
1
- import { PrinterImplementation } from "../types.js";
2
- export declare class PrinterFactory {
3
- private implementations;
4
- private bambuPrinterStore;
5
- private apiClient;
6
- constructor();
7
- getImplementation(type: string): PrinterImplementation;
8
- disconnectAll(): Promise<void>;
9
- }
@@ -1,33 +0,0 @@
1
- import { BambuPrinterStore } from "../types.js";
2
- import { OctoPrintImplementation } from "./octoprint.js";
3
- import { KlipperImplementation } from "./klipper.js";
4
- import { DuetImplementation } from "./duet.js";
5
- import { RepetierImplementation } from "./repetier.js";
6
- import { BambuImplementation } from "./bambu.js";
7
- import { PrusaImplementation } from "./prusa.js";
8
- import { CrealityImplementation } from "./creality.js";
9
- import axios from "axios";
10
- export class PrinterFactory {
11
- constructor() {
12
- this.implementations = new Map();
13
- this.bambuPrinterStore = new BambuPrinterStore();
14
- this.apiClient = axios.create({ timeout: 10000 });
15
- this.implementations.set("octoprint", new OctoPrintImplementation(this.apiClient));
16
- this.implementations.set("klipper", new KlipperImplementation(this.apiClient));
17
- this.implementations.set("duet", new DuetImplementation(this.apiClient));
18
- this.implementations.set("repetier", new RepetierImplementation(this.apiClient));
19
- this.implementations.set("bambu", new BambuImplementation(this.apiClient, this.bambuPrinterStore));
20
- this.implementations.set("prusa", new PrusaImplementation(this.apiClient));
21
- this.implementations.set("creality", new CrealityImplementation(this.apiClient));
22
- }
23
- getImplementation(type) {
24
- const implementation = this.implementations.get(type.toLowerCase());
25
- if (!implementation) {
26
- throw new Error(`Unsupported printer type: ${type}`);
27
- }
28
- return implementation;
29
- }
30
- async disconnectAll() {
31
- await this.bambuPrinterStore.disconnectAll();
32
- }
33
- }
@@ -1,10 +0,0 @@
1
- import { PrinterImplementation } from "../types.js";
2
- export declare class PrusaImplementation extends PrinterImplementation {
3
- getStatus(host: string, port: string, apiKey: string): Promise<any>;
4
- getFiles(host: string, port: string, apiKey: string): Promise<any>;
5
- getFile(host: string, port: string, apiKey: string, filename: string): Promise<any>;
6
- uploadFile(host: string, port: string, apiKey: string, filePath: string, filename: string, print: boolean): Promise<any>;
7
- startJob(host: string, port: string, apiKey: string, filename: string): Promise<any>;
8
- cancelJob(host: string, port: string, apiKey: string): Promise<any>;
9
- setTemperature(host: string, port: string, apiKey: string, component: string, temperature: number): Promise<any>;
10
- }
@@ -1,93 +0,0 @@
1
- import { PrinterImplementation } from "../types.js";
2
- import fs from "fs";
3
- import FormData from "form-data";
4
- export class PrusaImplementation extends PrinterImplementation {
5
- async getStatus(host, port, apiKey) {
6
- const url = `http://${host}:${port}/api/v1/printer`;
7
- const response = await this.apiClient.get(url, {
8
- headers: {
9
- "X-Api-Key": apiKey
10
- }
11
- });
12
- return response.data;
13
- }
14
- async getFiles(host, port, apiKey) {
15
- const url = `http://${host}:${port}/api/v1/storage`;
16
- const response = await this.apiClient.get(url, {
17
- headers: {
18
- "X-Api-Key": apiKey
19
- }
20
- });
21
- return response.data;
22
- }
23
- async getFile(host, port, apiKey, filename) {
24
- const url = `http://${host}:${port}/api/v1/storage/${encodeURIComponent(filename)}`;
25
- const response = await this.apiClient.get(url, {
26
- headers: {
27
- "X-Api-Key": apiKey
28
- }
29
- });
30
- return response.data;
31
- }
32
- async uploadFile(host, port, apiKey, filePath, filename, print) {
33
- const url = `http://${host}:${port}/api/v1/storage`;
34
- const formData = new FormData();
35
- formData.append("file", fs.createReadStream(filePath));
36
- formData.append("filename", filename);
37
- const response = await this.apiClient.post(url, formData, {
38
- headers: {
39
- "X-Api-Key": apiKey,
40
- ...formData.getHeaders()
41
- }
42
- });
43
- if (print && response.data.success) {
44
- await this.startJob(host, port, apiKey, filename);
45
- }
46
- return response.data;
47
- }
48
- async startJob(host, port, apiKey, filename) {
49
- const url = `http://${host}:${port}/api/v1/job`;
50
- const response = await this.apiClient.post(url, {
51
- command: "start",
52
- file: filename
53
- }, {
54
- headers: {
55
- "X-Api-Key": apiKey,
56
- "Content-Type": "application/json"
57
- }
58
- });
59
- return response.data;
60
- }
61
- async cancelJob(host, port, apiKey) {
62
- const url = `http://${host}:${port}/api/v1/job`;
63
- const response = await this.apiClient.post(url, {
64
- command: "cancel"
65
- }, {
66
- headers: {
67
- "X-Api-Key": apiKey,
68
- "Content-Type": "application/json"
69
- }
70
- });
71
- return response.data;
72
- }
73
- async setTemperature(host, port, apiKey, component, temperature) {
74
- const url = `http://${host}:${port}/api/v1/printer/temperature`;
75
- let data = { command: "set" };
76
- if (component === "bed") {
77
- data.target = { bed: temperature };
78
- }
79
- else if (component.startsWith("extruder")) {
80
- data.target = { tool0: temperature }; // Prusa typically uses tool0 for the extruder
81
- }
82
- else {
83
- throw new Error(`Unsupported component: ${component}`);
84
- }
85
- const response = await this.apiClient.post(url, data, {
86
- headers: {
87
- "X-Api-Key": apiKey,
88
- "Content-Type": "application/json"
89
- }
90
- });
91
- return response.data;
92
- }
93
- }
@@ -1,10 +0,0 @@
1
- import { PrinterImplementation } from "../types.js";
2
- export declare class RepetierImplementation extends PrinterImplementation {
3
- getStatus(host: string, port: string, apiKey: string): Promise<any>;
4
- getFiles(host: string, port: string, apiKey: string): Promise<any>;
5
- getFile(host: string, port: string, apiKey: string, filename: string): Promise<any>;
6
- uploadFile(host: string, port: string, apiKey: string, filePath: string, filename: string, print: boolean): Promise<any>;
7
- startJob(host: string, port: string, apiKey: string, filename: string): Promise<any>;
8
- cancelJob(host: string, port: string, apiKey: string): Promise<any>;
9
- setTemperature(host: string, port: string, apiKey: string, component: string, temperature: number): Promise<any>;
10
- }
@@ -1,59 +0,0 @@
1
- import { PrinterImplementation } from "../types.js";
2
- import fs from "fs";
3
- import FormData from "form-data";
4
- export class RepetierImplementation extends PrinterImplementation {
5
- async getStatus(host, port, apiKey) {
6
- const url = `http://${host}:${port}/printer/api/?a=getPrinterInfo&apikey=${apiKey}`;
7
- const response = await this.apiClient.get(url);
8
- return response.data;
9
- }
10
- async getFiles(host, port, apiKey) {
11
- const url = `http://${host}:${port}/printer/api/?a=ls&apikey=${apiKey}`;
12
- const response = await this.apiClient.get(url);
13
- return response.data;
14
- }
15
- async getFile(host, port, apiKey, filename) {
16
- const url = `http://${host}:${port}/printer/api/?a=getFileInfo&apikey=${apiKey}&filename=${encodeURIComponent(filename)}`;
17
- const response = await this.apiClient.get(url);
18
- return response.data;
19
- }
20
- async uploadFile(host, port, apiKey, filePath, filename, print) {
21
- const url = `http://${host}:${port}/printer/api/`;
22
- const formData = new FormData();
23
- formData.append("a", "upload");
24
- formData.append("apikey", apiKey);
25
- formData.append("filename", filename);
26
- formData.append("print", print ? "1" : "0");
27
- formData.append("file", fs.createReadStream(filePath));
28
- const response = await this.apiClient.post(url, formData, {
29
- headers: {
30
- ...formData.getHeaders()
31
- }
32
- });
33
- return response.data;
34
- }
35
- async startJob(host, port, apiKey, filename) {
36
- const url = `http://${host}:${port}/printer/api/?a=startJob&apikey=${apiKey}&filename=${encodeURIComponent(filename)}`;
37
- const response = await this.apiClient.get(url);
38
- return response.data;
39
- }
40
- async cancelJob(host, port, apiKey) {
41
- const url = `http://${host}:${port}/printer/api/?a=stopJob&apikey=${apiKey}`;
42
- const response = await this.apiClient.get(url);
43
- return response.data;
44
- }
45
- async setTemperature(host, port, apiKey, component, temperature) {
46
- let url;
47
- if (component === "bed") {
48
- url = `http://${host}:${port}/printer/api/?a=setBedTemp&apikey=${apiKey}&temp=${temperature}`;
49
- }
50
- else if (component === "extruder") {
51
- url = `http://${host}:${port}/printer/api/?a=setExtruderTemp&apikey=${apiKey}&temp=${temperature}`;
52
- }
53
- else {
54
- throw new Error(`Unsupported component: ${component}`);
55
- }
56
- const response = await this.apiClient.get(url);
57
- return response.data;
58
- }
59
- }
package/dist/types.d.ts DELETED
@@ -1,23 +0,0 @@
1
- import { AxiosInstance } from "axios";
2
- import { BambuPrinter } from "bambu-js";
3
- export type BambuFTP = {
4
- readDir: (path: string) => Promise<string[]>;
5
- sendFile: (sourcePath: string, destinationPath: string, progressCallback?: (progress: number) => void) => Promise<void>;
6
- removeFile: (path: string) => Promise<void>;
7
- };
8
- export declare abstract class PrinterImplementation {
9
- protected apiClient: AxiosInstance;
10
- constructor(apiClient: AxiosInstance);
11
- abstract getStatus(host: string, port: string, apiKey: string): Promise<any>;
12
- abstract getFiles(host: string, port: string, apiKey: string): Promise<any>;
13
- abstract getFile(host: string, port: string, apiKey: string, filename: string): Promise<any>;
14
- abstract uploadFile(host: string, port: string, apiKey: string, filePath: string, filename: string, print: boolean): Promise<any>;
15
- abstract startJob(host: string, port: string, apiKey: string, filename: string): Promise<any>;
16
- abstract cancelJob(host: string, port: string, apiKey: string): Promise<any>;
17
- abstract setTemperature(host: string, port: string, apiKey: string, component: string, temperature: number): Promise<any>;
18
- }
19
- export declare class BambuPrinterStore {
20
- private printers;
21
- get(host: string, serial: string, token: string): InstanceType<typeof BambuPrinter>;
22
- disconnectAll(): Promise<void>;
23
- }
package/dist/types.js DELETED
@@ -1,26 +0,0 @@
1
- import { BambuPrinter } from "bambu-js";
2
- // Base class for printer implementations
3
- export class PrinterImplementation {
4
- constructor(apiClient) {
5
- this.apiClient = apiClient;
6
- }
7
- }
8
- // Store for Bambu printers
9
- export class BambuPrinterStore {
10
- constructor() {
11
- this.printers = new Map();
12
- }
13
- get(host, serial, token) {
14
- const key = `${host}-${serial}`;
15
- if (!this.printers.has(key)) {
16
- const printer = new BambuPrinter(host, serial, token);
17
- this.printers.set(key, printer);
18
- }
19
- return this.printers.get(key);
20
- }
21
- async disconnectAll() {
22
- for (const printer of this.printers.values()) {
23
- await printer.disconnect();
24
- }
25
- }
26
- }