@insforge/mcp 1.1.7-dev.4 → 1.1.7-dev.6

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.
@@ -735,10 +735,74 @@ var functionUpdateRequestSchema = z13.object({
735
735
 
736
736
  // src/shared/tools.ts
737
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
+ };
738
744
  function registerInsforgeTools(server, config = {}) {
739
745
  const GLOBAL_API_KEY = config.apiKey || process.env.API_KEY || "";
740
746
  const API_BASE_URL = config.apiBaseUrl || process.env.API_BASE_URL || "http://localhost:7130";
741
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
+ }
742
806
  async function trackToolUsage(toolName, success = true) {
743
807
  if (GLOBAL_API_KEY) {
744
808
  await usageTracker.trackUsage(toolName, success);
@@ -783,14 +847,14 @@ function registerInsforgeTools(server, config = {}) {
783
847
  }
784
848
  };
785
849
  server.tool(
786
- "get-docs",
850
+ "fetch-docs",
787
851
  'Fetch Insforge documentation. Use "instructions" for essential backend setup (MANDATORY FIRST), or select specific SDK docs for database, auth, storage, functions, or AI integration.',
788
852
  {
789
- docType: z14.enum(["instructions", "db-sdk", "auth-sdk", "storage-sdk", "functions-sdk", "ai-integration-sdk"]).describe(
790
- 'Documentation type: "instructions" (essential backend setup - use FIRST), "db-sdk" (database operations), "auth-sdk" (authentication), "storage-sdk" (file storage), "functions-sdk" (edge functions), "ai-integration-sdk" (AI features)'
853
+ docType: z14.enum(["instructions", "db-sdk", "auth-sdk", "storage-sdk", "functions-sdk", "ai-integration-sdk", "auth-components-nextjs"]).describe(
854
+ 'Documentation type: "instructions" (essential backend setup - use FIRST), "db-sdk" (database operations), "auth-sdk" (authentication), "storage-sdk" (file storage), "functions-sdk" (edge functions), "ai-integration-sdk" (AI features), "auth-components-nextjs" (authentication components for Next.js applications)'
791
855
  )
792
856
  },
793
- withUsageTracking("get-docs", async ({ docType }) => {
857
+ withUsageTracking("fetch-docs", async ({ docType }) => {
794
858
  try {
795
859
  const content = await fetchDocumentation(docType);
796
860
  return {
@@ -1356,12 +1420,20 @@ ${JSON.stringify(metadata, null, 2)}`
1356
1420
  const actualApiKey = getApiKey(apiKey);
1357
1421
  const queryParams = new URLSearchParams();
1358
1422
  if (limit) queryParams.append("limit", limit.toString());
1359
- const response = await fetch2(`${API_BASE_URL}/api/logs/analytics/${source}?${queryParams}`, {
1423
+ let response = await fetch2(`${API_BASE_URL}/api/logs/${source}?${queryParams}`, {
1360
1424
  method: "GET",
1361
1425
  headers: {
1362
1426
  "x-api-key": actualApiKey
1363
1427
  }
1364
1428
  });
1429
+ if (response.status === 404) {
1430
+ response = await fetch2(`${API_BASE_URL}/api/logs/analytics/${source}?${queryParams}`, {
1431
+ method: "GET",
1432
+ headers: {
1433
+ "x-api-key": actualApiKey
1434
+ }
1435
+ });
1436
+ }
1365
1437
  const result = await handleApiResponse(response);
1366
1438
  return {
1367
1439
  content: [
@@ -1385,10 +1457,114 @@ ${JSON.stringify(metadata, null, 2)}`
1385
1457
  }
1386
1458
  })
1387
1459
  );
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
+ );
1388
1564
  return {
1389
1565
  apiKey: GLOBAL_API_KEY,
1390
1566
  apiBaseUrl: API_BASE_URL,
1391
- toolCount: 14
1567
+ toolCount: 16
1392
1568
  };
1393
1569
  }
1394
1570
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  registerInsforgeTools
4
- } from "./chunk-BY5473FJ.js";
4
+ } from "./chunk-Y75UHN6G.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-BY5473FJ.js";
4
+ } from "./chunk-Y75UHN6G.js";
5
5
 
6
6
  // src/stdio/index.ts
7
7
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
package/mcp.json CHANGED
@@ -1,7 +1,7 @@
1
- {
2
- "$schema": "https://glama.ai/mcp/schemas/server.json",
3
- "maintainers": [
4
- "InsForge",
5
- "tonychang04"
6
- ]
7
- }
1
+ {
2
+ "$schema": "https://glama.ai/mcp/schemas/server.json",
3
+ "maintainers": [
4
+ "InsForge",
5
+ "tonychang04"
6
+ ]
7
+ }
package/package.json CHANGED
@@ -1,53 +1,55 @@
1
- {
2
- "name": "@insforge/mcp",
3
- "version": "1.1.7-dev.4",
4
- "description": "MCP (Model Context Protocol) server for Insforge backend-as-a-service",
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "bin": {
8
- "insforge-mcp": "./dist/index.js"
9
- },
10
- "scripts": {
11
- "dev:stdio": "tsx watch src/stdio/index.ts",
12
- "dev:http": "tsx watch src/http/server.ts",
13
- "build": "tsup",
14
- "prepublishOnly": "npm run build"
15
- },
16
- "keywords": [
17
- "mcp",
18
- "model-context-protocol",
19
- "insforge",
20
- "backend-as-a-service"
21
- ],
22
- "author": "Insforge",
23
- "license": "Apache-2.0",
24
- "repository": {
25
- "type": "git",
26
- "url": "https://github.com/InsForge/insforge-mcp.git"
27
- },
28
- "homepage": "https://github.com/InsForge/insforge-mcp#readme",
29
- "bugs": {
30
- "url": "https://github.com/InsForge/insforge-mcp/issues"
31
- },
32
- "files": [
33
- "dist",
34
- "mcp.json"
35
- ],
36
- "dependencies": {
37
- "@insforge/shared-schemas": "^1.1.7",
38
- "@modelcontextprotocol/sdk": "^1.15.1",
39
- "@types/express": "^5.0.3",
40
- "commander": "^14.0.0",
41
- "express": "^5.1.0",
42
- "form-data": "^4.0.4",
43
- "node-fetch": "^3.3.2",
44
- "zod": "^3.23.8"
45
- },
46
- "devDependencies": {
47
- "@types/node": "^20.10.5",
48
- "rimraf": "^5.0.5",
49
- "tsup": "^8.5.0",
50
- "tsx": "^4.7.0",
51
- "typescript": "^5.3.3"
52
- }
53
- }
1
+ {
2
+ "name": "@insforge/mcp",
3
+ "version": "1.1.7-dev.6",
4
+ "description": "MCP (Model Context Protocol) server for Insforge backend-as-a-service",
5
+ "mcpName": "io.github.InsForge/insforge-mcp",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "bin": {
9
+ "insforge-mcp": "./dist/index.js"
10
+ },
11
+ "scripts": {
12
+ "dev:stdio": "tsx watch src/stdio/index.ts",
13
+ "dev:http": "tsx watch src/http/server.ts",
14
+ "build": "tsup",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "keywords": [
18
+ "mcp",
19
+ "model-context-protocol",
20
+ "insforge",
21
+ "backend-as-a-service"
22
+ ],
23
+ "author": "Insforge",
24
+ "license": "Apache-2.0",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/InsForge/insforge-mcp.git"
28
+ },
29
+ "homepage": "https://github.com/InsForge/insforge-mcp#readme",
30
+ "bugs": {
31
+ "url": "https://github.com/InsForge/insforge-mcp/issues"
32
+ },
33
+ "files": [
34
+ "dist",
35
+ "mcp.json",
36
+ "server.json"
37
+ ],
38
+ "dependencies": {
39
+ "@insforge/shared-schemas": "^1.1.7",
40
+ "@modelcontextprotocol/sdk": "^1.15.1",
41
+ "@types/express": "^5.0.3",
42
+ "commander": "^14.0.0",
43
+ "express": "^5.1.0",
44
+ "form-data": "^4.0.4",
45
+ "node-fetch": "^3.3.2",
46
+ "zod": "^3.23.8"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^20.10.5",
50
+ "rimraf": "^5.0.5",
51
+ "tsup": "^8.5.0",
52
+ "tsx": "^4.7.0",
53
+ "typescript": "^5.3.3"
54
+ }
55
+ }
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
+ }