@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.
- package/README.md +1 -1
- package/bin/suveren-gateway.js +9 -0
- package/content/integrations/calendar.json +1 -0
- package/content/integrations/crm.json +1 -67
- package/content/integrations/deploy-github.json +3 -5
- package/content/integrations/erp.json +1 -80
- package/content/integrations/gmail.json +1 -0
- package/content/integrations/linkedin.json +1 -0
- package/content/integrations/mail.json +1 -48
- package/content/integrations/mollie.json +1 -0
- package/content/integrations/records.json +1 -0
- package/dist/mcp-server/http.mjs +234 -51
- package/lib/node-version.d.mts +7 -0
- package/lib/node-version.mjs +28 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.js +9 -7
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/sse.d.ts +13 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/sse.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/sse.js +17 -4
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/sse.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.d.ts +13 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.js +23 -10
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/streamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/elicitationFormExample.js +63 -20
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/elicitationFormExample.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/elicitationUrlExample.js +71 -29
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/elicitationUrlExample.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/jsonResponseStreamableHttp.js +45 -6
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/jsonResponseStreamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/simpleStreamableHttp.js +71 -31
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/simpleStreamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/simpleTaskInteractive.js +61 -18
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/simpleTaskInteractive.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/sseAndStreamableHttpCompatibleServer.js +57 -19
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/sseAndStreamableHttpCompatibleServer.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/ssePollingExample.js +64 -17
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/ssePollingExample.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/standaloneSseWithGetStreamableHttp.js +61 -13
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/standaloneSseWithGetStreamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/interfaces.d.ts +4 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/interfaces.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/interfaces.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/stores/in-memory.d.ts +17 -8
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/stores/in-memory.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/stores/in-memory.js +31 -14
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/stores/in-memory.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/middleware/bearerAuth.d.ts +9 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/middleware/bearerAuth.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/middleware/bearerAuth.js +17 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/middleware/bearerAuth.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.d.ts +12 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.js +46 -2
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.d.ts +1 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.js +39 -9
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/transport.d.ts +10 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/transport.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/transport.js +77 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/transport.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js +9 -7
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.d.ts +13 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.js +18 -5
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.d.ts +13 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js +24 -11
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/elicitationFormExample.js +63 -20
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/elicitationFormExample.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/elicitationUrlExample.js +71 -29
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/elicitationUrlExample.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/jsonResponseStreamableHttp.js +45 -6
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/jsonResponseStreamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/simpleStreamableHttp.js +71 -31
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/simpleStreamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/simpleTaskInteractive.js +61 -18
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/simpleTaskInteractive.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/sseAndStreamableHttpCompatibleServer.js +57 -19
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/sseAndStreamableHttpCompatibleServer.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/ssePollingExample.js +64 -17
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/ssePollingExample.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/standaloneSseWithGetStreamableHttp.js +61 -13
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/standaloneSseWithGetStreamableHttp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.d.ts +4 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/stores/in-memory.d.ts +17 -8
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/stores/in-memory.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/stores/in-memory.js +31 -14
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/stores/in-memory.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/middleware/bearerAuth.d.ts +9 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/middleware/bearerAuth.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/middleware/bearerAuth.js +17 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/middleware/bearerAuth.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.d.ts +12 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js +46 -2
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.d.ts +1 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js +39 -9
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.d.ts +10 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.d.ts.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.js +72 -0
- package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/package.json +1 -1
- package/package.json +2 -2
- package/server.js +9 -0
package/dist/mcp-server/http.mjs
CHANGED
|
@@ -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/
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
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
|
-
|
|
3996
|
-
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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(
|
|
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
|
-
/**
|
|
4434
|
-
|
|
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
|
-
|
|
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",
|
|
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
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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
|
-
|
|
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
|
|
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,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":"AAEA,OAAO,EACH,mBAAmB,EAEnB,2BAA2B,EAC3B,WAAW,EACX,aAAa,EACb,0BAA0B,EAC1B,8BAA8B,EAE9B,2BAA2B,EAE9B,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,EAKH,UAAU,EAGb,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,
|
|
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
|
|
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.
|
|
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
|
|
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'
|