@insforge/mcp 1.1.7-dev.3 → 1.1.7-dev.30
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-RCSKABFT.js} +271 -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,75 @@ 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 parts1 = v1.split(".").map(Number);
|
|
782
|
+
const parts2 = v2.split(".").map(Number);
|
|
783
|
+
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
|
|
784
|
+
const part1 = parts1[i] || 0;
|
|
785
|
+
const part2 = parts2[i] || 0;
|
|
786
|
+
if (part1 > part2) return 1;
|
|
787
|
+
if (part1 < part2) return -1;
|
|
788
|
+
}
|
|
789
|
+
return 0;
|
|
790
|
+
}
|
|
791
|
+
async function checkToolVersion(toolName) {
|
|
792
|
+
const requiredVersion = TOOL_VERSION_REQUIREMENTS[toolName];
|
|
793
|
+
if (!requiredVersion) {
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
try {
|
|
797
|
+
const currentVersion = await getBackendVersion();
|
|
798
|
+
if (compareVersions(currentVersion, requiredVersion) < 0) {
|
|
799
|
+
throw new Error(
|
|
800
|
+
`Tool '${toolName}' requires backend version ${requiredVersion} or higher, but current version is ${currentVersion}. Please upgrade your Insforge backend server.`
|
|
801
|
+
);
|
|
802
|
+
}
|
|
803
|
+
} catch (error) {
|
|
804
|
+
if (error instanceof Error && error.message.includes("requires backend version")) {
|
|
805
|
+
throw error;
|
|
806
|
+
}
|
|
807
|
+
console.warn(`Warning: Could not verify backend version for tool '${toolName}': ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
742
810
|
async function trackToolUsage(toolName, success = true) {
|
|
743
811
|
if (GLOBAL_API_KEY) {
|
|
744
812
|
await usageTracker.trackUsage(toolName, success);
|
|
@@ -770,10 +838,14 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
770
838
|
"Content-Type": "application/json"
|
|
771
839
|
}
|
|
772
840
|
});
|
|
841
|
+
if (response.status === 404) {
|
|
842
|
+
throw new Error("Documentation not found");
|
|
843
|
+
}
|
|
773
844
|
const result = await handleApiResponse(response);
|
|
774
845
|
if (result && typeof result === "object" && "content" in result) {
|
|
775
846
|
let content = result.content;
|
|
776
847
|
content = content.replace(/http:\/\/localhost:7130/g, API_BASE_URL);
|
|
848
|
+
content = content.replace(/https:\/\/your-app\.region\.insforge\.app/g, API_BASE_URL);
|
|
777
849
|
return content;
|
|
778
850
|
}
|
|
779
851
|
throw new Error("Invalid response format from documentation endpoint");
|
|
@@ -782,25 +854,106 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
782
854
|
throw new Error(`Unable to retrieve ${docType} documentation: ${errMsg}`);
|
|
783
855
|
}
|
|
784
856
|
};
|
|
857
|
+
const fetchInsforgeInstructionsContext = async () => {
|
|
858
|
+
try {
|
|
859
|
+
return await fetchDocumentation("instructions");
|
|
860
|
+
} catch (error) {
|
|
861
|
+
console.error("Failed to fetch insforge-instructions.md:", error);
|
|
862
|
+
return null;
|
|
863
|
+
}
|
|
864
|
+
};
|
|
865
|
+
const addBackgroundContext = async (response) => {
|
|
866
|
+
try {
|
|
867
|
+
const currentVersion = await getBackendVersion();
|
|
868
|
+
const isLegacyVersion = compareVersions(currentVersion, "1.1.7") < 0;
|
|
869
|
+
if (isLegacyVersion) {
|
|
870
|
+
const context = await fetchInsforgeInstructionsContext();
|
|
871
|
+
if (context && response.content && Array.isArray(response.content)) {
|
|
872
|
+
response.content.push({
|
|
873
|
+
type: "text",
|
|
874
|
+
text: `
|
|
875
|
+
|
|
876
|
+
---
|
|
877
|
+
\u{1F527} INSFORGE DEVELOPMENT RULES (Auto-loaded):
|
|
878
|
+
${context}`
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
} catch {
|
|
883
|
+
console.warn("Could not determine backend version, skipping background context");
|
|
884
|
+
}
|
|
885
|
+
return response;
|
|
886
|
+
};
|
|
785
887
|
server.tool(
|
|
786
|
-
"
|
|
787
|
-
|
|
788
|
-
{
|
|
789
|
-
|
|
888
|
+
"fetch-docs",
|
|
889
|
+
'Fetch Insforge documentation. Use "instructions" for essential backend setup (MANDATORY FIRST), or select specific SDK docs for database, auth, storage, functions, or AI integration.',
|
|
890
|
+
{
|
|
891
|
+
docType: z14.enum(["instructions", "db-sdk", "storage-sdk", "functions-sdk", "ai-integration-sdk", "auth-components-react"]).describe(
|
|
892
|
+
'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,'
|
|
893
|
+
)
|
|
894
|
+
},
|
|
895
|
+
withUsageTracking("fetch-docs", async ({ docType }) => {
|
|
790
896
|
try {
|
|
791
|
-
const content = await fetchDocumentation(
|
|
792
|
-
return {
|
|
897
|
+
const content = await fetchDocumentation(docType);
|
|
898
|
+
return await addBackgroundContext({
|
|
793
899
|
content: [
|
|
794
900
|
{
|
|
795
901
|
type: "text",
|
|
796
902
|
text: content
|
|
797
903
|
}
|
|
798
904
|
]
|
|
905
|
+
});
|
|
906
|
+
} catch (error) {
|
|
907
|
+
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
908
|
+
if (errMsg.includes("404") || errMsg.toLowerCase().includes("not found")) {
|
|
909
|
+
return {
|
|
910
|
+
content: [{
|
|
911
|
+
type: "text",
|
|
912
|
+
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.`
|
|
913
|
+
}]
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
return {
|
|
917
|
+
content: [{ type: "text", text: `Error fetching ${docType} documentation: ${errMsg}` }]
|
|
799
918
|
};
|
|
919
|
+
}
|
|
920
|
+
})
|
|
921
|
+
);
|
|
922
|
+
server.tool(
|
|
923
|
+
"get-anon-key",
|
|
924
|
+
"Generate an anonymous JWT token that never expires. Requires admin API key. Use this for client-side applications that need public access.",
|
|
925
|
+
{
|
|
926
|
+
apiKey: z14.string().optional().describe("API key for authentication (optional if provided via --api_key)")
|
|
927
|
+
},
|
|
928
|
+
withUsageTracking("get-anon-key", async ({ apiKey }) => {
|
|
929
|
+
try {
|
|
930
|
+
const actualApiKey = getApiKey(apiKey);
|
|
931
|
+
const response = await fetch2(`${API_BASE_URL}/api/auth/tokens/anon`, {
|
|
932
|
+
method: "POST",
|
|
933
|
+
headers: {
|
|
934
|
+
"x-api-key": actualApiKey,
|
|
935
|
+
"Content-Type": "application/json"
|
|
936
|
+
}
|
|
937
|
+
});
|
|
938
|
+
const result = await handleApiResponse(response);
|
|
939
|
+
return await addBackgroundContext({
|
|
940
|
+
content: [
|
|
941
|
+
{
|
|
942
|
+
type: "text",
|
|
943
|
+
text: formatSuccessMessage("Anonymous token generated", result)
|
|
944
|
+
}
|
|
945
|
+
]
|
|
946
|
+
});
|
|
800
947
|
} catch (error) {
|
|
801
948
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
802
949
|
return {
|
|
803
|
-
content: [
|
|
950
|
+
content: [
|
|
951
|
+
{
|
|
952
|
+
type: "text",
|
|
953
|
+
text: `Error generating anonymous token: ${errMsg}`
|
|
954
|
+
}
|
|
955
|
+
],
|
|
956
|
+
isError: true
|
|
804
957
|
};
|
|
805
958
|
}
|
|
806
959
|
})
|
|
@@ -822,14 +975,14 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
822
975
|
}
|
|
823
976
|
});
|
|
824
977
|
const result = await handleApiResponse(response);
|
|
825
|
-
return {
|
|
978
|
+
return await addBackgroundContext({
|
|
826
979
|
content: [
|
|
827
980
|
{
|
|
828
981
|
type: "text",
|
|
829
982
|
text: formatSuccessMessage("Schema retrieved", result)
|
|
830
983
|
}
|
|
831
984
|
]
|
|
832
|
-
};
|
|
985
|
+
});
|
|
833
986
|
} catch (error) {
|
|
834
987
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
835
988
|
return {
|
|
@@ -860,7 +1013,7 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
860
1013
|
}
|
|
861
1014
|
});
|
|
862
1015
|
const metadata = await handleApiResponse(response);
|
|
863
|
-
return {
|
|
1016
|
+
return await addBackgroundContext({
|
|
864
1017
|
content: [
|
|
865
1018
|
{
|
|
866
1019
|
type: "text",
|
|
@@ -869,7 +1022,7 @@ function registerInsforgeTools(server, config = {}) {
|
|
|
869
1022
|
${JSON.stringify(metadata, null, 2)}`
|
|
870
1023
|
}
|
|
871
1024
|
]
|
|
872
|
-
};
|
|
1025
|
+
});
|
|
873
1026
|
} catch (error) {
|
|
874
1027
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
875
1028
|
return {
|
|
@@ -907,14 +1060,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
907
1060
|
body: JSON.stringify(requestBody)
|
|
908
1061
|
});
|
|
909
1062
|
const result = await handleApiResponse(response);
|
|
910
|
-
return {
|
|
1063
|
+
return await addBackgroundContext({
|
|
911
1064
|
content: [
|
|
912
1065
|
{
|
|
913
1066
|
type: "text",
|
|
914
1067
|
text: formatSuccessMessage("SQL query executed", result)
|
|
915
1068
|
}
|
|
916
1069
|
]
|
|
917
|
-
};
|
|
1070
|
+
});
|
|
918
1071
|
} catch (error) {
|
|
919
1072
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
920
1073
|
return {
|
|
@@ -929,9 +1082,85 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
929
1082
|
}
|
|
930
1083
|
})
|
|
931
1084
|
);
|
|
1085
|
+
server.tool(
|
|
1086
|
+
"download-template",
|
|
1087
|
+
"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.",
|
|
1088
|
+
{
|
|
1089
|
+
frame: z14.enum(["react"]).describe("Framework to use for the template (currently only React is supported)"),
|
|
1090
|
+
projectName: z14.string().optional().describe('Name for the project directory (optional, defaults to "insforge-react")')
|
|
1091
|
+
},
|
|
1092
|
+
withUsageTracking("download-template", async ({ frame, projectName }) => {
|
|
1093
|
+
try {
|
|
1094
|
+
const response = await fetch2(`${API_BASE_URL}/api/auth/tokens/anon`, {
|
|
1095
|
+
method: "POST",
|
|
1096
|
+
headers: {
|
|
1097
|
+
"x-api-key": getApiKey(),
|
|
1098
|
+
"Content-Type": "application/json"
|
|
1099
|
+
}
|
|
1100
|
+
});
|
|
1101
|
+
const result = await handleApiResponse(response);
|
|
1102
|
+
const anonKey = result.accessToken;
|
|
1103
|
+
if (!anonKey) {
|
|
1104
|
+
throw new Error("Failed to retrieve anon key from backend");
|
|
1105
|
+
}
|
|
1106
|
+
const tempDir = tmpdir();
|
|
1107
|
+
const targetDir = projectName || `insforge-${frame}`;
|
|
1108
|
+
const templatePath = `${tempDir}/${targetDir}`;
|
|
1109
|
+
console.error(`[download-template] Target path: ${templatePath}`);
|
|
1110
|
+
try {
|
|
1111
|
+
const stats = await fs.stat(templatePath);
|
|
1112
|
+
if (stats.isDirectory()) {
|
|
1113
|
+
console.error(`[download-template] Removing existing template at ${templatePath}`);
|
|
1114
|
+
await fs.rm(templatePath, { recursive: true, force: true });
|
|
1115
|
+
}
|
|
1116
|
+
} catch {
|
|
1117
|
+
}
|
|
1118
|
+
const command = `npx create-insforge-app ${targetDir} --frame ${frame} --base-url ${API_BASE_URL} --anon-key ${anonKey} --skip-install`;
|
|
1119
|
+
const { stdout, stderr } = await execAsync(command, {
|
|
1120
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
1121
|
+
// 10MB buffer
|
|
1122
|
+
cwd: tempDir
|
|
1123
|
+
});
|
|
1124
|
+
const output = stdout || stderr || "";
|
|
1125
|
+
if (output.toLowerCase().includes("error") && !output.includes("successfully")) {
|
|
1126
|
+
throw new Error(`Failed to download template: ${output}`);
|
|
1127
|
+
}
|
|
1128
|
+
return await addBackgroundContext({
|
|
1129
|
+
content: [
|
|
1130
|
+
{
|
|
1131
|
+
type: "text",
|
|
1132
|
+
text: `\u2705 React template downloaded successfully
|
|
1133
|
+
|
|
1134
|
+
\u{1F4C1} Template Location: ${templatePath}
|
|
1135
|
+
|
|
1136
|
+
\u26A0\uFE0F IMPORTANT: The template is in a temporary directory and NOT in your current working directory.
|
|
1137
|
+
|
|
1138
|
+
\u{1F534} CRITICAL NEXT STEP REQUIRED:
|
|
1139
|
+
You MUST copy ALL files (INCLUDING HIDDEN FILES like .env, .gitignore, etc.) from the temporary directory to your current project directory.
|
|
1140
|
+
|
|
1141
|
+
Copy all files from: ${templatePath}
|
|
1142
|
+
To: Your current project directory
|
|
1143
|
+
`
|
|
1144
|
+
}
|
|
1145
|
+
]
|
|
1146
|
+
});
|
|
1147
|
+
} catch (error) {
|
|
1148
|
+
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1149
|
+
return {
|
|
1150
|
+
content: [
|
|
1151
|
+
{
|
|
1152
|
+
type: "text",
|
|
1153
|
+
text: `Error downloading template: ${errMsg}`
|
|
1154
|
+
}
|
|
1155
|
+
],
|
|
1156
|
+
isError: true
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
})
|
|
1160
|
+
);
|
|
932
1161
|
server.tool(
|
|
933
1162
|
"bulk-upsert",
|
|
934
|
-
"Bulk insert or
|
|
1163
|
+
"Bulk insert or updallet data from CSV or JSON file. Supports upsert operations with a unique key.",
|
|
935
1164
|
{
|
|
936
1165
|
apiKey: z14.string().optional().describe("API key for authentication (optional if provided via --api_key)"),
|
|
937
1166
|
...bulkUpsertRequestSchema.shape,
|
|
@@ -958,7 +1187,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
958
1187
|
});
|
|
959
1188
|
const result = await handleApiResponse(response);
|
|
960
1189
|
const message = result.success ? `Successfully processed ${result.rowsAffected} of ${result.totalRecords} records into table "${result.table}"` : result.message || "Bulk upsert operation completed";
|
|
961
|
-
return {
|
|
1190
|
+
return await addBackgroundContext({
|
|
962
1191
|
content: [
|
|
963
1192
|
{
|
|
964
1193
|
type: "text",
|
|
@@ -971,7 +1200,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
971
1200
|
})
|
|
972
1201
|
}
|
|
973
1202
|
]
|
|
974
|
-
};
|
|
1203
|
+
});
|
|
975
1204
|
} catch (error) {
|
|
976
1205
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
977
1206
|
return {
|
|
@@ -1005,14 +1234,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1005
1234
|
body: JSON.stringify({ bucketName, isPublic })
|
|
1006
1235
|
});
|
|
1007
1236
|
const result = await handleApiResponse(response);
|
|
1008
|
-
return {
|
|
1237
|
+
return await addBackgroundContext({
|
|
1009
1238
|
content: [
|
|
1010
1239
|
{
|
|
1011
1240
|
type: "text",
|
|
1012
1241
|
text: formatSuccessMessage("Bucket created", result)
|
|
1013
1242
|
}
|
|
1014
1243
|
]
|
|
1015
|
-
};
|
|
1244
|
+
});
|
|
1016
1245
|
} catch (error) {
|
|
1017
1246
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1018
1247
|
return {
|
|
@@ -1040,14 +1269,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1040
1269
|
}
|
|
1041
1270
|
});
|
|
1042
1271
|
const result = await handleApiResponse(response);
|
|
1043
|
-
return {
|
|
1272
|
+
return await addBackgroundContext({
|
|
1044
1273
|
content: [
|
|
1045
1274
|
{
|
|
1046
1275
|
type: "text",
|
|
1047
1276
|
text: formatSuccessMessage("Buckets retrieved", result)
|
|
1048
1277
|
}
|
|
1049
1278
|
]
|
|
1050
|
-
};
|
|
1279
|
+
});
|
|
1051
1280
|
} catch (error) {
|
|
1052
1281
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1053
1282
|
return {
|
|
@@ -1079,14 +1308,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1079
1308
|
}
|
|
1080
1309
|
});
|
|
1081
1310
|
const result = await handleApiResponse(response);
|
|
1082
|
-
return {
|
|
1311
|
+
return await addBackgroundContext({
|
|
1083
1312
|
content: [
|
|
1084
1313
|
{
|
|
1085
1314
|
type: "text",
|
|
1086
1315
|
text: formatSuccessMessage("Bucket deleted", result)
|
|
1087
1316
|
}
|
|
1088
1317
|
]
|
|
1089
|
-
};
|
|
1318
|
+
});
|
|
1090
1319
|
} catch (error) {
|
|
1091
1320
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1092
1321
|
return {
|
|
@@ -1135,7 +1364,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1135
1364
|
})
|
|
1136
1365
|
});
|
|
1137
1366
|
const result = await handleApiResponse(response);
|
|
1138
|
-
return {
|
|
1367
|
+
return await addBackgroundContext({
|
|
1139
1368
|
content: [
|
|
1140
1369
|
{
|
|
1141
1370
|
type: "text",
|
|
@@ -1145,7 +1374,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1145
1374
|
)
|
|
1146
1375
|
}
|
|
1147
1376
|
]
|
|
1148
|
-
};
|
|
1377
|
+
});
|
|
1149
1378
|
} catch (error) {
|
|
1150
1379
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1151
1380
|
return {
|
|
@@ -1175,14 +1404,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1175
1404
|
}
|
|
1176
1405
|
});
|
|
1177
1406
|
const result = await handleApiResponse(response);
|
|
1178
|
-
return {
|
|
1407
|
+
return await addBackgroundContext({
|
|
1179
1408
|
content: [
|
|
1180
1409
|
{
|
|
1181
1410
|
type: "text",
|
|
1182
1411
|
text: formatSuccessMessage(`Edge function '${args.slug}' details`, result)
|
|
1183
1412
|
}
|
|
1184
1413
|
]
|
|
1185
|
-
};
|
|
1414
|
+
});
|
|
1186
1415
|
} catch (error) {
|
|
1187
1416
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1188
1417
|
return {
|
|
@@ -1238,7 +1467,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1238
1467
|
});
|
|
1239
1468
|
const result = await handleApiResponse(response);
|
|
1240
1469
|
const fileInfo = args.codeFile ? ` from ${args.codeFile}` : "";
|
|
1241
|
-
return {
|
|
1470
|
+
return await addBackgroundContext({
|
|
1242
1471
|
content: [
|
|
1243
1472
|
{
|
|
1244
1473
|
type: "text",
|
|
@@ -1248,7 +1477,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1248
1477
|
)
|
|
1249
1478
|
}
|
|
1250
1479
|
]
|
|
1251
|
-
};
|
|
1480
|
+
});
|
|
1252
1481
|
} catch (error) {
|
|
1253
1482
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1254
1483
|
return {
|
|
@@ -1278,14 +1507,14 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1278
1507
|
}
|
|
1279
1508
|
});
|
|
1280
1509
|
const result = await handleApiResponse(response);
|
|
1281
|
-
return {
|
|
1510
|
+
return await addBackgroundContext({
|
|
1282
1511
|
content: [
|
|
1283
1512
|
{
|
|
1284
1513
|
type: "text",
|
|
1285
1514
|
text: formatSuccessMessage(`Edge function '${args.slug}' deleted successfully`, result)
|
|
1286
1515
|
}
|
|
1287
1516
|
]
|
|
1288
|
-
};
|
|
1517
|
+
});
|
|
1289
1518
|
} catch (error) {
|
|
1290
1519
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1291
1520
|
return {
|
|
@@ -1313,21 +1542,29 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1313
1542
|
const actualApiKey = getApiKey(apiKey);
|
|
1314
1543
|
const queryParams = new URLSearchParams();
|
|
1315
1544
|
if (limit) queryParams.append("limit", limit.toString());
|
|
1316
|
-
|
|
1545
|
+
let response = await fetch2(`${API_BASE_URL}/api/logs/${source}?${queryParams}`, {
|
|
1317
1546
|
method: "GET",
|
|
1318
1547
|
headers: {
|
|
1319
1548
|
"x-api-key": actualApiKey
|
|
1320
1549
|
}
|
|
1321
1550
|
});
|
|
1551
|
+
if (response.status === 404) {
|
|
1552
|
+
response = await fetch2(`${API_BASE_URL}/api/logs/analytics/${source}?${queryParams}`, {
|
|
1553
|
+
method: "GET",
|
|
1554
|
+
headers: {
|
|
1555
|
+
"x-api-key": actualApiKey
|
|
1556
|
+
}
|
|
1557
|
+
});
|
|
1558
|
+
}
|
|
1322
1559
|
const result = await handleApiResponse(response);
|
|
1323
|
-
return {
|
|
1560
|
+
return await addBackgroundContext({
|
|
1324
1561
|
content: [
|
|
1325
1562
|
{
|
|
1326
1563
|
type: "text",
|
|
1327
1564
|
text: formatSuccessMessage(`Latest logs from ${source}`, result)
|
|
1328
1565
|
}
|
|
1329
1566
|
]
|
|
1330
|
-
};
|
|
1567
|
+
});
|
|
1331
1568
|
} catch (error) {
|
|
1332
1569
|
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
|
|
1333
1570
|
return {
|
|
@@ -1345,7 +1582,7 @@ ${JSON.stringify(metadata, null, 2)}`
|
|
|
1345
1582
|
return {
|
|
1346
1583
|
apiKey: GLOBAL_API_KEY,
|
|
1347
1584
|
apiBaseUrl: API_BASE_URL,
|
|
1348
|
-
toolCount:
|
|
1585
|
+
toolCount: 15
|
|
1349
1586
|
};
|
|
1350
1587
|
}
|
|
1351
1588
|
|
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.30",
|
|
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
|
+
}
|