@whattio/mcp-server 1.0.0

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.
Files changed (47) hide show
  1. package/README.md +48 -0
  2. package/build/api.js +18 -0
  3. package/build/index.js +11 -0
  4. package/build/server.js +140 -0
  5. package/build/tools/media.js +33 -0
  6. package/build/tools/registry.js +8 -0
  7. package/build/tools/types.js +1 -0
  8. package/build/tools/v1/category.js +65 -0
  9. package/build/tools/v1/incendo.js +66 -0
  10. package/build/tools/v1/index.js +16 -0
  11. package/build/tools/v1/material.js +79 -0
  12. package/build/tools/v1/product.js +85 -0
  13. package/build/tools/v1/simplyprint.js +44 -0
  14. package/build/tools/v1/unit.js +67 -0
  15. package/build/tools/v1/user.js +46 -0
  16. package/build/tools/v2/auth.js +75 -0
  17. package/build/tools/v2/category.js +109 -0
  18. package/build/tools/v2/device.js +97 -0
  19. package/build/tools/v2/index.js +16 -0
  20. package/build/tools/v2/material.js +114 -0
  21. package/build/tools/v2/part.js +102 -0
  22. package/build/tools/v2/product.js +99 -0
  23. package/build/tools/v2/unit.js +86 -0
  24. package/package.json +26 -0
  25. package/src/api.ts +24 -0
  26. package/src/index.ts +13 -0
  27. package/src/server.ts +165 -0
  28. package/src/tools/media.ts +36 -0
  29. package/src/tools/registry.ts +10 -0
  30. package/src/tools/types.ts +12 -0
  31. package/src/tools/v1/category.ts +67 -0
  32. package/src/tools/v1/incendo.ts +68 -0
  33. package/src/tools/v1/index.ts +18 -0
  34. package/src/tools/v1/material.ts +81 -0
  35. package/src/tools/v1/product.ts +87 -0
  36. package/src/tools/v1/simplyprint.ts +46 -0
  37. package/src/tools/v1/unit.ts +69 -0
  38. package/src/tools/v1/user.ts +48 -0
  39. package/src/tools/v2/auth.ts +77 -0
  40. package/src/tools/v2/category.ts +111 -0
  41. package/src/tools/v2/device.ts +99 -0
  42. package/src/tools/v2/index.ts +18 -0
  43. package/src/tools/v2/material.ts +116 -0
  44. package/src/tools/v2/part.ts +104 -0
  45. package/src/tools/v2/product.ts +101 -0
  46. package/src/tools/v2/unit.ts +88 -0
  47. package/tsconfig.json +15 -0
