@insforge/mcp 1.1.7-dev.8 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-YCORQXCY.js → chunk-MRGODXOM.js} +157 -137
- package/dist/http-server.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
import { z as z14 } from "zod";
|
|
5
5
|
import fetch2 from "node-fetch";
|
|
6
6
|
import { promises as fs } from "fs";
|
|
7
|
+
import { exec } from "child_process";
|
|
8
|
+
import { promisify } from "util";
|
|
9
|
+
import { tmpdir } from "os";
|
|
7
10
|
|
|
8
11
|
// src/shared/response-handler.ts
|
|
9
12
|
async function handleApiResponse(response) {
|
|
@@ -735,6 +738,7 @@ var functionUpdateRequestSchema = z13.object({
|
|
|
735
738
|
|
|
736
739
|
// src/shared/tools.ts
|
|
737
740
|
import FormData from "form-data";
|
|
741
|
+
var execAsync = promisify(exec);
|
|
738
742
|
var TOOL_VERSION_REQUIREMENTS = {
|
|
739
743
|
"upsert-schedule": "1.1.1",
|
|
740
744
|
// 'get-schedules': '1.1.1',
|
|
@@ -774,8 +778,10 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
774
778
|
}
|
|
775
779
|
}
|
|
776
780
|
function compareVersions(v1, v2) {
|
|
777
|
-
const
|
|
778
|
-
const
|
|
781
|
+
const clean1 = v1.replace(/^v/, "").split("-")[0];
|
|
782
|
+
const clean2 = v2.replace(/^v/, "").split("-")[0];
|
|
783
|
+
const parts1 = clean1.split(".").map(Number);
|
|
784
|
+
const parts2 = clean2.split(".").map(Number);
|
|
779
785
|
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
|
|
780
786
|
const part1 = parts1[i] || 0;
|
|
781
787
|
const part2 = parts2[i] || 0;
|
|
@@ -834,10 +840,14 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
834
840
|
"Content-Type": "application/json"
|
|
835
841
|
}
|
|
836
842
|
});
|
|
843
|
+
if (response.status === 404) {
|
|
844
|
+
throw new Error("Documentation not found");
|
|
845
|
+
}
|
|
837
846
|
const result = await handleApiResponse(response);
|
|
838
847
|
if (result && typeof result === "object" && "content" in result) {
|
|
839
848
|
let content = result.content;
|
|
840
849
|
content = content.replace(/http:\/\/localhost:7130/g, API_BASE_URL);
|
|
850
|
+
content = content.replace(/https:\/\/your-app\.region\.insforge\.app/g, API_BASE_URL);
|
|
841
851
|
return content;
|
|
842
852
|
}
|
|
843
853
|
throw new Error("Invalid response format from documentation endpoint");
|
|
@@ -846,27 +856,65 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
846
856
|
throw new Error(`Unable to retrieve ${docType} documentation: ${errMsg}`);
|
|
847
857
|
}
|
|
848
858
|
};
|
|
859
|
+
const fetchInsforgeInstructionsContext = async () => {
|
|
860
|
+
try {
|
|
861
|
+
return await fetchDocumentation("instructions");
|
|
862
|
+
} catch (error) {
|
|
863
|
+
console.error("Failed to fetch insforge-instructions.md:", error);
|
|
864
|
+
return null;
|
|
865
|
+
}
|
|
866
|
+
};
|
|
867
|
+
const addBackgroundContext = async (response) => {
|
|
868
|
+
try {
|
|
869
|
+
const currentVersion = await getBackendVersion();
|
|
870
|
+
const isLegacyVersion = compareVersions(currentVersion, "1.1.7") < 0;
|
|
871
|
+
if (isLegacyVersion) {
|
|
872
|
+
const context = await fetchInsforgeInstructionsContext();
|
|
873
|
+
if (context && response.content && Array.isArray(response.content)) {
|
|
874
|
+
response.content.push({
|
|
875
|
+
type: "text",
|
|
876
|
+
text: `
|
|
877
|
+
|
|
878
|
+
---
|
|
879
|
+
\u{1F527} INSFORGE DEVELOPMENT RULES (Auto-loaded):
|
|
880
|
+
${context}`
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
} catch {
|
|
885
|
+
console.warn("Could not determine backend version, skipping background context");
|
|
886
|
+
}
|
|
887
|
+
return response;
|
|
888
|
+
};
|
|
849
889
|
server.tool(
|
|
850
890
|
"fetch-docs",
|
|
851
891
|
'Fetch Insforge documentation. Use "instructions" for essential backend setup (MANDATORY FIRST), or select specific SDK docs for database, auth, storage, functions, or AI integration.',
|
|
852
892
|
{
|
|
853
|
-
docType: z14.enum(["instructions", "db-sdk", "storage-sdk", "functions-sdk", "ai-integration-sdk", "auth-components-
|
|
854
|
-
'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-
|
|
893
|
+
docType: z14.enum(["instructions", "db-sdk", "storage-sdk", "functions-sdk", "ai-integration-sdk", "auth-components-react"]).describe(
|
|
894
|
+
'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-react" (authentication components for React+Vite applications).'
|
|
855
895
|
)
|
|
856
896
|
},
|
|
857
897
|
withUsageTracking("fetch-docs", async ({ docType }) => {
|
|
858
898
|
try {
|
|
859
899
|
const content = await fetchDocumentation(docType);
|
|
860
|
-
return {
|
|
900
|
+
return await addBackgroundContext({
|
|
861
901
|
content: [
|
|
862
902
|
{
|
|
863
903
|
type: "text",
|
|
864
904
|
text: content
|
|
865
905
|
}
|
|
866
906
|
]
|
|
867
|
-
};
|
|
907
|
+
});
|
|
868
908
|
} catch (error) {
|
|
869
909
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
910
|
+
if (errMsg.includes("404") || errMsg.toLowerCase().includes("not found")) {
|
|
911
|
+
return {
|
|
912
|
+
content: [{
|
|
913
|
+
type: "text",
|
|
914
|
+
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.`
|
|
915
|
+
}]
|
|
916
|
+
};
|
|
917
|
+
}
|
|
870
918
|
return {
|
|
871
919
|
content: [{ type: "text", text: `Error fetching ${docType} documentation: ${errMsg}` }]
|
|
872
920
|
};
|
|
@@ -890,14 +938,14 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
890
938
|
}
|
|
891
939
|
});
|
|
892
940
|
const result = await handleApiResponse(response);
|
|
893
|
-
return {
|
|
941
|
+
return await addBackgroundContext({
|
|
894
942
|
content: [
|
|
895
943
|
{
|
|
896
944
|
type: "text",
|
|
897
945
|
text: formatSuccessMessage("Anonymous token generated", result)
|
|
898
946
|
}
|
|
899
947
|
]
|
|
900
|
-
};
|
|
948
|
+
});
|
|
901
949
|
} catch (error) {
|
|
902
950
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
903
951
|
return {
|
|
@@ -929,14 +977,14 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
929
977
|
}
|
|
930
978
|
});
|
|
931
979
|
const result = await handleApiResponse(response);
|
|
932
|
-
return {
|
|
980
|
+
return await addBackgroundContext({
|
|
933
981
|
content: [
|
|
934
982
|
{
|
|
935
983
|
type: "text",
|
|
936
984
|
text: formatSuccessMessage("Schema retrieved", result)
|
|
937
985
|
}
|
|
938
986
|
]
|
|
939
|
-
};
|
|
987
|
+
});
|
|
940
988
|
} catch (error) {
|
|
941
989
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
942
990
|
return {
|
|
@@ -967,7 +1015,7 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
967
1015
|
}
|
|
968
1016
|
});
|
|
969
1017
|
const metadata = await handleApiResponse(response);
|
|
970
|
-
return {
|
|
1018
|
+
return await addBackgroundContext({
|
|
971
1019
|
content: [
|
|
972
1020
|
{
|
|
973
1021
|
type: "text",
|
|
@@ -976,7 +1024,7 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
976
1024
|
${JSON.stringify(metadata, null, 2)}`
|
|
977
1025
|
}
|
|
978
1026
|
]
|
|
979
|
-
};
|
|
1027
|
+
});
|
|
980
1028
|
} catch (error) {
|
|
981
1029
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
982
1030
|
return {
|
|
@@ -1014,14 +1062,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1014
1062
|
body: JSON.stringify(requestBody)
|
|
1015
1063
|
});
|
|
1016
1064
|
const result = await handleApiResponse(response);
|
|
1017
|
-
return {
|
|
1065
|
+
return await addBackgroundContext({
|
|
1018
1066
|
content: [
|
|
1019
1067
|
{
|
|
1020
1068
|
type: "text",
|
|
1021
1069
|
text: formatSuccessMessage("SQL query executed", result)
|
|
1022
1070
|
}
|
|
1023
1071
|
]
|
|
1024
|
-
};
|
|
1072
|
+
});
|
|
1025
1073
|
} catch (error) {
|
|
1026
1074
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1027
1075
|
return {
|
|
@@ -1036,6 +1084,82 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1036
1084
|
}
|
|
1037
1085
|
})
|
|
1038
1086
|
);
|
|
1087
|
+
server.tool(
|
|
1088
|
+
"download-template",
|
|
1089
|
+
"CRITICAL: MANDATORY FIRST STEP for all new InsForge projects. Download pre-configured starter template (React) to a temporary directory. After download, you MUST copy files to current directory using the provided command.",
|
|
1090
|
+
{
|
|
1091
|
+
frame: z14.enum(["react"]).describe("Framework to use for the template (currently only React is supported)"),
|
|
1092
|
+
projectName: z14.string().optional().describe('Name for the project directory (optional, defaults to "insforge-react")')
|
|
1093
|
+
},
|
|
1094
|
+
withUsageTracking("download-template", async ({ frame, projectName }) => {
|
|
1095
|
+
try {
|
|
1096
|
+
const response = await fetch2(`${API_BASE_URL}/api/auth/tokens/anon`, {
|
|
1097
|
+
method: "POST",
|
|
1098
|
+
headers: {
|
|
1099
|
+
"x-api-key": getApiKey(),
|
|
1100
|
+
"Content-Type": "application/json"
|
|
1101
|
+
}
|
|
1102
|
+
});
|
|
1103
|
+
const result = await handleApiResponse(response);
|
|
1104
|
+
const anonKey = result.accessToken;
|
|
1105
|
+
if (!anonKey) {
|
|
1106
|
+
throw new Error("Failed to retrieve anon key from backend");
|
|
1107
|
+
}
|
|
1108
|
+
const tempDir = tmpdir();
|
|
1109
|
+
const targetDir = projectName || `insforge-${frame}`;
|
|
1110
|
+
const templatePath = `${tempDir}/${targetDir}`;
|
|
1111
|
+
console.error(`[download-template] Target path: ${templatePath}`);
|
|
1112
|
+
try {
|
|
1113
|
+
const stats = await fs.stat(templatePath);
|
|
1114
|
+
if (stats.isDirectory()) {
|
|
1115
|
+
console.error(`[download-template] Removing existing template at ${templatePath}`);
|
|
1116
|
+
await fs.rm(templatePath, { recursive: true, force: true });
|
|
1117
|
+
}
|
|
1118
|
+
} catch {
|
|
1119
|
+
}
|
|
1120
|
+
const command = `npx create-insforge-app ${targetDir} --frame ${frame} --base-url ${API_BASE_URL} --anon-key ${anonKey} --skip-install`;
|
|
1121
|
+
const { stdout, stderr } = await execAsync(command, {
|
|
1122
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
1123
|
+
// 10MB buffer
|
|
1124
|
+
cwd: tempDir
|
|
1125
|
+
});
|
|
1126
|
+
const output = stdout || stderr || "";
|
|
1127
|
+
if (output.toLowerCase().includes("error") && !output.includes("successfully")) {
|
|
1128
|
+
throw new Error(`Failed to download template: ${output}`);
|
|
1129
|
+
}
|
|
1130
|
+
return await addBackgroundContext({
|
|
1131
|
+
content: [
|
|
1132
|
+
{
|
|
1133
|
+
type: "text",
|
|
1134
|
+
text: `\u2705 React template downloaded successfully
|
|
1135
|
+
|
|
1136
|
+
\u{1F4C1} Template Location: ${templatePath}
|
|
1137
|
+
|
|
1138
|
+
\u26A0\uFE0F IMPORTANT: The template is in a temporary directory and NOT in your current working directory.
|
|
1139
|
+
|
|
1140
|
+
\u{1F534} CRITICAL NEXT STEP REQUIRED:
|
|
1141
|
+
You MUST copy ALL files (INCLUDING HIDDEN FILES like .env, .gitignore, etc.) from the temporary directory to your current project directory.
|
|
1142
|
+
|
|
1143
|
+
Copy all files from: ${templatePath}
|
|
1144
|
+
To: Your current project directory
|
|
1145
|
+
`
|
|
1146
|
+
}
|
|
1147
|
+
]
|
|
1148
|
+
});
|
|
1149
|
+
} catch (error) {
|
|
1150
|
+
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1151
|
+
return {
|
|
1152
|
+
content: [
|
|
1153
|
+
{
|
|
1154
|
+
type: "text",
|
|
1155
|
+
text: `Error downloading template: ${errMsg}`
|
|
1156
|
+
}
|
|
1157
|
+
],
|
|
1158
|
+
isError: true
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1161
|
+
})
|
|
1162
|
+
);
|
|
1039
1163
|
server.tool(
|
|
1040
1164
|
"bulk-upsert",
|
|
1041
1165
|
"Bulk insert or update data from CSV or JSON file. Supports upsert operations with a unique key.",
|
|
@@ -1065,7 +1189,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1065
1189
|
});
|
|
1066
1190
|
const result = await handleApiResponse(response);
|
|
1067
1191
|
const message = result.success ? `Successfully processed ${result.rowsAffected} of ${result.totalRecords} records into table "${result.table}"` : result.message || "Bulk upsert operation completed";
|
|
1068
|
-
return {
|
|
1192
|
+
return await addBackgroundContext({
|
|
1069
1193
|
content: [
|
|
1070
1194
|
{
|
|
1071
1195
|
type: "text",
|
|
@@ -1078,7 +1202,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1078
1202
|
})
|
|
1079
1203
|
}
|
|
1080
1204
|
]
|
|
1081
|
-
};
|
|
1205
|
+
});
|
|
1082
1206
|
} catch (error) {
|
|
1083
1207
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1084
1208
|
return {
|
|
@@ -1112,14 +1236,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1112
1236
|
body: JSON.stringify({ bucketName, isPublic })
|
|
1113
1237
|
});
|
|
1114
1238
|
const result = await handleApiResponse(response);
|
|
1115
|
-
return {
|
|
1239
|
+
return await addBackgroundContext({
|
|
1116
1240
|
content: [
|
|
1117
1241
|
{
|
|
1118
1242
|
type: "text",
|
|
1119
1243
|
text: formatSuccessMessage("Bucket created", result)
|
|
1120
1244
|
}
|
|
1121
1245
|
]
|
|
1122
|
-
};
|
|
1246
|
+
});
|
|
1123
1247
|
} catch (error) {
|
|
1124
1248
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1125
1249
|
return {
|
|
@@ -1147,14 +1271,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1147
1271
|
}
|
|
1148
1272
|
});
|
|
1149
1273
|
const result = await handleApiResponse(response);
|
|
1150
|
-
return {
|
|
1274
|
+
return await addBackgroundContext({
|
|
1151
1275
|
content: [
|
|
1152
1276
|
{
|
|
1153
1277
|
type: "text",
|
|
1154
1278
|
text: formatSuccessMessage("Buckets retrieved", result)
|
|
1155
1279
|
}
|
|
1156
1280
|
]
|
|
1157
|
-
};
|
|
1281
|
+
});
|
|
1158
1282
|
} catch (error) {
|
|
1159
1283
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1160
1284
|
return {
|
|
@@ -1186,14 +1310,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1186
1310
|
}
|
|
1187
1311
|
});
|
|
1188
1312
|
const result = await handleApiResponse(response);
|
|
1189
|
-
return {
|
|
1313
|
+
return await addBackgroundContext({
|
|
1190
1314
|
content: [
|
|
1191
1315
|
{
|
|
1192
1316
|
type: "text",
|
|
1193
1317
|
text: formatSuccessMessage("Bucket deleted", result)
|
|
1194
1318
|
}
|
|
1195
1319
|
]
|
|
1196
|
-
};
|
|
1320
|
+
});
|
|
1197
1321
|
} catch (error) {
|
|
1198
1322
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1199
1323
|
return {
|
|
@@ -1242,7 +1366,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1242
1366
|
})
|
|
1243
1367
|
});
|
|
1244
1368
|
const result = await handleApiResponse(response);
|
|
1245
|
-
return {
|
|
1369
|
+
return await addBackgroundContext({
|
|
1246
1370
|
content: [
|
|
1247
1371
|
{
|
|
1248
1372
|
type: "text",
|
|
@@ -1252,7 +1376,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1252
1376
|
)
|
|
1253
1377
|
}
|
|
1254
1378
|
]
|
|
1255
|
-
};
|
|
1379
|
+
});
|
|
1256
1380
|
} catch (error) {
|
|
1257
1381
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1258
1382
|
return {
|
|
@@ -1282,14 +1406,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1282
1406
|
}
|
|
1283
1407
|
});
|
|
1284
1408
|
const result = await handleApiResponse(response);
|
|
1285
|
-
return {
|
|
1409
|
+
return await addBackgroundContext({
|
|
1286
1410
|
content: [
|
|
1287
1411
|
{
|
|
1288
1412
|
type: "text",
|
|
1289
1413
|
text: formatSuccessMessage(`Edge function '${args.slug}' details`, result)
|
|
1290
1414
|
}
|
|
1291
1415
|
]
|
|
1292
|
-
};
|
|
1416
|
+
});
|
|
1293
1417
|
} catch (error) {
|
|
1294
1418
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1295
1419
|
return {
|
|
@@ -1345,7 +1469,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1345
1469
|
});
|
|
1346
1470
|
const result = await handleApiResponse(response);
|
|
1347
1471
|
const fileInfo = args.codeFile ? ` from ${args.codeFile}` : "";
|
|
1348
|
-
return {
|
|
1472
|
+
return await addBackgroundContext({
|
|
1349
1473
|
content: [
|
|
1350
1474
|
{
|
|
1351
1475
|
type: "text",
|
|
@@ -1355,7 +1479,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1355
1479
|
)
|
|
1356
1480
|
}
|
|
1357
1481
|
]
|
|
1358
|
-
};
|
|
1482
|
+
});
|
|
1359
1483
|
} catch (error) {
|
|
1360
1484
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1361
1485
|
return {
|
|
@@ -1385,14 +1509,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1385
1509
|
}
|
|
1386
1510
|
});
|
|
1387
1511
|
const result = await handleApiResponse(response);
|
|
1388
|
-
return {
|
|
1512
|
+
return await addBackgroundContext({
|
|
1389
1513
|
content: [
|
|
1390
1514
|
{
|
|
1391
1515
|
type: "text",
|
|
1392
1516
|
text: formatSuccessMessage(`Edge function '${args.slug}' deleted successfully`, result)
|
|
1393
1517
|
}
|
|
1394
1518
|
]
|
|
1395
|
-
};
|
|
1519
|
+
});
|
|
1396
1520
|
} catch (error) {
|
|
1397
1521
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1398
1522
|
return {
|
|
@@ -1435,14 +1559,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1435
1559
|
});
|
|
1436
1560
|
}
|
|
1437
1561
|
const result = await handleApiResponse(response);
|
|
1438
|
-
return {
|
|
1562
|
+
return await addBackgroundContext({
|
|
1439
1563
|
content: [
|
|
1440
1564
|
{
|
|
1441
1565
|
type: "text",
|
|
1442
1566
|
text: formatSuccessMessage(`Latest logs from ${source}`, result)
|
|
1443
1567
|
}
|
|
1444
1568
|
]
|
|
1445
|
-
};
|
|
1569
|
+
});
|
|
1446
1570
|
} catch (error) {
|
|
1447
1571
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1448
1572
|
return {
|
|
@@ -1457,114 +1581,10 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1457
1581
|
}
|
|
1458
1582
|
})
|
|
1459
1583
|
);
|
|
1460
|
-
server.tool(
|
|
1461
|
-
"upsert-schedule",
|
|
1462
|
-
"Create or update a cron job schedule. If id is provided, updates existing schedule; otherwise creates a new one.",
|
|
1463
|
-
{
|
|
1464
|
-
apiKey: z14.string().optional().describe("API key for authentication (optional if provided via --api_key)"),
|
|
1465
|
-
id: z14.string().uuid().optional().describe("The UUID of the schedule to update. If omitted, a new schedule will be created."),
|
|
1466
|
-
name: z14.string().min(3).describe("Schedule name (at least 3 characters)"),
|
|
1467
|
-
cronSchedule: z14.string().describe('Cron schedule format (5 or 6 parts, e.g., "0 */2 * * *" for every 2 hours)'),
|
|
1468
|
-
functionUrl: z14.string().url().describe("The URL to call when the schedule triggers"),
|
|
1469
|
-
httpMethod: z14.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).optional().default("POST").describe("HTTP method to use"),
|
|
1470
|
-
headers: z14.record(z14.string()).optional().describe('HTTP headers. Values starting with "secret:" will be resolved from secrets store.'),
|
|
1471
|
-
body: z14.record(z14.unknown()).optional().describe("JSON body to send with the request")
|
|
1472
|
-
},
|
|
1473
|
-
withUsageTracking("upsert-schedule", async ({ apiKey, id, name, cronSchedule, functionUrl, httpMethod, headers, body }) => {
|
|
1474
|
-
try {
|
|
1475
|
-
await checkToolVersion("upsert-schedule");
|
|
1476
|
-
const actualApiKey = getApiKey(apiKey);
|
|
1477
|
-
const requestBody = {
|
|
1478
|
-
name,
|
|
1479
|
-
cronSchedule,
|
|
1480
|
-
functionUrl,
|
|
1481
|
-
httpMethod: httpMethod || "POST"
|
|
1482
|
-
};
|
|
1483
|
-
if (id) {
|
|
1484
|
-
requestBody.id = id;
|
|
1485
|
-
}
|
|
1486
|
-
if (headers) {
|
|
1487
|
-
requestBody.headers = headers;
|
|
1488
|
-
}
|
|
1489
|
-
if (body) {
|
|
1490
|
-
requestBody.body = body;
|
|
1491
|
-
}
|
|
1492
|
-
const response = await fetch2(`${API_BASE_URL}/api/schedules`, {
|
|
1493
|
-
method: "POST",
|
|
1494
|
-
headers: {
|
|
1495
|
-
"x-api-key": actualApiKey,
|
|
1496
|
-
"Content-Type": "application/json"
|
|
1497
|
-
},
|
|
1498
|
-
body: JSON.stringify(requestBody)
|
|
1499
|
-
});
|
|
1500
|
-
const result = await handleApiResponse(response);
|
|
1501
|
-
const action = id ? "updated" : "created";
|
|
1502
|
-
return await addBackgroundContext({
|
|
1503
|
-
content: [
|
|
1504
|
-
{
|
|
1505
|
-
type: "text",
|
|
1506
|
-
text: formatSuccessMessage(`Schedule '${name}' ${action} successfully`, result)
|
|
1507
|
-
}
|
|
1508
|
-
]
|
|
1509
|
-
});
|
|
1510
|
-
} catch (error) {
|
|
1511
|
-
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1512
|
-
return await addBackgroundContext({
|
|
1513
|
-
content: [
|
|
1514
|
-
{
|
|
1515
|
-
type: "text",
|
|
1516
|
-
text: `Error upserting schedule: ${errMsg}`
|
|
1517
|
-
}
|
|
1518
|
-
],
|
|
1519
|
-
isError: true
|
|
1520
|
-
});
|
|
1521
|
-
}
|
|
1522
|
-
})
|
|
1523
|
-
);
|
|
1524
|
-
server.tool(
|
|
1525
|
-
"delete-schedule",
|
|
1526
|
-
"Delete a cron job schedule permanently",
|
|
1527
|
-
{
|
|
1528
|
-
apiKey: z14.string().optional().describe("API key for authentication (optional if provided via --api_key)"),
|
|
1529
|
-
scheduleId: z14.string().uuid().describe("The UUID of the schedule to delete")
|
|
1530
|
-
},
|
|
1531
|
-
withUsageTracking("delete-schedule", async ({ apiKey, scheduleId }) => {
|
|
1532
|
-
try {
|
|
1533
|
-
await checkToolVersion("delete-schedule");
|
|
1534
|
-
const actualApiKey = getApiKey(apiKey);
|
|
1535
|
-
const response = await fetch2(`${API_BASE_URL}/api/schedules/${scheduleId}`, {
|
|
1536
|
-
method: "DELETE",
|
|
1537
|
-
headers: {
|
|
1538
|
-
"x-api-key": actualApiKey
|
|
1539
|
-
}
|
|
1540
|
-
});
|
|
1541
|
-
const result = await handleApiResponse(response);
|
|
1542
|
-
return await addBackgroundContext({
|
|
1543
|
-
content: [
|
|
1544
|
-
{
|
|
1545
|
-
type: "text",
|
|
1546
|
-
text: formatSuccessMessage(`Schedule ${scheduleId} deleted successfully`, result)
|
|
1547
|
-
}
|
|
1548
|
-
]
|
|
1549
|
-
});
|
|
1550
|
-
} catch (error) {
|
|
1551
|
-
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1552
|
-
return await addBackgroundContext({
|
|
1553
|
-
content: [
|
|
1554
|
-
{
|
|
1555
|
-
type: "text",
|
|
1556
|
-
text: `Error deleting schedule: ${errMsg}`
|
|
1557
|
-
}
|
|
1558
|
-
],
|
|
1559
|
-
isError: true
|
|
1560
|
-
});
|
|
1561
|
-
}
|
|
1562
|
-
})
|
|
1563
|
-
);
|
|
1564
1584
|
return {
|
|
1565
1585
|
apiKey: GLOBAL_API_KEY,
|
|
1566
1586
|
apiBaseUrl: API_BASE_URL,
|
|
1567
|
-
toolCount:
|
|
1587
|
+
toolCount: 15
|
|
1568
1588
|
};
|
|
1569
1589
|
}
|
|
1570
1590
|
|
package/dist/http-server.js
CHANGED
package/dist/index.js
CHANGED