@insforge/mcp 1.1.6 → 1.1.7-dev.10

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.
@@ -161,10 +161,11 @@ var deleteTableResponse = z2.object({
161
161
  });
162
162
  var rawSQLRequestSchema = z2.object({
163
163
  query: z2.string().min(1, "Query is required"),
164
- params: z2.array(z2.any()).optional()
164
+ params: z2.array(z2.unknown()).optional()
165
+ // z.unknown() generates JSON Schema with items: {}
165
166
  });
166
167
  var rawSQLResponseSchema = z2.object({
167
- rows: z2.array(z2.any()),
168
+ rows: z2.array(z2.record(z2.string(), z2.unknown())),
168
169
  rowCount: z2.number().nullable(),
169
170
  fields: z2.array(z2.object({
170
171
  name: z2.string(),
@@ -222,7 +223,8 @@ var exportJsonDataSchema = z2.object({
222
223
  newTable: z2.string().nullable(),
223
224
  oldTable: z2.string().nullable()
224
225
  })),
225
- rows: z2.array(z2.any()).optional()
226
+ rows: z2.array(z2.record(z2.string(), z2.unknown())).optional(),
227
+ recordCount: z2.number().optional()
226
228
  })),
227
229
  functions: z2.array(z2.object({
228
230
  functionName: z2.string(),
@@ -364,7 +366,19 @@ var userSchema = z5.object({
364
366
  updatedAt: z5.string()
365
367
  // PostgreSQL timestamp
366
368
  });
367
- var oAuthProvidersSchema = z5.enum(["google", "github"]);
369
+ var oAuthProvidersSchema = z5.enum([
370
+ "google",
371
+ "github",
372
+ "discord",
373
+ "linkedin",
374
+ "facebook",
375
+ "instagram",
376
+ "tiktok",
377
+ "apple",
378
+ "x",
379
+ "spotify",
380
+ "microsoft"
381
+ ]);
368
382
  var oAuthStateSchema = z5.object({
369
383
  provider: oAuthProvidersSchema,
370
384
  redirectUri: z5.string().url().optional()
@@ -462,15 +476,20 @@ var authMetadataSchema = z7.object({
462
476
  oauths: z7.array(oAuthConfigSchema)
463
477
  });
464
478
  var databaseMetadataSchema = z7.object({
465
- tables: z7.array(tableSchema),
466
- totalSize: z7.number()
479
+ tables: z7.array(z7.object({
480
+ schema: z7.string(),
481
+ tableName: z7.string(),
482
+ recordCount: z7.number()
483
+ })),
484
+ totalSizeInGB: z7.number(),
485
+ hint: z7.string().optional()
467
486
  });
468
487
  var bucketMetadataSchema = storageBucketSchema.extend({
469
488
  objectCount: z7.number().optional()
470
489
  });
471
490
  var storageMetadataSchema = z7.object({
472
491
  buckets: z7.array(bucketMetadataSchema),
473
- totalSize: z7.number()
492
+ totalSizeInGB: z7.number()
474
493
  });
475
494
  var edgeFunctionMetadataSchema = z7.object({
476
495
  slug: z7.string(),
@@ -583,44 +602,13 @@ var imageGenerationResponseSchema = z9.object({
583
602
  }).optional()
584
603
  }).optional()
585
604
  });
586
- var openRouterModelSchema = z9.object({
605
+ var aiModelSchema = z9.object({
587
606
  id: z9.string(),
588
- name: z9.string(),
589
- created: z9.number(),
590
- description: z9.string().optional(),
591
- architecture: z9.object({
592
- inputModalities: z9.array(z9.string()),
593
- outputModalities: z9.array(z9.string()),
594
- tokenizer: z9.string(),
595
- instructType: z9.string()
596
- }).optional(),
597
- topProvider: z9.object({
598
- isModerated: z9.boolean(),
599
- contextLength: z9.number(),
600
- maxCompletionTokens: z9.number()
601
- }).optional(),
602
- pricing: z9.object({
603
- prompt: z9.string(),
604
- completion: z9.string(),
605
- image: z9.string().optional(),
606
- request: z9.string().optional(),
607
- webSearch: z9.string().optional(),
608
- internalReasoning: z9.string().optional(),
609
- inputCacheRead: z9.string().optional(),
610
- inputCacheWrite: z9.string().optional()
611
- })
612
- });
613
- var listModelsResponseSchema = z9.object({
614
- text: z9.array(z9.object({
615
- provider: z9.string(),
616
- configured: z9.boolean(),
617
- models: z9.array(openRouterModelSchema)
618
- })),
619
- image: z9.array(z9.object({
620
- provider: z9.string(),
621
- configured: z9.boolean(),
622
- models: z9.array(openRouterModelSchema)
623
- }))
607
+ inputModality: z9.array(modalitySchema).min(1),
608
+ outputModality: z9.array(modalitySchema).min(1),
609
+ provider: z9.string(),
610
+ modelId: z9.string(),
611
+ priceLevel: z9.number().min(0).max(3).optional()
624
612
  });
625
613
  var createAIConfigurationRequestSchema = aiConfigurationSchema.omit({
626
614
  id: true
@@ -656,6 +644,23 @@ var auditLogSchema = z10.object({
656
644
  createdAt: z10.string(),
657
645
  updatedAt: z10.string()
658
646
  });
647
+ var logSourceSchema = z10.object({
648
+ id: z10.string(),
649
+ name: z10.string(),
650
+ token: z10.string()
651
+ });
652
+ var logSchema = z10.object({
653
+ id: z10.string(),
654
+ eventMessage: z10.string(),
655
+ timestamp: z10.string(),
656
+ body: z10.record(z10.string(), z10.unknown()),
657
+ source: z10.string().optional()
658
+ });
659
+ var logStatsSchema = z10.object({
660
+ source: z10.string(),
661
+ count: z10.number(),
662
+ lastActivity: z10.string()
663
+ });
659
664
 
660
665
  // node_modules/@insforge/shared-schemas/dist/logs-api.schema.js
661
666
  import { z as z11 } from "zod";
@@ -693,6 +698,10 @@ var clearAuditLogsResponseSchema = z11.object({
693
698
  message: z11.string(),
694
699
  deleted: z11.number()
695
700
  });
701
+ var getLogsResponseSchema = z11.object({
702
+ logs: z11.array(logSchema),
703
+ total: z11.number()
704
+ });
696
705
 
697
706
  // node_modules/@insforge/shared-schemas/dist/functions.schema.js
698
707
  import { z as z12 } from "zod";
@@ -726,10 +735,74 @@ var functionUpdateRequestSchema = z13.object({
726
735
 
727
736
  // src/shared/tools.ts
728
737
  import FormData from "form-data";
738
+ var TOOL_VERSION_REQUIREMENTS = {
739
+ "upsert-schedule": "1.1.1",
740
+ // 'get-schedules': '1.1.1',
741
+ // 'get-schedule-logs': '1.1.1',
742
+ "delete-schedule": "1.1.1"
743
+ };
729
744
  function registerInsforgeTools(server, config = {}) {
730
745
  const GLOBAL_API_KEY = config.apiKey || process.env.API_KEY || "";
731
746
  const API_BASE_URL = config.apiBaseUrl || process.env.API_BASE_URL || "http://localhost:7130";
732
747
  const usageTracker = new UsageTracker(API_BASE_URL, GLOBAL_API_KEY);
748
+ let versionCache = null;
749
+ const VERSION_CACHE_TTL = 5 * 60 * 1e3;
750
+ async function getBackendVersion() {
751
+ const now = Date.now();
752
+ if (versionCache && now - versionCache.timestamp < VERSION_CACHE_TTL) {
753
+ return versionCache.version;
754
+ }
755
+ try {
756
+ const response = await fetch2(`${API_BASE_URL}/api/health`, {
757
+ method: "GET",
758
+ headers: {
759
+ "Content-Type": "application/json"
760
+ }
761
+ });
762
+ if (!response.ok) {
763
+ throw new Error(`Health check failed with status ${response.status}`);
764
+ }
765
+ const health = await response.json();
766
+ versionCache = {
767
+ version: health.version,
768
+ timestamp: now
769
+ };
770
+ return health.version;
771
+ } catch (error) {
772
+ const errMsg = error instanceof Error ? error.message : "Unknown error";
773
+ throw new Error(`Failed to fetch backend version: ${errMsg}`);
774
+ }
775
+ }
776
+ function compareVersions(v1, v2) {
777
+ const parts1 = v1.split(".").map(Number);
778
+ const parts2 = v2.split(".").map(Number);
779
+ for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
780
+ const part1 = parts1[i] || 0;
781
+ const part2 = parts2[i] || 0;
782
+ if (part1 > part2) return 1;
783
+ if (part1 < part2) return -1;
784
+ }
785
+ return 0;
786
+ }
787
+ async function checkToolVersion(toolName) {
788
+ const requiredVersion = TOOL_VERSION_REQUIREMENTS[toolName];
789
+ if (!requiredVersion) {
790
+ return;
791
+ }
792
+ try {
793
+ const currentVersion = await getBackendVersion();
794
+ if (compareVersions(currentVersion, requiredVersion) < 0) {
795
+ throw new Error(
796
+ `Tool '${toolName}' requires backend version ${requiredVersion} or higher, but current version is ${currentVersion}. Please upgrade your Insforge backend server.`
797
+ );
798
+ }
799
+ } catch (error) {
800
+ if (error instanceof Error && error.message.includes("requires backend version")) {
801
+ throw error;
802
+ }
803
+ console.warn(`Warning: Could not verify backend version for tool '${toolName}': ${error instanceof Error ? error.message : "Unknown error"}`);
804
+ }
805
+ }
733
806
  async function trackToolUsage(toolName, success = true) {
734
807
  if (GLOBAL_API_KEY) {
735
808
  await usageTracker.trackUsage(toolName, success);
@@ -747,16 +820,11 @@ function registerInsforgeTools(server, config = {}) {
747
820
  }
748
821
  };
749
822
  }
750
- const getApiKey = (toolApiKey) => {
751
- if (GLOBAL_API_KEY) {
752
- return GLOBAL_API_KEY;
753
- }
754
- if (toolApiKey) {
755
- return toolApiKey;
823
+ const getApiKey = (_toolApiKey) => {
824
+ if (!GLOBAL_API_KEY) {
825
+ throw new Error("API key is required. Pass --api_key when starting the MCP server.");
756
826
  }
757
- throw new Error(
758
- "API key is required. Either pass --api_key as command line argument or provide api_key in tool calls."
759
- );
827
+ return GLOBAL_API_KEY;
760
828
  };
761
829
  const fetchDocumentation = async (docType) => {
762
830
  try {
@@ -769,7 +837,8 @@ function registerInsforgeTools(server, config = {}) {
769
837
  const result = await handleApiResponse(response);
770
838
  if (result && typeof result === "object" && "content" in result) {
771
839
  let content = result.content;
772
- content = content.replace(/http:\/\/localhost:7130/g, API_BASE_URL);
840
+ content = content.replace(/http:\/\/localhost:7130\/?/g, API_BASE_URL);
841
+ content = content.replace(/https:\/\/your-app\.region\.insforge\.app\/?/g, API_BASE_URL);
773
842
  return content;
774
843
  }
775
844
  throw new Error("Invalid response format from documentation endpoint");
@@ -778,36 +847,18 @@ function registerInsforgeTools(server, config = {}) {
778
847
  throw new Error(`Unable to retrieve ${docType} documentation: ${errMsg}`);
779
848
  }
780
849
  };
781
- const fetchInsforgeInstructionsContext = async () => {
782
- try {
783
- return await fetchDocumentation("instructions");
784
- } catch (error) {
785
- console.error("Failed to fetch insforge-instructions.md:", error);
786
- return null;
787
- }
788
- };
789
- const addBackgroundContext = async (response) => {
790
- const context = await fetchInsforgeInstructionsContext();
791
- if (context && response.content && Array.isArray(response.content)) {
792
- response.content.push({
793
- type: "text",
794
- text: `
795
-
796
- ---
797
- \u{1F527} INSFORGE DEVELOPMENT RULES (Auto-loaded):
798
- ${context}`
799
- });
800
- }
801
- return response;
802
- };
803
850
  server.tool(
804
- "get-instructions",
805
- "Instruction Essential backend setup tool. <critical>MANDATORY: You MUST use this tool FIRST before attempting any backend operations. Contains required API endpoints, authentication details, and setup instructions.</critical>",
806
- {},
807
- withUsageTracking("get-instructions", async () => {
851
+ "fetch-docs",
852
+ 'Fetch Insforge documentation. Use "instructions" for essential backend setup (MANDATORY FIRST), or select specific SDK docs for database, auth, storage, functions, or AI integration.',
853
+ {
854
+ docType: z14.enum(["instructions", "db-sdk", "storage-sdk", "functions-sdk", "ai-integration-sdk", "auth-components-nextjs", "auth-components-react"]).describe(
855
+ 'Documentation type: "instructions" (essential backend setup - use FIRST), "db-sdk" (database operations), "storage-sdk" (file storage), "functions-sdk" (edge functions), "ai-integration-sdk" (AI features), "auth-components-nextjs" (authentication components for Next.js applications), "auth-components-react" (authentication components for React applications),'
856
+ )
857
+ },
858
+ withUsageTracking("fetch-docs", async ({ docType }) => {
808
859
  try {
809
- const content = await fetchDocumentation("instructions");
810
- const response = {
860
+ const content = await fetchDocumentation(docType);
861
+ return {
811
862
  content: [
812
863
  {
813
864
  type: "text",
@@ -815,32 +866,52 @@ ${context}`
815
866
  }
816
867
  ]
817
868
  };
818
- return await addBackgroundContext(response);
819
869
  } catch (error) {
820
870
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
821
- const errorResponse = {
822
- content: [{ type: "text", text: `Error: ${errMsg}` }]
871
+ return {
872
+ content: [{ type: "text", text: `Error fetching ${docType} documentation: ${errMsg}` }]
823
873
  };
824
- return await addBackgroundContext(errorResponse);
825
874
  }
826
875
  })
827
876
  );
828
877
  server.tool(
829
- "get-api-key",
830
- "Retrieves the API key for the Insforge OSS backend. This is used to authenticate all requests to the backend.",
831
- {},
832
- async () => {
878
+ "get-anon-key",
879
+ "Generate an anonymous JWT token that never expires. Requires admin API key. Use this for client-side applications that need public access.",
880
+ {
881
+ apiKey: z14.string().optional().describe("API key for authentication (optional if provided via --api_key)")
882
+ },
883
+ withUsageTracking("get-anon-key", async ({ apiKey }) => {
833
884
  try {
834
- return await addBackgroundContext({
835
- content: [{ type: "text", text: `API key: ${getApiKey()}` }]
885
+ const actualApiKey = getApiKey(apiKey);
886
+ const response = await fetch2(`${API_BASE_URL}/api/auth/tokens/anon`, {
887
+ method: "POST",
888
+ headers: {
889
+ "x-api-key": actualApiKey,
890
+ "Content-Type": "application/json"
891
+ }
836
892
  });
893
+ const result = await handleApiResponse(response);
894
+ return {
895
+ content: [
896
+ {
897
+ type: "text",
898
+ text: formatSuccessMessage("Anonymous token generated", result)
899
+ }
900
+ ]
901
+ };
837
902
  } catch (error) {
838
903
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
839
- return await addBackgroundContext({
840
- content: [{ type: "text", text: `Error: ${errMsg}` }]
841
- });
904
+ return {
905
+ content: [
906
+ {
907
+ type: "text",
908
+ text: `Error generating anonymous token: ${errMsg}`
909
+ }
910
+ ],
911
+ isError: true
912
+ };
842
913
  }
843
- }
914
+ })
844
915
  );
845
916
  server.tool(
846
917
  "get-table-schema",
@@ -859,17 +930,17 @@ ${context}`
859
930
  }
860
931
  });
861
932
  const result = await handleApiResponse(response);
862
- return await addBackgroundContext({
933
+ return {
863
934
  content: [
864
935
  {
865
936
  type: "text",
866
937
  text: formatSuccessMessage("Schema retrieved", result)
867
938
  }
868
939
  ]
869
- });
940
+ };
870
941
  } catch (error) {
871
942
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
872
- return await addBackgroundContext({
943
+ return {
873
944
  content: [
874
945
  {
875
946
  type: "text",
@@ -877,7 +948,7 @@ ${context}`
877
948
  }
878
949
  ],
879
950
  isError: true
880
- });
951
+ };
881
952
  }
882
953
  })
883
954
  );
@@ -897,7 +968,7 @@ ${context}`
897
968
  }
898
969
  });
899
970
  const metadata = await handleApiResponse(response);
900
- return await addBackgroundContext({
971
+ return {
901
972
  content: [
902
973
  {
903
974
  type: "text",
@@ -906,10 +977,10 @@ ${context}`
906
977
  ${JSON.stringify(metadata, null, 2)}`
907
978
  }
908
979
  ]
909
- });
980
+ };
910
981
  } catch (error) {
911
982
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
912
- return await addBackgroundContext({
983
+ return {
913
984
  content: [
914
985
  {
915
986
  type: "text",
@@ -917,7 +988,7 @@ ${JSON.stringify(metadata, null, 2)}`
917
988
  }
918
989
  ],
919
990
  isError: true
920
- });
991
+ };
921
992
  }
922
993
  })
923
994
  );
@@ -944,17 +1015,17 @@ ${JSON.stringify(metadata, null, 2)}`
944
1015
  body: JSON.stringify(requestBody)
945
1016
  });
946
1017
  const result = await handleApiResponse(response);
947
- return await addBackgroundContext({
1018
+ return {
948
1019
  content: [
949
1020
  {
950
1021
  type: "text",
951
1022
  text: formatSuccessMessage("SQL query executed", result)
952
1023
  }
953
1024
  ]
954
- });
1025
+ };
955
1026
  } catch (error) {
956
1027
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
957
- return await addBackgroundContext({
1028
+ return {
958
1029
  content: [
959
1030
  {
960
1031
  type: "text",
@@ -962,7 +1033,7 @@ ${JSON.stringify(metadata, null, 2)}`
962
1033
  }
963
1034
  ],
964
1035
  isError: true
965
- });
1036
+ };
966
1037
  }
967
1038
  })
968
1039
  );
@@ -995,7 +1066,7 @@ ${JSON.stringify(metadata, null, 2)}`
995
1066
  });
996
1067
  const result = await handleApiResponse(response);
997
1068
  const message = result.success ? `Successfully processed ${result.rowsAffected} of ${result.totalRecords} records into table "${result.table}"` : result.message || "Bulk upsert operation completed";
998
- return await addBackgroundContext({
1069
+ return {
999
1070
  content: [
1000
1071
  {
1001
1072
  type: "text",
@@ -1008,10 +1079,10 @@ ${JSON.stringify(metadata, null, 2)}`
1008
1079
  })
1009
1080
  }
1010
1081
  ]
1011
- });
1082
+ };
1012
1083
  } catch (error) {
1013
1084
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1014
- return await addBackgroundContext({
1085
+ return {
1015
1086
  content: [
1016
1087
  {
1017
1088
  type: "text",
@@ -1019,7 +1090,7 @@ ${JSON.stringify(metadata, null, 2)}`
1019
1090
  }
1020
1091
  ],
1021
1092
  isError: true
1022
- });
1093
+ };
1023
1094
  }
1024
1095
  })
1025
1096
  );
@@ -1042,17 +1113,17 @@ ${JSON.stringify(metadata, null, 2)}`
1042
1113
  body: JSON.stringify({ bucketName, isPublic })
1043
1114
  });
1044
1115
  const result = await handleApiResponse(response);
1045
- return await addBackgroundContext({
1116
+ return {
1046
1117
  content: [
1047
1118
  {
1048
1119
  type: "text",
1049
1120
  text: formatSuccessMessage("Bucket created", result)
1050
1121
  }
1051
1122
  ]
1052
- });
1123
+ };
1053
1124
  } catch (error) {
1054
1125
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1055
- return await addBackgroundContext({
1126
+ return {
1056
1127
  content: [
1057
1128
  {
1058
1129
  type: "text",
@@ -1060,7 +1131,7 @@ ${JSON.stringify(metadata, null, 2)}`
1060
1131
  }
1061
1132
  ],
1062
1133
  isError: true
1063
- });
1134
+ };
1064
1135
  }
1065
1136
  })
1066
1137
  );
@@ -1077,17 +1148,17 @@ ${JSON.stringify(metadata, null, 2)}`
1077
1148
  }
1078
1149
  });
1079
1150
  const result = await handleApiResponse(response);
1080
- return await addBackgroundContext({
1151
+ return {
1081
1152
  content: [
1082
1153
  {
1083
1154
  type: "text",
1084
1155
  text: formatSuccessMessage("Buckets retrieved", result)
1085
1156
  }
1086
1157
  ]
1087
- });
1158
+ };
1088
1159
  } catch (error) {
1089
1160
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1090
- return await addBackgroundContext({
1161
+ return {
1091
1162
  content: [
1092
1163
  {
1093
1164
  type: "text",
@@ -1095,7 +1166,7 @@ ${JSON.stringify(metadata, null, 2)}`
1095
1166
  }
1096
1167
  ],
1097
1168
  isError: true
1098
- });
1169
+ };
1099
1170
  }
1100
1171
  })
1101
1172
  );
@@ -1116,17 +1187,17 @@ ${JSON.stringify(metadata, null, 2)}`
1116
1187
  }
1117
1188
  });
1118
1189
  const result = await handleApiResponse(response);
1119
- return await addBackgroundContext({
1190
+ return {
1120
1191
  content: [
1121
1192
  {
1122
1193
  type: "text",
1123
1194
  text: formatSuccessMessage("Bucket deleted", result)
1124
1195
  }
1125
1196
  ]
1126
- });
1197
+ };
1127
1198
  } catch (error) {
1128
1199
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1129
- return await addBackgroundContext({
1200
+ return {
1130
1201
  content: [
1131
1202
  {
1132
1203
  type: "text",
@@ -1134,7 +1205,7 @@ ${JSON.stringify(metadata, null, 2)}`
1134
1205
  }
1135
1206
  ],
1136
1207
  isError: true
1137
- });
1208
+ };
1138
1209
  }
1139
1210
  })