@@ -0,0 +1,81 @@
1
+ import { McpTool } from '../types.js';
2
+
3
+ export const materialTools: McpTool[] = [
4
+ {
5
+ name: "v1_list_materials",
6
+ description: "Show all materials within a team",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {}
10
+ },
11
+ handler: async (_args, apiClient) => {
12
+ const response = await apiClient.get('/api/materials');
13
+ return response.data;
14
+ }
15
+ },
16
+ {
17
+ name: "v1_create_material",
18
+ description: "Add a new material",
19
+ inputSchema: {
20
+ type: "object",
21
+ properties: {
22
+ brand: { type: "string" },
23
+ name: { type: "string" },
24
+ code: { type: "string" },
25
+ color_code: { type: "number" },
26
+ data_sheet: { type: "string" },
27
+ safety_sheet: { type: "string" },
28
+ origin_type: { type: "string" },
29
+ origin_country: { type: "string" },
30
+ waste_category: { type: "string" },
31
+ resin_id: { type: "string" },
32
+ chem_name: { type: "string" },
33
+ recycled: { type: "boolean" },
34
+ bioderived: { type: "boolean" },
35
+ biodegradable: { type: "string" },
36
+ biodegrade_comment: { type: "string" },
37
+ recyclable: { type: "boolean" },
38
+ recycle_info: { type: "string" },
39
+ recycle_url: { type: "string" },
40
+ recycling_img: { type: "string" },
41
+ bio_derived: { type: "string" },
42
+ buy_url: { type: "string" }
43
+ },
44
+ required: ["brand", "name", "origin_country"]
45
+ },
46
+ handler: async (args, apiClient) => {
47
+ const response = await apiClient.post('/api/material', null, { params: args });
48
+ return response.data;
49
+ }
50
+ },
51
+ {
52
+ name: "v1_get_material",
53
+ description: "Get information about a specific material",
54
+ inputSchema: {
55
+ type: "object",
56
+ properties: {
57
+ id: { type: "number" }
58
+ },
59
+ required: ["id"]
60
+ },
61
+ handler: async (args, apiClient) => {
62
+ const response = await apiClient.get(`/api/material/${args.id}`);
63
+ return response.data;
64
+ }
65
+ },
66
+ {
67
+ name: "v1_delete_material",
68
+ description: "Delete a specific material",
69
+ inputSchema: {
70
+ type: "object",
71
+ properties: {
72
+ id: { type: "number" }
73
+ },
74
+ required: ["id"]
75
+ },
76
+ handler: async (args, apiClient) => {
77
+ const response = await apiClient.delete(`/api/material/${args.id}`);
78
+ return response.data;
79
+ }
80
+ }
81
+ ];
@@ -0,0 +1,87 @@
1
+ import { McpTool } from '../types.js';
2
+
3
+ export const productTools: McpTool[] = [
4
+ {
5
+ name: "v1_list_products",
6
+ description: "Show all products within a team. Also use this tool whenever the user mentions 'DPP', 'Digital Product Passports', 'digital twins', or wants to search their whatt.io product catalog.",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {}
10
+ },
11
+ handler: async (_args, apiClient) => {
12
+ const response = await apiClient.get('/api/products');
13
+ return response.data;
14
+ }
15
+ },
16
+ {
17
+ name: "v1_create_product",
18
+ description: "Add a new product",
19
+ inputSchema: {
20
+ type: "object",
21
+ properties: {
22
+ name: { type: "string" },
23
+ product_number: { type: "string" },
24
+ version: { type: "string" },
25
+ description: { type: "string" },
26
+ gtin: { type: "string" },
27
+ image: { type: "string" },
28
+ video: { type: "string" },
29
+ buy_url: { type: "string" },
30
+ category_id: { type: "number" },
31
+ ai_description: { type: "string" },
32
+ type: { type: "string" },
33
+ public: { type: "number" }
34
+ },
35
+ required: ["name", "product_number", "description"]
36
+ },
37
+ handler: async (args, apiClient) => {
38
+ const response = await apiClient.post('/api/product', null, { params: args });
39
+ return response.data;
40
+ }
41
+ },
42
+ {
43
+ name: "v1_get_product",
44
+ description: "Get information about a specific product",
45
+ inputSchema: {
46
+ type: "object",
47
+ properties: {
48
+ id: { type: "number" }
49
+ },
50
+ required: ["id"]
51
+ },
52
+ handler: async (args, apiClient) => {
53
+ const response = await apiClient.get(`/api/product/${args.id}`);
54
+ return response.data;
55
+ }
56
+ },
57
+ {
58
+ name: "v1_get_ext_product",
59
+ description: "Get information about a specific product with extended format",
60
+ inputSchema: {
61
+ type: "object",
62
+ properties: {
63
+ id: { type: "number" }
64
+ },
65
+ required: ["id"]
66
+ },
67
+ handler: async (args, apiClient) => {
68
+ const response = await apiClient.get(`/api/product/ext/${args.id}`);
69
+ return response.data;
70
+ }
71
+ },
72
+ {
73
+ name: "v1_delete_product",
74
+ description: "Delete a specific product",
75
+ inputSchema: {
76
+ type: "object",
77
+ properties: {
78
+ id: { type: "number" }
79
+ },
80
+ required: ["id"]
81
+ },
82
+ handler: async (args, apiClient) => {
83
+ const response = await apiClient.delete(`/api/product/${args.id}`);
84
+ return response.data;
85
+ }
86
+ }
87
+ ];
@@ -0,0 +1,46 @@
1
+ import { McpTool } from '../types.js';
2
+
3
+ export const simplyprintTools: McpTool[] = [
4
+ {
5
+ name: "v1_simplyprint_printers",
6
+ description: "Fetch SimplyPrint printers associated with user",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {}
10
+ },
11
+ handler: async (_args, apiClient) => {
12
+ const response = await apiClient.get('/api/simplyprint/printers');
13
+ return response.data;
14
+ }
15
+ },
16
+ {
17
+ name: "v1_simplyprint_jobs",
18
+ description: "Fetch SimplyPrint print jobs for a specific printer",
19
+ inputSchema: {
20
+ type: "object",
21
+ properties: {
22
+ printer_id: { type: "string", description: "Printer ID" }
23
+ },
24
+ required: ["printer_id"]
25
+ },
26
+ handler: async (args, apiClient) => {
27
+ const response = await apiClient.get(`/api/simplyprint/jobs/${args.printer_id}`);
28
+ return response.data;
29
+ }
30
+ },
31
+ {
32
+ name: "v1_simplyprint_filament",
33
+ description: "Fetch remaining filament info for a specific printer",
34
+ inputSchema: {
35
+ type: "object",
36
+ properties: {
37
+ printer_id: { type: "string", description: "Printer ID" }
38
+ },
39
+ required: ["printer_id"]
40
+ },
41
+ handler: async (args, apiClient) => {
42
+ const response = await apiClient.get(`/api/getFilament/filament/${args.printer_id}`);
43
+ return response.data;
44
+ }
45
+ }
46
+ ];
@@ -0,0 +1,69 @@
1
+ import { McpTool } from '../types.js';
2
+
3
+ export const unitTools: McpTool[] = [
4
+ {
5
+ name: "v1_check_serial_unit",
6
+ description: "Check if unit serial is available in system/team",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {
10
+ team: { type: "number", description: "Team ID" },
11
+ serial: { type: "string", description: "Serial UUID" }
12
+ },
13
+ required: ["team", "serial"]
14
+ },
15
+ handler: async (args, apiClient) => {
16
+ const response = await apiClient.get(`/api/checkserial/${args.team}/${args.serial}`);
17
+ return response.data;
18
+ }
19
+ },
20
+ {
21
+ name: "v1_create_unit",
22
+ description: "Add a new unit to a product",
23
+ inputSchema: {
24
+ type: "object",
25
+ properties: {
26
+ id: { type: "number", description: "Product ID" },
27
+ unit_identifier: { type: "string", description: "Serial UUID" },
28
+ public: { type: "number" }
29
+ },
30
+ required: ["id", "unit_identifier"]
31
+ },
32
+ handler: async (args, apiClient) => {
33
+ const response = await apiClient.post('/api/unit', null, { params: args });
34
+ return response.data;
35
+ }
36
+ },
37
+ {
38
+ name: "v1_get_unit",
39
+ description: "Get information about a specific unit by serial via token auth mode",
40
+ inputSchema: {
41
+ type: "object",
42
+ properties: {
43
+ serial: { type: "string", description: "Serial UUID" },
44
+ token: { type: "string", description: "Auth token" }
45
+ },
46
+ required: ["serial", "token"]
47
+ },
48
+ handler: async (args, apiClient) => {
49
+ const response = await apiClient.get(`/api/unit/${args.serial}/${args.token}`);
50
+ return response.data;
51
+ }
52
+ },
53
+ {
54
+ name: "v1_delete_unit",
55
+ description: "Delete a specific product unit by ID",
56
+ inputSchema: {
57
+ type: "object",
58
+ properties: {
59
+ id: { type: "number", description: "Unit ID" },
60
+ token: { type: "string", description: "Auth token" }
61
+ },
62
+ required: ["id", "token"]
63
+ },
64
+ handler: async (args, apiClient) => {
65
+ const response = await apiClient.delete(`/api/unit/${args.id}/${args.token}`);
66
+ return response.data;
67
+ }
68
+ }
69
+ ];
@@ -0,0 +1,48 @@
1
+ import { McpTool } from '../types.js';
2
+
3
+ export const userTools: McpTool[] = [
4
+ {
5
+ name: "v1_generate_token",
6
+ description: "Generate an auth token",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {
10
+ email: { type: "string" },
11
+ password: { type: "string" },
12
+ device_name: { type: "string" }
13
+ },
14
+ required: ["email", "password", "device_name"]
15
+ },
16
+ handler: async (args, apiClient) => {
17
+ const response = await apiClient.post('/api/sanctum/token', null, { params: args });
18
+ return response.data;
19
+ }
20
+ },
21
+ {
22
+ name: "v1_switch_team",
23
+ description: "Switch your active team. CRITICAL: Use this tool to change context if you encounter 404 Not Found or 403 Forbidden errors when trying to update/view specific resources.",
24
+ inputSchema: {
25
+ type: "object",
26
+ properties: {
27
+ team_id: { type: "number" }
28
+ },
29
+ required: ["team_id"]
30
+ },
31
+ handler: async (args, apiClient) => {
32
+ const response = await apiClient.post('/api/set_team', null, { params: args });
33
+ return response.data;
34
+ }
35
+ },
36
+ {
37
+ name: "v1_get_user",
38
+ description: "Get current authenticated user information",
39
+ inputSchema: {
40
+ type: "object",
41
+ properties: {}
42
+ },
43
+ handler: async (_args, apiClient) => {
44
+ const response = await apiClient.get('/api/user');
45
+ return response.data;
46
+ }
47
+ }
48
+ ];
@@ -0,0 +1,77 @@
1
+ import { McpTool } from '../types.js';
2
+
3
+ export const authTools: McpTool[] = [
4
+ {
5
+ name: "v2_login",
6
+ description: "Authenticate user with email and password, returns user data and API token",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {
10
+ email: { type: "string", description: "Email Address" },
11
+ password: { type: "string", description: "Password" }
12
+ },
13
+ required: ["email", "password"]
14
+ },
15
+ handler: async (args, apiClient) => {
16
+ const response = await apiClient.post('/api/v2/login', null, { params: args });
17
+ return response.data;
18
+ }
19
+ },
20
+ {
21
+ name: "v2_register",
22
+ description: "Create a new user account and generate auth token",
23
+ inputSchema: {
24
+ type: "object",
25
+ properties: {
26
+ name: { type: "string", description: "Full Name" },
27
+ email: { type: "string", description: "Email Address" },
28
+ password: { type: "string", description: "Password" },
29
+ password_confirmation: { type: "string", description: "Password Confirmation" }
30
+ },
31
+ required: ["name", "email", "password", "password_confirmation"]
32
+ },
33
+ handler: async (args, apiClient) => {
34
+ const response = await apiClient.post('/api/v2/register', null, { params: args });
35
+ return response.data;
36
+ }
37
+ },
38
+ {
39
+ name: "v2_get_user",
40
+ description: "Retrieve current authenticated user information from V2 api",
41
+ inputSchema: {
42
+ type: "object",
43
+ properties: {}
44
+ },
45
+ handler: async (_args, apiClient) => {
46
+ const response = await apiClient.get('/api/v2/user');
47
+ return response.data;
48
+ }
49
+ },
50
+ {
51
+ name: "v2_switch_team",
52
+ description: "Change the current active team for the authenticated user. CRITICAL: Use this tool to change context if you encounter 404 Not Found or 403 Forbidden errors when trying to update/view specific resources.",
53
+ inputSchema: {
54
+ type: "object",
55
+ properties: {
56
+ team_id: { type: "number", description: "Team ID to switch to" }
57
+ },
58
+ required: ["team_id"]
59
+ },
60
+ handler: async (args, apiClient) => {
61
+ const response = await apiClient.post('/api/v2/switch-team', null, { params: args });
62
+ return response.data;
63
+ }
64
+ },
65
+ {
66
+ name: "v2_logout",
67
+ description: "Revoke current authentication token from V2 api",
68
+ inputSchema: {
69
+ type: "object",
70
+ properties: {}
71
+ },
72
+ handler: async (_args, apiClient) => {
73
+ const response = await apiClient.post('/api/v2/logout');
74
+ return response.data;
75
+ }
76
+ }
77
+ ];
@@ -0,0 +1,111 @@
1
+ import { McpTool } from '../types.js';
2
+
3
+ export const categoryTools: McpTool[] = [
4
+ {
5
+ name: "v2_list_categories",
6
+ description: "Retrieve a paginated list of all categories belonging to the authenticated user's current team",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {
10
+ page: { type: "number", description: "The page number to retrieve" },
11
+ per_page: { type: "number", description: "Number of items per page" }
12
+ }
13
+ },
14
+ handler: async (args, apiClient) => {
15
+ const response = await apiClient.get('/api/v2/category', { params: args });
16
+ return response.data;
17
+ }
18
+ },
19
+ {
20
+ name: "v2_create_category",
21
+ description: "Create a new category, brand, or manufacturer",
22
+ inputSchema: {
23
+ type: "object",
24
+ properties: {
25
+ name: { type: "string" },
26
+ country: { type: "string" },
27
+ city: { type: "string" },
28
+ email: { type: "string" },
29
+ phone: { type: "string" },
30
+ website: { type: "string" },
31
+ ai_description: { type: "string" },
32
+ logo: { type: "string", description: "Base64 encoded image or path to file if supported by client" }
33
+ },
34
+ required: ["name", "country", "city", "email"]
35
+ },
36
+ handler: async (args, apiClient) => {
37
+ // Sends args as JSON. If the whatt.io API strictly requires multipart/form-data,
38
+ // it should be capable of parsing application/json as an alternative.
39
+ const response = await apiClient.post('/api/v2/category/create', args);
40
+ return response.data;
41
+ }
42
+ },
43
+ {
44
+ name: "v2_show_category",
45
+ description: "Get detailed information about a specific category",
46
+ inputSchema: {
47
+ type: "object",
48
+ properties: {
49
+ id: { type: "number", description: "Category ID" }
50
+ },
51
+ required: ["id"]
52
+ },
53
+ handler: async (args, apiClient) => {
54
+ const response = await apiClient.get(`/api/v2/category/${args.id}/show`);
55
+ return response.data;
56
+ }
57
+ },
58
+ {
59
+ name: "v2_get_category_products",
60
+ description: "Get products by category",
61
+ inputSchema: {
62
+ type: "object",
63
+ properties: {
64
+ id: { type: "number", description: "Category ID" }
65
+ },
66
+ required: ["id"]
67
+ },
68
+ handler: async (args, apiClient) => {
69
+ const response = await apiClient.get(`/api/v2/category/${args.id}/products`);
70
+ return response.data;
71
+ }
72
+ },
73
+ {
74
+ name: "v2_update_category",
75
+ description: "Update an existing category's information",
76
+ inputSchema: {
77
+ type: "object",
78
+ properties: {
79
+ id: { type: "number", description: "Category ID" },
80
+ name: { type: "string" },
81
+ country: { type: "string" },
82
+ city: { type: "string" },
83
+ email: { type: "string" },
84
+ phone: { type: "string" },
85
+ website: { type: "string" },
86
+ ai_description: { type: "string" }
87
+ },
88
+ required: ["id"]
89
+ },
90
+ handler: async (args, apiClient) => {
91
+ const { id, ...data } = args;
92
+ const response = await apiClient.post(`/api/v2/category/${id}/update`, { ...data, _method: 'PUT' });
93
+ return response.data;
94
+ }
95
+ },
96
+ {
97
+ name: "v2_delete_category",
98
+ description: "Permanently delete a category from the system",
99
+ inputSchema: {
100
+ type: "object",
101
+ properties: {
102
+ id: { type: "number", description: "Category ID" }
103
+ },
104
+ required: ["id"]
105
+ },
106
+ handler: async (args, apiClient) => {
107
+ const response = await apiClient.delete(`/api/v2/category/${args.id}/delete`);
108
+ return response.data;
109
+ }
110
+ }
111
+ ];
@@ -0,0 +1,99 @@
1
+ import { McpTool } from '../types.js';
2
+
3
+ export const deviceTools: McpTool[] = [
4
+ {
5
+ name: "v2_list_devices",
6
+ description: "Retrieve a paginated list of all IoT devices and printers belonging to the authenticated user's current team",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {
10
+ page: { type: "number", description: "The page number to retrieve" },
11
+ per_page: { type: "number", description: "Number of items per page" }
12
+ }
13
+ },
14
+ handler: async (args, apiClient) => {
15
+ const response = await apiClient.get('/api/v2/device', { params: args });
16
+ return response.data;
17
+ }
18
+ },
19
+ {
20
+ name: "v2_create_device",
21
+ description: "Register a new IoT device, workstation, or printer to your team. Each device is assigned a unique API key and setup code.",
22
+ inputSchema: {
23
+ type: "object",
24
+ properties: {
25
+ name: { type: "string" },
26
+ location: { type: "string" },
27
+ mode: { type: "string", description: "Device operation mode" },
28
+ serial_no: { type: "string", description: "Unique Hardware Serial Number" },
29
+ ethernet: { type: "boolean" },
30
+ ip_address: { type: "string" },
31
+ mac_address: { type: "string" },
32
+ ssid: { type: "string" },
33
+ active_product_id: { type: "number" },
34
+ version_no: { type: "string" }
35
+ },
36
+ required: ["name", "location", "mode", "serial_no"]
37
+ },
38
+ handler: async (args, apiClient) => {
39
+ const response = await apiClient.post('/api/v2/device/create', null, { params: args });
40
+ return response.data;
41
+ }
42
+ },
43
+ {
44
+ name: "v2_show_device",
45
+ description: "Get detailed information about a specific device",
46
+ inputSchema: {
47
+ type: "object",
48
+ properties: {
49
+ id: { type: "number", description: "Device ID" }
50
+ },
51
+ required: ["id"]
52
+ },
53
+ handler: async (args, apiClient) => {
54
+ const response = await apiClient.get(`/api/v2/device/${args.id}/show`);
55
+ return response.data;
56
+ }
57
+ },
58
+ {
59
+ name: "v2_update_device",
60
+ description: "Update the details of an existing IoT device or printer",
61
+ inputSchema: {
62
+ type: "object",
63
+ properties: {
64
+ id: { type: "number", description: "Device ID" },
65
+ name: { type: "string" },
66
+ location: { type: "string" },
67
+ mode: { type: "string" },
68
+ serial_no: { type: "string" },
69
+ ethernet: { type: "boolean" },
70
+ ip_address: { type: "string" },
71
+ mac_address: { type: "string" },
72
+ ssid: { type: "string" },
73
+ active_product_id: { type: "number" },
74
+ version_no: { type: "string" }
75
+ },
76
+ required: ["id"]
77
+ },
78
+ handler: async (args, apiClient) => {
79
+ const { id, ...data } = args;
80
+ const response = await apiClient.put(`/api/v2/device/${id}/update`, null, { params: data });
81
+ return response.data;
82
+ }
83
+ },
84
+ {
85
+ name: "v2_delete_device",
86
+ description: "Permanently remove a device from your system",
87
+ inputSchema: {
88
+ type: "object",
89
+ properties: {
90
+ id: { type: "number", description: "Device ID" }
91
+ },
92
+ required: ["id"]
93
+ },
94
+ handler: async (args, apiClient) => {
95
+ const response = await apiClient.delete(`/api/v2/device/${args.id}/delete`);
96
+ return response.data;
97
+ }
98
+ }
99
+ ];
@@ -0,0 +1,18 @@
1
+ import { authTools } from './auth.js';
2
+ import { categoryTools } from './category.js';
3
+ import { deviceTools } from './device.js';
4
+ import { materialTools } from './material.js';
5
+ import { partTools } from './part.js';
6
+ import { productTools } from './product.js';
7
+ import { unitTools } from './unit.js';
8
+ import { McpTool } from '../types.js';
9
+
10
+ export const v2Tools: McpTool[] = [
11
+ ...authTools,
12
+ ...categoryTools,
13
+ ...deviceTools,
14
+ ...materialTools,
15
+ ...partTools,
16
+ ...productTools,
17
+ ...unitTools
18
+ ];