@suveren/gateway 0.11.1 → 0.12.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.
Files changed (117) hide show
  1. package/README.md +1 -1
  2. package/bin/suveren-gateway.js +9 -0
  3. package/content/integrations/calendar.json +1 -0
  4. package/content/integrations/crm.json +1 -67
  5. package/content/integrations/deploy-github.json +3 -5
  6. package/content/integrations/erp.json +1 -80
  7. package/content/integrations/gmail.json +1 -0
  8. package/content/integrations/linkedin.json +1 -0
  9. package/content/integrations/mail.json +1 -48
  10. package/content/integrations/mollie.json +1 -0
  11. package/content/integrations/records.json +1 -0
  12. package/dist/mcp-server/http.mjs +234 -51
  13. package/lib/node-version.d.mts +7 -0
  14. package/lib/node-version.mjs +28 -0
  15. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.d.ts.map +1 -1
  16. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.js +9 -7
  17. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.js.map +1 -1
  18. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/sse.d.ts +13 -0
  19. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/sse.d.ts.map +1 -1
  20. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/sse.js +17 -4
  21. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/sse.js.map +1 -1
  22. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.d.ts +13 -0
  23. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.d.ts.map +1 -1
  24. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.js +23 -10
  25. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.js.map +1 -1
  26. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/elicitationFormExample.js +63 -20
  27. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/elicitationFormExample.js.map +1 -1
  28. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/elicitationUrlExample.js +71 -29
  29. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/elicitationUrlExample.js.map +1 -1
  30. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/jsonResponseStreamableHttp.js +45 -6
  31. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/jsonResponseStreamableHttp.js.map +1 -1
  32. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/simpleStreamableHttp.js +71 -31
  33. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/simpleStreamableHttp.js.map +1 -1
  34. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/simpleTaskInteractive.js +61 -18
  35. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/simpleTaskInteractive.js.map +1 -1
  36. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/sseAndStreamableHttpCompatibleServer.js +57 -19
  37. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/sseAndStreamableHttpCompatibleServer.js.map +1 -1
  38. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/ssePollingExample.js +64 -17
  39. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/ssePollingExample.js.map +1 -1
  40. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/standaloneSseWithGetStreamableHttp.js +61 -13
  41. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/standaloneSseWithGetStreamableHttp.js.map +1 -1
  42. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/interfaces.d.ts +4 -0
  43. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/interfaces.d.ts.map +1 -1
  44. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/interfaces.js.map +1 -1
  45. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/stores/in-memory.d.ts +17 -8
  46. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/stores/in-memory.d.ts.map +1 -1
  47. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/stores/in-memory.js +31 -14
  48. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/stores/in-memory.js.map +1 -1
  49. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/middleware/bearerAuth.d.ts +9 -1
  50. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/middleware/bearerAuth.d.ts.map +1 -1
  51. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/middleware/bearerAuth.js +17 -1
  52. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/middleware/bearerAuth.js.map +1 -1
  53. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.d.ts +12 -1
  54. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.d.ts.map +1 -1
  55. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.js +46 -2
  56. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.js.map +1 -1
  57. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.d.ts +1 -0
  58. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.d.ts.map +1 -1
  59. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.js +39 -9
  60. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.js.map +1 -1
  61. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/transport.d.ts +10 -0
  62. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/transport.d.ts.map +1 -1
  63. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/transport.js +77 -0
  64. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/transport.js.map +1 -1
  65. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.d.ts.map +1 -1
  66. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js +9 -7
  67. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js.map +1 -1
  68. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.d.ts +13 -0
  69. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.d.ts.map +1 -1
  70. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.js +18 -5
  71. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.js.map +1 -1
  72. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.d.ts +13 -0
  73. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.d.ts.map +1 -1
  74. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js +24 -11
  75. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js.map +1 -1
  76. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/elicitationFormExample.js +63 -20
  77. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/elicitationFormExample.js.map +1 -1
  78. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/elicitationUrlExample.js +71 -29
  79. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/elicitationUrlExample.js.map +1 -1
  80. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/jsonResponseStreamableHttp.js +45 -6
  81. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/jsonResponseStreamableHttp.js.map +1 -1
  82. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/simpleStreamableHttp.js +71 -31
  83. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/simpleStreamableHttp.js.map +1 -1
  84. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/simpleTaskInteractive.js +61 -18
  85. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/simpleTaskInteractive.js.map +1 -1
  86. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/sseAndStreamableHttpCompatibleServer.js +57 -19
  87. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/sseAndStreamableHttpCompatibleServer.js.map +1 -1
  88. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/ssePollingExample.js +64 -17
  89. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/ssePollingExample.js.map +1 -1
  90. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/standaloneSseWithGetStreamableHttp.js +61 -13
  91. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/standaloneSseWithGetStreamableHttp.js.map +1 -1
  92. package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.d.ts +4 -0
  93. package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.d.ts.map +1 -1
  94. package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js.map +1 -1
  95. package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/stores/in-memory.d.ts +17 -8
  96. package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/stores/in-memory.d.ts.map +1 -1
  97. package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/stores/in-memory.js +31 -14
  98. package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/stores/in-memory.js.map +1 -1
  99. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/middleware/bearerAuth.d.ts +9 -1
  100. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/middleware/bearerAuth.d.ts.map +1 -1
  101. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/middleware/bearerAuth.js +17 -1
  102. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/middleware/bearerAuth.js.map +1 -1
  103. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.d.ts +12 -1
  104. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.d.ts.map +1 -1
  105. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js +46 -2
  106. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js.map +1 -1
  107. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.d.ts +1 -0
  108. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.d.ts.map +1 -1
  109. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js +39 -9
  110. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js.map +1 -1
  111. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.d.ts +10 -0
  112. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.d.ts.map +1 -1
  113. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.js +72 -0
  114. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.js.map +1 -1
  115. package/node_modules/@modelcontextprotocol/sdk/package.json +1 -1
  116. package/package.json +2 -2
  117. package/server.js +9 -0