1140
1211
  );
@@ -1172,7 +1243,7 @@ ${JSON.stringify(metadata, null, 2)}`
1172
1243
  })
1173
1244
  });
1174
1245
  const result = await handleApiResponse(response);
1175
- return await addBackgroundContext({
1246
+ return {
1176
1247
  content: [
1177
1248
  {
1178
1249
  type: "text",
@@ -1182,10 +1253,10 @@ ${JSON.stringify(metadata, null, 2)}`
1182
1253
  )
1183
1254
  }
1184
1255
  ]
1185
- });
1256
+ };
1186
1257
  } catch (error) {
1187
1258
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1188
- return await addBackgroundContext({
1259
+ return {
1189
1260
  content: [
1190
1261
  {
1191
1262
  type: "text",
@@ -1193,7 +1264,7 @@ ${JSON.stringify(metadata, null, 2)}`
1193
1264
  }
1194
1265
  ],
1195
1266
  isError: true
1196
- });
1267
+ };
1197
1268
  }
1198
1269
  })
1199
1270
  );
@@ -1212,17 +1283,17 @@ ${JSON.stringify(metadata, null, 2)}`
1212
1283
  }
1213
1284
  });
1214
1285
  const result = await handleApiResponse(response);
1215
- return await addBackgroundContext({
1286
+ return {
1216
1287
  content: [
1217
1288
  {
1218
1289
  type: "text",
1219
1290
  text: formatSuccessMessage(`Edge function '${args.slug}' details`, result)
1220
1291
  }
1221
1292
  ]
1222
- });
1293
+ };
1223
1294
  } catch (error) {
1224
1295
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1225
- return await addBackgroundContext({
1296
+ return {
1226
1297
  content: [
1227
1298
  {
1228
1299
  type: "text",
@@ -1230,7 +1301,7 @@ ${JSON.stringify(metadata, null, 2)}`
1230
1301
  }
1231
1302
  ],
1232
1303
  isError: true
1233
- });
1304
+ };
1234
1305
  }
1235
1306
  })
1236
1307
  );
@@ -1275,7 +1346,7 @@ ${JSON.stringify(metadata, null, 2)}`
1275
1346
  });
1276
1347
  const result = await handleApiResponse(response);
1277
1348
  const fileInfo = args.codeFile ? ` from ${args.codeFile}` : "";
1278
- return await addBackgroundContext({
1349
+ return {
1279
1350
  content: [
1280
1351
  {
1281
1352
  type: "text",
@@ -1285,10 +1356,10 @@ ${JSON.stringify(metadata, null, 2)}`
1285
1356
  )
1286
1357
  }
1287
1358
  ]
1288
- });
1359
+ };
1289
1360
  } catch (error) {
1290
1361
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1291
- return await addBackgroundContext({
1362
+ return {
1292
1363
  content: [
1293
1364
  {
1294
1365
  type: "text",
@@ -1296,7 +1367,7 @@ ${JSON.stringify(metadata, null, 2)}`
1296
1367
  }
1297
1368
  ],
1298
1369
  isError: true
1299
- });
1370
+ };
1300
1371
  }
1301
1372
  })
1302
1373
  );
@@ -1315,17 +1386,17 @@ ${JSON.stringify(metadata, null, 2)}`
1315
1386
  }
1316
1387
  });
1317
1388
  const result = await handleApiResponse(response);
1318
- return await addBackgroundContext({
1389
+ return {
1319
1390
  content: [
1320
1391
  {
1321
1392
  type: "text",
1322
1393
  text: formatSuccessMessage(`Edge function '${args.slug}' deleted successfully`, result)
1323
1394
  }
1324
1395
  ]
1325
- });
1396
+ };
1326
1397
  } catch (error) {
1327
1398
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1328
- return await addBackgroundContext({
1399
+ return {
1329
1400
  content: [
1330
1401
  {
1331
1402
  type: "text",
@@ -1333,7 +1404,7 @@ ${JSON.stringify(metadata, null, 2)}`
1333
1404
  }
1334
1405
  ],
