@insforge/mcp 1.1.7-dev.1 → 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);
@@ -764,7 +837,8 @@ function registerInsforgeTools(server, config = {}) {
764
837
  const result = await handleApiResponse(response);
765
838
  if (result && typeof result === "object" && "content" in result) {
766
839
  let content = result.content;
767
- 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);
768
842
  return content;
769
843
  }
770
844
  throw new Error("Invalid response format from documentation endpoint");
@@ -774,12 +848,16 @@ function registerInsforgeTools(server, config = {}) {
774
848
  }
775
849
  };
776
850
  server.tool(
777
- "get-instructions",
778
- "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>",
779
- {},
780
- 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 }) => {
781
859
  try {
782
- const content = await fetchDocumentation("instructions");
860
+ const content = await fetchDocumentation(docType);
783
861
  return {
784
862
  content: [
785
863
  {
@@ -791,7 +869,46 @@ function registerInsforgeTools(server, config = {}) {
791
869
  } catch (error) {
792
870
  const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
793
871
  return {
794
- content: [{ type: "text", text: `Error: ${errMsg}` }]
872
+ content: [{ type: "text", text: `Error fetching ${docType} documentation: ${errMsg}` }]
873
+ };
874
+ }
875
+ })
876
+ );
877
+ server.tool(
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 }) => {
884
+ try {
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
+ }
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
+ };
902
+ } catch (error) {
903
+ const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
904
+ return {
905
+ content: [
906
+ {
907
+ type: "text",
908
+ text: `Error generating anonymous token: ${errMsg}`
909
+ }
910
+ ],
911
+ isError: true
795
912
  };
796
913
  }
797
914
  })
@@ -1304,12 +1421,20 @@ ${JSON.stringify(metadata, null, 2)}`
1304
1421
  const actualApiKey = getApiKey(apiKey);
1305
1422
  const queryParams = new URLSearchParams();
1306
1423
  if (limit) queryParams.append("limit", limit.toString());
1307
- const response = await fetch2(`${API_BASE_URL}/api/logs/analytics/${source}?${queryParams}`, {
1424
+ let response = await fetch2(`${API_BASE_URL}/api/logs/${source}?${queryParams}`, {
1308
1425
  method: "GET",
1309
1426
  headers: {
1310
1427
  "x-api-key": actualApiKey
1311
1428
  }
1312
1429
  });
1430
+ if (response.status === 404) {
1431
+ response = await fetch2(`${API_BASE_URL}/api/logs/analytics/${source}?${queryParams}`, {
1432
+ method: "GET",
1433
+ headers: {
1434
+ "x-api-key": actualApiKey
1435
+ }
1436
+ });
1437
+ }
1313
1438
  const result = await handleApiResponse(response);
1314
1439
  return {
1315
1440
  content: [
@@ -1333,10 +1458,114 @@ ${JSON.stringify(metadata, null, 2)}`
1333
1458
  }
1334
1459
  })
1335
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)
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
+ };
1562
+ }
1563
+ })
1564
+ );
1336
1565
  return {
1337
1566
  apiKey: GLOBAL_API_KEY,
1338
1567
  apiBaseUrl: API_BASE_URL,
1339
- toolCount: 14
1568
+ toolCount: 16
1340
1569
  };
1341
1570
  }
1342
1571
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  registerInsforgeTools
4
- } from "./chunk-CGHSBGKB.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-CGHSBGKB.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,7 +1,8 @@
1
1
  {
2
2
  "name": "@insforge/mcp",
3
- "version": "1.1.7-dev.1",
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
6
  "type": "module",
6
7
  "main": "dist/index.js",
7
8
  "bin": {
@@ -31,10 +32,11 @@
31
32
  },
32
33
  "files": [
33
34
  "dist",
34
- "mcp.json"
35
+ "mcp.json",
36
+ "server.json"
35
37
  ],
36
38
  "dependencies": {
37
- "@insforge/shared-schemas": "^1.1.1",
39
+ "@insforge/shared-schemas": "^1.1.7",
38
40
  "@modelcontextprotocol/sdk": "^1.15.1",
39
41
  "@types/express": "^5.0.3",
40
42
  "commander": "^14.0.0",
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
+ }