@insforge/mcp 1.2.5-dev.0 → 1.2.6-dev.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.
@@ -0,0 +1,2347 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/shared/tools.ts
4
+ import { z as z23 } from "zod";
5
+ import fetch2 from "node-fetch";
6
+ import { promises as fs } from "fs";
7
+ import { exec } from "child_process";
8
+ import { promisify } from "util";
9
+ import { tmpdir } from "os";
10
+ import archiver from "archiver";
11
+
12
+ // src/shared/response-handler.ts
13
+ async function handleApiResponse(response) {
14
+ const responseData = await response.json();
15
+ if (!response.ok) {
16
+ const errorData = responseData;
17
+ let fullMessage = errorData.message || errorData.error || "Unknown error";
18
+ if (errorData.nextAction) {
19
+ fullMessage += `. ${errorData.nextAction}`;
20
+ }
21
+ throw new Error(fullMessage);
22
+ }
23
+ return responseData;
24
+ }
25
+ function formatSuccessMessage(operation, data) {
26
+ if (data && typeof data === "object" && "message" in data) {
27
+ return `${data.message}
28
+ ${JSON.stringify(data, null, 2)}`;
29
+ }
30
+ return `${operation} completed successfully:
31
+ ${JSON.stringify(data, null, 2)}`;
32
+ }
33
+
34
+ // src/shared/usage-tracker.ts
35
+ import fetch from "node-fetch";
36
+ var UsageTracker = class {
37
+ apiBaseUrl;
38
+ apiKey;
39
+ constructor(apiBaseUrl, apiKey) {
40
+ this.apiBaseUrl = apiBaseUrl;
41
+ this.apiKey = apiKey;
42
+ }
43
+ async trackUsage(toolName, success = true) {
44
+ if (!this.apiKey) {
45
+ return;
46
+ }
47
+ try {
48
+ const payload = {
49
+ tool_name: toolName,
50
+ success,
51
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
52
+ };
53
+ await fetch(`${this.apiBaseUrl}/api/usage/mcp`, {
54
+ method: "POST",
55
+ headers: {
56
+ "Content-Type": "application/json",
57
+ "x-api-key": this.apiKey
58
+ },
59
+ body: JSON.stringify(payload)
60
+ });
61
+ } catch (error) {
62
+ console.error("Failed to track usage:", error);
63
+ }
64
+ }
65
+ };
66
+
67
+ // node_modules/@insforge/shared-schemas/dist/database.schema.js
68
+ import { z } from "zod";
69
+ var ColumnType;
70
+ (function(ColumnType2) {
71
+ ColumnType2["STRING"] = "string";
72
+ ColumnType2["DATE"] = "date";
73
+ ColumnType2["DATETIME"] = "datetime";
74
+ ColumnType2["INTEGER"] = "integer";
75
+ ColumnType2["FLOAT"] = "float";
76
+ ColumnType2["BOOLEAN"] = "boolean";
77
+ ColumnType2["UUID"] = "uuid";
78
+ ColumnType2["JSON"] = "json";
79
+ })(ColumnType || (ColumnType = {}));
80
+ var onUpdateActionSchema = z.enum(["CASCADE", "RESTRICT", "NO ACTION"]);
81
+ var onDeleteActionSchema = z.enum([
82
+ "CASCADE",
83
+ "SET NULL",
84
+ "SET DEFAULT",
85
+ "RESTRICT",
86
+ "NO ACTION"
87
+ ]);
88
+ var columnTypeSchema = z.enum([
89
+ ColumnType.STRING,
90
+ ColumnType.DATE,
91
+ ColumnType.DATETIME,
92
+ ColumnType.INTEGER,
93
+ ColumnType.FLOAT,
94
+ ColumnType.BOOLEAN,
95
+ ColumnType.UUID,
96
+ ColumnType.JSON
97
+ ]);
98
+ var foreignKeySchema = z.object({
99
+ referenceTable: z.string().min(1, "Target table cannot be empty"),
100
+ referenceColumn: z.string().min(1, "Target column cannot be empty"),
101
+ onDelete: onDeleteActionSchema,
102
+ onUpdate: onUpdateActionSchema
103
+ });
104
+ var columnSchema = z.object({
105
+ columnName: z.string().min(1, "Column name cannot be empty").max(64, "Column name must be less than 64 characters"),
106
+ type: z.union([columnTypeSchema, z.string()]),
107
+ defaultValue: z.string().optional(),
108
+ isPrimaryKey: z.boolean().optional(),
109
+ isNullable: z.boolean(),
110
+ isUnique: z.boolean(),
111
+ foreignKey: foreignKeySchema.optional()
112
+ });
113
+ var tableSchema = z.object({
114
+ tableName: z.string().min(1, "Table name cannot be empty").max(64, "Table name must be less than 64 characters"),
115
+ columns: z.array(columnSchema).min(1, "At least one column is required"),
116
+ recordCount: z.number().optional(),
117
+ createdAt: z.string().optional(),
118
+ updatedAt: z.string().optional()
119
+ });
120
+ var databaseFunctionSchema = z.object({
121
+ functionName: z.string(),
122
+ functionDef: z.string(),
123
+ kind: z.string()
124
+ });
125
+ var databaseIndexSchema = z.object({
126
+ tableName: z.string(),
127
+ indexName: z.string(),
128
+ indexDef: z.string(),
129
+ isUnique: z.boolean().nullable(),
130
+ isPrimary: z.boolean().nullable()
131
+ });
132
+ var databasePolicySchema = z.object({
133
+ tableName: z.string(),
134
+ policyName: z.string(),
135
+ cmd: z.string(),
136
+ roles: z.array(z.string()),
137
+ qual: z.string().nullable(),
138
+ withCheck: z.string().nullable()
139
+ });
140
+ var databaseTriggerSchema = z.object({
141
+ tableName: z.string(),
142
+ triggerName: z.string(),
143
+ actionTiming: z.string(),
144
+ eventManipulation: z.string(),
145
+ actionOrientation: z.string(),
146
+ actionCondition: z.string().nullable(),
147
+ actionStatement: z.string()
148
+ });
149
+
150
+ // node_modules/@insforge/shared-schemas/dist/database-api.schema.js
151
+ import { z as z2 } from "zod";
152
+ var createTableRequestSchema = tableSchema.pick({
153
+ tableName: true,
154
+ columns: true
155
+ }).extend({
156
+ rlsEnabled: z2.boolean().default(true)
157
+ });
158
+ var createTableResponseSchema = tableSchema.pick({
159
+ tableName: true,
160
+ columns: true
161
+ }).extend({
162
+ message: z2.string(),
163
+ autoFields: z2.array(z2.string()),
164
+ nextActions: z2.string()
165
+ });
166
+ var updateTableSchemaRequestSchema = z2.object({
167
+ addColumns: z2.array(columnSchema.omit({
168
+ foreignKey: true
169
+ })).optional(),
170
+ dropColumns: z2.array(z2.string()).optional(),
171
+ updateColumns: z2.array(z2.object({
172
+ columnName: z2.string(),
173
+ defaultValue: z2.string().optional(),
174
+ newColumnName: z2.string().min(1, "New column name cannot be empty").max(64, "New column name must be less than 64 characters").optional()
175
+ })).optional(),
176
+ addForeignKeys: z2.array(z2.object({
177
+ columnName: z2.string().min(1, "Column name is required for adding foreign key"),
178
+ foreignKey: foreignKeySchema
179
+ })).optional(),
180
+ dropForeignKeys: z2.array(z2.string()).optional(),
181
+ renameTable: z2.object({
182
+ newTableName: z2.string().min(1, "New table name cannot be empty").max(64, "New table name must be less than 64 characters")
183
+ }).optional()
184
+ });
185
+ var updateTableSchemaResponse = z2.object({
186
+ message: z2.string(),
187
+ tableName: z2.string(),
188
+ operations: z2.array(z2.string())
189
+ });
190
+ var deleteTableResponse = z2.object({
191
+ message: z2.string(),
192
+ tableName: z2.string(),
193
+ nextActions: z2.string()
194
+ });
195
+ var rawSQLRequestSchema = z2.object({
196
+ query: z2.string().min(1, "Query is required"),
197
+ params: z2.array(z2.unknown()).optional()
198
+ });
199
+ var rawSQLResponseSchema = z2.object({
200
+ rows: z2.array(z2.record(z2.string(), z2.unknown())),
201
+ rowCount: z2.number().nullable(),
202
+ fields: z2.array(z2.object({
203
+ name: z2.string(),
204
+ dataTypeID: z2.number()
205
+ })).optional()
206
+ });
207
+ var exportRequestSchema = z2.object({
208
+ tables: z2.array(z2.string()).optional(),
209
+ format: z2.enum(["sql", "json"]).default("sql"),
210
+ includeData: z2.boolean().default(true),
211
+ includeFunctions: z2.boolean().default(false),
212
+ includeSequences: z2.boolean().default(false),
213
+ includeViews: z2.boolean().default(false),
214
+ rowLimit: z2.number().int().positive().max(1e4).default(1e3)
215
+ });
216
+ var exportJsonDataSchema = z2.object({
217
+ timestamp: z2.string(),
218
+ tables: z2.record(z2.string(), z2.object({
219
+ schema: z2.array(z2.object({
220
+ columnName: z2.string(),
221
+ dataType: z2.string(),
222
+ characterMaximumLength: z2.number().nullable(),
223
+ isNullable: z2.string(),
224
+ columnDefault: z2.string().nullable()
225
+ })),
226
+ indexes: z2.array(z2.object({
227
+ indexname: z2.string(),
228
+ indexdef: z2.string(),
229
+ isUnique: z2.boolean().nullable(),
230
+ isPrimary: z2.boolean().nullable()
231
+ })),
232
+ foreignKeys: z2.array(z2.object({
233
+ constraintName: z2.string(),
234
+ columnName: z2.string(),
235
+ foreignTableName: z2.string(),
236
+ foreignColumnName: z2.string(),
237
+ deleteRule: z2.string().nullable(),
238
+ updateRule: z2.string().nullable()
239
+ })),
240
+ rlsEnabled: z2.boolean().optional(),
241
+ policies: z2.array(z2.object({
242
+ policyname: z2.string(),
243
+ cmd: z2.string(),
244
+ roles: z2.array(z2.string()),
245
+ qual: z2.string().nullable(),
246
+ withCheck: z2.string().nullable()
247
+ })),
248
+ triggers: z2.array(z2.object({
249
+ triggerName: z2.string(),
250
+ actionTiming: z2.string(),
251
+ eventManipulation: z2.string(),
252
+ actionOrientation: z2.string(),
253
+ actionCondition: z2.string().nullable(),
254
+ actionStatement: z2.string(),
255
+ newTable: z2.string().nullable(),
256
+ oldTable: z2.string().nullable()
257
+ })),
258
+ rows: z2.array(z2.record(z2.string(), z2.unknown())).optional(),
259
+ recordCount: z2.number().optional()
260
+ })),
261
+ functions: z2.array(z2.object({
262
+ functionName: z2.string(),
263
+ functionDef: z2.string(),
264
+ kind: z2.string()
265
+ })),
266
+ sequences: z2.array(z2.object({
267
+ sequenceName: z2.string(),
268
+ startValue: z2.string(),
269
+ increment: z2.string(),
270
+ minValue: z2.string().nullable(),
271
+ maxValue: z2.string().nullable(),
272
+ cycle: z2.string()
273
+ })),
274
+ views: z2.array(z2.object({
275
+ viewName: z2.string(),
276
+ definition: z2.string()
277
+ }))
278
+ });
279
+ var exportResponseSchema = z2.object({
280
+ format: z2.enum(["sql", "json"]),
281
+ data: z2.union([z2.string(), exportJsonDataSchema]),
282
+ timestamp: z2.string()
283
+ });
284
+ var importRequestSchema = z2.object({
285
+ truncate: z2.union([
286
+ z2.boolean(),
287
+ z2.string().transform((val) => {
288
+ if (val === "true")
289
+ return true;
290
+ if (val === "false")
291
+ return false;
292
+ throw new Error("Invalid boolean string");
293
+ })
294
+ ]).default(false)
295
+ });
296
+ var importResponseSchema = z2.object({
297
+ success: z2.boolean(),
298
+ message: z2.string(),
299
+ filename: z2.string(),
300
+ tables: z2.array(z2.string()),
301
+ rowsImported: z2.number(),
302
+ fileSize: z2.number()
303
+ });
304
+ var bulkUpsertRequestSchema = z2.object({
305
+ table: z2.string().min(1, "Table name is required"),
306
+ upsertKey: z2.string().optional()
307
+ // Note: File handling is done at the API layer via multipart/form-data
308
+ });
309
+ var bulkUpsertResponseSchema = z2.object({
310
+ success: z2.boolean(),
311
+ message: z2.string(),
312
+ table: z2.string(),
313
+ rowsAffected: z2.number(),
314
+ totalRecords: z2.number(),
315
+ filename: z2.string()
316
+ });
317
+ var databaseFunctionsResponseSchema = z2.object({
318
+ functions: z2.array(databaseFunctionSchema)
319
+ });
320
+ var databaseIndexesResponseSchema = z2.object({
321
+ indexes: z2.array(databaseIndexSchema)
322
+ });
323
+ var databasePoliciesResponseSchema = z2.object({
324
+ policies: z2.array(databasePolicySchema)
325
+ });
326
+ var databaseTriggersResponseSchema = z2.object({
327
+ triggers: z2.array(databaseTriggerSchema)
328
+ });
329
+
330
+ // node_modules/@insforge/shared-schemas/dist/secrets.schema.js
331
+ import { z as z3 } from "zod";
332
+ var secretSchema = z3.object({
333
+ id: z3.string(),
334
+ key: z3.string(),
335
+ isActive: z3.boolean(),
336
+ isReserved: z3.boolean(),
337
+ lastUsedAt: z3.string().nullable(),
338
+ expiresAt: z3.string().nullable(),
339
+ createdAt: z3.string(),
340
+ updatedAt: z3.string()
341
+ });
342
+
343
+ // node_modules/@insforge/shared-schemas/dist/secrets-api.schema.js
344
+ import { z as z4 } from "zod";
345
+ var listSecretsResponseSchema = z4.object({
346
+ secrets: z4.array(secretSchema)
347
+ });
348
+ var getSecretValueResponseSchema = z4.object({
349
+ key: z4.string(),
350
+ value: z4.string()
351
+ });
352
+ var createSecretRequestSchema = z4.object({
353
+ key: z4.string().regex(/^[A-Z0-9_]+$/, "Use uppercase letters, numbers, and underscores only"),
354
+ value: z4.string().min(1, "Value is required")
355
+ });
356
+ var createSecretResponseSchema = z4.object({
357
+ success: z4.literal(true),
358
+ message: z4.string(),
359
+ id: z4.string()
360
+ });
361
+ var updateSecretResponseSchema = z4.object({
362
+ success: z4.literal(true),
363
+ message: z4.string()
364
+ });
365
+ var deleteSecretResponseSchema = z4.object({
366
+ success: z4.literal(true),
367
+ message: z4.string()
368
+ });
369
+
370
+ // node_modules/@insforge/shared-schemas/dist/storage.schema.js
371
+ import { z as z5 } from "zod";
372
+ var storageFileSchema = z5.object({
373
+ key: z5.string(),
374
+ bucket: z5.string(),
375
+ size: z5.number(),
376
+ mimeType: z5.string().optional(),
377
+ uploadedAt: z5.string(),
378
+ url: z5.string()
379
+ });
380
+ var storageBucketSchema = z5.object({
381
+ name: z5.string(),
382
+ public: z5.boolean(),
383
+ createdAt: z5.string()
384
+ });
385
+
386
+ // node_modules/@insforge/shared-schemas/dist/storage-api.schema.js
387
+ import { z as z6 } from "zod";
388
+ var createBucketRequestSchema = z6.object({
389
+ bucketName: z6.string().min(1, "Bucket name cannot be empty"),
390
+ isPublic: z6.boolean().default(true)
391
+ });
392
+ var updateBucketRequestSchema = z6.object({
393
+ isPublic: z6.boolean()
394
+ });
395
+ var listObjectsResponseSchema = z6.object({
396
+ objects: z6.array(storageFileSchema),
397
+ pagination: z6.object({
398
+ offset: z6.number(),
399
+ limit: z6.number(),
400
+ total: z6.number()
401
+ })
402
+ });
403
+ var uploadStrategyRequestSchema = z6.object({
404
+ filename: z6.string().min(1, "Filename cannot be empty"),
405
+ contentType: z6.string().optional(),
406
+ size: z6.number().optional()
407
+ });
408
+ var uploadStrategyResponseSchema = z6.object({
409
+ method: z6.enum(["presigned", "direct"]),
410
+ uploadUrl: z6.string(),
411
+ fields: z6.record(z6.string()).optional(),
412
+ key: z6.string(),
413
+ confirmRequired: z6.boolean(),
414
+ confirmUrl: z6.string().optional(),
415
+ expiresAt: z6.date().optional()
416
+ });
417
+ var downloadStrategyRequestSchema = z6.object({
418
+ expiresIn: z6.number().optional().default(3600)
419
+ });
420
+ var downloadStrategyResponseSchema = z6.object({
421
+ method: z6.enum(["presigned", "direct"]),
422
+ url: z6.string(),
423
+ expiresAt: z6.date().optional(),
424
+ headers: z6.record(z6.string()).optional()
425
+ });
426
+ var confirmUploadRequestSchema = z6.object({
427
+ size: z6.number(),
428
+ contentType: z6.string().optional(),
429
+ etag: z6.string().optional()
430
+ });
431
+
432
+ // node_modules/@insforge/shared-schemas/dist/auth.schema.js
433
+ import { z as z7 } from "zod";
434
+ var userIdSchema = z7.string().uuid("Invalid user ID format");
435
+ var emailSchema = z7.string().email("Invalid email format").toLowerCase().trim();
436
+ var passwordSchema = z7.string();
437
+ var nameSchema = z7.string().min(1, "Name is required").max(100, "Name must be less than 100 characters").trim();
438
+ var roleSchema = z7.enum(["anon", "authenticated", "project_admin"]);
439
+ var verificationMethodSchema = z7.enum(["code", "link"]);
440
+ var profileSchema = z7.object({
441
+ name: z7.string().optional(),
442
+ // eslint-disable-next-line @typescript-eslint/naming-convention
443
+ avatar_url: z7.string().url().optional()
444
+ }).passthrough();
445
+ var userSchema = z7.object({
446
+ id: userIdSchema,
447
+ email: emailSchema,
448
+ emailVerified: z7.boolean(),
449
+ providers: z7.array(z7.string()).optional(),
450
+ createdAt: z7.string(),
451
+ // PostgreSQL timestamp
452
+ updatedAt: z7.string(),
453
+ // PostgreSQL timestamp
454
+ profile: profileSchema.nullable(),
455
+ // User profile data (name, avatar_url, bio, etc.)
456
+ metadata: z7.record(z7.unknown()).nullable()
457
+ // System metadata (device ID, login IP, etc.)
458
+ });
459
+ var oAuthProvidersSchema = z7.enum([
460
+ "google",
461
+ "github",
462
+ "discord",
463
+ "linkedin",
464
+ "facebook",
465
+ "instagram",
466
+ "tiktok",
467
+ "apple",
468
+ "x",
469
+ "spotify",
470
+ "microsoft"
471
+ ]);
472
+ var oAuthStateSchema = z7.object({
473
+ provider: oAuthProvidersSchema,
474
+ redirectUri: z7.string().url().optional()
475
+ });
476
+ var oAuthConfigSchema = z7.object({
477
+ id: z7.string().uuid(),
478
+ provider: oAuthProvidersSchema,
479
+ clientId: z7.string().optional(),
480
+ scopes: z7.array(z7.string()).optional(),
481
+ redirectUri: z7.string().optional(),
482
+ useSharedKey: z7.boolean(),
483
+ createdAt: z7.string(),
484
+ // PostgreSQL timestamp
485
+ updatedAt: z7.string()
486
+ // PostgreSQL timestamp
487
+ });
488
+ var authConfigSchema = z7.object({
489
+ id: z7.string().uuid(),
490
+ requireEmailVerification: z7.boolean(),
491
+ passwordMinLength: z7.number().min(4).max(128),
492
+ requireNumber: z7.boolean(),
493
+ requireLowercase: z7.boolean(),
494
+ requireUppercase: z7.boolean(),
495
+ requireSpecialChar: z7.boolean(),
496
+ verifyEmailMethod: verificationMethodSchema,
497
+ resetPasswordMethod: verificationMethodSchema,
498
+ signInRedirectTo: z7.union([z7.string().url(), z7.literal(""), z7.null()]).optional().transform((val) => val === "" ? null : val),
499
+ createdAt: z7.string(),
500
+ // PostgreSQL timestamp
501
+ updatedAt: z7.string()
502
+ // PostgreSQL timestamp
503
+ });
504
+ var tokenPayloadSchema = z7.object({
505
+ sub: userIdSchema,
506
+ // Subject (user ID)
507
+ email: emailSchema,
508
+ role: roleSchema,
509
+ iat: z7.number().optional(),
510
+ // Issued at
511
+ exp: z7.number().optional()
512
+ // Expiration
513
+ });
514
+
515
+ // node_modules/@insforge/shared-schemas/dist/auth-api.schema.js
516
+ import { z as z8 } from "zod";
517
+ var paginationSchema = z8.object({
518
+ limit: z8.string().optional(),
519
+ offset: z8.string().optional()
520
+ });
521
+ var createUserRequestSchema = z8.object({
522
+ email: emailSchema,
523
+ password: passwordSchema,
524
+ name: nameSchema.optional()
525
+ });
526
+ var createSessionRequestSchema = z8.object({
527
+ email: emailSchema,
528
+ password: passwordSchema
529
+ });
530
+ var exchangeAdminSessionRequestSchema = z8.object({
531
+ code: z8.string()
532
+ });
533
+ var listUsersRequestSchema = paginationSchema.extend({
534
+ search: z8.string().optional()
535
+ }).optional();
536
+ var deleteUsersRequestSchema = z8.object({
537
+ userIds: z8.array(userIdSchema).min(1, "At least one user ID is required")
538
+ });
539
+ var updateProfileRequestSchema = z8.object({
540
+ profile: z8.record(z8.unknown())
541
+ });
542
+ var sendVerificationEmailRequestSchema = z8.object({
543
+ email: emailSchema
544
+ });
545
+ var verifyEmailRequestSchema = z8.object({
546
+ email: emailSchema.optional(),
547
+ otp: z8.string().min(1)
548
+ }).refine((data) => data.email || data.otp, {
549
+ message: "Either email or otp must be provided"
550
+ });
551
+ var sendResetPasswordEmailRequestSchema = z8.object({
552
+ email: emailSchema
553
+ });
554
+ var exchangeResetPasswordTokenRequestSchema = z8.object({
555
+ email: emailSchema,
556
+ code: z8.string().min(1)
557
+ });
558
+ var resetPasswordRequestSchema = z8.object({
559
+ newPassword: passwordSchema,
560
+ otp: z8.string().min(1, "OTP/token is required")
561
+ });
562
+ var createUserResponseSchema = z8.object({
563
+ user: userSchema.optional(),
564
+ accessToken: z8.string().nullable(),
565
+ requireEmailVerification: z8.boolean().optional(),
566
+ redirectTo: z8.string().url().optional(),
567
+ csrfToken: z8.string().nullable().optional()
568
+ });
569
+ var createSessionResponseSchema = z8.object({
570
+ user: userSchema,
571
+ accessToken: z8.string(),
572
+ redirectTo: z8.string().url().optional(),
573
+ csrfToken: z8.string().nullable().optional()
574
+ });
575
+ var verifyEmailResponseSchema = z8.object({
576
+ user: userSchema,
577
+ accessToken: z8.string(),
578
+ redirectTo: z8.string().url().optional(),
579
+ csrfToken: z8.string().nullable().optional()
580
+ });
581
+ var refreshSessionResponseSchema = z8.object({
582
+ accessToken: z8.string(),
583
+ user: userSchema,
584
+ csrfToken: z8.string()
585
+ });
586
+ var exchangeResetPasswordTokenResponseSchema = z8.object({
587
+ token: z8.string(),
588
+ expiresAt: z8.string().datetime()
589
+ });
590
+ var resetPasswordResponseSchema = z8.object({
591
+ message: z8.string()
592
+ });
593
+ var getCurrentSessionResponseSchema = z8.object({
594
+ user: userSchema
595
+ });
596
+ var getProfileResponseSchema = z8.object({
597
+ id: userIdSchema,
598
+ profile: profileSchema.nullable()
599
+ });
600
+ var listUsersResponseSchema = z8.object({
601
+ data: z8.array(userSchema),
602
+ pagination: z8.object({
603
+ offset: z8.number(),
604
+ limit: z8.number(),
605
+ total: z8.number()
606
+ })
607
+ });
608
+ var deleteUsersResponseSchema = z8.object({
609
+ message: z8.string(),
610
+ deletedCount: z8.number().int().nonnegative()
611
+ });
612
+ var getOauthUrlResponseSchema = z8.object({
613
+ authUrl: z8.string().url()
614
+ });
615
+ var createOAuthConfigRequestSchema = oAuthConfigSchema.omit({
616
+ id: true,
617
+ createdAt: true,
618
+ updatedAt: true
619
+ }).extend({
620
+ clientSecret: z8.string().optional()
621
+ });
622
+ var updateOAuthConfigRequestSchema = oAuthConfigSchema.omit({
623
+ id: true,
624
+ provider: true,
625
+ createdAt: true,
626
+ updatedAt: true
627
+ }).extend({
628
+ clientSecret: z8.string().optional()
629
+ }).partial();
630
+ var listOAuthConfigsResponseSchema = z8.object({
631
+ data: z8.array(oAuthConfigSchema),
632
+ count: z8.number()
633
+ });
634
+ var updateAuthConfigRequestSchema = authConfigSchema.omit({
635
+ id: true,
636
+ createdAt: true,
637
+ updatedAt: true
638
+ }).partial();
639
+ var getPublicAuthConfigResponseSchema = z8.object({
640
+ oAuthProviders: z8.array(oAuthProvidersSchema),
641
+ ...authConfigSchema.omit({
642
+ id: true,
643
+ updatedAt: true,
644
+ createdAt: true,
645
+ signInRedirectTo: true
646
+ }).shape
647
+ });
648
+ var authErrorResponseSchema = z8.object({
649
+ error: z8.string(),
650
+ message: z8.string(),
651
+ statusCode: z8.number().int(),
652
+ nextActions: z8.string().optional()
653
+ });
654
+
655
+ // node_modules/@insforge/shared-schemas/dist/metadata.schema.js
656
+ import { z as z11 } from "zod";
657
+
658
+ // node_modules/@insforge/shared-schemas/dist/realtime.schema.js
659
+ import { z as z9 } from "zod";
660
+ var senderTypeSchema = z9.enum(["system", "user"]);
661
+ var realtimeChannelSchema = z9.object({
662
+ id: z9.string().uuid(),
663
+ pattern: z9.string().min(1),
664
+ description: z9.string().nullable(),
665
+ webhookUrls: z9.array(z9.string().url()).nullable(),
666
+ enabled: z9.boolean(),
667
+ createdAt: z9.string().datetime(),
668
+ updatedAt: z9.string().datetime()
669
+ });
670
+ var realtimeMessageSchema = z9.object({
671
+ id: z9.string().uuid(),
672
+ eventName: z9.string().min(1),
673
+ channelId: z9.string().uuid().nullable(),
674
+ channelName: z9.string().min(1),
675
+ payload: z9.record(z9.string(), z9.unknown()),
676
+ senderType: senderTypeSchema,
677
+ senderId: z9.string().uuid().nullable(),
678
+ wsAudienceCount: z9.number().int().min(0),
679
+ whAudienceCount: z9.number().int().min(0),
680
+ whDeliveredCount: z9.number().int().min(0),
681
+ createdAt: z9.string().datetime()
682
+ });
683
+ var subscribeChannelPayloadSchema = z9.object({
684
+ channel: z9.string().min(1)
685
+ // The resolved channel instance, e.g., "order:123"
686
+ });
687
+ var unsubscribeChannelPayloadSchema = z9.object({
688
+ channel: z9.string().min(1)
689
+ // The resolved channel instance, e.g., "order:123"
690
+ });
691
+ var publishEventPayloadSchema = z9.object({
692
+ channel: z9.string().min(1),
693
+ event: z9.string().min(1),
694
+ payload: z9.record(z9.string(), z9.unknown())
695
+ });
696
+ var subscribeResponseSchema = z9.discriminatedUnion("ok", [
697
+ z9.object({
698
+ ok: z9.literal(true),
699
+ channel: z9.string().min(1)
700
+ }),
701
+ z9.object({
702
+ ok: z9.literal(false),
703
+ channel: z9.string().min(1),
704
+ error: z9.object({
705
+ code: z9.string().min(1),
706
+ message: z9.string().min(1)
707
+ })
708
+ })
709
+ ]);
710
+ var realtimeErrorPayloadSchema = z9.object({
711
+ channel: z9.string().optional(),
712
+ code: z9.string().min(1),
713
+ message: z9.string().min(1)
714
+ });
715
+ var webhookMessageSchema = z9.object({
716
+ messageId: z9.string().uuid(),
717
+ channel: z9.string().min(1),
718
+ eventName: z9.string().min(1),
719
+ payload: z9.record(z9.string(), z9.unknown())
720
+ });
721
+ var socketMessageMetaSchema = z9.object({
722
+ channel: z9.string().optional(),
723
+ // Present for room broadcasts
724
+ messageId: z9.string().uuid(),
725
+ senderType: senderTypeSchema,
726
+ senderId: z9.string().uuid().optional(),
727
+ timestamp: z9.string().datetime()
728
+ });
729
+ var socketMessageSchema = z9.object({
730
+ meta: socketMessageMetaSchema
731
+ }).passthrough();
732
+
733
+ // node_modules/@insforge/shared-schemas/dist/realtime-api.schema.js
734
+ import { z as z10 } from "zod";
735
+ var createChannelRequestSchema = z10.object({
736
+ pattern: z10.string().min(1, "Channel pattern is required"),
737
+ description: z10.string().optional(),
738
+ webhookUrls: z10.array(z10.string().url()).optional(),
739
+ enabled: z10.boolean().optional().default(true)
740
+ });
741
+ var updateChannelRequestSchema = z10.object({
742
+ pattern: z10.string().min(1).optional(),
743
+ description: z10.string().optional(),
744
+ webhookUrls: z10.array(z10.string().url()).optional(),
745
+ enabled: z10.boolean().optional()
746
+ });
747
+ var listChannelsResponseSchema = z10.array(realtimeChannelSchema);
748
+ var deleteChannelResponseSchema = z10.object({
749
+ message: z10.string()
750
+ });
751
+ var listMessagesRequestSchema = z10.object({
752
+ channelId: z10.string().uuid().optional(),
753
+ eventName: z10.string().optional(),
754
+ limit: z10.coerce.number().int().min(1).max(1e3).optional().default(100),
755
+ offset: z10.coerce.number().int().min(0).optional().default(0)
756
+ });
757
+ var listMessagesResponseSchema = z10.array(realtimeMessageSchema);
758
+ var messageStatsRequestSchema = z10.object({
759
+ channelId: z10.string().uuid().optional(),
760
+ since: z10.coerce.date().optional()
761
+ });
762
+ var messageStatsResponseSchema = z10.object({
763
+ totalMessages: z10.number().int().min(0),
764
+ whDeliveryRate: z10.number().min(0).max(1),
765
+ topEvents: z10.array(z10.object({
766
+ eventName: z10.string(),
767
+ count: z10.number().int().min(0)
768
+ }))
769
+ });
770
+ var rlsPolicySchema = z10.object({
771
+ policyName: z10.string(),
772
+ tableName: z10.string(),
773
+ command: z10.string(),
774
+ roles: z10.array(z10.string()),
775
+ using: z10.string().nullable(),
776
+ withCheck: z10.string().nullable()
777
+ });
778
+ var realtimePermissionsResponseSchema = z10.object({
779
+ subscribe: z10.object({
780
+ policies: z10.array(rlsPolicySchema)
781
+ }),
782
+ publish: z10.object({
783
+ policies: z10.array(rlsPolicySchema)
784
+ })
785
+ });
786
+
787
+ // node_modules/@insforge/shared-schemas/dist/metadata.schema.js
788
+ var authMetadataSchema = getPublicAuthConfigResponseSchema;
789
+ var databaseMetadataSchema = z11.object({
790
+ tables: z11.array(z11.object({
791
+ tableName: z11.string(),
792
+ recordCount: z11.number()
793
+ })),
794
+ totalSizeInGB: z11.number(),
795
+ hint: z11.string().optional()
796
+ });
797
+ var bucketMetadataSchema = storageBucketSchema.extend({
798
+ objectCount: z11.number().optional()
799
+ });
800
+ var storageMetadataSchema = z11.object({
801
+ buckets: z11.array(bucketMetadataSchema),
802
+ totalSizeInGB: z11.number()
803
+ });
804
+ var edgeFunctionMetadataSchema = z11.object({
805
+ slug: z11.string(),
806
+ name: z11.string(),
807
+ description: z11.string().nullable(),
808
+ status: z11.string()
809
+ });
810
+ var aiMetadataSchema = z11.object({
811
+ models: z11.array(z11.object({
812
+ inputModality: z11.array(z11.string()),
813
+ outputModality: z11.array(z11.string()),
814
+ modelId: z11.string()
815
+ }))
816
+ });
817
+ var realtimeMetadataSchema = z11.object({
818
+ channels: z11.array(realtimeChannelSchema),
819
+ permissions: realtimePermissionsResponseSchema
820
+ });
821
+ var appMetaDataSchema = z11.object({
822
+ auth: authMetadataSchema,
823
+ database: databaseMetadataSchema,
824
+ storage: storageMetadataSchema,
825
+ aiIntegration: aiMetadataSchema.optional(),
826
+ functions: z11.array(edgeFunctionMetadataSchema),
827
+ realtime: realtimeMetadataSchema.optional(),
828
+ version: z11.string().optional()
829
+ });
830
+ var databaseConnectionParametersSchema = z11.object({
831
+ host: z11.string(),
832
+ port: z11.number(),
833
+ database: z11.string(),
834
+ user: z11.string(),
835
+ password: z11.string(),
836
+ sslmode: z11.string()
837
+ });
838
+ var databaseConnectionInfoSchema = z11.object({
839
+ connectionURL: z11.string(),
840
+ parameters: databaseConnectionParametersSchema
841
+ });
842
+ var databasePasswordInfoSchema = z11.object({
843
+ databasePassword: z11.string()
844
+ });
845
+ var apiKeyResponseSchema = z11.object({
846
+ apiKey: z11.string()
847
+ });
848
+
849
+ // node_modules/@insforge/shared-schemas/dist/ai.schema.js
850
+ import { z as z12 } from "zod";
851
+ var modalitySchema = z12.enum(["text", "image", "audio"]);
852
+ var aiConfigurationInputSchema = z12.object({
853
+ inputModality: z12.array(modalitySchema).min(1),
854
+ outputModality: z12.array(modalitySchema).min(1),
855
+ provider: z12.string(),
856
+ modelId: z12.string(),
857
+ systemPrompt: z12.string().optional()
858
+ });
859
+ var aiConfigurationSchema = aiConfigurationInputSchema.extend({
860
+ id: z12.string().uuid()
861
+ });
862
+ var aiConfigurationWithUsageSchema = aiConfigurationSchema.extend({
863
+ usageStats: z12.object({
864
+ totalInputTokens: z12.number(),
865
+ totalOutputTokens: z12.number(),
866
+ totalTokens: z12.number(),
867
+ totalImageCount: z12.number(),
868
+ totalRequests: z12.number()
869
+ }).optional()
870
+ });
871
+ var aiUsageDataSchema = z12.object({
872
+ configId: z12.string().uuid(),
873
+ inputTokens: z12.number().int().optional(),
874
+ outputTokens: z12.number().int().optional(),
875
+ imageCount: z12.number().int().optional(),
876
+ imageResolution: z12.string().optional()
877
+ });
878
+ var aiUsageRecordSchema = aiUsageDataSchema.extend({
879
+ id: z12.string().uuid(),
880
+ createdAt: z12.date(),
881
+ modelId: z12.string().nullable().optional(),
882
+ model: z12.string().nullable(),
883
+ provider: z12.string().nullable(),
884
+ inputModality: z12.array(modalitySchema).nullable(),
885
+ outputModality: z12.array(modalitySchema).nullable()
886
+ });
887
+ var aiUsageSummarySchema = z12.object({
888
+ totalInputTokens: z12.number(),
889
+ totalOutputTokens: z12.number(),
890
+ totalTokens: z12.number(),
891
+ totalImageCount: z12.number(),
892
+ totalRequests: z12.number()
893
+ });
894
+
895
+ // node_modules/@insforge/shared-schemas/dist/ai-api.schema.js
896
+ import { z as z13 } from "zod";
897
+ var textContentSchema = z13.object({
898
+ type: z13.literal("text"),
899
+ text: z13.string()
900
+ });
901
+ var imageContentSchema = z13.object({
902
+ type: z13.literal("image_url"),
903
+ // eslint-disable-next-line @typescript-eslint/naming-convention
904
+ image_url: z13.object({
905
+ // URL can be either a public URL or base64-encoded data URI
906
+ // Examples:
907
+ // - Public URL: "https://example.com/image.jpg"
908
+ // - Base64: "data:image/jpeg;base64,/9j/4AAQ..."
909
+ url: z13.string(),
910
+ detail: z13.enum(["auto", "low", "high"]).optional()
911
+ })
912
+ });
913
+ var audioContentSchema = z13.object({
914
+ type: z13.literal("input_audio"),
915
+ // eslint-disable-next-line @typescript-eslint/naming-convention
916
+ input_audio: z13.object({
917
+ // Base64-encoded audio data (direct URLs not supported for audio)
918
+ data: z13.string(),
919
+ format: z13.enum(["wav", "mp3", "aiff", "aac", "ogg", "flac", "m4a"])
920
+ })
921
+ });
922
+ var contentSchema = z13.union([textContentSchema, imageContentSchema, audioContentSchema]);
923
+ var chatMessageSchema = z13.object({
924
+ role: z13.enum(["user", "assistant", "system"]),
925
+ // New format: content can be string or array of content parts (OpenAI-compatible)
926
+ content: z13.union([z13.string(), z13.array(contentSchema)]),
927
+ // Legacy format: separate images field (deprecated but supported for backward compatibility)
928
+ images: z13.array(z13.object({ url: z13.string() })).optional()
929
+ });
930
+ var chatCompletionRequestSchema = z13.object({
931
+ model: z13.string(),
932
+ messages: z13.array(chatMessageSchema),
933
+ temperature: z13.number().min(0).max(2).optional(),
934
+ maxTokens: z13.number().positive().optional(),
935
+ topP: z13.number().min(0).max(1).optional(),
936
+ stream: z13.boolean().optional()
937
+ });
938
+ var chatCompletionResponseSchema = z13.object({
939
+ text: z13.string(),
940
+ metadata: z13.object({
941
+ model: z13.string(),
942
+ usage: z13.object({
943
+ promptTokens: z13.number().optional(),
944
+ completionTokens: z13.number().optional(),
945
+ totalTokens: z13.number().optional()
946
+ }).optional()
947
+ }).optional()
948
+ });
949
+ var imageGenerationRequestSchema = z13.object({
950
+ model: z13.string(),
951
+ prompt: z13.string(),
952
+ images: z13.array(z13.object({
953
+ url: z13.string()
954
+ })).optional()
955
+ });
956
+ var imageGenerationResponseSchema = z13.object({
957
+ text: z13.string().optional(),
958
+ images: z13.array(z13.object({
959
+ type: z13.literal("imageUrl"),
960
+ imageUrl: z13.string()
961
+ })),
962
+ metadata: z13.object({
963
+ model: z13.string(),
964
+ usage: z13.object({
965
+ promptTokens: z13.number().optional(),
966
+ completionTokens: z13.number().optional(),
967
+ totalTokens: z13.number().optional()
968
+ }).optional()
969
+ }).optional()
970
+ });
971
+ var aiModelSchema = z13.object({
972
+ id: z13.string(),
973
+ inputModality: z13.array(modalitySchema).min(1),
974
+ outputModality: z13.array(modalitySchema).min(1),
975
+ provider: z13.string(),
976
+ modelId: z13.string(),
977
+ priceLevel: z13.number().min(0).max(3).optional()
978
+ });
979
+ var createAIConfigurationRequestSchema = aiConfigurationSchema.omit({
980
+ id: true
981
+ });
982
+ var updateAIConfigurationRequestSchema = z13.object({
983
+ systemPrompt: z13.string().nullable()
984
+ });
985
+ var listAIUsageResponseSchema = z13.object({
986
+ records: z13.array(aiUsageRecordSchema),
987
+ total: z13.number()
988
+ });
989
+ var getAIUsageRequestSchema = z13.object({
990
+ startDate: z13.string().datetime().optional(),
991
+ endDate: z13.string().datetime().optional(),
992
+ limit: z13.string().regex(/^\d+$/).default("50"),
993
+ offset: z13.string().regex(/^\d+$/).default("0")
994
+ });
995
+ var getAIUsageSummaryRequestSchema = z13.object({
996
+ configId: z13.string().uuid().optional(),
997
+ startDate: z13.string().datetime().optional(),
998
+ endDate: z13.string().datetime().optional()
999
+ });
1000
+
1001
+ // node_modules/@insforge/shared-schemas/dist/logs.schema.js
1002
+ import { z as z14 } from "zod";
1003
+ var auditLogSchema = z14.object({
1004
+ id: z14.string(),
1005
+ actor: z14.string(),
1006
+ action: z14.string(),
1007
+ module: z14.string(),
1008
+ details: z14.record(z14.unknown()).nullable(),
1009
+ ipAddress: z14.string().nullable(),
1010
+ createdAt: z14.string(),
1011
+ updatedAt: z14.string()
1012
+ });
1013
+ var logSourceSchema = z14.object({
1014
+ id: z14.string(),
1015
+ name: z14.string(),
1016
+ token: z14.string()
1017
+ });
1018
+ var logSchema = z14.object({
1019
+ id: z14.string(),
1020
+ eventMessage: z14.string(),
1021
+ timestamp: z14.string(),
1022
+ body: z14.record(z14.string(), z14.unknown()),
1023
+ source: z14.string().optional()
1024
+ });
1025
+ var logStatsSchema = z14.object({
1026
+ source: z14.string(),
1027
+ count: z14.number(),
1028
+ lastActivity: z14.string()
1029
+ });
1030
+
1031
+ // node_modules/@insforge/shared-schemas/dist/logs-api.schema.js
1032
+ import { z as z15 } from "zod";
1033
+ var getAuditLogsRequestSchema = z15.object({
1034
+ limit: z15.number().default(100),
1035
+ offset: z15.number().default(0),
1036
+ actor: z15.string().optional(),
1037
+ action: z15.string().optional(),
1038
+ module: z15.string().optional(),
1039
+ startDate: z15.string().optional(),
1040
+ endDate: z15.string().optional()
1041
+ });
1042
+ var getAuditLogsResponseSchema = z15.object({
1043
+ data: z15.array(auditLogSchema),
1044
+ pagination: z15.object({
1045
+ limit: z15.number(),
1046
+ offset: z15.number(),
1047
+ total: z15.number()
1048
+ })
1049
+ });
1050
+ var getAuditLogStatsRequestSchema = z15.object({
1051
+ days: z15.number().default(7)
1052
+ });
1053
+ var getAuditLogStatsResponseSchema = z15.object({
1054
+ totalLogs: z15.number(),
1055
+ uniqueActors: z15.number(),
1056
+ uniqueModules: z15.number(),
1057
+ actionsByModule: z15.record(z15.number()),
1058
+ recentActivity: z15.array(auditLogSchema)
1059
+ });
1060
+ var clearAuditLogsRequestSchema = z15.object({
1061
+ daysToKeep: z15.number().default(90)
1062
+ });
1063
+ var clearAuditLogsResponseSchema = z15.object({
1064
+ message: z15.string(),
1065
+ deleted: z15.number()
1066
+ });
1067
+ var getLogsResponseSchema = z15.object({
1068
+ logs: z15.array(logSchema),
1069
+ total: z15.number()
1070
+ });
1071
+
1072
+ // node_modules/@insforge/shared-schemas/dist/functions.schema.js
1073
+ import { z as z16 } from "zod";
1074
+ var functionSchema = z16.object({
1075
+ id: z16.string(),
1076
+ slug: z16.string(),
1077
+ name: z16.string(),
1078
+ description: z16.string().nullable(),
1079
+ code: z16.string(),
1080
+ status: z16.enum(["draft", "active", "error"]),
1081
+ createdAt: z16.string(),
1082
+ updatedAt: z16.string(),
1083
+ deployedAt: z16.string().nullable()
1084
+ });
1085
+
1086
+ // node_modules/@insforge/shared-schemas/dist/functions-api.schema.js
1087
+ import { z as z17 } from "zod";
1088
+ var uploadFunctionRequestSchema = z17.object({
1089
+ name: z17.string().min(1, "Name is required"),
1090
+ slug: z17.string().regex(/^[a-zA-Z0-9_-]+$/, "Invalid slug format - must be alphanumeric with hyphens or underscores only").optional(),
1091
+ code: z17.string().min(1),
1092
+ description: z17.string().optional(),
1093
+ status: z17.enum(["draft", "active"]).optional().default("active")
1094
+ });
1095
+ var updateFunctionRequestSchema = z17.object({
1096
+ name: z17.string().optional(),
1097
+ code: z17.string().optional(),
1098
+ description: z17.string().optional(),
1099
+ status: z17.enum(["draft", "active"]).optional()
1100
+ });
1101
+ var listFunctionsResponseSchema = z17.object({
1102
+ functions: z17.array(functionSchema),
1103
+ runtime: z17.object({
1104
+ status: z17.enum(["running", "unavailable"])
1105
+ })
1106
+ });
1107
+
1108
+ // node_modules/@insforge/shared-schemas/dist/cloud-events.schema.js
1109
+ import { z as z18 } from "zod";
1110
+ var appRouteChangeEventSchema = z18.object({
1111
+ type: z18.literal("APP_ROUTE_CHANGE"),
1112
+ path: z18.string()
1113
+ });
1114
+ var authSuccessEventSchema = z18.object({
1115
+ type: z18.literal("AUTH_SUCCESS")
1116
+ });
1117
+ var authErrorEventSchema = z18.object({
1118
+ type: z18.literal("AUTH_ERROR"),
1119
+ message: z18.string()
1120
+ });
1121
+ var mcpConnectionStatusEventSchema = z18.object({
1122
+ type: z18.literal("MCP_CONNECTION_STATUS"),
1123
+ connected: z18.boolean(),
1124
+ toolName: z18.string(),
1125
+ timestamp: z18.union([z18.number(), z18.string()])
1126
+ });
1127
+ var showOnboardingOverlayEventSchema = z18.object({
1128
+ type: z18.literal("SHOW_ONBOARDING_OVERLAY")
1129
+ });
1130
+ var showSettingsOverlayEventSchema = z18.object({
1131
+ type: z18.literal("SHOW_SETTINGS_OVERLAY")
1132
+ });
1133
+ var onboardingSuccessSchema = z18.object({
1134
+ type: z18.literal("ONBOARDING_SUCCESS")
1135
+ });
1136
+ var navigateToUsageSchema = z18.object({
1137
+ type: z18.literal("NAVIGATE_TO_USAGE")
1138
+ });
1139
+ var showContactModalEventSchema = z18.object({
1140
+ type: z18.literal("SHOW_CONTACT_MODAL")
1141
+ });
1142
+ var showConnectOverlayEventSchema = z18.object({
1143
+ type: z18.literal("SHOW_CONNECT_OVERLAY")
1144
+ });
1145
+ var authorizationCodeEventSchema = z18.object({
1146
+ type: z18.literal("AUTHORIZATION_CODE"),
1147
+ code: z18.string()
1148
+ });
1149
+ var routeChangeEventSchema = z18.object({
1150
+ type: z18.literal("ROUTE_CHANGE"),
1151
+ path: z18.string()
1152
+ });
1153
+ var cloudEventSchema = z18.discriminatedUnion("type", [
1154
+ appRouteChangeEventSchema,
1155
+ authSuccessEventSchema,
1156
+ authErrorEventSchema,
1157
+ mcpConnectionStatusEventSchema,
1158
+ showOnboardingOverlayEventSchema,
1159
+ showSettingsOverlayEventSchema,
1160
+ onboardingSuccessSchema,
1161
+ navigateToUsageSchema,
1162
+ showContactModalEventSchema,
1163
+ showConnectOverlayEventSchema,
1164
+ authorizationCodeEventSchema,
1165
+ routeChangeEventSchema
1166
+ ]);
1167
+
1168
+ // node_modules/@insforge/shared-schemas/dist/docs.schema.js
1169
+ import { z as z19 } from "zod";
1170
+ var sdkFeatureSchema = z19.enum(["db", "storage", "functions", "auth", "ai", "realtime"]).describe(`
1171
+ SDK feature categories:
1172
+
1173
+ - "db" - Database operations
1174
+ - "storage" - File storage
1175
+ - "functions" - Edge functions
1176
+ - "auth" - User authentication
1177
+ - "ai" - AI features
1178
+ - "realtime" - Real-time WebSockets
1179
+ `);
1180
+ var sdkLanguageSchema = z19.enum([
1181
+ "typescript",
1182
+ "swift",
1183
+ "kotlin",
1184
+ // 'flutter',
1185
+ "rest-api"
1186
+ ]).describe(`
1187
+ SDK languages:
1188
+
1189
+ - "typescript" - JavaScript/TypeScript SDK
1190
+ - "swift" - Swift SDK
1191
+ - "kotlin" - Kotlin SDK
1192
+ - "rest-api" - REST API
1193
+ `);
1194
+ var docTypeSchema = z19.enum([
1195
+ "instructions",
1196
+ "auth-sdk",
1197
+ "db-sdk",
1198
+ "storage-sdk",
1199
+ "functions-sdk",
1200
+ "ai-integration-sdk",
1201
+ "auth-components-react",
1202
+ "auth-components-nextjs",
1203
+ "real-time",
1204
+ "deployment"
1205
+ ]).describe(`
1206
+ Documentation type:
1207
+ "instructions" (essential backend setup - use FIRST),
1208
+ "db-sdk" (database operations),
1209
+ "storage-sdk" (file storage),
1210
+ "functions-sdk" (edge functions),
1211
+ "auth-sdk" (direct SDK methods for custom auth flows),
1212
+ "auth-components-react" (authentication components for React+Vite applications),
1213
+ "auth-components-nextjs" (authentication components for Next.js applications),
1214
+ "ai-integration-sdk" (AI features),
1215
+ "real-time" (real-time pub/sub through WebSockets),
1216
+ "deployment" (deploy frontend applications via MCP tool)
1217
+ `);
1218
+
1219
+ // node_modules/@insforge/shared-schemas/dist/email-api.schema.js
1220
+ import { z as z20 } from "zod";
1221
+ var emailOrEmails = z20.union([
1222
+ emailSchema,
1223
+ z20.array(emailSchema).min(1, "At least one email is required").max(50, "Maximum 50 recipients allowed")
1224
+ ]);
1225
+ var sendRawEmailRequestSchema = z20.object({
1226
+ to: emailOrEmails,
1227
+ subject: z20.string().trim().min(1, "Subject is required").max(500, "Subject too long"),
1228
+ html: z20.string().trim().min(1, "HTML content is required"),
1229
+ cc: emailOrEmails.optional(),
1230
+ bcc: emailOrEmails.optional(),
1231
+ from: z20.string().trim().max(100, "From name too long").optional(),
1232
+ replyTo: z20.string().email("Reply-To must be a valid email").optional()
1233
+ });
1234
+ var sendEmailResponseSchema = z20.object({});
1235
+
1236
+ // node_modules/@insforge/shared-schemas/dist/deployments.schema.js
1237
+ import { z as z21 } from "zod";
1238
+ var deploymentStatusSchema = z21.enum([
1239
+ "WAITING",
1240
+ // Record created, waiting for client to upload zip to S3
1241
+ "UPLOADING",
1242
+ // Server is downloading from S3 and uploading to Vercel
1243
+ "QUEUED",
1244
+ // Vercel: deployment queued
1245
+ "BUILDING",
1246
+ // Vercel: deployment building
1247
+ "READY",
1248
+ // Vercel: deployment ready
1249
+ "ERROR",
1250
+ // Vercel: deployment failed
1251
+ "CANCELED"
1252
+ // Vercel: deployment canceled
1253
+ ]);
1254
+ var deploymentSchema = z21.object({
1255
+ id: z21.string().uuid(),
1256
+ providerDeploymentId: z21.string().nullable(),
1257
+ // Provider's deployment ID, null until deployment starts
1258
+ provider: z21.string(),
1259
+ status: deploymentStatusSchema,
1260
+ url: z21.string().nullable(),
1261
+ metadata: z21.record(z21.unknown()).nullable(),
1262
+ createdAt: z21.string().datetime(),
1263
+ updatedAt: z21.string().datetime()
1264
+ });
1265
+
1266
+ // node_modules/@insforge/shared-schemas/dist/deployments-api.schema.js
1267
+ import { z as z22 } from "zod";
1268
+ var projectSettingsSchema = z22.object({
1269
+ buildCommand: z22.string().nullable().optional(),
1270
+ outputDirectory: z22.string().nullable().optional(),
1271
+ installCommand: z22.string().nullable().optional(),
1272
+ devCommand: z22.string().nullable().optional(),
1273
+ rootDirectory: z22.string().nullable().optional()
1274
+ });
1275
+ var envVarSchema = z22.object({
1276
+ key: z22.string(),
1277
+ value: z22.string()
1278
+ });
1279
+ var createDeploymentResponseSchema = z22.object({
1280
+ id: z22.string().uuid(),
1281
+ uploadUrl: z22.string().url(),
1282
+ uploadFields: z22.record(z22.string())
1283
+ // Required for S3 presigned POST (policy, signature, key, etc.)
1284
+ });
1285
+ var startDeploymentRequestSchema = z22.object({
1286
+ projectSettings: projectSettingsSchema.optional(),
1287
+ envVars: z22.array(envVarSchema).optional(),
1288
+ meta: z22.record(z22.string()).optional()
1289
+ });
1290
+ var listDeploymentsResponseSchema = z22.object({
1291
+ data: z22.array(deploymentSchema),
1292
+ pagination: z22.object({
1293
+ limit: z22.number(),
1294
+ offset: z22.number(),
1295
+ total: z22.number()
1296
+ })
1297
+ });
1298
+
1299
+ // src/shared/tools.ts
1300
+ import FormData from "form-data";
1301
+ var execAsync = promisify(exec);
1302
+ var TOOL_VERSION_REQUIREMENTS = {
1303
+ // Schedule tools - require backend v1.1.1+
1304
+ // 'upsert-schedule': { minVersion: '1.1.1' },
1305
+ // 'delete-schedule': { minVersion: '1.1.1' },
1306
+ // 'get-schedules': { minVersion: '1.1.1' },
1307
+ // 'get-schedule-logs': { minVersion: '1.1.1' },
1308
+ "create-deployment": { minVersion: "1.4.7" }
1309
+ // 'fetch-sdk-docs': { minVersion: '1.4.7' },
1310
+ // Example of a deprecated tool (uncomment when needed):
1311
+ // 'legacy-tool': { minVersion: '1.0.0', maxVersion: '1.5.0' },
1312
+ };
1313
+ function compareVersions(v1, v2) {
1314
+ const clean1 = v1.replace(/^v/, "").split("-")[0];
1315
+ const clean2 = v2.replace(/^v/, "").split("-")[0];
1316
+ const parts1 = clean1.split(".").map(Number);
1317
+ const parts2 = clean2.split(".").map(Number);
1318
+ for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
1319
+ const part1 = parts1[i] || 0;
1320
+ const part2 = parts2[i] || 0;
1321
+ if (part1 > part2) return 1;
1322
+ if (part1 < part2) return -1;
1323
+ }
1324
+ return 0;
1325
+ }
1326
+ function shouldRegisterTool(toolName, backendVersion) {
1327
+ const requirement = TOOL_VERSION_REQUIREMENTS[toolName];
1328
+ if (!requirement) {
1329
+ return true;
1330
+ }
1331
+ const { minVersion, maxVersion } = requirement;
1332
+ if (minVersion && compareVersions(backendVersion, minVersion) < 0) {
1333
+ return false;
1334
+ }
1335
+ if (maxVersion && compareVersions(backendVersion, maxVersion) > 0) {
1336
+ return false;
1337
+ }
1338
+ return true;
1339
+ }
1340
+ async function fetchBackendVersion(apiBaseUrl) {
1341
+ const response = await fetch2(`${apiBaseUrl}/api/health`, {
1342
+ method: "GET",
1343
+ headers: {
1344
+ "Content-Type": "application/json"
1345
+ }
1346
+ });
1347
+ if (!response.ok) {
1348
+ throw new Error(`Health check failed with status ${response.status}`);
1349
+ }
1350
+ const health = await response.json();
1351
+ return health.version;
1352
+ }
1353
+ async function registerInsforgeTools(server, config = {}) {
1354
+ const GLOBAL_API_KEY = config.apiKey || process.env.API_KEY || "";
1355
+ const API_BASE_URL = config.apiBaseUrl || process.env.API_BASE_URL || "http://localhost:7130";
1356
+ const usageTracker = new UsageTracker(API_BASE_URL, GLOBAL_API_KEY);
1357
+ const backendVersion = await fetchBackendVersion(API_BASE_URL);
1358
+ console.error(`Backend version: ${backendVersion}`);
1359
+ let toolCount = 0;
1360
+ const registerTool = (toolName, ...args) => {
1361
+ if (shouldRegisterTool(toolName, backendVersion)) {
1362
+ server.tool(toolName, ...args);
1363
+ toolCount++;
1364
+ return true;
1365
+ } else {
1366
+ const req = TOOL_VERSION_REQUIREMENTS[toolName];
1367
+ const reason = req?.minVersion && compareVersions(backendVersion, req.minVersion) < 0 ? `requires backend >= ${req.minVersion}` : `deprecated after backend ${req?.maxVersion}`;
1368
+ console.error(`Skipping tool '${toolName}': ${reason} (current: ${backendVersion})`);
1369
+ return false;
1370
+ }
1371
+ };
1372
+ async function trackToolUsage(toolName, success = true) {
1373
+ if (GLOBAL_API_KEY) {
1374
+ await usageTracker.trackUsage(toolName, success);
1375
+ }
1376
+ }
1377
+ function withUsageTracking(toolName, handler) {
1378
+ return async (...args) => {
1379
+ try {
1380
+ const result = await handler(...args);
1381
+ await trackToolUsage(toolName, true);
1382
+ return result;
1383
+ } catch (error) {
1384
+ await trackToolUsage(toolName, false);
1385
+ throw error;
1386
+ }
1387
+ };
1388
+ }
1389
+ const getApiKey = (_toolApiKey) => {
1390
+ if (!GLOBAL_API_KEY) {
1391
+ throw new Error("API key is required. Pass --api_key when starting the MCP server.");
1392
+ }
1393
+ return GLOBAL_API_KEY;
1394
+ };
1395
+ const fetchDocumentation = async (docType) => {
1396
+ try {
1397
+ const response = await fetch2(`${API_BASE_URL}/api/docs/${docType}`, {
1398
+ method: "GET",
1399
+ headers: {
1400
+ "Content-Type": "application/json"
1401
+ }
1402
+ });
1403
+ if (response.status === 404) {
1404
+ throw new Error("Documentation not found. This feature may not be supported in your project version. Please contact the Insforge team for assistance.");
1405
+ }
1406
+ const result = await handleApiResponse(response);
1407
+ if (result && typeof result === "object" && "content" in result) {
1408
+ let content = result.content;
1409
+ content = content.replace(/http:\/\/localhost:7130/g, API_BASE_URL);
1410
+ content = content.replace(/https:\/\/your-app\.region\.insforge\.app/g, API_BASE_URL);
1411
+ content = content.replace(/https:\/\/your-app\.insforge\.app/g, API_BASE_URL);
1412
+ return content;
1413
+ }
1414
+ throw new Error("Invalid response format from documentation endpoint");
1415
+ } catch (error) {
1416
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1417
+ throw new Error(`Unable to retrieve ${docType} documentation: ${errMsg}`);
1418
+ }
1419
+ };
1420
+ const fetchSDKDocumentation = async (feature, language) => {
1421
+ try {
1422
+ const response = await fetch2(`${API_BASE_URL}/api/docs/${feature}/${language}`, {
1423
+ method: "GET",
1424
+ headers: {
1425
+ "Content-Type": "application/json"
1426
+ }
1427
+ });
1428
+ if (response.status === 404) {
1429
+ throw new Error("Documentation not found. This feature may not be supported in your project version. Please contact the Insforge team for assistance.");
1430
+ }
1431
+ const result = await handleApiResponse(response);
1432
+ if (result && typeof result === "object" && "content" in result) {
1433
+ let content = result.content;
1434
+ content = content.replace(/http:\/\/localhost:7130/g, API_BASE_URL);
1435
+ content = content.replace(/https:\/\/your-app\.region\.insforge\.app/g, API_BASE_URL);
1436
+ content = content.replace(/https:\/\/your-app\.insforge\.app/g, API_BASE_URL);
1437
+ return content;
1438
+ }
1439
+ throw new Error("Invalid response format from documentation endpoint");
1440
+ } catch (error) {
1441
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1442
+ throw new Error(`Unable to retrieve ${feature}-${language} documentation: ${errMsg}`);
1443
+ }
1444
+ };
1445
+ const fetchInsforgeInstructionsContext = async () => {
1446
+ try {
1447
+ return await fetchDocumentation("instructions");
1448
+ } catch (error) {
1449
+ console.error("Failed to fetch insforge-instructions.md:", error);
1450
+ return null;
1451
+ }
1452
+ };
1453
+ const addBackgroundContext = async (response) => {
1454
+ const isLegacyVersion = compareVersions(backendVersion, "1.1.7") < 0;
1455
+ if (isLegacyVersion) {
1456
+ const context = await fetchInsforgeInstructionsContext();
1457
+ if (context && response.content && Array.isArray(response.content)) {
1458
+ response.content.push({
1459
+ type: "text",
1460
+ text: `
1461
+
1462
+ ---
1463
+ \u{1F527} INSFORGE DEVELOPMENT RULES (Auto-loaded):
1464
+ ${context}`
1465
+ });
1466
+ }
1467
+ }
1468
+ return response;
1469
+ };
1470
+ registerTool(
1471
+ "fetch-docs",
1472
+ 'Fetch Insforge documentation. Use "instructions" for essential backend setup (MANDATORY FIRST), or select specific SDK docs for database, auth, storage, functions, or AI integration.',
1473
+ {
1474
+ docType: docTypeSchema
1475
+ },
1476
+ withUsageTracking("fetch-docs", async ({ docType }) => {
1477
+ try {
1478
+ const content = await fetchDocumentation(docType);
1479
+ return await addBackgroundContext({
1480
+ content: [
1481
+ {
1482
+ type: "text",
1483
+ text: content
1484
+ }
1485
+ ]
1486
+ });
1487
+ } catch (error) {
1488
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1489
+ if (errMsg.includes("404") || errMsg.toLowerCase().includes("not found")) {
1490
+ return {
1491
+ content: [{
1492
+ type: "text",
1493
+ text: `Documentation for "${docType}" is not available. This is likely because your backend version is too old and doesn't support this documentation endpoint yet. This won't affect the functionality of the tools - they will still work correctly.`
1494
+ }]
1495
+ };
1496
+ }
1497
+ return {
1498
+ content: [{ type: "text", text: `Error fetching ${docType} documentation: ${errMsg}` }]
1499
+ };
1500
+ }
1501
+ })
1502
+ );
1503
+ registerTool(
1504
+ "fetch-sdk-docs",
1505
+ `Fetch Insforge SDK documentation for a specific feature and language combination.
1506
+
1507
+ Supported features: ${sdkFeatureSchema.options.join(", ")}
1508
+ Supported languages: ${sdkLanguageSchema.options.join(", ")}`,
1509
+ {
1510
+ sdkFeature: sdkFeatureSchema,
1511
+ sdkLanguage: sdkLanguageSchema
1512
+ },
1513
+ withUsageTracking("fetch-sdk-docs", async ({ sdkFeature, sdkLanguage }) => {
1514
+ try {
1515
+ const content = await fetchSDKDocumentation(sdkFeature, sdkLanguage);
1516
+ return await addBackgroundContext({
1517
+ content: [
1518
+ {
1519
+ type: "text",
1520
+ text: content
1521
+ }
1522
+ ]
1523
+ });
1524
+ } catch (error) {
1525
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1526
+ if (errMsg.includes("404") || errMsg.toLowerCase().includes("not found")) {
1527
+ return {
1528
+ content: [{
1529
+ type: "text",
1530
+ text: `Documentation for "${sdkFeature}-${sdkLanguage}" is not available. This is likely because your backend version is too old and doesn't support this documentation endpoint yet. This won't affect the functionality of the tools - they will still work correctly.`
1531
+ }]
1532
+ };
1533
+ }
1534
+ return {
1535
+ content: [{ type: "text", text: `Error fetching ${sdkFeature}-${sdkLanguage} documentation: ${errMsg}` }]
1536
+ };
1537
+ }
1538
+ })
1539
+ );
1540
+ registerTool(
1541
+ "get-anon-key",
1542
+ "Generate an anonymous JWT token that never expires. Requires admin API key. Use this for client-side applications that need public access.",
1543
+ {
1544
+ apiKey: z23.string().optional().describe("API key for authentication (optional if provided via --api_key)")
1545
+ },
1546
+ withUsageTracking("get-anon-key", async ({ apiKey }) => {
1547
+ try {
1548
+ const actualApiKey = getApiKey(apiKey);
1549
+ const response = await fetch2(`${API_BASE_URL}/api/auth/tokens/anon`, {
1550
+ method: "POST",
1551
+ headers: {
1552
+ "x-api-key": actualApiKey,
1553
+ "Content-Type": "application/json"
1554
+ }
1555
+ });
1556
+ const result = await handleApiResponse(response);
1557
+ return await addBackgroundContext({
1558
+ content: [
1559
+ {
1560
+ type: "text",
1561
+ text: formatSuccessMessage("Anonymous token generated", result)
1562
+ }
1563
+ ]
1564
+ });
1565
+ } catch (error) {
1566
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1567
+ return {
1568
+ content: [
1569
+ {
1570
+ type: "text",
1571
+ text: `Error generating anonymous token: ${errMsg}`
1572
+ }
1573
+ ],
1574
+ isError: true
1575
+ };
1576
+ }
1577
+ })
1578
+ );
1579
+ registerTool(
1580
+ "get-table-schema",
1581
+ "Returns the detailed schema(including RLS, indexes, constraints, etc.) of a specific table",
1582
+ {
1583
+ apiKey: z23.string().optional().describe("API key for authentication (optional if provided via --api_key)"),
1584
+ tableName: z23.string().describe("Name of the table")
1585
+ },
1586
+ withUsageTracking("get-table-schema", async ({ apiKey, tableName }) => {
1587
+ try {
1588
+ const actualApiKey = getApiKey(apiKey);
1589
+ const response = await fetch2(`${API_BASE_URL}/api/metadata/${tableName}`, {
1590
+ method: "GET",
1591
+ headers: {
1592
+ "x-api-key": actualApiKey
1593
+ }
1594
+ });
1595
+ const result = await handleApiResponse(response);
1596
+ return await addBackgroundContext({
1597
+ content: [
1598
+ {
1599
+ type: "text",
1600
+ text: formatSuccessMessage("Schema retrieved", result)
1601
+ }
1602
+ ]
1603
+ });
1604
+ } catch (error) {
1605
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1606
+ return {
1607
+ content: [
1608
+ {
1609
+ type: "text",
1610
+ text: `Error getting table schema: ${errMsg}`
1611
+ }
1612
+ ],
1613
+ isError: true
1614
+ };
1615
+ }
1616
+ })
1617
+ );
1618
+ registerTool(
1619
+ "get-backend-metadata",
1620
+ "Index all backend metadata",
1621
+ {
1622
+ apiKey: z23.string().optional().describe("API key for authentication (optional if provided via --api_key)")
1623
+ },
1624
+ withUsageTracking("get-backend-metadata", async ({ apiKey }) => {
1625
+ try {
1626
+ const actualApiKey = getApiKey(apiKey);
1627
+ const response = await fetch2(`${API_BASE_URL}/api/metadata?mcp=true`, {
1628
+ method: "GET",
1629
+ headers: {
1630
+ "x-api-key": actualApiKey
1631
+ }
1632
+ });
1633
+ const metadata = await handleApiResponse(response);
1634
+ return await addBackgroundContext({
1635
+ content: [
1636
+ {
1637
+ type: "text",
1638
+ text: `Backend metadata:
1639
+
1640
+ ${JSON.stringify(metadata, null, 2)}`
1641
+ }
1642
+ ]
1643
+ });
1644
+ } catch (error) {
1645
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1646
+ return {
1647
+ content: [
1648
+ {
1649
+ type: "text",
1650
+ text: `Error retrieving backend metadata: ${errMsg}`
1651
+ }
1652
+ ],
1653
+ isError: true
1654
+ };
1655
+ }
1656
+ })
1657
+ );
1658
+ registerTool(
1659
+ "run-raw-sql",
1660
+ "Execute raw SQL query with optional parameters. Admin access required. Use with caution as it can modify data directly.",
1661
+ {
1662
+ apiKey: z23.string().optional().describe("API key for authentication (optional if provided via --api_key)"),
1663
+ ...rawSQLRequestSchema.shape
1664
+ },
1665
+ withUsageTracking("run-raw-sql", async ({ apiKey, query, params }) => {
1666
+ try {
1667
+ const actualApiKey = getApiKey(apiKey);
1668
+ const requestBody = {
1669
+ query,
1670
+ params: params || []
1671
+ };
1672
+ const response = await fetch2(`${API_BASE_URL}/api/database/advance/rawsql`, {
1673
+ method: "POST",
1674
+ headers: {
1675
+ "x-api-key": actualApiKey,
1676
+ "Content-Type": "application/json"
1677
+ },
1678
+ body: JSON.stringify(requestBody)
1679
+ });
1680
+ const result = await handleApiResponse(response);
1681
+ return await addBackgroundContext({
1682
+ content: [
1683
+ {
1684
+ type: "text",
1685
+ text: formatSuccessMessage("SQL query executed", result)
1686
+ }
1687
+ ]
1688
+ });
1689
+ } catch (error) {
1690
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1691
+ return {
1692
+ content: [
1693
+ {
1694
+ type: "text",
1695
+ text: `Error executing SQL query: ${errMsg}`
1696
+ }
1697
+ ],
1698
+ isError: true
1699
+ };
1700
+ }
1701
+ })
1702
+ );
1703
+ registerTool(
1704
+ "download-template",
1705
+ "CRITICAL: MANDATORY FIRST STEP for all new InsForge projects. Download pre-configured starter template to a temporary directory. After download, you MUST copy files to current directory using the provided command.",
1706
+ {
1707
+ frame: z23.enum(["react", "nextjs"]).describe("Framework to use for the template (support React and Next.js)"),
1708
+ projectName: z23.string().optional().describe('Name for the project directory (optional, defaults to "insforge-react")')
1709
+ },
1710
+ withUsageTracking("download-template", async ({ frame, projectName }) => {
1711
+ try {
1712
+ const response = await fetch2(`${API_BASE_URL}/api/auth/tokens/anon`, {
1713
+ method: "POST",
1714
+ headers: {
1715
+ "x-api-key": getApiKey(),
1716
+ "Content-Type": "application/json"
1717
+ }
1718
+ });
1719
+ const result = await handleApiResponse(response);
1720
+ const anonKey = result.accessToken;
1721
+ if (!anonKey) {
1722
+ throw new Error("Failed to retrieve anon key from backend");
1723
+ }
1724
+ const tempDir = tmpdir();
1725
+ const targetDir = projectName || `insforge-${frame}`;
1726
+ const templatePath = `${tempDir}/${targetDir}`;
1727
+ console.error(`[download-template] Target path: ${templatePath}`);
1728
+ try {
1729
+ const stats = await fs.stat(templatePath);
1730
+ if (stats.isDirectory()) {
1731
+ console.error(`[download-template] Removing existing template at ${templatePath}`);
1732
+ await fs.rm(templatePath, { recursive: true, force: true });
1733
+ }
1734
+ } catch {
1735
+ }
1736
+ const command = `npx create-insforge-app ${targetDir} --frame ${frame} --base-url ${API_BASE_URL} --anon-key ${anonKey} --skip-install`;
1737
+ const { stdout, stderr } = await execAsync(command, {
1738
+ maxBuffer: 10 * 1024 * 1024,
1739
+ // 10MB buffer
1740
+ cwd: tempDir
1741
+ });
1742
+ const output = stdout || stderr || "";
1743
+ if (output.toLowerCase().includes("error") && !output.includes("successfully")) {
1744
+ throw new Error(`Failed to download template: ${output}`);
1745
+ }
1746
+ return await addBackgroundContext({
1747
+ content: [
1748
+ {
1749
+ type: "text",
1750
+ text: `\u2705 React template downloaded successfully
1751
+
1752
+ \u{1F4C1} Template Location: ${templatePath}
1753
+
1754
+ \u26A0\uFE0F IMPORTANT: The template is in a temporary directory and NOT in your current working directory.
1755
+
1756
+ \u{1F534} CRITICAL NEXT STEP REQUIRED:
1757
+ You MUST copy ALL files (INCLUDING HIDDEN FILES like .env, .gitignore, etc.) from the temporary directory to your current project directory.
1758
+
1759
+ Copy all files from: ${templatePath}
1760
+ To: Your current project directory
1761
+ `
1762
+ }
1763
+ ]
1764
+ });
1765
+ } catch (error) {
1766
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1767
+ return {
1768
+ content: [
1769
+ {
1770
+ type: "text",
1771
+ text: `Error downloading template: ${errMsg}`
1772
+ }
1773
+ ],
1774
+ isError: true
1775
+ };
1776
+ }
1777
+ })
1778
+ );
1779
+ registerTool(
1780
+ "bulk-upsert",
1781
+ "Bulk insert or update data from CSV or JSON file. Supports upsert operations with a unique key.",
1782
+ {
1783
+ apiKey: z23.string().optional().describe("API key for authentication (optional if provided via --api_key)"),
1784
+ ...bulkUpsertRequestSchema.shape,
1785
+ filePath: z23.string().describe("Path to CSV or JSON file containing data to import")
1786
+ },
1787
+ withUsageTracking("bulk-upsert", async ({ apiKey, table, filePath, upsertKey }) => {
1788
+ try {
1789
+ const actualApiKey = getApiKey(apiKey);
1790
+ const fileBuffer = await fs.readFile(filePath);
1791
+ const fileName = filePath.split("/").pop() || "data.csv";
1792
+ const formData = new FormData();
1793
+ formData.append("file", fileBuffer, fileName);
1794
+ formData.append("table", table);
1795
+ if (upsertKey) {
1796
+ formData.append("upsertKey", upsertKey);
1797
+ }
1798
+ const response = await fetch2(`${API_BASE_URL}/api/database/advance/bulk-upsert`, {
1799
+ method: "POST",
1800
+ headers: {
1801
+ "x-api-key": actualApiKey,
1802
+ ...formData.getHeaders()
1803
+ },
1804
+ body: formData
1805
+ });
1806
+ const result = await handleApiResponse(response);
1807
+ const message = result.success ? `Successfully processed ${result.rowsAffected} of ${result.totalRecords} records into table "${result.table}"` : result.message || "Bulk upsert operation completed";
1808
+ return await addBackgroundContext({
1809
+ content: [
1810
+ {
1811
+ type: "text",
1812
+ text: formatSuccessMessage("Bulk upsert completed", {
1813
+ message,
1814
+ table: result.table,
1815
+ rowsAffected: result.rowsAffected,
1816
+ totalRecords: result.totalRecords,
1817
+ errors: result.errors
1818
+ })
1819
+ }
1820
+ ]
1821
+ });
1822
+ } catch (error) {
1823
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1824
+ return {
1825
+ content: [
1826
+ {
1827
+ type: "text",
1828
+ text: `Error performing bulk upsert: ${errMsg}`
1829
+ }
1830
+ ],
1831
+ isError: true
1832
+ };
1833
+ }
1834
+ })
1835
+ );
1836
+ registerTool(
1837
+ "create-bucket",
1838
+ "Create new storage bucket",
1839
+ {
1840
+ apiKey: z23.string().optional().describe("API key for authentication (optional if provided via --api_key)"),
1841
+ ...createBucketRequestSchema.shape
1842
+ },
1843
+ withUsageTracking("create-bucket", async ({ apiKey, bucketName, isPublic }) => {
1844
+ try {
1845
+ const actualApiKey = getApiKey(apiKey);
1846
+ const response = await fetch2(`${API_BASE_URL}/api/storage/buckets`, {
1847
+ method: "POST",
1848
+ headers: {
1849
+ "x-api-key": actualApiKey,
1850
+ "Content-Type": "application/json"
1851
+ },
1852
+ body: JSON.stringify({ bucketName, isPublic })
1853
+ });
1854
+ const result = await handleApiResponse(response);
1855
+ return await addBackgroundContext({
1856
+ content: [
1857
+ {
1858
+ type: "text",
1859
+ text: formatSuccessMessage("Bucket created", result)
1860
+ }
1861
+ ]
1862
+ });
1863
+ } catch (error) {
1864
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1865
+ return {
1866
+ content: [
1867
+ {
1868
+ type: "text",
1869
+ text: `Error creating bucket: ${errMsg}`
1870
+ }
1871
+ ],
1872
+ isError: true
1873
+ };
1874
+ }
1875
+ })
1876
+ );
1877
+ registerTool(
1878
+ "list-buckets",
1879
+ "Lists all storage buckets",
1880
+ {},
1881
+ withUsageTracking("list-buckets", async () => {
1882
+ try {
1883
+ const response = await fetch2(`${API_BASE_URL}/api/storage/buckets`, {
1884
+ method: "GET",
1885
+ headers: {
1886
+ "x-api-key": getApiKey()
1887
+ }
1888
+ });
1889
+ const result = await handleApiResponse(response);
1890
+ return await addBackgroundContext({
1891
+ content: [
1892
+ {
1893
+ type: "text",
1894
+ text: formatSuccessMessage("Buckets retrieved", result)
1895
+ }
1896
+ ]
1897
+ });
1898
+ } catch (error) {
1899
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1900
+ return {
1901
+ content: [
1902
+ {
1903
+ type: "text",
1904
+ text: `Error listing buckets: ${errMsg}`
1905
+ }
1906
+ ],
1907
+ isError: true
1908
+ };
1909
+ }
1910
+ })
1911
+ );
1912
+ registerTool(
1913
+ "delete-bucket",
1914
+ "Deletes a storage bucket",
1915
+ {
1916
+ apiKey: z23.string().optional().describe("API key for authentication (optional if provided via --api_key)"),
1917
+ bucketName: z23.string().describe("Name of the bucket to delete")
1918
+ },
1919
+ withUsageTracking("delete-bucket", async ({ apiKey, bucketName }) => {
1920
+ try {
1921
+ const actualApiKey = getApiKey(apiKey);
1922
+ const response = await fetch2(`${API_BASE_URL}/api/storage/buckets/${bucketName}`, {
1923
+ method: "DELETE",
1924
+ headers: {
1925
+ "x-api-key": actualApiKey
1926
+ }
1927
+ });
1928
+ const result = await handleApiResponse(response);
1929
+ return await addBackgroundContext({
1930
+ content: [
1931
+ {
1932
+ type: "text",
1933
+ text: formatSuccessMessage("Bucket deleted", result)
1934
+ }
1935
+ ]
1936
+ });
1937
+ } catch (error) {
1938
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1939
+ return {
1940
+ content: [
1941
+ {
1942
+ type: "text",
1943
+ text: `Error deleting bucket: ${errMsg}`
1944
+ }
1945
+ ],
1946
+ isError: true
1947
+ };
1948
+ }
1949
+ })
1950
+ );
1951
+ registerTool(
1952
+ "create-function",
1953
+ "Create a new edge function that runs in Deno runtime. The code must be written to a file first for version control",
1954
+ {
1955
+ ...uploadFunctionRequestSchema.omit({ code: true }).shape,
1956
+ codeFile: z23.string().describe(
1957
+ "Path to JavaScript file containing the function code. Must export: module.exports = async function(request) { return new Response(...) }"
1958
+ )
1959
+ },
1960
+ withUsageTracking("create-function", async (args) => {
1961
+ try {
1962
+ let code;
1963
+ try {
1964
+ code = await fs.readFile(args.codeFile, "utf-8");
1965
+ } catch (fileError) {
1966
+ throw new Error(
1967
+ `Failed to read code file '${args.codeFile}': ${fileError instanceof Error ? fileError.message : "Unknown error"}`
1968
+ );
1969
+ }
1970
+ const response = await fetch2(`${API_BASE_URL}/api/functions`, {
1971
+ method: "POST",
1972
+ headers: {
1973
+ "Content-Type": "application/json",
1974
+ "x-api-key": getApiKey()
1975
+ },
1976
+ body: JSON.stringify({
1977
+ slug: args.slug,
1978
+ name: args.name,
1979
+ code,
1980
+ description: args.description,
1981
+ status: args.status
1982
+ })
1983
+ });
1984
+ const result = await handleApiResponse(response);
1985
+ return await addBackgroundContext({
1986
+ content: [
1987
+ {
1988
+ type: "text",
1989
+ text: formatSuccessMessage(
1990
+ `Edge function '${args.slug}' created successfully from ${args.codeFile}`,
1991
+ result
1992
+ )
1993
+ }
1994
+ ]
1995
+ });
1996
+ } catch (error) {
1997
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1998
+ return {
1999
+ content: [
2000
+ {
2001
+ type: "text",
2002
+ text: `Error creating function: ${errMsg}`
2003
+ }
2004
+ ],
2005
+ isError: true
2006
+ };
2007
+ }
2008
+ })
2009
+ );
2010
+ registerTool(
2011
+ "get-function",
2012
+ "Get details of a specific edge function including its code",
2013
+ {
2014
+ slug: z23.string().describe("The slug identifier of the function")
2015
+ },
2016
+ withUsageTracking("get-function", async (args) => {
2017
+ try {
2018
+ const response = await fetch2(`${API_BASE_URL}/api/functions/${args.slug}`, {
2019
+ method: "GET",
2020
+ headers: {
2021
+ "x-api-key": getApiKey()
2022
+ }
2023
+ });
2024
+ const result = await handleApiResponse(response);
2025
+ return await addBackgroundContext({
2026
+ content: [
2027
+ {
2028
+ type: "text",
2029
+ text: formatSuccessMessage(`Edge function '${args.slug}' details`, result)
2030
+ }
2031
+ ]
2032
+ });
2033
+ } catch (error) {
2034
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
2035
+ return {
2036
+ content: [
2037
+ {
2038
+ type: "text",
2039
+ text: `Error getting function: ${errMsg}`
2040
+ }
2041
+ ],
2042
+ isError: true
2043
+ };
2044
+ }
2045
+ })
2046
+ );
2047
+ registerTool(
2048
+ "update-function",
2049
+ "Update an existing edge function code or metadata",
2050
+ {
2051
+ slug: z23.string().describe("The slug identifier of the function to update"),
2052
+ ...updateFunctionRequestSchema.omit({ code: true }).shape,
2053
+ codeFile: z23.string().optional().describe(
2054
+ "Path to JavaScript file containing the new function code. Must export: module.exports = async function(request) { return new Response(...) }"
2055
+ )
2056
+ },
2057
+ withUsageTracking("update-function", async (args) => {
2058
+ try {
2059
+ const updateData = {};
2060
+ if (args.name) {
2061
+ updateData.name = args.name;
2062
+ }
2063
+ if (args.codeFile) {
2064
+ try {
2065
+ updateData.code = await fs.readFile(args.codeFile, "utf-8");
2066
+ } catch (fileError) {
2067
+ throw new Error(
2068
+ `Failed to read code file '${args.codeFile}': ${fileError instanceof Error ? fileError.message : "Unknown error"}`
2069
+ );
2070
+ }
2071
+ }
2072
+ if (args.description !== void 0) {
2073
+ updateData.description = args.description;
2074
+ }
2075
+ if (args.status) {
2076
+ updateData.status = args.status;
2077
+ }
2078
+ const response = await fetch2(`${API_BASE_URL}/api/functions/${args.slug}`, {
2079
+ method: "PUT",
2080
+ headers: {
2081
+ "Content-Type": "application/json",
2082
+ "x-api-key": getApiKey()
2083
+ },
2084
+ body: JSON.stringify(updateData)
2085
+ });
2086
+ const result = await handleApiResponse(response);
2087
+ const fileInfo = args.codeFile ? ` from ${args.codeFile}` : "";
2088
+ return await addBackgroundContext({
2089
+ content: [
2090
+ {
2091
+ type: "text",
2092
+ text: formatSuccessMessage(
2093
+ `Edge function '${args.slug}' updated successfully${fileInfo}`,
2094
+ result
2095
+ )
2096
+ }
2097
+ ]
2098
+ });
2099
+ } catch (error) {
2100
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
2101
+ return {
2102
+ content: [
2103
+ {
2104
+ type: "text",
2105
+ text: `Error updating function: ${errMsg}`
2106
+ }
2107
+ ],
2108
+ isError: true
2109
+ };
2110
+ }
2111
+ })
2112
+ );
2113
+ registerTool(
2114
+ "delete-function",
2115
+ "Delete an edge function permanently",
2116
+ {
2117
+ slug: z23.string().describe("The slug identifier of the function to delete")
2118
+ },
2119
+ withUsageTracking("delete-function", async (args) => {
2120
+ try {
2121
+ const response = await fetch2(`${API_BASE_URL}/api/functions/${args.slug}`, {
2122
+ method: "DELETE",
2123
+ headers: {
2124
+ "x-api-key": getApiKey()
2125
+ }
2126
+ });
2127
+ const result = await handleApiResponse(response);
2128
+ return await addBackgroundContext({
2129
+ content: [
2130
+ {
2131
+ type: "text",
2132
+ text: formatSuccessMessage(`Edge function '${args.slug}' deleted successfully`, result)
2133
+ }
2134
+ ]
2135
+ });
2136
+ } catch (error) {
2137
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
2138
+ return {
2139
+ content: [
2140
+ {
2141
+ type: "text",
2142
+ text: `Error deleting function: ${errMsg}`
2143
+ }
2144
+ ],
2145
+ isError: true
2146
+ };
2147
+ }
2148
+ })
2149
+ );
2150
+ registerTool(
2151
+ "get-container-logs",
2152
+ "Get latest logs from a specific container/service. Use this to help debug problems with your app.",
2153
+ {
2154
+ apiKey: z23.string().optional().describe("API key for authentication (optional if provided via --api_key)"),
2155
+ source: z23.enum(["insforge.logs", "postgREST.logs", "postgres.logs", "function.logs"]).describe("Log source to retrieve"),
2156
+ limit: z23.number().optional().default(20).describe("Number of logs to return (default: 20)")
2157
+ },
2158
+ withUsageTracking("get-container-logs", async ({ apiKey, source, limit }) => {
2159
+ try {
2160
+ const actualApiKey = getApiKey(apiKey);
2161
+ const queryParams = new URLSearchParams();
2162
+ if (limit) queryParams.append("limit", limit.toString());
2163
+ let response = await fetch2(`${API_BASE_URL}/api/logs/${source}?${queryParams}`, {
2164
+ method: "GET",
2165
+ headers: {
2166
+ "x-api-key": actualApiKey
2167
+ }
2168
+ });
2169
+ if (response.status === 404) {
2170
+ response = await fetch2(`${API_BASE_URL}/api/logs/analytics/${source}?${queryParams}`, {
2171
+ method: "GET",
2172
+ headers: {
2173
+ "x-api-key": actualApiKey
2174
+ }
2175
+ });
2176
+ }
2177
+ const result = await handleApiResponse(response);
2178
+ return await addBackgroundContext({
2179
+ content: [
2180
+ {
2181
+ type: "text",
2182
+ text: formatSuccessMessage(`Latest logs from ${source}`, result)
2183
+ }
2184
+ ]
2185
+ });
2186
+ } catch (error) {
2187
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
2188
+ return {
2189
+ content: [
2190
+ {
2191
+ type: "text",
2192
+ text: `Error retrieving container logs: ${errMsg}`
2193
+ }
2194
+ ],
2195
+ isError: true
2196
+ };
2197
+ }
2198
+ })
2199
+ );
2200
+ registerTool(
2201
+ "create-deployment",
2202
+ "Deploy source code from a directory. This tool zips files, uploads to cloud storage, and triggers deployment with optional environment variables and project settings.",
2203
+ {
2204
+ sourceDirectory: z23.string().describe('Absolute path to the source directory containing files to deploy (e.g., /Users/name/project or C:\\Users\\name\\project). Do not use relative paths like "."'),
2205
+ ...startDeploymentRequestSchema.shape
2206
+ },
2207
+ withUsageTracking("create-deployment", async ({ sourceDirectory, projectSettings, envVars, meta }) => {
2208
+ try {
2209
+ const isAbsolutePath = sourceDirectory.startsWith("/") || /^[a-zA-Z]:[/\\]/.test(sourceDirectory);
2210
+ if (!isAbsolutePath) {
2211
+ return {
2212
+ content: [
2213
+ {
2214
+ type: "text",
2215
+ text: `Error: sourceDirectory must be an absolute path, not a relative path like "${sourceDirectory}". Please provide the full path to the source directory (e.g., /Users/name/project on macOS/Linux or C:\\Users\\name\\project on Windows).`
2216
+ }
2217
+ ],
2218
+ isError: true
2219
+ };
2220
+ }
2221
+ try {
2222
+ const stats = await fs.stat(sourceDirectory);
2223
+ if (!stats.isDirectory()) {
2224
+ return {
2225
+ content: [
2226
+ {
2227
+ type: "text",
2228
+ text: `Error: "${sourceDirectory}" is not a directory. Please provide a path to a directory containing the source code.`
2229
+ }
2230
+ ],
2231
+ isError: true
2232
+ };
2233
+ }
2234
+ } catch (statError) {
2235
+ return {
2236
+ content: [
2237
+ {
2238
+ type: "text",
2239
+ text: `Error: Directory "${sourceDirectory}" does not exist or is not accessible. Please verify the path is correct.`
2240
+ }
2241
+ ],
2242
+ isError: true
2243
+ };
2244
+ }
2245
+ const resolvedSourceDir = sourceDirectory;
2246
+ const createResponse = await fetch2(`${API_BASE_URL}/api/deployments`, {
2247
+ method: "POST",
2248
+ headers: {
2249
+ "x-api-key": getApiKey(),
2250
+ "Content-Type": "application/json"
2251
+ }
2252
+ });
2253
+ const createResult = await handleApiResponse(createResponse);
2254
+ const { id: deploymentId, uploadUrl, uploadFields } = createResult;
2255
+ const zipBuffer = await new Promise((resolve, reject) => {
2256
+ const archive = archiver("zip", { zlib: { level: 9 } });
2257
+ const chunks = [];
2258
+ archive.on("data", (chunk) => chunks.push(chunk));
2259
+ archive.on("end", () => resolve(Buffer.concat(chunks)));
2260
+ archive.on("error", (err) => reject(err));
2261
+ const excludePatterns = [
2262
+ "node_modules",
2263
+ ".git",
2264
+ ".next",
2265
+ ".env",
2266
+ ".env.local",
2267
+ "dist",
2268
+ "build",
2269
+ ".DS_Store"
2270
+ ];
2271
+ archive.directory(resolvedSourceDir, false, (entry) => {
2272
+ const normalizedName = entry.name.replace(/\\/g, "/");
2273
+ for (const pattern of excludePatterns) {
2274
+ if (normalizedName.startsWith(pattern + "/") || normalizedName === pattern || normalizedName.endsWith("/" + pattern) || normalizedName.includes("/" + pattern + "/")) {
2275
+ return false;
2276
+ }
2277
+ }
2278
+ if (normalizedName.endsWith(".log")) {
2279
+ return false;
2280
+ }
2281
+ return entry;
2282
+ });
2283
+ archive.finalize();
2284
+ });
2285
+ const uploadFormData = new FormData();
2286
+ for (const [key, value] of Object.entries(uploadFields)) {
2287
+ uploadFormData.append(key, value);
2288
+ }
2289
+ uploadFormData.append("file", zipBuffer, {
2290
+ filename: "deployment.zip",
2291
+ contentType: "application/zip"
2292
+ });
2293
+ const uploadResponse = await fetch2(uploadUrl, {
2294
+ method: "POST",
2295
+ body: uploadFormData,
2296
+ headers: uploadFormData.getHeaders()
2297
+ });
2298
+ if (!uploadResponse.ok) {
2299
+ const uploadError = await uploadResponse.text();
2300
+ throw new Error(`Failed to upload zip file: ${uploadError}`);
2301
+ }
2302
+ const startBody = {};
2303
+ if (projectSettings) startBody.projectSettings = projectSettings;
2304
+ if (envVars) startBody.envVars = envVars;
2305
+ if (meta) startBody.meta = meta;
2306
+ const startResponse = await fetch2(`${API_BASE_URL}/api/deployments/${deploymentId}/start`, {
2307
+ method: "POST",
2308
+ headers: {
2309
+ "x-api-key": getApiKey(),
2310
+ "Content-Type": "application/json"
2311
+ },
2312
+ body: JSON.stringify(startBody)
2313
+ });
2314
+ const startResult = await handleApiResponse(startResponse);
2315
+ return await addBackgroundContext({
2316
+ content: [
2317
+ {
2318
+ type: "text",
2319
+ text: formatSuccessMessage("Deployment started", startResult) + "\n\nNote: You can check deployment status by querying the system.deployments table."
2320
+ }
2321
+ ]
2322
+ });
2323
+ } catch (error) {
2324
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
2325
+ return {
2326
+ content: [
2327
+ {
2328
+ type: "text",
2329
+ text: `Error creating deployment: ${errMsg}`
2330
+ }
2331
+ ],
2332
+ isError: true
2333
+ };
2334
+ }
2335
+ })
2336
+ );
2337
+ return {
2338
+ apiKey: GLOBAL_API_KEY,
2339
+ apiBaseUrl: API_BASE_URL,
2340
+ toolCount,
2341
+ backendVersion
2342
+ };
2343
+ }
2344
+
2345
+ export {
2346
+ registerInsforgeTools
2347
+ };