1335
1406
  isError: true
1336
- });
1407
+ };
1337
1408
  }
1338
1409
  })
1339
1410
  );
@@ -1365,17 +1436,17 @@ ${JSON.stringify(metadata, null, 2)}`
1365
1436
  });
1366
1437
  }
1367
1438
  const result = await handleApiResponse(response);
1368
- return await addBackgroundContext({
1439
+ return {
1369
1440
  content: [
1370
1441
  {
1371
1442
  type: "text",
1372
1443
  text: formatSuccessMessage(`Latest logs from ${source}`, result)
1373
1444
  }
1374
1445
  ]
1375
- });
1446
+ };
1376
1447
  } catch (error) {
1377
1448
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1378
- return await addBackgroundContext({
1449
+ return {
1379
1450
  content: [
1380
1451
  {
1381
1452
  type: "text",
@@ -1383,14 +1454,118 @@ ${JSON.stringify(metadata, null, 2)}`
1383
1454
  }
1384
1455
  ],
1385
1456
  isError: true
1457
+ };
1458
+ }
1459
+ })
1460
+ );
1461
+ server.tool(
1462
+ "upsert-schedule",
1463
+ "Create or update a cron job schedule. If id is provided, updates existing schedule; otherwise creates a new one.",
1464
+ {
1465
+ apiKey: z14.string().optional().describe("API key for authentication (optional if provided via --api_key)"),
1466
+ id: z14.string().uuid().optional().describe("The UUID of the schedule to update. If omitted, a new schedule will be created."),
1467
+ name: z14.string().min(3).describe("Schedule name (at least 3 characters)"),
1468
+ cronSchedule: z14.string().describe('Cron schedule format (5 or 6 parts, e.g., "0 */2 * * *" for every 2 hours)'),
1469
+ functionUrl: z14.string().url().describe("The URL to call when the schedule triggers"),
1470
+ httpMethod: z14.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).optional().default("POST").describe("HTTP method to use"),
1471
+ headers: z14.record(z14.string()).optional().describe('HTTP headers. Values starting with "secret:" will be resolved from secrets store.'),
1472
+ body: z14.record(z14.unknown()).optional().describe("JSON body to send with the request")
1473
+ },
1474
+ withUsageTracking("upsert-schedule", async ({ apiKey, id, name, cronSchedule, functionUrl, httpMethod, headers, body }) => {
1475
+ try {
1476
+ await checkToolVersion("upsert-schedule");
1477
+ const actualApiKey = getApiKey(apiKey);
1478
+ const requestBody = {
1479
+ name,
1480
+ cronSchedule,
1481
+ functionUrl,
1482
+ httpMethod: httpMethod || "POST"
1483
+ };
1484
+ if (id) {
1485
+ requestBody.id = id;
1486
+ }
1487
+ if (headers) {
1488
+ requestBody.headers = headers;
1489
+ }
1490
+ if (body) {
1491
+ requestBody.body = body;
1492
+ }
1493
+ const response = await fetch2(`${API_BASE_URL}/api/schedules`, {
1494
+ method: "POST",
1495
+ headers: {
1496
+ "x-api-key": actualApiKey,
1497
+ "Content-Type": "application/json"
1498
+ },
1499
+ body: JSON.stringify(requestBody)
1386
1500
  });
1501
+ const result = await handleApiResponse(response);
1502
+ const action = id ? "updated" : "created";
1503
+ return {
1504
+ content: [
1505
+ {
1506
+ type: "text",
1507
+ text: formatSuccessMessage(`Schedule '${name}' ${action} successfully`, result)
1508
+ }
1509
+ ]
1510
+ };
1511
+ } catch (error) {
1512
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1513
+ return {
1514
+ content: [
1515
+ {
1516
+ type: "text",
1517
+ text: `Error upserting schedule: ${errMsg}`
1518
+ }
1519
+ ],
1520
+ isError: true
1521
+ };
1522
+ }
1523
+ })
1524
+ );
1525
+ server.tool(
1526
+ "delete-schedule",
1527
+ "Delete a cron job schedule permanently",
1528
+ {
1529
+ apiKey: z14.string().optional().describe("API key for authentication (optional if provided via --api_key)"),
1530
+ scheduleId: z14.string().uuid().describe("The UUID of the schedule to delete")
1531
+ },
1532
+ withUsageTracking("delete-schedule", async ({ apiKey, scheduleId }) => {
1533
+ try {
1534
+ await checkToolVersion("delete-schedule");
1535
+ const actualApiKey = getApiKey(apiKey);
1536
+ const response = await fetch2(`${API_BASE_URL}/api/schedules/${scheduleId}`, {
1537
+ method: "DELETE",
1538
+ headers: {
1539
+ "x-api-key": actualApiKey
1540
+ }
1541
+ });
1542
+ const result = await handleApiResponse(response);
1543
+ return {
1544
+ content: [
1545
+ {
1546
+ type: "text",
1547
+ text: formatSuccessMessage(`Schedule ${scheduleId} deleted successfully`, result)
1548
+ }
1549
+ ]
1550
+ };
1551
+ } catch (error) {
1552
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
1553
+ return {
1554
+ content: [
1555
+ {
1556
+ type: "text",
1557
+ text: `Error deleting schedule: ${errMsg}`
1558
+ }
1559
+ ],
1560
+ isError: true
1561
+ };
1387
1562
  }
1388
1563
  })
1389
1564
  );
