@sealab/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/PROPOSED-CHANGES-INSERTION-POINTS.md +220 -0
- package/SEALAB_MCP_DOCUMENTATION.md +1136 -0
- package/dist/client/api-client.js +44 -0
- package/dist/index.js +42 -0
- package/dist/tools/canvas.js +446 -0
- package/dist/tools/catalog.js +95 -0
- package/dist/tools/configuration-info.js +299 -0
- package/dist/tools/configuration.js +32 -0
- package/dist/tools/orders.js +1267 -0
- package/dist/tools/saved-settings.js +271 -0
- package/package.json +32 -0
- package/resources/tooltips/backPanel.txt +17 -0
- package/resources/tooltips/backPanelMaterial.txt +29 -0
- package/resources/tooltips/caseEdge.txt +18 -0
- package/resources/tooltips/caseMaterial.txt +31 -0
- package/resources/tooltips/depth.txt +11 -0
- package/resources/tooltips/drawerType.txt +12 -0
- package/resources/tooltips/edgeBandingType.txt +18 -0
- package/resources/tooltips/excludeFronts.txt +5 -0
- package/resources/tooltips/frontEdge.txt +18 -0
- package/resources/tooltips/frontMaterial.txt +35 -0
- package/resources/tooltips/gapBottom.txt +2 -0
- package/resources/tooltips/gapCenter.txt +2 -0
- package/resources/tooltips/gapLeft.txt +15 -0
- package/resources/tooltips/gapRight.txt +15 -0
- package/resources/tooltips/gapTop.txt +2 -0
- package/resources/tooltips/height.txt +6 -0
- package/resources/tooltips/hingePlate.txt +11 -0
- package/resources/tooltips/includeLegLevelers.txt +8 -0
- package/resources/tooltips/jointMethod.txt +7 -0
- package/resources/tooltips/leftCornerWidth.txt +2 -0
- package/resources/tooltips/numOfShelves.txt +6 -0
- package/resources/tooltips/positionName.txt +3 -0
- package/resources/tooltips/rightCornerDepth.txt +2 -0
- package/resources/tooltips/topDrwrHeight.txt +8 -0
- package/resources/tooltips/width.txt +5 -0
- package/src/client/api-client.ts +37 -0
- package/src/index.ts +52 -0
- package/src/tools/canvas.ts +442 -0
- package/src/tools/catalog.test.ts +61 -0
- package/src/tools/catalog.ts +80 -0
- package/src/tools/configuration-info.ts +274 -0
- package/src/tools/configuration.test.ts +43 -0
- package/src/tools/configuration.ts +25 -0
- package/src/tools/orders.test.ts +260 -0
- package/src/tools/orders.ts +1229 -0
- package/src/tools/saved-settings.ts +241 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { client, handleAxiosError } from '../client/api-client';
|
|
3
|
+
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// Schemas
|
|
6
|
+
// ============================================================================
|
|
7
|
+
|
|
8
|
+
const SavedSettingSchema = z.object({
|
|
9
|
+
savedSettingsId: z.number().optional(),
|
|
10
|
+
name: z.string().describe('Name of the saved setting (e.g., "Modern Euro", "Traditional")'),
|
|
11
|
+
frontMaterial: z.string().describe('Front material specification'),
|
|
12
|
+
caseMaterial: z.string().describe('Case material specification'),
|
|
13
|
+
backPanelMaterial: z.string().describe('Back panel material'),
|
|
14
|
+
backPanel: z.string().describe('Back panel type'),
|
|
15
|
+
drawerType: z.string().describe('Drawer type'),
|
|
16
|
+
jointMethod: z.string().describe('Joint method'),
|
|
17
|
+
caseEdge: z.string().describe('Case edge treatment'),
|
|
18
|
+
frontEdge: z.string().describe('Front edge treatment'),
|
|
19
|
+
numOfShelves: z.string().describe('Number of shelves'),
|
|
20
|
+
bottomPanelConnector: z.string().describe('Bottom panel connector (e.g., "Leg Levelers")'),
|
|
21
|
+
topDrwrHeightValue: z.string().describe('Top drawer height value'),
|
|
22
|
+
hingePlate: z.string().describe('Hinge plate type'),
|
|
23
|
+
includeLegLevelers: z.string().describe('Include leg levelers flag'),
|
|
24
|
+
isPreset: z.number().optional().describe('1 = public preset, 0 = user-specific'),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const GetSavedSettingsPresetsSchema = z.object({});
|
|
28
|
+
|
|
29
|
+
const GetMySavedSettingsSchema = z.object({});
|
|
30
|
+
|
|
31
|
+
const GetSavedSettingByIdSchema = z.object({
|
|
32
|
+
id: z.number().describe('Saved setting ID'),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const CreateSavedSettingSchema = SavedSettingSchema.omit({ savedSettingsId: true, isPreset: true }).extend({
|
|
36
|
+
isPreset: z.boolean().optional().default(false).describe('Set to true to create a public preset (requires admin privileges)'),
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const UpdateSavedSettingSchema = SavedSettingSchema.pick({
|
|
40
|
+
savedSettingsId: true,
|
|
41
|
+
name: true,
|
|
42
|
+
frontMaterial: true,
|
|
43
|
+
caseMaterial: true,
|
|
44
|
+
backPanelMaterial: true,
|
|
45
|
+
backPanel: true,
|
|
46
|
+
drawerType: true,
|
|
47
|
+
jointMethod: true,
|
|
48
|
+
caseEdge: true,
|
|
49
|
+
frontEdge: true,
|
|
50
|
+
numOfShelves: true,
|
|
51
|
+
bottomPanelConnector: true,
|
|
52
|
+
topDrwrHeightValue: true,
|
|
53
|
+
hingePlate: true,
|
|
54
|
+
includeLegLevelers: true,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const DeleteSavedSettingSchema = z.object({
|
|
58
|
+
id: z.number().describe('Saved setting ID to delete'),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// ============================================================================
|
|
62
|
+
// Handlers
|
|
63
|
+
// ============================================================================
|
|
64
|
+
|
|
65
|
+
export async function getSavedSettingsPresets(): Promise<string> {
|
|
66
|
+
try {
|
|
67
|
+
const { data } = await client.get('/saved-settings/presets');
|
|
68
|
+
if (!data || data.length === 0) return 'No preset saved settings found.';
|
|
69
|
+
return JSON.stringify(data, null, 2);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
try { handleAxiosError(error); } catch (e: any) { return e.message; }
|
|
72
|
+
return 'Unexpected error fetching preset saved settings.';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export async function getMySavedSettings(): Promise<string> {
|
|
77
|
+
try {
|
|
78
|
+
const { data } = await client.get('/saved-settings/user');
|
|
79
|
+
if (!data || data.length === 0) return 'No saved settings found for your account.';
|
|
80
|
+
return JSON.stringify(data, null, 2);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
try { handleAxiosError(error); } catch (e: any) { return e.message; }
|
|
83
|
+
return 'Unexpected error fetching your saved settings.';
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export async function getSavedSettingById(input: z.infer<typeof GetSavedSettingByIdSchema>): Promise<string> {
|
|
88
|
+
try {
|
|
89
|
+
const { data } = await client.get(`/saved-settings/${input.id}`);
|
|
90
|
+
return JSON.stringify(data, null, 2);
|
|
91
|
+
} catch (error) {
|
|
92
|
+
try { handleAxiosError(error); } catch (e: any) { return e.message; }
|
|
93
|
+
return 'Unexpected error fetching saved setting.';
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export async function createSavedSetting(input: z.infer<typeof CreateSavedSettingSchema>): Promise<string> {
|
|
98
|
+
try {
|
|
99
|
+
const { data } = await client.post('/saved-settings/user', input);
|
|
100
|
+
return `Saved setting created successfully. ID: ${data.savedSettingsId}`;
|
|
101
|
+
} catch (error) {
|
|
102
|
+
try { handleAxiosError(error); } catch (e: any) { return e.message; }
|
|
103
|
+
return 'Unexpected error creating saved setting.';
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export async function updateSavedSetting(input: z.infer<typeof UpdateSavedSettingSchema>): Promise<string> {
|
|
108
|
+
try {
|
|
109
|
+
const { data } = await client.put(`/saved-settings/${input.savedSettingsId}`, input);
|
|
110
|
+
return `Saved setting updated successfully. ID: ${data.savedSettingsId}`;
|
|
111
|
+
} catch (error) {
|
|
112
|
+
try { handleAxiosError(error); } catch (e: any) { return e.message; }
|
|
113
|
+
return 'Unexpected error updating saved setting.';
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export async function deleteSavedSetting(input: z.infer<typeof DeleteSavedSettingSchema>): Promise<string> {
|
|
118
|
+
try {
|
|
119
|
+
await client.delete(`/saved-settings/${input.id}`);
|
|
120
|
+
return `Saved setting ${input.id} deleted successfully.`;
|
|
121
|
+
} catch (error) {
|
|
122
|
+
try { handleAxiosError(error); } catch (e: any) { return e.message; }
|
|
123
|
+
return 'Unexpected error deleting saved setting.';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ============================================================================
|
|
128
|
+
// Tool definitions
|
|
129
|
+
// ============================================================================
|
|
130
|
+
|
|
131
|
+
export const savedSettingsTools = [
|
|
132
|
+
{
|
|
133
|
+
name: 'get_saved_settings_presets',
|
|
134
|
+
description: `Get all public preset saved settings. These are shared templates available to all users.
|
|
135
|
+
|
|
136
|
+
Use this tool when:
|
|
137
|
+
- User wants to see available preset templates
|
|
138
|
+
- User is looking for standard configurations (e.g., "Modern Euro", "Traditional")
|
|
139
|
+
- User wants to apply a preset to their current configuration
|
|
140
|
+
|
|
141
|
+
IMPORTANT: When you use values from a saved setting to configure an article (via create_saved_cart, create_order, or add_articles_to_cart),
|
|
142
|
+
you MUST also set the "settingsName" field INSIDE each article object to the exact name of the saved setting (e.g., "Modern Euro", "Zach's Kitchen").
|
|
143
|
+
CRITICAL: settingsName is an ARTICLE-LEVEL field only. NEVER pass it at the order level — it will cause a validation error.
|
|
144
|
+
|
|
145
|
+
Returns: Array of preset saved settings with all configuration fields.`,
|
|
146
|
+
inputSchema: GetSavedSettingsPresetsSchema,
|
|
147
|
+
handler: getSavedSettingsPresets,
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: 'get_my_saved_settings',
|
|
151
|
+
description: `Get all saved settings for the currently authenticated user.
|
|
152
|
+
|
|
153
|
+
This includes:
|
|
154
|
+
- User's personal saved settings (created by the user)
|
|
155
|
+
- Public presets (available to all users)
|
|
156
|
+
|
|
157
|
+
Use this tool when:
|
|
158
|
+
- User wants to see their saved configurations
|
|
159
|
+
- User wants to load a previously saved setting
|
|
160
|
+
- User is managing their saved settings
|
|
161
|
+
|
|
162
|
+
IMPORTANT: When you use values from a saved setting to configure an article (via create_saved_cart, create_order, or add_articles_to_cart),
|
|
163
|
+
you MUST also set the "settingsName" field INSIDE each article object to the exact name of the saved setting (e.g., "Modern Euro", "Zach's Kitchen").
|
|
164
|
+
CRITICAL: settingsName is an ARTICLE-LEVEL field only. NEVER pass it at the order level — it will cause a validation error.
|
|
165
|
+
|
|
166
|
+
Returns: Array of saved settings (both personal and presets).`,
|
|
167
|
+
inputSchema: GetMySavedSettingsSchema,
|
|
168
|
+
handler: getMySavedSettings,
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: 'get_saved_setting_by_id',
|
|
172
|
+
description: `Get a specific saved setting by its ID.
|
|
173
|
+
|
|
174
|
+
Authorization:
|
|
175
|
+
- Presets (isPreset=1): Available to all authenticated users
|
|
176
|
+
- User settings: Only available to the owner
|
|
177
|
+
|
|
178
|
+
Use this tool when:
|
|
179
|
+
- User wants to view details of a specific saved setting
|
|
180
|
+
- You have a saved setting ID from a previous operation
|
|
181
|
+
|
|
182
|
+
Returns: Single saved setting object.`,
|
|
183
|
+
inputSchema: GetSavedSettingByIdSchema,
|
|
184
|
+
handler: getSavedSettingById,
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
name: 'create_saved_setting',
|
|
188
|
+
description: `Create a new saved setting for the current user.
|
|
189
|
+
|
|
190
|
+
Use this tool when:
|
|
191
|
+
- User wants to save their current configuration for later use
|
|
192
|
+
- User has configured materials, edges, and options and wants to reuse them
|
|
193
|
+
- User says "save these settings" or "save this as a preset"
|
|
194
|
+
|
|
195
|
+
Required fields:
|
|
196
|
+
- name: A descriptive name for the setting (e.g., "My Modern Kitchen")
|
|
197
|
+
- frontMaterial: Front material specification
|
|
198
|
+
- caseMaterial: Case material specification
|
|
199
|
+
- Other fields as needed
|
|
200
|
+
|
|
201
|
+
Note: User-created settings are private by default (isPreset=0).`,
|
|
202
|
+
inputSchema: CreateSavedSettingSchema,
|
|
203
|
+
handler: createSavedSetting,
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: 'update_saved_setting',
|
|
207
|
+
description: `Update an existing saved setting.
|
|
208
|
+
|
|
209
|
+
Authorization:
|
|
210
|
+
- Can only update user's own settings (not presets)
|
|
211
|
+
- savedSettingsId is required to identify which setting to update
|
|
212
|
+
|
|
213
|
+
Use this tool when:
|
|
214
|
+
- User wants to modify a previously saved setting
|
|
215
|
+
- User wants to update material choices or configuration
|
|
216
|
+
- User says "update my saved setting" or "change the settings I saved"
|
|
217
|
+
|
|
218
|
+
Required fields:
|
|
219
|
+
- savedSettingsId: ID of the setting to update
|
|
220
|
+
- At least one field to update`,
|
|
221
|
+
inputSchema: UpdateSavedSettingSchema,
|
|
222
|
+
handler: updateSavedSetting,
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
name: 'delete_saved_setting',
|
|
226
|
+
description: `Delete a saved setting.
|
|
227
|
+
|
|
228
|
+
Authorization:
|
|
229
|
+
- Can only delete user's own settings (not presets)
|
|
230
|
+
- User must be the owner of the setting
|
|
231
|
+
|
|
232
|
+
Use this tool when:
|
|
233
|
+
- User wants to remove a saved setting
|
|
234
|
+
- User says "delete my saved setting" or "remove this configuration"
|
|
235
|
+
|
|
236
|
+
Required fields:
|
|
237
|
+
- id: ID of the setting to delete`,
|
|
238
|
+
inputSchema: DeleteSavedSettingSchema,
|
|
239
|
+
handler: deleteSavedSetting,
|
|
240
|
+
},
|
|
241
|
+
];
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"lib": ["ES2022"],
|
|
6
|
+
"outDir": "dist",
|
|
7
|
+
"rootDir": "src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"resolveJsonModule": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["src/**/*"],
|
|
14
|
+
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
|
15
|
+
}
|