@insforge/mcp 1.1.7-dev.3 → 1.1.7-dev.31
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-CLLI7UFN.js → chunk-TOH3XKIT.js} +273 -34
- package/dist/http-server.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +4 -2
- package/server.json +17 -0
|
@@ -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,10 +738,77 @@ var functionUpdateRequestSchema = z13.object({
|
|
|
735
738
|
|
|
736
739
|
// src/shared/tools.ts
|
|
737
740
|
import FormData from "form-data";
|
|
741
|
+
var execAsync = promisify(exec);
|
|
742
|
+
var TOOL_VERSION_REQUIREMENTS = {
|
|
743
|
+
"upsert-schedule": "1.1.1",
|
|
744
|
+
// 'get-schedules': '1.1.1',
|
|
745
|
+
// 'get-schedule-logs': '1.1.1',
|
|
746
|
+
"delete-schedule": "1.1.1"
|
|
747
|
+
};
|
|
738
748
|
function registerInsforgeTools(server, config = {}) {
|
|
739
749
|
const GLOBAL_API_KEY = config.apiKey || process.env.API_KEY || "";
|
|
740
750
|
const API_BASE_URL = config.apiBaseUrl || process.env.API_BASE_URL || "http://localhost:7130";
|
|
741
751
|
const usageTracker = new UsageTracker(API_BASE_URL, GLOBAL_API_KEY);
|
|
752
|
+
let versionCache = null;
|
|
753
|
+
const VERSION_CACHE_TTL = 5 * 60 * 1e3;
|
|
754
|
+
async function getBackendVersion() {
|
|
755
|
+
const now = Date.now();
|
|
756
|
+
if (versionCache && now - versionCache.timestamp < VERSION_CACHE_TTL) {
|
|
757
|
+
return versionCache.version;
|
|
758
|
+
}
|
|
759
|
+
try {
|
|
760
|
+
const response = await fetch2(`${API_BASE_URL}/api/health`, {
|
|
761
|
+
method: "GET",
|
|
762
|
+
headers: {
|
|
763
|
+
"Content-Type": "application/json"
|
|
764
|
+
}
|
|
765
|
+
});
|
|
766
|
+
if (!response.ok) {
|
|
767
|
+
throw new Error(`Health check failed with status ${response.status}`);
|
|
768
|
+
}
|
|
769
|
+
const health = await response.json();
|
|
770
|
+
versionCache = {
|
|
771
|
+
version: health.version,
|
|
772
|
+
timestamp: now
|
|
773
|
+
};
|
|
774
|
+
return health.version;
|
|
775
|
+
} catch (error) {
|
|
776
|
+
const errMsg = error instanceof Error ? error.message : "Unknown error";
|
|
777
|
+
throw new Error(`Failed to fetch backend version: ${errMsg}`);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
function compareVersions(v1, v2) {
|
|
781
|
+
const clean1 = v1.replace(/^v/, "");
|
|
782
|
+
const clean2 = v2.replace(/^v/, "");
|
|
783
|
+
const parts1 = clean1.split(".").map(Number);
|
|
784
|
+
const parts2 = clean2.split(".").map(Number);
|
|
785
|
+
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
|
|
786
|
+
const part1 = parts1[i] || 0;
|
|
787
|
+
const part2 = parts2[i] || 0;
|
|
788
|
+
if (part1 > part2) return 1;
|
|
789
|
+
if (part1 < part2) return -1;
|
|
790
|
+
}
|
|
791
|
+
return 0;
|
|
792
|
+
}
|
|
793
|
+
async function checkToolVersion(toolName) {
|
|
794
|
+
const requiredVersion = TOOL_VERSION_REQUIREMENTS[toolName];
|
|
795
|
+
if (!requiredVersion) {
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
try {
|
|
799
|
+
const currentVersion = await getBackendVersion();
|
|
800
|
+
if (compareVersions(currentVersion, requiredVersion) < 0) {
|
|
801
|
+
throw new Error(
|
|
802
|
+
`Tool '${toolName}' requires backend version ${requiredVersion} or higher, but current version is ${currentVersion}. Please upgrade your Insforge backend server.`
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
} catch (error) {
|
|
806
|
+
if (error instanceof Error && error.message.includes("requires backend version")) {
|
|
807
|
+
throw error;
|
|
808
|
+
}
|
|
809
|
+
console.warn(`Warning: Could not verify backend version for tool '${toolName}': ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
810
|
+
}
|
|
811
|
+
}
|
|
742
812
|
async function trackToolUsage(toolName, success = true) {
|
|
743
813
|
if (GLOBAL_API_KEY) {
|
|
744
814
|
await usageTracker.trackUsage(toolName, success);
|
|
@@ -770,10 +840,14 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
770
840
|
"Content-Type": "application/json"
|
|
771
841
|
}
|
|
772
842
|
});
|
|
843
|
+
if (response.status === 404) {
|
|
844
|
+
throw new Error("Documentation not found");
|
|
845
|
+
}
|
|
773
846
|
const result = await handleApiResponse(response);
|
|
774
847
|
if (result && typeof result === "object" && "content" in result) {
|
|
775
848
|
let content = result.content;
|
|
776
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);
|
|
777
851
|
return content;
|
|
778
852
|
}
|
|
779
853
|
throw new Error("Invalid response format from documentation endpoint");
|
|
@@ -782,25 +856,106 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
782
856
|
throw new Error(`Unable to retrieve ${docType} documentation: ${errMsg}`);
|
|
783
857
|
}
|
|
784
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
|
+
};
|
|
785
889
|
server.tool(
|
|
786
|
-
"
|
|
787
|
-
|
|
788
|
-
{
|
|
789
|
-
|
|
890
|
+
"fetch-docs",
|
|
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.',
|
|
892
|
+
{
|
|
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,'
|
|
895
|
+
)
|
|
896
|
+
},
|
|
897
|
+
withUsageTracking("fetch-docs", async ({ docType }) => {
|
|
790
898
|
try {
|
|
791
|
-
const content = await fetchDocumentation(
|
|
792
|
-
return {
|
|
899
|
+
const content = await fetchDocumentation(docType);
|
|
900
|
+
return await addBackgroundContext({
|
|
793
901
|
content: [
|
|
794
902
|
{
|
|
795
903
|
type: "text",
|
|
796
904
|
text: content
|
|
797
905
|
}
|
|
798
906
|
]
|
|
907
|
+
});
|
|
908
|
+
} catch (error) {
|
|
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
|
+
}
|
|
918
|
+
return {
|
|
919
|
+
content: [{ type: "text", text: `Error fetching ${docType} documentation: ${errMsg}` }]
|
|
799
920
|
};
|
|
921
|
+
}
|
|
922
|
+
})
|
|
923
|
+
);
|
|
924
|
+
server.tool(
|
|
925
|
+
"get-anon-key",
|
|
926
|
+
"Generate an anonymous JWT token that never expires. Requires admin API key. Use this for client-side applications that need public access.",
|
|
927
|
+
{
|
|
928
|
+
apiKey: z14.string().optional().describe("API key for authentication (optional if provided via --api_key)")
|
|
929
|
+
},
|
|
930
|
+
withUsageTracking("get-anon-key", async ({ apiKey }) => {
|
|
931
|
+
try {
|
|
932
|
+
const actualApiKey = getApiKey(apiKey);
|
|
933
|
+
const response = await fetch2(`${API_BASE_URL}/api/auth/tokens/anon`, {
|
|
934
|
+
method: "POST",
|
|
935
|
+
headers: {
|
|
936
|
+
"x-api-key": actualApiKey,
|
|
937
|
+
"Content-Type": "application/json"
|
|
938
|
+
}
|
|
939
|
+
});
|
|
940
|
+
const result = await handleApiResponse(response);
|
|
941
|
+
return await addBackgroundContext({
|
|
942
|
+
content: [
|
|
943
|
+
{
|
|
944
|
+
type: "text",
|
|
945
|
+
text: formatSuccessMessage("Anonymous token generated", result)
|
|
946
|
+
}
|
|
947
|
+
]
|
|
948
|
+
});
|
|
800
949
|
} catch (error) {
|
|
801
950
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
802
951
|
return {
|
|
803
|
-
content: [
|
|
952
|
+
content: [
|
|
953
|
+
{
|
|
954
|
+
type: "text",
|
|
955
|
+
text: `Error generating anonymous token: ${errMsg}`
|
|
956
|
+
}
|
|
957
|
+
],
|
|
958
|
+
isError: true
|
|
804
959
|
};
|
|
805
960
|
}
|
|
806
961
|
})
|
|
@@ -822,14 +977,14 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
822
977
|
}
|
|
823
978
|
});
|
|
824
979
|
const result = await handleApiResponse(response);
|
|
825
|
-
return {
|
|
980
|
+
return await addBackgroundContext({
|
|
826
981
|
content: [
|
|
827
982
|
{
|
|
828
983
|
type: "text",
|
|
829
984
|
text: formatSuccessMessage("Schema retrieved", result)
|
|
830
985
|
}
|
|
831
986
|
]
|
|
832
|
-
};
|
|
987
|
+
});
|
|
833
988
|
} catch (error) {
|
|
834
989
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
835
990
|
return {
|
|
@@ -860,7 +1015,7 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
860
1015
|
}
|
|
861
1016
|
});
|
|
862
1017
|
const metadata = await handleApiResponse(response);
|
|
863
|
-
return {
|
|
1018
|
+
return await addBackgroundContext({
|
|
864
1019
|
content: [
|
|
865
1020
|
{
|
|
866
1021
|
type: "text",
|
|
@@ -869,7 +1024,7 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
869
1024
|
${JSON.stringify(metadata, null, 2)}`
|
|
870
1025
|
}
|
|
871
1026
|
]
|
|
872
|
-
};
|
|
1027
|
+
});
|
|
873
1028
|
} catch (error) {
|
|
874
1029
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
875
1030
|
return {
|
|
@@ -907,14 +1062,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
907
1062
|
body: JSON.stringify(requestBody)
|
|
908
1063
|
});
|
|
909
1064
|
const result = await handleApiResponse(response);
|
|
910
|
-
return {
|
|
1065
|
+
return await addBackgroundContext({
|
|
911
1066
|
content: [
|
|
912
1067
|
{
|
|
913
1068
|
type: "text",
|
|
914
1069
|
text: formatSuccessMessage("SQL query executed", result)
|
|
915
1070
|
}
|
|
916
1071
|
]
|
|
917
|
-
};
|
|
1072
|
+
});
|
|
918
1073
|
} catch (error) {
|
|
919
1074
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
920
1075
|
return {
|
|
@@ -929,9 +1084,85 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
929
1084
|
}
|
|
930
1085
|
})
|
|
931
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
|
+
);
|
|
932
1163
|
server.tool(
|
|
933
1164
|
"bulk-upsert",
|
|
934
|
-
"Bulk insert or
|
|
1165
|
+
"Bulk insert or updallet data from CSV or JSON file. Supports upsert operations with a unique key.",
|
|
935
1166
|
{
|
|
936
1167
|
apiKey: z14.string().optional().describe("API key for authentication (optional if provided via --api_key)"),
|
|
937
1168
|
...bulkUpsertRequestSchema.shape,
|
|
@@ -958,7 +1189,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
958
1189
|
});
|
|
959
1190
|
const result = await handleApiResponse(response);
|
|
960
1191
|
const message = result.success ? `Successfully processed ${result.rowsAffected} of ${result.totalRecords} records into table "${result.table}"` : result.message || "Bulk upsert operation completed";
|
|
961
|
-
return {
|
|
1192
|
+
return await addBackgroundContext({
|
|
962
1193
|
content: [
|
|
963
1194
|
{
|
|
964
1195
|
type: "text",
|
|
@@ -971,7 +1202,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
971
1202
|
})
|
|
972
1203
|
}
|
|
973
1204
|
]
|
|
974
|
-
};
|
|
1205
|
+
});
|
|
975
1206
|
} catch (error) {
|
|
976
1207
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
977
1208
|
return {
|
|
@@ -1005,14 +1236,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1005
1236
|
body: JSON.stringify({ bucketName, isPublic })
|
|
1006
1237
|
});
|
|
1007
1238
|
const result = await handleApiResponse(response);
|
|
1008
|
-
return {
|
|
1239
|
+
return await addBackgroundContext({
|
|
1009
1240
|
content: [
|
|
1010
1241
|
{
|
|
1011
1242
|
type: "text",
|
|
1012
1243
|
text: formatSuccessMessage("Bucket created", result)
|
|
1013
1244
|
}
|
|
1014
1245
|
]
|
|
1015
|
-
};
|
|
1246
|
+
});
|
|
1016
1247
|
} catch (error) {
|
|
1017
1248
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1018
1249
|
return {
|
|
@@ -1040,14 +1271,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1040
1271
|
}
|
|
1041
1272
|
});
|
|
1042
1273
|
const result = await handleApiResponse(response);
|
|
1043
|
-
return {
|
|
1274
|
+
return await addBackgroundContext({
|
|
1044
1275
|
content: [
|
|
1045
1276
|
{
|
|
1046
1277
|
type: "text",
|
|
1047
1278
|
text: formatSuccessMessage("Buckets retrieved", result)
|
|
1048
1279
|
}
|
|
1049
1280
|
]
|
|
1050
|
-
};
|
|
1281
|
+
});
|
|
1051
1282
|
} catch (error) {
|
|
1052
1283
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1053
1284
|
return {
|
|
@@ -1079,14 +1310,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1079
1310
|
}
|
|
1080
1311
|
});
|
|
1081
1312
|
const result = await handleApiResponse(response);
|
|
1082
|
-
return {
|
|
1313
|
+
return await addBackgroundContext({
|
|
1083
1314
|
content: [
|
|
1084
1315
|
{
|
|
1085
1316
|
type: "text",
|
|
1086
1317
|
text: formatSuccessMessage("Bucket deleted", result)
|
|
1087
1318
|
}
|
|
1088
1319
|
]
|
|
1089
|
-
};
|
|
1320
|
+
});
|
|
1090
1321
|
} catch (error) {
|
|
1091
1322
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1092
1323
|
return {
|
|
@@ -1135,7 +1366,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1135
1366
|
})
|
|
1136
1367
|
});
|
|
1137
1368
|
const result = await handleApiResponse(response);
|
|
1138
|
-
return {
|
|
1369
|
+
return await addBackgroundContext({
|
|
1139
1370
|
content: [
|
|
1140
1371
|
{
|
|
1141
1372
|
type: "text",
|
|
@@ -1145,7 +1376,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1145
1376
|
)
|
|
1146
1377
|
}
|
|
1147
1378
|
]
|
|
1148
|
-
};
|
|
1379
|
+
});
|
|
1149
1380
|
} catch (error) {
|
|
1150
1381
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1151
1382
|
return {
|
|
@@ -1175,14 +1406,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1175
1406
|
}
|
|
1176
1407
|
});
|
|
1177
1408
|
const result = await handleApiResponse(response);
|
|
1178
|
-
return {
|
|
1409
|
+
return await addBackgroundContext({
|
|
1179
1410
|
content: [
|
|
1180
1411
|
{
|
|
1181
1412
|
type: "text",
|
|
1182
1413
|
text: formatSuccessMessage(`Edge function '${args.slug}' details`, result)
|
|
1183
1414
|
}
|
|
1184
1415
|
]
|
|
1185
|
-
};
|
|
1416
|
+
});
|
|
1186
1417
|
} catch (error) {
|
|
1187
1418
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1188
1419
|
return {
|
|
@@ -1238,7 +1469,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1238
1469
|
});
|
|
1239
1470
|
const result = await handleApiResponse(response);
|
|
1240
1471
|
const fileInfo = args.codeFile ? ` from ${args.codeFile}` : "";
|
|
1241
|
-
return {
|
|
1472
|
+
return await addBackgroundContext({
|
|
1242
1473
|
content: [
|
|
1243
1474
|
{
|
|
1244
1475
|
type: "text",
|
|
@@ -1248,7 +1479,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1248
1479
|
)
|
|
1249
1480
|
}
|
|
1250
1481
|
]
|
|
1251
|
-
};
|
|
1482
|
+
});
|
|
1252
1483
|
} catch (error) {
|
|
1253
1484
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1254
1485
|
return {
|
|
@@ -1278,14 +1509,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1278
1509
|
}
|
|
1279
1510
|
});
|
|
1280
1511
|
const result = await handleApiResponse(response);
|
|
1281
|
-
return {
|
|
1512
|
+
return await addBackgroundContext({
|
|
1282
1513
|
content: [
|
|
1283
1514
|
{
|
|
1284
1515
|
type: "text",
|
|
1285
1516
|
text: formatSuccessMessage(`Edge function '${args.slug}' deleted successfully`, result)
|
|
1286
1517
|
}
|
|
1287
1518
|
]
|
|
1288
|
-
};
|
|
1519
|
+
});
|
|
1289
1520
|
} catch (error) {
|
|
1290
1521
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1291
1522
|
return {
|
|
@@ -1313,21 +1544,29 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1313
1544
|
const actualApiKey = getApiKey(apiKey);
|
|
1314
1545
|
const queryParams = new URLSearchParams();
|
|
1315
1546
|
if (limit) queryParams.append("limit", limit.toString());
|
|
1316
|
-
|
|
1547
|
+
let response = await fetch2(`${API_BASE_URL}/api/logs/${source}?${queryParams}`, {
|
|
1317
1548
|
method: "GET",
|
|
1318
1549
|
headers: {
|
|
1319
1550
|
"x-api-key": actualApiKey
|
|
1320
1551
|
}
|
|
1321
1552
|
});
|
|
1553
|
+
if (response.status === 404) {
|
|
1554
|
+
response = await fetch2(`${API_BASE_URL}/api/logs/analytics/${source}?${queryParams}`, {
|
|
1555
|
+
method: "GET",
|
|
1556
|
+
headers: {
|
|
1557
|
+
"x-api-key": actualApiKey
|
|
1558
|
+
}
|
|
1559
|
+
});
|
|
1560
|
+
}
|
|
1322
1561
|
const result = await handleApiResponse(response);
|
|
1323
|
-
return {
|
|
1562
|
+
return await addBackgroundContext({
|
|
1324
1563
|
content: [
|
|
1325
1564
|
{
|
|
1326
1565
|
type: "text",
|
|
1327
1566
|
text: formatSuccessMessage(`Latest logs from ${source}`, result)
|
|
1328
1567
|
}
|
|
1329
1568
|
]
|
|
1330
|
-
};
|
|
1569
|
+
});
|
|
1331
1570
|
} catch (error) {
|
|
1332
1571
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1333
1572
|
return {
|
|
@@ -1345,7 +1584,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1345
1584
|
return {
|
|
1346
1585
|
apiKey: GLOBAL_API_KEY,
|
|
1347
1586
|
apiBaseUrl: API_BASE_URL,
|
|
1348
|
-
toolCount:
|
|
1587
|
+
toolCount: 15
|
|
1349
1588
|
};
|
|
1350
1589
|
}
|
|
1351
1590
|
|
package/dist/http-server.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@insforge/mcp",
|
|
3
|
-
"version": "1.1.7-dev.
|
|
3
|
+
"version": "1.1.7-dev.31",
|
|
4
4
|
"description": "MCP (Model Context Protocol) server for Insforge backend-as-a-service",
|
|
5
|
+
"mcpName": "io.github.InsForge/insforge-mcp",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"main": "dist/index.js",
|
|
7
8
|
"bin": {
|
|
@@ -31,7 +32,8 @@
|
|
|
31
32
|
},
|
|
32
33
|
"files": [
|
|
33
34
|
"dist",
|
|
34
|
-
"mcp.json"
|
|
35
|
+
"mcp.json",
|
|
36
|
+
"server.json"
|
|
35
37
|
],
|
|
36
38
|
"dependencies": {
|
|
37
39
|
"@insforge/shared-schemas": "^1.1.7",
|
package/server.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json",
|
|
3
|
+
"name": "io.github.InsForge/insforge-mcp",
|
|
4
|
+
"title": "Insforge",
|
|
5
|
+
"description": "MCP server for Insforge BaaS - database, auth, storage, edge functions, and container logs",
|
|
6
|
+
"version": "1.1.5",
|
|
7
|
+
"packages": [
|
|
8
|
+
{
|
|
9
|
+
"registryType": "npm",
|
|
10
|
+
"identifier": "@insforge/mcp",
|
|
11
|
+
"version": "1.1.5",
|
|
12
|
+
"transport": {
|
|
13
|
+
"type": "stdio"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|