1390
1565
  return {
1391
1566
  apiKey: GLOBAL_API_KEY,
1392
1567
  apiBaseUrl: API_BASE_URL,
1393
- toolCount: 14
1568
+ toolCount: 16
1394
1569
  };
1395
1570
  }
1396
1571
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  registerInsforgeTools
4
- } from "./chunk-7CREF7XU.js";
4
+ } from "./chunk-3KG7LI73.js";
5
5
 
6
6
  // src/http/server.ts
7
7
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  registerInsforgeTools
4
- } from "./chunk-7CREF7XU.js";
4
+ } from "./chunk-3KG7LI73.js";
5
5
 
6
6
  // src/stdio/index.ts
7
7
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@insforge/mcp",
3
- "version": "1.1.6",
3
+ "version": "1.1.7-dev.10",
4
4
  "description": "MCP (Model Context Protocol) server for Insforge backend-as-a-service",
5
- "mcpName": "io.github.insforge/insforge-mcp",
5
+ "mcpName": "io.github.InsForge/insforge-mcp",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
8
8
  "bin": {
@@ -36,7 +36,7 @@
36
36
  "server.json"
37
37
  ],
38
38
  "dependencies": {
39
- "@insforge/shared-schemas": "^1.1.1",
39
+ "@insforge/shared-schemas": "^1.1.7",
40
40
  "@modelcontextprotocol/sdk": "^1.15.1",
41
41
  "@types/express": "^5.0.3",
42
42
  "commander": "^14.0.0",