@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.
- package/README.md +48 -0
- package/build/api.js +18 -0
- package/build/index.js +11 -0
- package/build/server.js +140 -0
- package/build/tools/media.js +33 -0
- package/build/tools/registry.js +8 -0
- package/build/tools/types.js +1 -0
- package/build/tools/v1/category.js +65 -0
- package/build/tools/v1/incendo.js +66 -0
- package/build/tools/v1/index.js +16 -0
- package/build/tools/v1/material.js +79 -0
- package/build/tools/v1/product.js +85 -0
- package/build/tools/v1/simplyprint.js +44 -0
- package/build/tools/v1/unit.js +67 -0
- package/build/tools/v1/user.js +46 -0
- package/build/tools/v2/auth.js +75 -0
- package/build/tools/v2/category.js +109 -0
- package/build/tools/v2/device.js +97 -0
- package/build/tools/v2/index.js +16 -0
- package/build/tools/v2/material.js +114 -0
- package/build/tools/v2/part.js +102 -0
- package/build/tools/v2/product.js +99 -0
- package/build/tools/v2/unit.js +86 -0
- package/package.json +26 -0
- package/src/api.ts +24 -0
- package/src/index.ts +13 -0
- package/src/server.ts +165 -0
- package/src/tools/media.ts +36 -0
- package/src/tools/registry.ts +10 -0
- package/src/tools/types.ts +12 -0
- package/src/tools/v1/category.ts +67 -0
- package/src/tools/v1/incendo.ts +68 -0
- package/src/tools/v1/index.ts +18 -0
- package/src/tools/v1/material.ts +81 -0
- package/src/tools/v1/product.ts +87 -0
- package/src/tools/v1/simplyprint.ts +46 -0
- package/src/tools/v1/unit.ts +69 -0
- package/src/tools/v1/user.ts +48 -0
- package/src/tools/v2/auth.ts +77 -0
- package/src/tools/v2/category.ts +111 -0
- package/src/tools/v2/device.ts +99 -0
- package/src/tools/v2/index.ts +18 -0
- package/src/tools/v2/material.ts +116 -0
- package/src/tools/v2/part.ts +104 -0
- package/src/tools/v2/product.ts +101 -0
- package/src/tools/v2/unit.ts +88 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { McpTool } from '../types.js';
|
|
2
|
+
|
|
3
|
+
export const materialTools: McpTool[] = [
|
|
4
|
+
{
|
|
5
|
+
name: "v2_list_materials",
|
|
6
|
+
description: "Retrieve a paginated list of materials",
|
|
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
|
+
public: { type: "boolean", description: "If true, returns global public materials instead of team-specific ones" }
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
handler: async (args, apiClient) => {
|
|
16
|
+
const response = await apiClient.get('/api/v2/material', { params: args });
|
|
17
|
+
return response.data;
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "v2_create_material",
|
|
22
|
+
description: "Create a new material",
|
|
23
|
+
inputSchema: {
|
|
24
|
+
type: "object",
|
|
25
|
+
properties: {
|
|
26
|
+
brand: { type: "string", description: "Brand Name" },
|
|
27
|
+
name: { type: "string", description: "Material Name" },
|
|
28
|
+
origin_country: { type: "string", description: "Country of Origin" },
|
|
29
|
+
code: { type: "string", description: "Material Code" },
|
|
30
|
+
color_code: { type: "string", description: "Color Code" },
|
|
31
|
+
resin_id: { type: "number", description: "Resin Identification Code (1-7)" },
|
|
32
|
+
chem_name: { type: "string", description: "Material Chemical Name" },
|
|
33
|
+
recycled: { type: "boolean", description: "Contains recycled content" },
|
|
34
|
+
recycle_info: { type: "string", description: "Recycling instructions or information" },
|
|
35
|
+
recycle_url: { type: "string", description: "External recycling information URL" },
|
|
36
|
+
bioderived: { type: "boolean", description: "Is bio-derived material" },
|
|
37
|
+
bio_derived: { type: "string", description: "Bio-Derived From/Details" },
|
|
38
|
+
waste_category: { type: "string", description: "Waste Category" },
|
|
39
|
+
origin_type: { type: "string", description: "Origin Type" },
|
|
40
|
+
recyclable: { type: "boolean", description: "Is Recyclable" },
|
|
41
|
+
biodegradable: { type: "boolean", description: "Is biodegradable material" },
|
|
42
|
+
biodegrade_comment: { type: "string", description: "Biodegradability Comments" },
|
|
43
|
+
buy_link: { type: "string", description: "Material Buy URL" }
|
|
44
|
+
},
|
|
45
|
+
required: ["brand", "name", "origin_country"]
|
|
46
|
+
},
|
|
47
|
+
handler: async (args, apiClient) => {
|
|
48
|
+
const response = await apiClient.post('/api/v2/material/create', args);
|
|
49
|
+
return response.data;
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "v2_show_material",
|
|
54
|
+
description: "Get detailed information about a specific material",
|
|
55
|
+
inputSchema: {
|
|
56
|
+
type: "object",
|
|
57
|
+
properties: {
|
|
58
|
+
id: { type: "number", description: "Material ID" }
|
|
59
|
+
},
|
|
60
|
+
required: ["id"]
|
|
61
|
+
},
|
|
62
|
+
handler: async (args, apiClient) => {
|
|
63
|
+
const response = await apiClient.get(`/api/v2/material/${args.id}/show`);
|
|
64
|
+
return response.data;
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "v2_update_material",
|
|
69
|
+
description: "Update the details of an existing material",
|
|
70
|
+
inputSchema: {
|
|
71
|
+
type: "object",
|
|
72
|
+
properties: {
|
|
73
|
+
id: { type: "number", description: "Material ID" },
|
|
74
|
+
brand: { type: "string", description: "Brand Name" },
|
|
75
|
+
name: { type: "string", description: "Material Name" },
|
|
76
|
+
origin_country: { type: "string", description: "Country of Origin" },
|
|
77
|
+
code: { type: "string", description: "Material Code" },
|
|
78
|
+
color_code: { type: "string", description: "Color Code" },
|
|
79
|
+
resin_id: { type: "number", description: "Resin Identification Code (1-7)" },
|
|
80
|
+
chem_name: { type: "string", description: "Material Chemical Name" },
|
|
81
|
+
recycled: { type: "boolean", description: "Contains recycled content" },
|
|
82
|
+
recycle_info: { type: "string", description: "Recycling instructions or information" },
|
|
83
|
+
recycle_url: { type: "string", description: "External recycling information URL" },
|
|
84
|
+
bioderived: { type: "boolean", description: "Is bio-derived material" },
|
|
85
|
+
bio_derived: { type: "string", description: "Bio-Derived From/Details" },
|
|
86
|
+
waste_category: { type: "string", description: "Waste Category" },
|
|
87
|
+
origin_type: { type: "string", description: "Origin Type" },
|
|
88
|
+
recyclable: { type: "boolean", description: "Is Recyclable" },
|
|
89
|
+
biodegradable: { type: "boolean", description: "Is biodegradable material" },
|
|
90
|
+
biodegrade_comment: { type: "string", description: "Biodegradability Comments" },
|
|
91
|
+
buy_link: { type: "string", description: "Material Buy URL" }
|
|
92
|
+
},
|
|
93
|
+
required: ["id"]
|
|
94
|
+
},
|
|
95
|
+
handler: async (args, apiClient) => {
|
|
96
|
+
const { id, ...data } = args;
|
|
97
|
+
const response = await apiClient.post(`/api/v2/material/${id}/update`, { ...data, _method: 'PUT' });
|
|
98
|
+
return response.data;
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: "v2_delete_material",
|
|
103
|
+
description: "Permanently delete a material from the system",
|
|
104
|
+
inputSchema: {
|
|
105
|
+
type: "object",
|
|
106
|
+
properties: {
|
|
107
|
+
id: { type: "number", description: "Material ID" }
|
|
108
|
+
},
|
|
109
|
+
required: ["id"]
|
|
110
|
+
},
|
|
111
|
+
handler: async (args, apiClient) => {
|
|
112
|
+
const response = await apiClient.delete(`/api/v2/material/${args.id}/delete`);
|
|
113
|
+
return response.data;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
];
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { McpTool } from '../types.js';
|
|
2
|
+
|
|
3
|
+
export const partTools: McpTool[] = [
|
|
4
|
+
{
|
|
5
|
+
name: "v2_list_parts",
|
|
6
|
+
description: "Retrieve a paginated list of parts. Use this tool automatically whenever the user asks about their whatt.io parts, components, sub-assemblies, or manufacturing pieces.",
|
|
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
|
+
public: { type: "boolean", description: "If true, returns global public parts instead of team-specific ones" }
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
handler: async (args, apiClient) => {
|
|
16
|
+
const response = await apiClient.get('/api/v2/part', { params: args });
|
|
17
|
+
return response.data;
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "v2_create_part",
|
|
22
|
+
description: "Create a new part",
|
|
23
|
+
inputSchema: {
|
|
24
|
+
type: "object",
|
|
25
|
+
properties: {
|
|
26
|
+
name: { type: "string" },
|
|
27
|
+
part_number: { type: "string" },
|
|
28
|
+
default_method: { type: "string" },
|
|
29
|
+
material_id: { type: "number" },
|
|
30
|
+
amount: { type: "number" },
|
|
31
|
+
description: { type: "string" },
|
|
32
|
+
self_print: { type: "boolean" },
|
|
33
|
+
ai_description: { type: "string" },
|
|
34
|
+
weight: { type: "number" },
|
|
35
|
+
version: { type: "number" },
|
|
36
|
+
is_main: { type: "boolean" },
|
|
37
|
+
buy_link: { type: "string" }
|
|
38
|
+
},
|
|
39
|
+
required: ["name", "part_number", "default_method", "amount"]
|
|
40
|
+
},
|
|
41
|
+
handler: async (args, apiClient) => {
|
|
42
|
+
const response = await apiClient.post('/api/v2/part/create', args);
|
|
43
|
+
return response.data;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "v2_show_part",
|
|
48
|
+
description: "Get detailed information about a specific part",
|
|
49
|
+
inputSchema: {
|
|
50
|
+
type: "object",
|
|
51
|
+
properties: {
|
|
52
|
+
id: { type: "number", description: "Part ID" }
|
|
53
|
+
},
|
|
54
|
+
required: ["id"]
|
|
55
|
+
},
|
|
56
|
+
handler: async (args, apiClient) => {
|
|
57
|
+
const response = await apiClient.get(`/api/v2/part/${args.id}/show`);
|
|
58
|
+
return response.data;
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: "v2_update_part",
|
|
63
|
+
description: "Update the details of an existing part",
|
|
64
|
+
inputSchema: {
|
|
65
|
+
type: "object",
|
|
66
|
+
properties: {
|
|
67
|
+
id: { type: "number", description: "Part ID" },
|
|
68
|
+
name: { type: "string" },
|
|
69
|
+
part_number: { type: "string" },
|
|
70
|
+
default_method: { type: "string" },
|
|
71
|
+
material_id: { type: "number" },
|
|
72
|
+
amount: { type: "number" },
|
|
73
|
+
self_print: { type: "boolean" },
|
|
74
|
+
description: { type: "string" },
|
|
75
|
+
ai_description: { type: "string" },
|
|
76
|
+
weight: { type: "number" },
|
|
77
|
+
version: { type: "number" },
|
|
78
|
+
is_main: { type: "boolean" },
|
|
79
|
+
buy_link: { type: "string" }
|
|
80
|
+
},
|
|
81
|
+
required: ["id"]
|
|
82
|
+
},
|
|
83
|
+
handler: async (args, apiClient) => {
|
|
84
|
+
const { id, ...data } = args;
|
|
85
|
+
const response = await apiClient.post(`/api/v2/part/${id}/update`, { ...data, _method: 'PUT' });
|
|
86
|
+
return response.data;
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: "v2_delete_part",
|
|
91
|
+
description: "Permanently delete a part from the system",
|
|
92
|
+
inputSchema: {
|
|
93
|
+
type: "object",
|
|
94
|
+
properties: {
|
|
95
|
+
id: { type: "number", description: "Part ID" }
|
|
96
|
+
},
|
|
97
|
+
required: ["id"]
|
|
98
|
+
},
|
|
99
|
+
handler: async (args, apiClient) => {
|
|
100
|
+
const response = await apiClient.delete(`/api/v2/part/${args.id}/delete`);
|
|
101
|
+
return response.data;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
];
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { McpTool } from '../types.js';
|
|
2
|
+
|
|
3
|
+
export const productTools: McpTool[] = [
|
|
4
|
+
{
|
|
5
|
+
name: "v2_list_products",
|
|
6
|
+
description: "Retrieve a paginated list of all products belonging to the authenticated user's current team. Also use this tool whenever the user mentions 'DPP', 'Digital Product Passports', 'digital twins', or wants to search their whatt.io catalog.",
|
|
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/product', { params: args });
|
|
16
|
+
return response.data;
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: "v2_create_product",
|
|
21
|
+
description: "Create a new product",
|
|
22
|
+
inputSchema: {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
name: { type: "string" },
|
|
26
|
+
product_number: { type: "string" },
|
|
27
|
+
description: { type: "string" },
|
|
28
|
+
gtin_number: { type: "string" },
|
|
29
|
+
category_id: { type: "number" },
|
|
30
|
+
ai_description: { type: "string" },
|
|
31
|
+
buy_link: { type: "string" },
|
|
32
|
+
video_url: { type: "string" },
|
|
33
|
+
primaryMaterial: { type: "number" },
|
|
34
|
+
secondaryMaterial: { type: "number" },
|
|
35
|
+
public: { type: "boolean" }
|
|
36
|
+
},
|
|
37
|
+
required: ["name", "product_number", "description"]
|
|
38
|
+
},
|
|
39
|
+
handler: async (args, apiClient) => {
|
|
40
|
+
const response = await apiClient.post('/api/v2/product/create', args);
|
|
41
|
+
return response.data;
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "v2_show_product",
|
|
46
|
+
description: "Get detailed information about a specific product",
|
|
47
|
+
inputSchema: {
|
|
48
|
+
type: "object",
|
|
49
|
+
properties: {
|
|
50
|
+
id: { type: "number", description: "Product ID" }
|
|
51
|
+
},
|
|
52
|
+
required: ["id"]
|
|
53
|
+
},
|
|
54
|
+
handler: async (args, apiClient) => {
|
|
55
|
+
const response = await apiClient.get(`/api/v2/product/${args.id}/show`);
|
|
56
|
+
return response.data;
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "v2_update_product",
|
|
61
|
+
description: "Update the details of an existing product",
|
|
62
|
+
inputSchema: {
|
|
63
|
+
type: "object",
|
|
64
|
+
properties: {
|
|
65
|
+
id: { type: "number", description: "Product ID" },
|
|
66
|
+
name: { type: "string" },
|
|
67
|
+
product_number: { type: "string" },
|
|
68
|
+
description: { type: "string" },
|
|
69
|
+
gtin_number: { type: "string" },
|
|
70
|
+
category_id: { type: "number" },
|
|
71
|
+
ai_description: { type: "string" },
|
|
72
|
+
buy_link: { type: "string" },
|
|
73
|
+
video_url: { type: "string" },
|
|
74
|
+
primaryMaterial: { type: "number" },
|
|
75
|
+
secondaryMaterial: { type: "number" },
|
|
76
|
+
public: { type: "boolean" }
|
|
77
|
+
},
|
|
78
|
+
required: ["id"]
|
|
79
|
+
},
|
|
80
|
+
handler: async (args, apiClient) => {
|
|
81
|
+
const { id, ...data } = args;
|
|
82
|
+
const response = await apiClient.post(`/api/v2/product/${id}/update`, { ...data, _method: 'PUT' });
|
|
83
|
+
return response.data;
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: "v2_delete_product",
|
|
88
|
+
description: "Delete a product from the system",
|
|
89
|
+
inputSchema: {
|
|
90
|
+
type: "object",
|
|
91
|
+
properties: {
|
|
92
|
+
id: { type: "number", description: "Product ID" }
|
|
93
|
+
},
|
|
94
|
+
required: ["id"]
|
|
95
|
+
},
|
|
96
|
+
handler: async (args, apiClient) => {
|
|
97
|
+
const response = await apiClient.delete(`/api/v2/product/${args.id}/delete`);
|
|
98
|
+
return response.data;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
];
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { McpTool } from '../types.js';
|
|
2
|
+
|
|
3
|
+
export const unitTools: McpTool[] = [
|
|
4
|
+
{
|
|
5
|
+
name: "v2_list_units",
|
|
6
|
+
description: "Retrieve a paginated list of all product units",
|
|
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/unit', { params: args });
|
|
16
|
+
return response.data;
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: "v2_create_unit",
|
|
21
|
+
description: "Create a new product unit",
|
|
22
|
+
inputSchema: {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
serial: { type: "string" },
|
|
26
|
+
product_id: { type: "number" },
|
|
27
|
+
parts: { type: "string", description: "JSON string of component parts used in this unit" },
|
|
28
|
+
public: { type: "boolean" }
|
|
29
|
+
},
|
|
30
|
+
required: ["serial", "product_id"]
|
|
31
|
+
},
|
|
32
|
+
handler: async (args, apiClient) => {
|
|
33
|
+
const response = await apiClient.post('/api/v2/unit/create', args);
|
|
34
|
+
return response.data;
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "v2_show_unit",
|
|
39
|
+
description: "Get detailed information about a specific unit",
|
|
40
|
+
inputSchema: {
|
|
41
|
+
type: "object",
|
|
42
|
+
properties: {
|
|
43
|
+
id: { type: "number", description: "Unit ID" }
|
|
44
|
+
},
|
|
45
|
+
required: ["id"]
|
|
46
|
+
},
|
|
47
|
+
handler: async (args, apiClient) => {
|
|
48
|
+
const response = await apiClient.get(`/api/v2/unit/${args.id}/show`);
|
|
49
|
+
return response.data;
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "v2_update_unit",
|
|
54
|
+
description: "Update the details of an existing product unit instance",
|
|
55
|
+
inputSchema: {
|
|
56
|
+
type: "object",
|
|
57
|
+
properties: {
|
|
58
|
+
id: { type: "number", description: "Unit ID" },
|
|
59
|
+
serial: { type: "string" },
|
|
60
|
+
product_id: { type: "number" },
|
|
61
|
+
parts: { type: "string" },
|
|
62
|
+
public: { type: "boolean" }
|
|
63
|
+
},
|
|
64
|
+
required: ["id"]
|
|
65
|
+
},
|
|
66
|
+
handler: async (args, apiClient) => {
|
|
67
|
+
const { id, ...data } = args;
|
|
68
|
+
// The openapi explicitly shows PUT for this endpoint for v2
|
|
69
|
+
const response = await apiClient.put(`/api/v2/unit/${id}/update`, data);
|
|
70
|
+
return response.data;
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: "v2_delete_unit",
|
|
75
|
+
description: "Permanently delete a unit from the system",
|
|
76
|
+
inputSchema: {
|
|
77
|
+
type: "object",
|
|
78
|
+
properties: {
|
|
79
|
+
id: { type: "number", description: "Unit ID" }
|
|
80
|
+
},
|
|
81
|
+
required: ["id"]
|
|
82
|
+
},
|
|
83
|
+
handler: async (args, apiClient) => {
|
|
84
|
+
const response = await apiClient.delete(`/api/v2/unit/${args.id}/delete`);
|
|
85
|
+
return response.data;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
];
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"outDir": "./build",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"types": ["node"]
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/**/*"]
|
|
15
|
+
}
|