@@ -1885,7 +1885,7 @@ var SharedState = class {
1885
1885
 
1886
1886
  // src/index.ts
1887
1887
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
1888
- import { z } from "zod";
1888
+ import { z as z2 } from "zod";
1889
1889
 
1890
1890
  // src/lib/mandate-brief.ts
1891
1891
  import { getProfile } from "@hap/core";
@@ -2607,6 +2607,20 @@ import { randomUUID } from "crypto";
2607
2607
  // src/lib/manifest-loader.ts
2608
2608
  import { readFileSync as readFileSync12, existsSync as existsSync11 } from "fs";
2609
2609
  import { join as join11, resolve } from "path";
2610
+ var EXACT_SEMVER_RE = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
2611
+ function isExactSemver(value) {
2612
+ return typeof value === "string" && EXACT_SEMVER_RE.test(value);
2613
+ }
2614
+ function invalidNpmPinReason(manifest) {
2615
+ if (!manifest.npmPackage) return null;
2616
+ if (manifest.npmVersion === void 0) {
2617
+ return `npmPackage "${manifest.npmPackage}" is set but npmVersion is missing \u2014 every connector manifest must pin an exact tested version`;
2618
+ }
2619
+ if (!isExactSemver(manifest.npmVersion)) {
2620
+ return `npmVersion ${JSON.stringify(manifest.npmVersion)} for "${manifest.npmPackage}" is not an exact semver (e.g. "1.2.3") \u2014 ranges, dist-tags like "latest", git specs, URLs, and file paths are not allowed`;
2621
+ }
2622
+ return null;
2623
+ }
2610
2624
  var manifests = /* @__PURE__ */ new Map();
2611
2625
  function loadManifests(integrationsDir) {
2612
2626
  const dir = resolve(
@@ -2629,6 +2643,11 @@ function loadManifests(integrationsDir) {
2629
2643
  const manifestPath = join11(dir, relativePath);
2630
2644
  try {
2631
2645
  const manifest = JSON.parse(readFileSync12(manifestPath, "utf-8"));
2646
+ const pinReason = invalidNpmPinReason(manifest);
2647
+ if (pinReason) {
2648
+ console.error(`[ManifestLoader] Refusing manifest ${id} (${manifestPath}): ${pinReason}`);
2649
+ continue;
2650
+ }
2632
2651
  manifests.set(id, manifest);
2633
2652
  loaded++;
2634
2653
  } catch (err) {
@@ -3960,45 +3979,83 @@ ${lines.join("\n")}`
3960
3979
  };
3961
3980
  }
3962
3981
 
3963
- // src/index.ts
3964
- function jsonSchemaToZodShape(schema) {
3965
- const properties = schema.properties ?? {};
3966
- const required = new Set(schema.required ?? []);
3967
- const shape = {};
3968
- for (const [key, prop] of Object.entries(properties)) {
3969
- let zodType;
3970
- switch (prop.type) {
3971
- case "string":
3972
- if (prop.enum && Array.isArray(prop.enum)) {
3973
- zodType = z.enum(prop.enum);
3974
- } else {
3975
- zodType = z.string();
3976
- }
3977
- break;
3978
- case "number":
3979
- case "integer":
3980
- zodType = z.number();
3981
- break;
3982
- case "boolean":
3983
- zodType = z.boolean();
3984
- break;
3985
- case "array":
3986
- zodType = z.array(z.unknown());
3987
- break;
3988
- case "object":
3989
- zodType = z.record(z.unknown());
3990
- break;
3991
- default:
3992
- zodType = z.unknown();
3982
+ // src/lib/json-schema-to-zod.ts
3983
+ import { z } from "zod";
3984
+ var MAX_DEPTH = 8;
3985
+ function convert(schema, depth) {
3986
+ if (!schema || typeof schema !== "object" || depth > MAX_DEPTH) return z.unknown();
3987
+ const s = schema;
3988
+ if ("$ref" in s) return withDescription(z.unknown(), s);
3989
+ let t;
3990
+ const type = Array.isArray(s.type) ? void 0 : s.type;
3991
+ switch (type) {
3992
+ case "string": {
3993
+ if (Array.isArray(s.enum) && s.enum.length > 0 && s.enum.every((v) => typeof v === "string")) {
3994
+ t = z.enum(s.enum);
3993
3995
  break;
3996
+ }
3997
+ let str = z.string();
3998
+ if (typeof s.minLength === "number") str = str.min(s.minLength);
3999
+ if (typeof s.maxLength === "number") str = str.max(s.maxLength);
4000
+ if (typeof s.pattern === "string") {
4001
+ try {
4002
+ str = str.regex(new RegExp(s.pattern));
4003
+ } catch {
4004
+ }
4005
+ }
4006
+ t = str;
4007
+ break;
3994
4008
  }
3995
- if (typeof prop.description === "string") {
3996
- zodType = zodType.describe(prop.description);
4009
+ case "number":
4010
+ case "integer": {
4011
+ let num = z.number();
4012
+ if (type === "integer") num = num.int();
4013
+ if (typeof s.minimum === "number") num = num.min(s.minimum);
4014
+ if (typeof s.maximum === "number") num = num.max(s.maximum);
4015
+ t = num;
4016
+ break;
4017
+ }
4018
+ case "boolean":
4019
+ t = z.boolean();
4020
+ break;
4021
+ case "array": {
4022
+ let arr = z.array(s.items ? convert(s.items, depth + 1) : z.unknown());
4023
+ if (typeof s.minItems === "number") arr = arr.min(s.minItems);
4024
+ if (typeof s.maxItems === "number") arr = arr.max(s.maxItems);
4025
+ t = arr;
4026
+ break;
4027
+ }
4028
+ case "object": {
4029
+ if (s.properties && typeof s.properties === "object") {
4030
+ t = z.object(shapeOf(s, depth + 1)).passthrough();
4031
+ } else {
4032
+ t = z.record(z.unknown());
4033
+ }
4034
+ break;
3997
4035
  }
3998
- shape[key] = required.has(key) ? zodType : zodType.optional();
4036
+ default:
4037
+ t = z.unknown();
4038
+ }
4039
+ return withDescription(t, s);
4040
+ }
4041
+ function withDescription(t, s) {
4042
+ return typeof s.description === "string" ? t.describe(s.description) : t;
4043
+ }
4044
+ function shapeOf(schema, depth) {
4045
+ const properties = schema.properties ?? {};
4046
+ const required = new Set(Array.isArray(schema.required) ? schema.required : []);
4047
+ const shape = {};
4048
+ for (const [key, prop] of Object.entries(properties)) {
4049
+ const t = convert(prop, depth);
4050
+ shape[key] = required.has(key) ? t : t.optional();
3999
4051
  }
4000
4052
  return shape;
4001
4053
  }
4054
+ function jsonSchemaToZodShape(schema) {
4055
+ return shapeOf(schema ?? {}, 1);
4056
+ }
4057
+
4058
+ // src/index.ts
4002
4059
  function createMcpServer(state2, integrationManager2) {
4003
4060
  const { cache } = state2;
4004
4061
  const enriched = state2.getEnrichedAuthorizations();
@@ -4016,7 +4073,7 @@ function createMcpServer(state2, integrationManager2) {
4016
4073
  {
4017
4074
  description: 'List what you are currently authorized to do. Call with no arguments for a compact overview, or with a domain (e.g., "charge") for full details including consumption, bounds, and capability map.',
4018
4075
  inputSchema: {
4019
- domain: z.string().optional().describe('Profile domain to show full details for (e.g., "charge", "deploy"). Omit for compact overview.')
4076
+ domain: z2.string().optional().describe('Profile domain to show full details for (e.g., "charge", "deploy"). Omit for compact overview.')
4020
4077
  }
4021
4078
  },
4022
4079
  listAuthorizationsHandler(state2, integrationManager2)
@@ -4026,7 +4083,7 @@ function createMcpServer(state2, integrationManager2) {
4026
4083
  {
4027
4084
  description: "Check if any attestations are waiting for your owner's approval.",
4028
4085
  inputSchema: {
4029
- domain: z.string().describe(`The owner's domain (e.g., "compliance")`)
4086
+ domain: z2.string().describe(`The owner's domain (e.g., "compliance")`)
4030
4087
  }
4031
4088
  },
4032
4089
  checkPendingHandler(cache)
@@ -4044,7 +4101,7 @@ function createMcpServer(state2, integrationManager2) {
4044
4101
  {
4045
4102
  description: "Check status of pending proposals awaiting domain owner commitment. Call with a proposal_id to check a specific proposal, or without to see all.",
4046
4103
  inputSchema: {
4047
- proposal_id: z.string().optional().describe("Specific proposal ID to check. Omit to see all.")
4104
+ proposal_id: z2.string().optional().describe("Specific proposal ID to check. Omit to see all.")
4048
4105
  }
4049
4106
  },
4050
4107
  checkPendingCommitmentsHandler(state2, integrationManager2)
@@ -4345,6 +4402,17 @@ var IntegrationManager = class {
4345
4402
  }
4346
4403
  running = /* @__PURE__ */ new Map();
4347
4404
  onToolsChanged = null;
4405
+ /**
4406
+ * Called when a persisted config was migrated to the manifest's command/args
4407
+ * (see `migrateNpxConfig`) so the caller can write the fix back to
4408
+ * `integrations.json` — the manager itself has no registry/persistence
4409
+ * handle, by design (mirrors `onToolsChanged`). Without a subscriber the
4410
+ * migration still takes effect for THIS start (the in-memory config is
4411
+ * still corrected before spawn); only the one-time persistence is skipped,
4412
+ * so every later start keeps re-migrating in memory, which is safe, if
4413
+ * redundant.
4414
+ */
4415
+ onConfigMigrated = null;
4348
4416
  /**
4349
4417
  * Per-integration operation queue. Start/stop for one id are serialized
4350
4418
  * through here; without it, a second start issued while the first is still
@@ -4370,6 +4438,16 @@ var IntegrationManager = class {
4370
4438
  setOnToolsChanged(cb) {
4371
4439
  this.onToolsChanged = cb;
4372
4440
  }
4441
+ /**
4442
+ * Register a callback invoked when a persisted config is migrated off a
4443
+ * stale `npx` command to the current manifest's command/args (see
4444
+ * `migrateNpxConfig`). The caller is expected to persist `updates` against
4445
+ * `id` in `integrations.json` so the fix survives the next boot instead of
4446
+ * silently reapplying on every start.
4447
+ */
4448
+ setOnConfigMigrated(cb) {
4449
+ this.onConfigMigrated = cb;
4450
+ }
4373
4451
  /**
4374
4452
  * Is `npmPackage` present AND usable?
4375
4453
  *
@@ -4400,6 +4478,23 @@ var IntegrationManager = class {
4400
4478
  return false;
4401
4479
  }
4402
4480
  }
4481
+ /**
4482
+ * The installed version of `npmPackage`, or null if it isn't usably
4483
+ * installed at all (see `isUsableInstall`) or its package.json has no
4484
+ * parseable `version`. Never throws — an unreadable version is treated the
4485
+ * same as "not installed", which is the safe direction: it drives a
4486
+ * (re)install rather than a false "already pinned".
4487
+ */
4488
+ readInstalledVersion(npmPackage) {
4489
+ if (!this.isUsableInstall(npmPackage)) return null;
4490
+ const pkgJson = join13(INTEGRATIONS_DIR, "node_modules", ...npmPackage.split("/"), "package.json");
4491
+ try {
4492
+ const pkg = JSON.parse(readFileSync14(pkgJson, "utf8"));
4493
+ return typeof pkg.version === "string" ? pkg.version : null;
4494
+ } catch {
4495
+ return null;
4496
+ }
4497
+ }
4403
4498
  /**
4404
4499
  * Does the node_modules/.bin shim for `binName` exist? On Windows npm writes
4405
4500
  * `<name>`, `<name>.cmd`, and `<name>.ps1`; the .cmd variant is what actually
@@ -4410,9 +4505,32 @@ var IntegrationManager = class {
4410
4505
  const candidates = process.platform === "win32" ? [binName, `${binName}.cmd`, `${binName}.CMD`, `${binName}.ps1`] : [binName];
4411
4506
  return candidates.some((c) => existsSync13(join13(INTEGRATIONS_BIN, c)));
4412
4507
  }
4508
+ /**
4509
+ * The exact version THIS gateway's CURRENTLY LOADED manifest pins
4510
+ * `config.npmPackage` to — or undefined when there's no npmPackage, no
4511
+ * manifest for this id, or the manifest's `npmPackage` no longer names the
4512
+ * same package as `config` (a manually re-pointed integration: nothing in
4513
+ * the manifest vouches for a version of config's actual package).
4514
+ *
4515
+ * Read fresh from `getManifest(config.id)` on every call, never from
4516
+ * anything persisted on `config` itself — manifests are reloaded fresh on
4517
+ * every boot, `integrations.json` is not, so this is what keeps the pin
4518
+ * from going stale the day after an integration was first activated. Used
4519
+ * both to decide the npm install/update (`ensureInstalled`) and to decide
4520
+ * whether a persisted `npx …` command must be refused/migrated
4521
+ * (`migrateNpxConfig`) — one definition of "pinned", so the two can't
4522
+ * disagree about which connectors it applies to.
4523
+ */
4524
+ pinnedVersionFor(config) {
4525
+ if (!config.npmPackage) return void 0;
4526
+ const manifest = getManifest(config.id);
4527
+ return manifest?.npmPackage === config.npmPackage ? manifest.npmVersion : void 0;
4528
+ }
4413
4529
  /**
4414
4530
  * Install an npm package into the managed integrations directory if not
4415
- * already present. Called automatically before spawning when
4531
+ * already present, and — when `config`'s manifest pins an exact
4532
+ * `npmVersion` for this same package — bring the installed copy to EXACTLY
4533
+ * that version, older or newer. Called automatically before spawning when
4416
4534
  * config.npmPackage is set.
4417
4535
  *
4418
4536
  * Asynchronous ON PURPOSE. This used to be execSync, which blocked the MCP
@@ -4422,19 +4540,49 @@ var IntegrationManager = class {
4422
4540
  * CI runners: ~3.6s (Linux), ~5.4s (macOS), ~14s (Windows), and far worse
4423
4541
  * on machines with real-time antivirus.
4424
4542
  */
4425
- async ensureInstalled(npmPackage) {
4543
+ async ensureInstalled(config) {
4544
+ const npmPackage = config.npmPackage;
4545
+ if (!npmPackage) return;
4426
4546
  ensureIntegrationsDir();
4547
+ const pinnedVersion = this.pinnedVersionFor(config);
4548
+ if (pinnedVersion) {
4549
+ if (this.readInstalledVersion(npmPackage) === pinnedVersion) return;
4550
+ return withInstallLock(async () => {
4551
+ const current = this.readInstalledVersion(npmPackage);
4552
+ if (current === pinnedVersion) return;
4553
+ console.error(
4554
+ `[IntegrationManager] ${npmPackage} ${current ?? "(not installed)"} \u2192 ${pinnedVersion} (pinned by manifest)`
4555
+ );
4556
+ const cleanFirst = !this.isUsableInstall(npmPackage);
4557
+ await this.installNow(npmPackage, pinnedVersion, cleanFirst);
4558
+ });
4559
+ }
4427
4560
  if (this.isUsableInstall(npmPackage)) return;
4428
4561
  return withInstallLock(async () => {
4429
4562
  if (this.isUsableInstall(npmPackage)) return;
4430
4563
  await this.installNow(npmPackage);
4431
4564
  });
4432
4565
  }
4433
- /** The actual install. Callers MUST hold the install lock. */
4434
- async installNow(npmPackage) {
4566
+ /**
4567
+ * The actual install. Callers MUST hold the install lock.
4568
+ *
4569
+ * `exactVersion`, when given, is a pin already validated as an exact semver
4570
+ * by the manifest loader (`isExactSemver`) — re-validated here anyway
4571
+ * because this method does not trust its caller's caller, and because the
4572
+ * version reaches a shell on Windows (see the package-name check below).
4573
+ *
4574
+ * `cleanFirst` (default true, i.e. today's behaviour for every caller
4575
+ * except a version-only pin correction): wipe any existing package
4576
+ * directory before installing. Needed for a genuinely broken/partial
4577
+ * install, where stale files can make the reinstall itself fail; skipped
4578
+ * for a USABLE install being corrected to a different pinned version, so a
4579
+ * failed update leaves the previously-working version on disk instead of
4580
+ * nothing at all.
4581
+ */
4582
+ async installNow(npmPackage, exactVersion, cleanFirst = true) {
4435
4583
  const pkgDir = join13(INTEGRATIONS_DIR, "node_modules", ...npmPackage.split("/"));
4436
- if (existsSync13(pkgDir)) {
4437
- console.error(`[IntegrationManager] Removing unusable install of ${npmPackage}`);
4584
+ if (cleanFirst && existsSync13(pkgDir)) {
4585
+ console.error(`[IntegrationManager] Removing ${exactVersion ? "outdated" : "unusable"} install of ${npmPackage}`);
4438
4586
  try {
4439
4587
  rmSync(pkgDir, { recursive: true, force: true });
4440
4588
  } catch (err) {
@@ -4444,18 +4592,22 @@ var IntegrationManager = class {
4444
4592
  if (!/^(@[a-z0-9][\w.-]*\/)?[a-z0-9][\w.-]*$/i.test(npmPackage)) {
4445
4593
  throw new Error(`Refusing to install unsafe package name: ${JSON.stringify(npmPackage)}`);
4446
4594
  }
4447
- console.error(`[IntegrationManager] Installing ${npmPackage}...`);
4595
+ if (exactVersion !== void 0 && !isExactSemver(exactVersion)) {
4596
+ throw new Error(`Refusing to install ${npmPackage} at unsafe/non-exact version spec: ${JSON.stringify(exactVersion)}`);
4597
+ }
4598
+ const spec = exactVersion ? `${npmPackage}@${exactVersion}` : npmPackage;
4599
+ console.error(`[IntegrationManager] Installing ${spec}...`);
4448
4600
  const startedAt = Date.now();
4449
4601
  const isWin = process.platform === "win32";
4450
4602
  await new Promise((resolve3, reject) => {
4451
4603
  const child = execFile(
4452
4604
  "npm",
4453
- ["install", "--no-fund", "--no-audit", npmPackage],
4605
+ ["install", "--no-fund", "--no-audit", spec],
4454
4606
  {
4455
4607
  cwd: INTEGRATIONS_DIR,
4456
4608
  // Windows: a shell so cmd.exe finds npm.cmd (see EINVAL note above).
4457
4609
  // POSIX: no shell — npm is a normal executable and keeping shell off
4458
- // means the validated package name is still passed as a bare argv.
4610
+ // means the validated package spec is still passed as a bare argv.
4459
4611
  shell: isWin,
4460
4612
  // No timeout: a slow install on a machine with antivirus is not an
4461
4613
  // error, and killing it midway is what created broken installs in
@@ -4465,20 +4617,28 @@ var IntegrationManager = class {
4465
4617
  },
4466
4618
  (err, _stdout, stderr) => {
4467
4619
  if (err) {
4468
- reject(new Error(`Failed to install ${npmPackage}: ${err.message}${stderr ? ` \u2014 ${stderr.trim()}` : ""}`));
4620
+ reject(new Error(`Failed to install ${spec}: ${err.message}${stderr ? ` \u2014 ${stderr.trim()}` : ""}`));
4469
4621
  return;
4470
4622
  }
4471
4623
  resolve3();
4472
4624
  }
4473
4625
  );
4474
- child.on("error", (err) => reject(new Error(`Failed to run npm for ${npmPackage}: ${err.message}`)));
4626
+ child.on("error", (err) => reject(new Error(`Failed to run npm for ${spec}: ${err.message}`)));
4475
4627
  });
4476
4628
  if (!this.isUsableInstall(npmPackage)) {
4477
4629
  throw new Error(
4478
- `Installed ${npmPackage} but it is not usable \u2014 package.json or its bin target is missing. Check ${INTEGRATIONS_DIR} for a partial install.`
4630
+ `Installed ${spec} but it is not usable \u2014 package.json or its bin target is missing. Check ${INTEGRATIONS_DIR} for a partial install.`
4479
4631
  );
4480
4632
  }
4481
- console.error(`[IntegrationManager] Installed ${npmPackage} (${((Date.now() - startedAt) / 1e3).toFixed(1)}s)`);
4633
+ if (exactVersion !== void 0) {
4634
+ const installed = this.readInstalledVersion(npmPackage);
4635
+ if (installed !== exactVersion) {
4636
+ throw new Error(
4637
+ `Installed ${npmPackage} but got version ${installed ?? "unknown"}, expected the pinned ${exactVersion}.`
4638
+ );
4639
+ }
4640
+ }
4641
+ console.error(`[IntegrationManager] Installed ${spec} (${((Date.now() - startedAt) / 1e3).toFixed(1)}s)`);
4482
4642
  }
4483
4643
  /**
4484
4644
  * Connect a client to its transport, but never wait indefinitely. Resolves
@@ -4537,7 +4697,26 @@ var IntegrationManager = class {
4537
4697
  throw new Error(`${config.id}: ${SIMULATION_BLOCK_REASON}`);
4538
4698
  }
4539
4699
  if (config.npmPackage) {
4540
- await this.ensureInstalled(config.npmPackage);
4700
+ await this.ensureInstalled(config);
4701
+ }
4702
+ const pinnedVersion = this.pinnedVersionFor(config);
4703
+ if (pinnedVersion && config.command === "npx") {
4704
+ const manifest = getManifest(config.id);
4705
+ const migrated = {
4706
+ command: manifest.mcp.command,
4707
+ args: manifest.mcp.args,
4708
+ env: manifest.mcp.env ?? config.env
4709
+ };
4710
+ console.error(
4711
+ `[IntegrationManager] ${config.id}: command migrated to manifest (was npx ${config.args.join(" ")})`
4712
+ );
4713
+ config = { ...config, ...migrated };
4714
+ this.onConfigMigrated?.(config.id, migrated);
4715
+ }
4716
+ if (pinnedVersion && config.command === "npx") {
4717
+ throw new Error(
4718
+ `${config.id}: refusing to spawn a pinned connector ("${config.npmPackage}"@${pinnedVersion}) via npx \u2014 this would ignore the pinned local install and fetch the package fresh on every start. The manifest's mcp.command must name the installed binary, not "npx".`
4719
+ );
4541
4720
  }
4542
4721
  const env = this.resolveEnvKeys(config);
4543
4722
  if (isSimulationMode()) {
@@ -5091,6 +5270,10 @@ function refreshAllSessions() {
5091
5270
  integrationManager.setOnToolsChanged(() => {
5092
5271
  refreshAllSessions();
5093
5272
  });
5273
+ integrationManager.setOnConfigMigrated((id, updates) => {
5274
+ integrationRegistry.update(id, updates);
5275
+ console.error(`[Suveren MCP] ${id}: persisted config migrated (${Object.keys(updates).join(", ")})`);
5276
+ });
5094
5277
  var app = express();
5095
5278
  app.use(express.json());
5096
5279
  app.use((_req, res, next) => {
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Types for the plain-ESM Node version check (see config.d.mts for why the
3
+ * .mjs modules ship declarations).
4
+ */
5
+
6
+ export declare const MIN_NODE_MAJOR: number;
7
+ export declare function unsupportedNodeReason(version: string): string | null;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Minimum Node.js version for the gateway — checked at start by
3
+ * bundle/bin/suveren-gateway.js and bundle/server.js.
4
+ *
5
+ * The connectors the gateway installs (crm, erp, email, records — all built on
6
+ * better-sqlite3 13) need Node 22. `engines` in package.json is not enough:
7
+ * npm only WARNS on a mismatch, and for an unpinned install it silently picks
8
+ * an older connector that still runs on the old Node. With pinned connector
9
+ * versions the pinned connector is installed anyway and crashes on its first
10
+ * database call. Refusing at start, with the reason, is the only visible
11
+ * failure. Keep MIN_NODE_MAJOR in step with `engines` in package.json.tpl.
12
+ */
13
+
14
+ export const MIN_NODE_MAJOR = 22;
15
+
16
+ /**
17
+ * Returns null when `version` (e.g. process.versions.node, "22.11.0") is
18
+ * supported, otherwise a message naming both versions. An unparseable version
19
+ * is refused — the safe direction.
20
+ */
21
+ export function unsupportedNodeReason(version) {
22
+ const major = Number.parseInt(String(version).split('.')[0], 10);
23
+ if (Number.isInteger(major) && major >= MIN_NODE_MAJOR) return null;
24
+ return (
25
+ `Suveren gateway needs Node.js ${MIN_NODE_MAJOR} or newer — this is Node.js ${version}. ` +
26
+ `Install a current Node.js (https://nodejs.org) and start the gateway again.`
27
+ );
28
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/client/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/client/auth.ts"],"names":[],"mappings":"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"}
@@ -28,6 +28,7 @@ const auth_js_1 = require("../shared/auth.js");
28
28
  const auth_js_2 = require("../shared/auth.js");
29
29
  const auth_utils_js_1 = require("../shared/auth-utils.js");
30
30
  const errors_js_1 = require("../server/auth/errors.js");
31
+ const transport_js_1 = require("../shared/transport.js");
31
32
  class UnauthorizedError extends Error {
32
33
  constructor(message) {
33
34
  super(message ?? 'Unauthorized');
@@ -158,7 +159,8 @@ async function parseErrorResponse(input) {
158
159
  }
159
160
  catch (error) {
160
161
  // Not a valid OAuth error response, but try to inform the user of the raw data anyway
161
- const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ''}Invalid OAuth error response: ${error}. Raw body: ${body}`;
162
+ const redirect = input instanceof Response ? (0, transport_js_1.unfollowedRedirect)(input, input.url) : undefined;
163
+ const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ''}${redirect ?? `Invalid OAuth error response: ${error}. Raw body: ${body}`}`;
162
164
  return new errors_js_1.ServerError(errorMessage);
163
165
  }
164
166
  }
@@ -555,7 +557,7 @@ async function discoverOAuthProtectedResourceMetadata(serverUrl, opts, fetchFn =
555
557
  */
556
558
  async function fetchWithCorsRetry(url, headers, fetchFn = fetch) {
557
559
  try {
558
- return await fetchFn(url, { headers });
560
+ return await (0, transport_js_1.fetchWithinOrigin)(fetchFn)(url, { headers });
559
561
  }
560
562
  catch (error) {
561
563
  if (error instanceof TypeError) {
@@ -594,7 +596,7 @@ async function tryMetadataDiscovery(url, protocolVersion, fetchFn = fetch) {
594
596
  * Determines if fallback to root discovery should be attempted
595
597
  */
596
598
  function shouldAttemptFallback(response, pathname) {
597
- return !response || (response.status >= 400 && response.status < 500 && pathname !== '/');
599
+ return !response || (!response.ok && response.status < 500 && pathname !== '/');
598
600
  }
599
601
  /**
600
602
  * Generic function for discovering OAuth metadata with fallback support
@@ -735,8 +737,8 @@ async function discoverAuthorizationServerMetadata(authorizationServerUrl, { fet
735
737
  }
736
738
  if (!response.ok) {
737
739
  await response.body?.cancel();
738
- // Continue looking for any 4xx response code.
739
- if (response.status >= 400 && response.status < 500) {
740
+ // Continue looking for any 4xx response code, or a redirect that was not followed.
741
+ if (response.status < 500) {
740
742
  continue; // Try next URL
741
743
  }
742
744
  throw new Error(`HTTP ${response.status} trying to load ${type === 'oauth' ? 'OAuth' : 'OpenID provider'} metadata from ${endpointUrl}`);
@@ -882,7 +884,7 @@ async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequ
882
884
  const authMethod = selectClientAuthMethod(clientInformation, supportedMethods);
883
885
  applyClientAuthentication(authMethod, clientInformation, headers, tokenRequestParams);
884
886
  }
885
- const response = await (fetchFn ?? fetch)(tokenUrl, {
887
+ const response = await (0, transport_js_1.fetchWithinOrigin)(fetchFn ?? fetch)(tokenUrl, {
886
888
  method: 'POST',
887
889
  headers,
888
890
  body: tokenRequestParams
@@ -1026,7 +1028,7 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
1026
1028
  else {
1027
1029
  registrationUrl = new URL('/register', authorizationServerUrl);
1028
1030
  }
1029
- const response = await (fetchFn ?? fetch)(registrationUrl, {
1031
+ const response = await (0, transport_js_1.fetchWithinOrigin)(fetchFn ?? fetch)(registrationUrl, {
1030
1032
  method: 'POST',
1031
1033
  headers: {
1032
1034
  'Content-Type': 'application/json'