@clawos-dev/clawd 0.2.560 → 0.2.561
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-builder-plugin/mcp-server.cjs +2 -0
- package/dist/cli.cjs +150 -92
- package/dist/dispatch/mcp-server.cjs +2 -0
- package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/mcp-server.cjs +2 -0
- package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/mcp-server.cjs +2 -0
- package/dist/pi-mcp-bridge/extension.cjs +1705 -30
- package/dist/share-ui/assets/{guest-CYJu0n-K.js → guest-CbQApsnE.js} +133 -133
- package/dist/share-ui/guest.html +1 -1
- package/package.json +1 -1
|
@@ -6580,7 +6580,7 @@ var require_formats = __commonJS({
|
|
|
6580
6580
|
}
|
|
6581
6581
|
exports2.fullFormats = {
|
|
6582
6582
|
// date: http://tools.ietf.org/html/rfc3339#section-5.6
|
|
6583
|
-
date: fmtDef(
|
|
6583
|
+
date: fmtDef(date4, compareDate),
|
|
6584
6584
|
// date-time: http://tools.ietf.org/html/rfc3339#section-5.6
|
|
6585
6585
|
time: fmtDef(getTime(true), compareTime),
|
|
6586
6586
|
"date-time": fmtDef(getDateTime(true), compareDateTime),
|
|
@@ -6646,7 +6646,7 @@ var require_formats = __commonJS({
|
|
|
6646
6646
|
}
|
|
6647
6647
|
var DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
|
|
6648
6648
|
var DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
6649
|
-
function
|
|
6649
|
+
function date4(str) {
|
|
6650
6650
|
const matches = DATE.exec(str);
|
|
6651
6651
|
if (!matches)
|
|
6652
6652
|
return false;
|
|
@@ -6715,7 +6715,7 @@ var require_formats = __commonJS({
|
|
|
6715
6715
|
const time3 = getTime(strictTimeZone);
|
|
6716
6716
|
return function date_time(str) {
|
|
6717
6717
|
const dateTime = str.split(DATE_TIME_SEPARATOR);
|
|
6718
|
-
return dateTime.length === 2 &&
|
|
6718
|
+
return dateTime.length === 2 && date4(dateTime[0]) && time3(dateTime[1]);
|
|
6719
6719
|
};
|
|
6720
6720
|
}
|
|
6721
6721
|
function compareDateTime(dt1, dt2) {
|
|
@@ -7211,8 +7211,8 @@ var require_shebang_command = __commonJS({
|
|
|
7211
7211
|
"../node_modules/.pnpm/shebang-command@2.0.0/node_modules/shebang-command/index.js"(exports2, module2) {
|
|
7212
7212
|
"use strict";
|
|
7213
7213
|
var shebangRegex = require_shebang_regex();
|
|
7214
|
-
module2.exports = (
|
|
7215
|
-
const match =
|
|
7214
|
+
module2.exports = (string4 = "") => {
|
|
7215
|
+
const match = string4.match(shebangRegex);
|
|
7216
7216
|
if (!match) {
|
|
7217
7217
|
return null;
|
|
7218
7218
|
}
|
|
@@ -7390,8 +7390,11 @@ var require_cross_spawn = __commonJS({
|
|
|
7390
7390
|
// src/pi-mcp-bridge/extension.ts
|
|
7391
7391
|
var extension_exports = {};
|
|
7392
7392
|
__export(extension_exports, {
|
|
7393
|
+
POD_KEY_ENV: () => POD_KEY_ENV,
|
|
7393
7394
|
bridgeMcpServers: () => bridgeMcpServers,
|
|
7394
|
-
default: () => clawdPiMcpBridge
|
|
7395
|
+
default: () => clawdPiMcpBridge,
|
|
7396
|
+
mcpChildEnv: () => mcpChildEnv,
|
|
7397
|
+
mcpHttpHeaders: () => mcpHttpHeaders
|
|
7395
7398
|
});
|
|
7396
7399
|
module.exports = __toCommonJS(extension_exports);
|
|
7397
7400
|
|
|
@@ -8151,6 +8154,7 @@ var string = (params) => {
|
|
|
8151
8154
|
const regex = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
|
|
8152
8155
|
return new RegExp(`^${regex}$`);
|
|
8153
8156
|
};
|
|
8157
|
+
var bigint = /^\d+n?$/;
|
|
8154
8158
|
var integer = /^\d+$/;
|
|
8155
8159
|
var number = /^-?\d+(?:\.\d+)?/i;
|
|
8156
8160
|
var boolean = /true|false/i;
|
|
@@ -8728,11 +8732,11 @@ var $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
|
|
|
8728
8732
|
inst._zod.check = (payload) => {
|
|
8729
8733
|
try {
|
|
8730
8734
|
const orig = payload.value;
|
|
8731
|
-
const
|
|
8732
|
-
const href =
|
|
8735
|
+
const url2 = new URL(orig);
|
|
8736
|
+
const href = url2.href;
|
|
8733
8737
|
if (def.hostname) {
|
|
8734
8738
|
def.hostname.lastIndex = 0;
|
|
8735
|
-
if (!def.hostname.test(
|
|
8739
|
+
if (!def.hostname.test(url2.hostname)) {
|
|
8736
8740
|
payload.issues.push({
|
|
8737
8741
|
code: "invalid_format",
|
|
8738
8742
|
format: "url",
|
|
@@ -8746,7 +8750,7 @@ var $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
|
|
|
8746
8750
|
}
|
|
8747
8751
|
if (def.protocol) {
|
|
8748
8752
|
def.protocol.lastIndex = 0;
|
|
8749
|
-
if (!def.protocol.test(
|
|
8753
|
+
if (!def.protocol.test(url2.protocol.endsWith(":") ? url2.protocol.slice(0, -1) : url2.protocol)) {
|
|
8750
8754
|
payload.issues.push({
|
|
8751
8755
|
code: "invalid_format",
|
|
8752
8756
|
format: "url",
|
|
@@ -9019,6 +9023,26 @@ var $ZodBoolean = /* @__PURE__ */ $constructor("$ZodBoolean", (inst, def) => {
|
|
|
9019
9023
|
return payload;
|
|
9020
9024
|
};
|
|
9021
9025
|
});
|
|
9026
|
+
var $ZodBigInt = /* @__PURE__ */ $constructor("$ZodBigInt", (inst, def) => {
|
|
9027
|
+
$ZodType.init(inst, def);
|
|
9028
|
+
inst._zod.pattern = bigint;
|
|
9029
|
+
inst._zod.parse = (payload, _ctx) => {
|
|
9030
|
+
if (def.coerce)
|
|
9031
|
+
try {
|
|
9032
|
+
payload.value = BigInt(payload.value);
|
|
9033
|
+
} catch (_) {
|
|
9034
|
+
}
|
|
9035
|
+
if (typeof payload.value === "bigint")
|
|
9036
|
+
return payload;
|
|
9037
|
+
payload.issues.push({
|
|
9038
|
+
expected: "bigint",
|
|
9039
|
+
code: "invalid_type",
|
|
9040
|
+
input: payload.value,
|
|
9041
|
+
inst
|
|
9042
|
+
});
|
|
9043
|
+
return payload;
|
|
9044
|
+
};
|
|
9045
|
+
});
|
|
9022
9046
|
var $ZodNull = /* @__PURE__ */ $constructor("$ZodNull", (inst, def) => {
|
|
9023
9047
|
$ZodType.init(inst, def);
|
|
9024
9048
|
inst._zod.pattern = _null;
|
|
@@ -9036,6 +9060,10 @@ var $ZodNull = /* @__PURE__ */ $constructor("$ZodNull", (inst, def) => {
|
|
|
9036
9060
|
return payload;
|
|
9037
9061
|
};
|
|
9038
9062
|
});
|
|
9063
|
+
var $ZodAny = /* @__PURE__ */ $constructor("$ZodAny", (inst, def) => {
|
|
9064
|
+
$ZodType.init(inst, def);
|
|
9065
|
+
inst._zod.parse = (payload) => payload;
|
|
9066
|
+
});
|
|
9039
9067
|
var $ZodUnknown = /* @__PURE__ */ $constructor("$ZodUnknown", (inst, def) => {
|
|
9040
9068
|
$ZodType.init(inst, def);
|
|
9041
9069
|
inst._zod.parse = (payload) => payload;
|
|
@@ -9052,6 +9080,30 @@ var $ZodNever = /* @__PURE__ */ $constructor("$ZodNever", (inst, def) => {
|
|
|
9052
9080
|
return payload;
|
|
9053
9081
|
};
|
|
9054
9082
|
});
|
|
9083
|
+
var $ZodDate = /* @__PURE__ */ $constructor("$ZodDate", (inst, def) => {
|
|
9084
|
+
$ZodType.init(inst, def);
|
|
9085
|
+
inst._zod.parse = (payload, _ctx) => {
|
|
9086
|
+
if (def.coerce) {
|
|
9087
|
+
try {
|
|
9088
|
+
payload.value = new Date(payload.value);
|
|
9089
|
+
} catch (_err) {
|
|
9090
|
+
}
|
|
9091
|
+
}
|
|
9092
|
+
const input = payload.value;
|
|
9093
|
+
const isDate = input instanceof Date;
|
|
9094
|
+
const isValidDate = isDate && !Number.isNaN(input.getTime());
|
|
9095
|
+
if (isValidDate)
|
|
9096
|
+
return payload;
|
|
9097
|
+
payload.issues.push({
|
|
9098
|
+
expected: "date",
|
|
9099
|
+
code: "invalid_type",
|
|
9100
|
+
input,
|
|
9101
|
+
...isDate ? { received: "Invalid Date" } : {},
|
|
9102
|
+
inst
|
|
9103
|
+
});
|
|
9104
|
+
return payload;
|
|
9105
|
+
};
|
|
9106
|
+
});
|
|
9055
9107
|
function handleArrayResult(result, final, index) {
|
|
9056
9108
|
if (result.issues.length) {
|
|
9057
9109
|
final.issues.push(...prefixIssues(index, result.issues));
|
|
@@ -9997,6 +10049,13 @@ function _string(Class2, params) {
|
|
|
9997
10049
|
...normalizeParams(params)
|
|
9998
10050
|
});
|
|
9999
10051
|
}
|
|
10052
|
+
function _coercedString(Class2, params) {
|
|
10053
|
+
return new Class2({
|
|
10054
|
+
type: "string",
|
|
10055
|
+
coerce: true,
|
|
10056
|
+
...normalizeParams(params)
|
|
10057
|
+
});
|
|
10058
|
+
}
|
|
10000
10059
|
function _email(Class2, params) {
|
|
10001
10060
|
return new Class2({
|
|
10002
10061
|
type: "string",
|
|
@@ -10241,6 +10300,14 @@ function _number(Class2, params) {
|
|
|
10241
10300
|
...normalizeParams(params)
|
|
10242
10301
|
});
|
|
10243
10302
|
}
|
|
10303
|
+
function _coercedNumber(Class2, params) {
|
|
10304
|
+
return new Class2({
|
|
10305
|
+
type: "number",
|
|
10306
|
+
coerce: true,
|
|
10307
|
+
checks: [],
|
|
10308
|
+
...normalizeParams(params)
|
|
10309
|
+
});
|
|
10310
|
+
}
|
|
10244
10311
|
function _int(Class2, params) {
|
|
10245
10312
|
return new Class2({
|
|
10246
10313
|
type: "number",
|
|
@@ -10256,12 +10323,31 @@ function _boolean(Class2, params) {
|
|
|
10256
10323
|
...normalizeParams(params)
|
|
10257
10324
|
});
|
|
10258
10325
|
}
|
|
10326
|
+
function _coercedBoolean(Class2, params) {
|
|
10327
|
+
return new Class2({
|
|
10328
|
+
type: "boolean",
|
|
10329
|
+
coerce: true,
|
|
10330
|
+
...normalizeParams(params)
|
|
10331
|
+
});
|
|
10332
|
+
}
|
|
10333
|
+
function _coercedBigint(Class2, params) {
|
|
10334
|
+
return new Class2({
|
|
10335
|
+
type: "bigint",
|
|
10336
|
+
coerce: true,
|
|
10337
|
+
...normalizeParams(params)
|
|
10338
|
+
});
|
|
10339
|
+
}
|
|
10259
10340
|
function _null2(Class2, params) {
|
|
10260
10341
|
return new Class2({
|
|
10261
10342
|
type: "null",
|
|
10262
10343
|
...normalizeParams(params)
|
|
10263
10344
|
});
|
|
10264
10345
|
}
|
|
10346
|
+
function _any(Class2) {
|
|
10347
|
+
return new Class2({
|
|
10348
|
+
type: "any"
|
|
10349
|
+
});
|
|
10350
|
+
}
|
|
10265
10351
|
function _unknown(Class2) {
|
|
10266
10352
|
return new Class2({
|
|
10267
10353
|
type: "unknown"
|
|
@@ -10273,6 +10359,13 @@ function _never(Class2, params) {
|
|
|
10273
10359
|
...normalizeParams(params)
|
|
10274
10360
|
});
|
|
10275
10361
|
}
|
|
10362
|
+
function _coercedDate(Class2, params) {
|
|
10363
|
+
return new Class2({
|
|
10364
|
+
type: "date",
|
|
10365
|
+
coerce: true,
|
|
10366
|
+
...normalizeParams(params)
|
|
10367
|
+
});
|
|
10368
|
+
}
|
|
10276
10369
|
function _lt(value, params) {
|
|
10277
10370
|
return new $ZodCheckLessThan({
|
|
10278
10371
|
check: "less_than",
|
|
@@ -10716,6 +10809,9 @@ var ZodURL = /* @__PURE__ */ $constructor("ZodURL", (inst, def) => {
|
|
|
10716
10809
|
$ZodURL.init(inst, def);
|
|
10717
10810
|
ZodStringFormat.init(inst, def);
|
|
10718
10811
|
});
|
|
10812
|
+
function url(params) {
|
|
10813
|
+
return _url(ZodURL, params);
|
|
10814
|
+
}
|
|
10719
10815
|
var ZodEmoji = /* @__PURE__ */ $constructor("ZodEmoji", (inst, def) => {
|
|
10720
10816
|
$ZodEmoji.init(inst, def);
|
|
10721
10817
|
ZodStringFormat.init(inst, def);
|
|
@@ -10818,6 +10914,27 @@ var ZodBoolean = /* @__PURE__ */ $constructor("ZodBoolean", (inst, def) => {
|
|
|
10818
10914
|
function boolean2(params) {
|
|
10819
10915
|
return _boolean(ZodBoolean, params);
|
|
10820
10916
|
}
|
|
10917
|
+
var ZodBigInt = /* @__PURE__ */ $constructor("ZodBigInt", (inst, def) => {
|
|
10918
|
+
$ZodBigInt.init(inst, def);
|
|
10919
|
+
ZodType.init(inst, def);
|
|
10920
|
+
inst.gte = (value, params) => inst.check(_gte(value, params));
|
|
10921
|
+
inst.min = (value, params) => inst.check(_gte(value, params));
|
|
10922
|
+
inst.gt = (value, params) => inst.check(_gt(value, params));
|
|
10923
|
+
inst.gte = (value, params) => inst.check(_gte(value, params));
|
|
10924
|
+
inst.min = (value, params) => inst.check(_gte(value, params));
|
|
10925
|
+
inst.lt = (value, params) => inst.check(_lt(value, params));
|
|
10926
|
+
inst.lte = (value, params) => inst.check(_lte(value, params));
|
|
10927
|
+
inst.max = (value, params) => inst.check(_lte(value, params));
|
|
10928
|
+
inst.positive = (params) => inst.check(_gt(BigInt(0), params));
|
|
10929
|
+
inst.negative = (params) => inst.check(_lt(BigInt(0), params));
|
|
10930
|
+
inst.nonpositive = (params) => inst.check(_lte(BigInt(0), params));
|
|
10931
|
+
inst.nonnegative = (params) => inst.check(_gte(BigInt(0), params));
|
|
10932
|
+
inst.multipleOf = (value, params) => inst.check(_multipleOf(value, params));
|
|
10933
|
+
const bag = inst._zod.bag;
|
|
10934
|
+
inst.minValue = bag.minimum ?? null;
|
|
10935
|
+
inst.maxValue = bag.maximum ?? null;
|
|
10936
|
+
inst.format = bag.format ?? null;
|
|
10937
|
+
});
|
|
10821
10938
|
var ZodNull = /* @__PURE__ */ $constructor("ZodNull", (inst, def) => {
|
|
10822
10939
|
$ZodNull.init(inst, def);
|
|
10823
10940
|
ZodType.init(inst, def);
|
|
@@ -10825,6 +10942,13 @@ var ZodNull = /* @__PURE__ */ $constructor("ZodNull", (inst, def) => {
|
|
|
10825
10942
|
function _null3(params) {
|
|
10826
10943
|
return _null2(ZodNull, params);
|
|
10827
10944
|
}
|
|
10945
|
+
var ZodAny = /* @__PURE__ */ $constructor("ZodAny", (inst, def) => {
|
|
10946
|
+
$ZodAny.init(inst, def);
|
|
10947
|
+
ZodType.init(inst, def);
|
|
10948
|
+
});
|
|
10949
|
+
function any() {
|
|
10950
|
+
return _any(ZodAny);
|
|
10951
|
+
}
|
|
10828
10952
|
var ZodUnknown = /* @__PURE__ */ $constructor("ZodUnknown", (inst, def) => {
|
|
10829
10953
|
$ZodUnknown.init(inst, def);
|
|
10830
10954
|
ZodType.init(inst, def);
|
|
@@ -10839,6 +10963,15 @@ var ZodNever = /* @__PURE__ */ $constructor("ZodNever", (inst, def) => {
|
|
|
10839
10963
|
function never(params) {
|
|
10840
10964
|
return _never(ZodNever, params);
|
|
10841
10965
|
}
|
|
10966
|
+
var ZodDate = /* @__PURE__ */ $constructor("ZodDate", (inst, def) => {
|
|
10967
|
+
$ZodDate.init(inst, def);
|
|
10968
|
+
ZodType.init(inst, def);
|
|
10969
|
+
inst.min = (value, params) => inst.check(_gte(value, params));
|
|
10970
|
+
inst.max = (value, params) => inst.check(_lte(value, params));
|
|
10971
|
+
const c = inst._zod.bag;
|
|
10972
|
+
inst.minDate = c.minimum ? new Date(c.minimum) : null;
|
|
10973
|
+
inst.maxDate = c.maximum ? new Date(c.maximum) : null;
|
|
10974
|
+
});
|
|
10842
10975
|
var ZodArray = /* @__PURE__ */ $constructor("ZodArray", (inst, def) => {
|
|
10843
10976
|
$ZodArray.init(inst, def);
|
|
10844
10977
|
ZodType.init(inst, def);
|
|
@@ -11184,6 +11317,46 @@ function preprocess(fn, schema) {
|
|
|
11184
11317
|
return pipe(transform(fn), schema);
|
|
11185
11318
|
}
|
|
11186
11319
|
|
|
11320
|
+
// ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/classic/compat.js
|
|
11321
|
+
var ZodIssueCode = {
|
|
11322
|
+
invalid_type: "invalid_type",
|
|
11323
|
+
too_big: "too_big",
|
|
11324
|
+
too_small: "too_small",
|
|
11325
|
+
invalid_format: "invalid_format",
|
|
11326
|
+
not_multiple_of: "not_multiple_of",
|
|
11327
|
+
unrecognized_keys: "unrecognized_keys",
|
|
11328
|
+
invalid_union: "invalid_union",
|
|
11329
|
+
invalid_key: "invalid_key",
|
|
11330
|
+
invalid_element: "invalid_element",
|
|
11331
|
+
invalid_value: "invalid_value",
|
|
11332
|
+
custom: "custom"
|
|
11333
|
+
};
|
|
11334
|
+
|
|
11335
|
+
// ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/classic/coerce.js
|
|
11336
|
+
var coerce_exports = {};
|
|
11337
|
+
__export(coerce_exports, {
|
|
11338
|
+
bigint: () => bigint2,
|
|
11339
|
+
boolean: () => boolean3,
|
|
11340
|
+
date: () => date3,
|
|
11341
|
+
number: () => number3,
|
|
11342
|
+
string: () => string3
|
|
11343
|
+
});
|
|
11344
|
+
function string3(params) {
|
|
11345
|
+
return _coercedString(ZodString, params);
|
|
11346
|
+
}
|
|
11347
|
+
function number3(params) {
|
|
11348
|
+
return _coercedNumber(ZodNumber, params);
|
|
11349
|
+
}
|
|
11350
|
+
function boolean3(params) {
|
|
11351
|
+
return _coercedBoolean(ZodBoolean, params);
|
|
11352
|
+
}
|
|
11353
|
+
function bigint2(params) {
|
|
11354
|
+
return _coercedBigint(ZodBigInt, params);
|
|
11355
|
+
}
|
|
11356
|
+
function date3(params) {
|
|
11357
|
+
return _coercedDate(ZodDate, params);
|
|
11358
|
+
}
|
|
11359
|
+
|
|
11187
11360
|
// ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/classic/external.js
|
|
11188
11361
|
config(en_default());
|
|
11189
11362
|
|
|
@@ -11588,6 +11761,7 @@ var InitializedNotificationSchema = NotificationSchema.extend({
|
|
|
11588
11761
|
method: literal("notifications/initialized"),
|
|
11589
11762
|
params: NotificationsParamsSchema.optional()
|
|
11590
11763
|
});
|
|
11764
|
+
var isInitializedNotification = (value) => InitializedNotificationSchema.safeParse(value).success;
|
|
11591
11765
|
var PingRequestSchema = RequestSchema.extend({
|
|
11592
11766
|
method: literal("ping"),
|
|
11593
11767
|
params: BaseRequestParamsSchema.optional()
|
|
@@ -14664,11 +14838,1478 @@ var StdioClientTransport = class {
|
|
|
14664
14838
|
}
|
|
14665
14839
|
};
|
|
14666
14840
|
|
|
14667
|
-
//
|
|
14841
|
+
// ../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.js
|
|
14842
|
+
function normalizeHeaders(headers) {
|
|
14843
|
+
if (!headers)
|
|
14844
|
+
return {};
|
|
14845
|
+
if (headers instanceof Headers) {
|
|
14846
|
+
return Object.fromEntries(headers.entries());
|
|
14847
|
+
}
|
|
14848
|
+
if (Array.isArray(headers)) {
|
|
14849
|
+
return Object.fromEntries(headers);
|
|
14850
|
+
}
|
|
14851
|
+
return { ...headers };
|
|
14852
|
+
}
|
|
14853
|
+
function createFetchWithInit(baseFetch = fetch, baseInit) {
|
|
14854
|
+
if (!baseInit) {
|
|
14855
|
+
return baseFetch;
|
|
14856
|
+
}
|
|
14857
|
+
return async (url2, init) => {
|
|
14858
|
+
const mergedInit = {
|
|
14859
|
+
...baseInit,
|
|
14860
|
+
...init,
|
|
14861
|
+
// Headers need special handling - merge instead of replace
|
|
14862
|
+
headers: init?.headers ? { ...normalizeHeaders(baseInit.headers), ...normalizeHeaders(init.headers) } : baseInit.headers
|
|
14863
|
+
};
|
|
14864
|
+
return baseFetch(url2, mergedInit);
|
|
14865
|
+
};
|
|
14866
|
+
}
|
|
14867
|
+
|
|
14868
|
+
// ../node_modules/.pnpm/pkce-challenge@5.0.1/node_modules/pkce-challenge/dist/index.node.js
|
|
14869
|
+
var crypto;
|
|
14870
|
+
crypto = globalThis.crypto?.webcrypto ?? // Node.js [18-16] REPL
|
|
14871
|
+
globalThis.crypto ?? // Node.js >18
|
|
14872
|
+
import("crypto").then((m) => m.webcrypto);
|
|
14873
|
+
async function getRandomValues(size) {
|
|
14874
|
+
return (await crypto).getRandomValues(new Uint8Array(size));
|
|
14875
|
+
}
|
|
14876
|
+
async function random(size) {
|
|
14877
|
+
const mask = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~";
|
|
14878
|
+
const evenDistCutoff = Math.pow(2, 8) - Math.pow(2, 8) % mask.length;
|
|
14879
|
+
let result = "";
|
|
14880
|
+
while (result.length < size) {
|
|
14881
|
+
const randomBytes = await getRandomValues(size - result.length);
|
|
14882
|
+
for (const randomByte of randomBytes) {
|
|
14883
|
+
if (randomByte < evenDistCutoff) {
|
|
14884
|
+
result += mask[randomByte % mask.length];
|
|
14885
|
+
}
|
|
14886
|
+
}
|
|
14887
|
+
}
|
|
14888
|
+
return result;
|
|
14889
|
+
}
|
|
14890
|
+
async function generateVerifier(length) {
|
|
14891
|
+
return await random(length);
|
|
14892
|
+
}
|
|
14893
|
+
async function generateChallenge(code_verifier) {
|
|
14894
|
+
const buffer = await (await crypto).subtle.digest("SHA-256", new TextEncoder().encode(code_verifier));
|
|
14895
|
+
return btoa(String.fromCharCode(...new Uint8Array(buffer))).replace(/\//g, "_").replace(/\+/g, "-").replace(/=/g, "");
|
|
14896
|
+
}
|
|
14897
|
+
async function pkceChallenge(length) {
|
|
14898
|
+
if (!length)
|
|
14899
|
+
length = 43;
|
|
14900
|
+
if (length < 43 || length > 128) {
|
|
14901
|
+
throw `Expected a length between 43 and 128. Received ${length}.`;
|
|
14902
|
+
}
|
|
14903
|
+
const verifier = await generateVerifier(length);
|
|
14904
|
+
const challenge = await generateChallenge(verifier);
|
|
14905
|
+
return {
|
|
14906
|
+
code_verifier: verifier,
|
|
14907
|
+
code_challenge: challenge
|
|
14908
|
+
};
|
|
14909
|
+
}
|
|
14910
|
+
|
|
14911
|
+
// ../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth.js
|
|
14912
|
+
var SafeUrlSchema = url().superRefine((val, ctx) => {
|
|
14913
|
+
if (!URL.canParse(val)) {
|
|
14914
|
+
ctx.addIssue({
|
|
14915
|
+
code: ZodIssueCode.custom,
|
|
14916
|
+
message: "URL must be parseable",
|
|
14917
|
+
fatal: true
|
|
14918
|
+
});
|
|
14919
|
+
return NEVER;
|
|
14920
|
+
}
|
|
14921
|
+
}).refine((url2) => {
|
|
14922
|
+
const u = new URL(url2);
|
|
14923
|
+
return u.protocol !== "javascript:" && u.protocol !== "data:" && u.protocol !== "vbscript:";
|
|
14924
|
+
}, { message: "URL cannot use javascript:, data:, or vbscript: scheme" });
|
|
14925
|
+
var OAuthProtectedResourceMetadataSchema = looseObject({
|
|
14926
|
+
resource: string2().url(),
|
|
14927
|
+
authorization_servers: array(SafeUrlSchema).optional(),
|
|
14928
|
+
jwks_uri: string2().url().optional(),
|
|
14929
|
+
scopes_supported: array(string2()).optional(),
|
|
14930
|
+
bearer_methods_supported: array(string2()).optional(),
|
|
14931
|
+
resource_signing_alg_values_supported: array(string2()).optional(),
|
|
14932
|
+
resource_name: string2().optional(),
|
|
14933
|
+
resource_documentation: string2().optional(),
|
|
14934
|
+
resource_policy_uri: string2().url().optional(),
|
|
14935
|
+
resource_tos_uri: string2().url().optional(),
|
|
14936
|
+
tls_client_certificate_bound_access_tokens: boolean2().optional(),
|
|
14937
|
+
authorization_details_types_supported: array(string2()).optional(),
|
|
14938
|
+
dpop_signing_alg_values_supported: array(string2()).optional(),
|
|
14939
|
+
dpop_bound_access_tokens_required: boolean2().optional()
|
|
14940
|
+
});
|
|
14941
|
+
var OAuthMetadataSchema = looseObject({
|
|
14942
|
+
issuer: string2(),
|
|
14943
|
+
authorization_endpoint: SafeUrlSchema,
|
|
14944
|
+
token_endpoint: SafeUrlSchema,
|
|
14945
|
+
registration_endpoint: SafeUrlSchema.optional(),
|
|
14946
|
+
scopes_supported: array(string2()).optional(),
|
|
14947
|
+
response_types_supported: array(string2()),
|
|
14948
|
+
response_modes_supported: array(string2()).optional(),
|
|
14949
|
+
grant_types_supported: array(string2()).optional(),
|
|
14950
|
+
token_endpoint_auth_methods_supported: array(string2()).optional(),
|
|
14951
|
+
token_endpoint_auth_signing_alg_values_supported: array(string2()).optional(),
|
|
14952
|
+
service_documentation: SafeUrlSchema.optional(),
|
|
14953
|
+
revocation_endpoint: SafeUrlSchema.optional(),
|
|
14954
|
+
revocation_endpoint_auth_methods_supported: array(string2()).optional(),
|
|
14955
|
+
revocation_endpoint_auth_signing_alg_values_supported: array(string2()).optional(),
|
|
14956
|
+
introspection_endpoint: string2().optional(),
|
|
14957
|
+
introspection_endpoint_auth_methods_supported: array(string2()).optional(),
|
|
14958
|
+
introspection_endpoint_auth_signing_alg_values_supported: array(string2()).optional(),
|
|
14959
|
+
code_challenge_methods_supported: array(string2()).optional(),
|
|
14960
|
+
client_id_metadata_document_supported: boolean2().optional()
|
|
14961
|
+
});
|
|
14962
|
+
var OpenIdProviderMetadataSchema = looseObject({
|
|
14963
|
+
issuer: string2(),
|
|
14964
|
+
authorization_endpoint: SafeUrlSchema,
|
|
14965
|
+
token_endpoint: SafeUrlSchema,
|
|
14966
|
+
userinfo_endpoint: SafeUrlSchema.optional(),
|
|
14967
|
+
jwks_uri: SafeUrlSchema,
|
|
14968
|
+
registration_endpoint: SafeUrlSchema.optional(),
|
|
14969
|
+
scopes_supported: array(string2()).optional(),
|
|
14970
|
+
response_types_supported: array(string2()),
|
|
14971
|
+
response_modes_supported: array(string2()).optional(),
|
|
14972
|
+
grant_types_supported: array(string2()).optional(),
|
|
14973
|
+
acr_values_supported: array(string2()).optional(),
|
|
14974
|
+
subject_types_supported: array(string2()),
|
|
14975
|
+
id_token_signing_alg_values_supported: array(string2()),
|
|
14976
|
+
id_token_encryption_alg_values_supported: array(string2()).optional(),
|
|
14977
|
+
id_token_encryption_enc_values_supported: array(string2()).optional(),
|
|
14978
|
+
userinfo_signing_alg_values_supported: array(string2()).optional(),
|
|
14979
|
+
userinfo_encryption_alg_values_supported: array(string2()).optional(),
|
|
14980
|
+
userinfo_encryption_enc_values_supported: array(string2()).optional(),
|
|
14981
|
+
request_object_signing_alg_values_supported: array(string2()).optional(),
|
|
14982
|
+
request_object_encryption_alg_values_supported: array(string2()).optional(),
|
|
14983
|
+
request_object_encryption_enc_values_supported: array(string2()).optional(),
|
|
14984
|
+
token_endpoint_auth_methods_supported: array(string2()).optional(),
|
|
14985
|
+
token_endpoint_auth_signing_alg_values_supported: array(string2()).optional(),
|
|
14986
|
+
display_values_supported: array(string2()).optional(),
|
|
14987
|
+
claim_types_supported: array(string2()).optional(),
|
|
14988
|
+
claims_supported: array(string2()).optional(),
|
|
14989
|
+
service_documentation: string2().optional(),
|
|
14990
|
+
claims_locales_supported: array(string2()).optional(),
|
|
14991
|
+
ui_locales_supported: array(string2()).optional(),
|
|
14992
|
+
claims_parameter_supported: boolean2().optional(),
|
|
14993
|
+
request_parameter_supported: boolean2().optional(),
|
|
14994
|
+
request_uri_parameter_supported: boolean2().optional(),
|
|
14995
|
+
require_request_uri_registration: boolean2().optional(),
|
|
14996
|
+
op_policy_uri: SafeUrlSchema.optional(),
|
|
14997
|
+
op_tos_uri: SafeUrlSchema.optional(),
|
|
14998
|
+
client_id_metadata_document_supported: boolean2().optional()
|
|
14999
|
+
});
|
|
15000
|
+
var OpenIdProviderDiscoveryMetadataSchema = object2({
|
|
15001
|
+
...OpenIdProviderMetadataSchema.shape,
|
|
15002
|
+
...OAuthMetadataSchema.pick({
|
|
15003
|
+
code_challenge_methods_supported: true
|
|
15004
|
+
}).shape
|
|
15005
|
+
});
|
|
15006
|
+
var OAuthTokensSchema = object2({
|
|
15007
|
+
access_token: string2(),
|
|
15008
|
+
id_token: string2().optional(),
|
|
15009
|
+
// Optional for OAuth 2.1, but necessary in OpenID Connect
|
|
15010
|
+
token_type: string2(),
|
|
15011
|
+
expires_in: coerce_exports.number().optional(),
|
|
15012
|
+
scope: string2().optional(),
|
|
15013
|
+
refresh_token: string2().optional()
|
|
15014
|
+
}).strip();
|
|
15015
|
+
var OAuthErrorResponseSchema = object2({
|
|
15016
|
+
error: string2(),
|
|
15017
|
+
error_description: string2().optional(),
|
|
15018
|
+
error_uri: string2().optional()
|
|
15019
|
+
});
|
|
15020
|
+
var OptionalSafeUrlSchema = SafeUrlSchema.optional().or(literal("").transform(() => void 0));
|
|
15021
|
+
var OAuthClientMetadataSchema = object2({
|
|
15022
|
+
redirect_uris: array(SafeUrlSchema),
|
|
15023
|
+
token_endpoint_auth_method: string2().optional(),
|
|
15024
|
+
grant_types: array(string2()).optional(),
|
|
15025
|
+
response_types: array(string2()).optional(),
|
|
15026
|
+
client_name: string2().optional(),
|
|
15027
|
+
client_uri: SafeUrlSchema.optional(),
|
|
15028
|
+
logo_uri: OptionalSafeUrlSchema,
|
|
15029
|
+
scope: string2().optional(),
|
|
15030
|
+
contacts: array(string2()).optional(),
|
|
15031
|
+
tos_uri: OptionalSafeUrlSchema,
|
|
15032
|
+
policy_uri: string2().optional(),
|
|
15033
|
+
jwks_uri: SafeUrlSchema.optional(),
|
|
15034
|
+
jwks: any().optional(),
|
|
15035
|
+
software_id: string2().optional(),
|
|
15036
|
+
software_version: string2().optional(),
|
|
15037
|
+
software_statement: string2().optional()
|
|
15038
|
+
}).strip();
|
|
15039
|
+
var OAuthClientInformationSchema = object2({
|
|
15040
|
+
client_id: string2(),
|
|
15041
|
+
client_secret: string2().optional(),
|
|
15042
|
+
client_id_issued_at: number2().optional(),
|
|
15043
|
+
client_secret_expires_at: number2().optional()
|
|
15044
|
+
}).strip();
|
|
15045
|
+
var OAuthClientInformationFullSchema = OAuthClientMetadataSchema.merge(OAuthClientInformationSchema);
|
|
15046
|
+
var OAuthClientRegistrationErrorSchema = object2({
|
|
15047
|
+
error: string2(),
|
|
15048
|
+
error_description: string2().optional()
|
|
15049
|
+
}).strip();
|
|
15050
|
+
var OAuthTokenRevocationRequestSchema = object2({
|
|
15051
|
+
token: string2(),
|
|
15052
|
+
token_type_hint: string2().optional()
|
|
15053
|
+
}).strip();
|
|
15054
|
+
|
|
15055
|
+
// ../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth-utils.js
|
|
15056
|
+
function resourceUrlFromServerUrl(url2) {
|
|
15057
|
+
const resourceURL = typeof url2 === "string" ? new URL(url2) : new URL(url2.href);
|
|
15058
|
+
resourceURL.hash = "";
|
|
15059
|
+
return resourceURL;
|
|
15060
|
+
}
|
|
15061
|
+
function checkResourceAllowed({ requestedResource, configuredResource }) {
|
|
15062
|
+
const requested = typeof requestedResource === "string" ? new URL(requestedResource) : new URL(requestedResource.href);
|
|
15063
|
+
const configured = typeof configuredResource === "string" ? new URL(configuredResource) : new URL(configuredResource.href);
|
|
15064
|
+
if (requested.origin !== configured.origin) {
|
|
15065
|
+
return false;
|
|
15066
|
+
}
|
|
15067
|
+
if (requested.pathname.length < configured.pathname.length) {
|
|
15068
|
+
return false;
|
|
15069
|
+
}
|
|
15070
|
+
const requestedPath = requested.pathname.endsWith("/") ? requested.pathname : requested.pathname + "/";
|
|
15071
|
+
const configuredPath = configured.pathname.endsWith("/") ? configured.pathname : configured.pathname + "/";
|
|
15072
|
+
return requestedPath.startsWith(configuredPath);
|
|
15073
|
+
}
|
|
15074
|
+
|
|
15075
|
+
// ../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/errors.js
|
|
15076
|
+
var OAuthError = class extends Error {
|
|
15077
|
+
constructor(message, errorUri) {
|
|
15078
|
+
super(message);
|
|
15079
|
+
this.errorUri = errorUri;
|
|
15080
|
+
this.name = this.constructor.name;
|
|
15081
|
+
}
|
|
15082
|
+
/**
|
|
15083
|
+
* Converts the error to a standard OAuth error response object
|
|
15084
|
+
*/
|
|
15085
|
+
toResponseObject() {
|
|
15086
|
+
const response = {
|
|
15087
|
+
error: this.errorCode,
|
|
15088
|
+
error_description: this.message
|
|
15089
|
+
};
|
|
15090
|
+
if (this.errorUri) {
|
|
15091
|
+
response.error_uri = this.errorUri;
|
|
15092
|
+
}
|
|
15093
|
+
return response;
|
|
15094
|
+
}
|
|
15095
|
+
get errorCode() {
|
|
15096
|
+
return this.constructor.errorCode;
|
|
15097
|
+
}
|
|
15098
|
+
};
|
|
15099
|
+
var InvalidRequestError = class extends OAuthError {
|
|
15100
|
+
};
|
|
15101
|
+
InvalidRequestError.errorCode = "invalid_request";
|
|
15102
|
+
var InvalidClientError = class extends OAuthError {
|
|
15103
|
+
};
|
|
15104
|
+
InvalidClientError.errorCode = "invalid_client";
|
|
15105
|
+
var InvalidGrantError = class extends OAuthError {
|
|
15106
|
+
};
|
|
15107
|
+
InvalidGrantError.errorCode = "invalid_grant";
|
|
15108
|
+
var UnauthorizedClientError = class extends OAuthError {
|
|
15109
|
+
};
|
|
15110
|
+
UnauthorizedClientError.errorCode = "unauthorized_client";
|
|
15111
|
+
var UnsupportedGrantTypeError = class extends OAuthError {
|
|
15112
|
+
};
|
|
15113
|
+
UnsupportedGrantTypeError.errorCode = "unsupported_grant_type";
|
|
15114
|
+
var InvalidScopeError = class extends OAuthError {
|
|
15115
|
+
};
|
|
15116
|
+
InvalidScopeError.errorCode = "invalid_scope";
|
|
15117
|
+
var AccessDeniedError = class extends OAuthError {
|
|
15118
|
+
};
|
|
15119
|
+
AccessDeniedError.errorCode = "access_denied";
|
|
15120
|
+
var ServerError = class extends OAuthError {
|
|
15121
|
+
};
|
|
15122
|
+
ServerError.errorCode = "server_error";
|
|
15123
|
+
var TemporarilyUnavailableError = class extends OAuthError {
|
|
15124
|
+
};
|
|
15125
|
+
TemporarilyUnavailableError.errorCode = "temporarily_unavailable";
|
|
15126
|
+
var UnsupportedResponseTypeError = class extends OAuthError {
|
|
15127
|
+
};
|
|
15128
|
+
UnsupportedResponseTypeError.errorCode = "unsupported_response_type";
|
|
15129
|
+
var UnsupportedTokenTypeError = class extends OAuthError {
|
|
15130
|
+
};
|
|
15131
|
+
UnsupportedTokenTypeError.errorCode = "unsupported_token_type";
|
|
15132
|
+
var InvalidTokenError = class extends OAuthError {
|
|
15133
|
+
};
|
|
15134
|
+
InvalidTokenError.errorCode = "invalid_token";
|
|
15135
|
+
var MethodNotAllowedError = class extends OAuthError {
|
|
15136
|
+
};
|
|
15137
|
+
MethodNotAllowedError.errorCode = "method_not_allowed";
|
|
15138
|
+
var TooManyRequestsError = class extends OAuthError {
|
|
15139
|
+
};
|
|
15140
|
+
TooManyRequestsError.errorCode = "too_many_requests";
|
|
15141
|
+
var InvalidClientMetadataError = class extends OAuthError {
|
|
15142
|
+
};
|
|
15143
|
+
InvalidClientMetadataError.errorCode = "invalid_client_metadata";
|
|
15144
|
+
var InsufficientScopeError = class extends OAuthError {
|
|
15145
|
+
};
|
|
15146
|
+
InsufficientScopeError.errorCode = "insufficient_scope";
|
|
15147
|
+
var InvalidTargetError = class extends OAuthError {
|
|
15148
|
+
};
|
|
15149
|
+
InvalidTargetError.errorCode = "invalid_target";
|
|
15150
|
+
var OAUTH_ERRORS = {
|
|
15151
|
+
[InvalidRequestError.errorCode]: InvalidRequestError,
|
|
15152
|
+
[InvalidClientError.errorCode]: InvalidClientError,
|
|
15153
|
+
[InvalidGrantError.errorCode]: InvalidGrantError,
|
|
15154
|
+
[UnauthorizedClientError.errorCode]: UnauthorizedClientError,
|
|
15155
|
+
[UnsupportedGrantTypeError.errorCode]: UnsupportedGrantTypeError,
|
|
15156
|
+
[InvalidScopeError.errorCode]: InvalidScopeError,
|
|
15157
|
+
[AccessDeniedError.errorCode]: AccessDeniedError,
|
|
15158
|
+
[ServerError.errorCode]: ServerError,
|
|
15159
|
+
[TemporarilyUnavailableError.errorCode]: TemporarilyUnavailableError,
|
|
15160
|
+
[UnsupportedResponseTypeError.errorCode]: UnsupportedResponseTypeError,
|
|
15161
|
+
[UnsupportedTokenTypeError.errorCode]: UnsupportedTokenTypeError,
|
|
15162
|
+
[InvalidTokenError.errorCode]: InvalidTokenError,
|
|
15163
|
+
[MethodNotAllowedError.errorCode]: MethodNotAllowedError,
|
|
15164
|
+
[TooManyRequestsError.errorCode]: TooManyRequestsError,
|
|
15165
|
+
[InvalidClientMetadataError.errorCode]: InvalidClientMetadataError,
|
|
15166
|
+
[InsufficientScopeError.errorCode]: InsufficientScopeError,
|
|
15167
|
+
[InvalidTargetError.errorCode]: InvalidTargetError
|
|
15168
|
+
};
|
|
15169
|
+
|
|
15170
|
+
// ../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js
|
|
15171
|
+
var UnauthorizedError = class extends Error {
|
|
15172
|
+
constructor(message) {
|
|
15173
|
+
super(message ?? "Unauthorized");
|
|
15174
|
+
}
|
|
15175
|
+
};
|
|
15176
|
+
function isClientAuthMethod(method) {
|
|
15177
|
+
return ["client_secret_basic", "client_secret_post", "none"].includes(method);
|
|
15178
|
+
}
|
|
15179
|
+
var AUTHORIZATION_CODE_RESPONSE_TYPE = "code";
|
|
15180
|
+
var AUTHORIZATION_CODE_CHALLENGE_METHOD = "S256";
|
|
15181
|
+
function selectClientAuthMethod(clientInformation, supportedMethods) {
|
|
15182
|
+
const hasClientSecret = clientInformation.client_secret !== void 0;
|
|
15183
|
+
if ("token_endpoint_auth_method" in clientInformation && clientInformation.token_endpoint_auth_method && isClientAuthMethod(clientInformation.token_endpoint_auth_method) && (supportedMethods.length === 0 || supportedMethods.includes(clientInformation.token_endpoint_auth_method))) {
|
|
15184
|
+
return clientInformation.token_endpoint_auth_method;
|
|
15185
|
+
}
|
|
15186
|
+
if (supportedMethods.length === 0) {
|
|
15187
|
+
return hasClientSecret ? "client_secret_basic" : "none";
|
|
15188
|
+
}
|
|
15189
|
+
if (hasClientSecret && supportedMethods.includes("client_secret_basic")) {
|
|
15190
|
+
return "client_secret_basic";
|
|
15191
|
+
}
|
|
15192
|
+
if (hasClientSecret && supportedMethods.includes("client_secret_post")) {
|
|
15193
|
+
return "client_secret_post";
|
|
15194
|
+
}
|
|
15195
|
+
if (supportedMethods.includes("none")) {
|
|
15196
|
+
return "none";
|
|
15197
|
+
}
|
|
15198
|
+
return hasClientSecret ? "client_secret_post" : "none";
|
|
15199
|
+
}
|
|
15200
|
+
function applyClientAuthentication(method, clientInformation, headers, params) {
|
|
15201
|
+
const { client_id, client_secret } = clientInformation;
|
|
15202
|
+
switch (method) {
|
|
15203
|
+
case "client_secret_basic":
|
|
15204
|
+
applyBasicAuth(client_id, client_secret, headers);
|
|
15205
|
+
return;
|
|
15206
|
+
case "client_secret_post":
|
|
15207
|
+
applyPostAuth(client_id, client_secret, params);
|
|
15208
|
+
return;
|
|
15209
|
+
case "none":
|
|
15210
|
+
applyPublicAuth(client_id, params);
|
|
15211
|
+
return;
|
|
15212
|
+
default:
|
|
15213
|
+
throw new Error(`Unsupported client authentication method: ${method}`);
|
|
15214
|
+
}
|
|
15215
|
+
}
|
|
15216
|
+
function applyBasicAuth(clientId, clientSecret, headers) {
|
|
15217
|
+
if (!clientSecret) {
|
|
15218
|
+
throw new Error("client_secret_basic authentication requires a client_secret");
|
|
15219
|
+
}
|
|
15220
|
+
const credentials = btoa(`${clientId}:${clientSecret}`);
|
|
15221
|
+
headers.set("Authorization", `Basic ${credentials}`);
|
|
15222
|
+
}
|
|
15223
|
+
function applyPostAuth(clientId, clientSecret, params) {
|
|
15224
|
+
params.set("client_id", clientId);
|
|
15225
|
+
if (clientSecret) {
|
|
15226
|
+
params.set("client_secret", clientSecret);
|
|
15227
|
+
}
|
|
15228
|
+
}
|
|
15229
|
+
function applyPublicAuth(clientId, params) {
|
|
15230
|
+
params.set("client_id", clientId);
|
|
15231
|
+
}
|
|
15232
|
+
async function parseErrorResponse(input) {
|
|
15233
|
+
const statusCode = input instanceof Response ? input.status : void 0;
|
|
15234
|
+
const body = input instanceof Response ? await input.text() : input;
|
|
15235
|
+
try {
|
|
15236
|
+
const result = OAuthErrorResponseSchema.parse(JSON.parse(body));
|
|
15237
|
+
const { error: error2, error_description, error_uri } = result;
|
|
15238
|
+
const errorClass = OAUTH_ERRORS[error2] || ServerError;
|
|
15239
|
+
return new errorClass(error_description || "", error_uri);
|
|
15240
|
+
} catch (error2) {
|
|
15241
|
+
const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ""}Invalid OAuth error response: ${error2}. Raw body: ${body}`;
|
|
15242
|
+
return new ServerError(errorMessage);
|
|
15243
|
+
}
|
|
15244
|
+
}
|
|
15245
|
+
async function auth(provider, options) {
|
|
15246
|
+
try {
|
|
15247
|
+
return await authInternal(provider, options);
|
|
15248
|
+
} catch (error2) {
|
|
15249
|
+
if (error2 instanceof InvalidClientError || error2 instanceof UnauthorizedClientError) {
|
|
15250
|
+
await provider.invalidateCredentials?.("all");
|
|
15251
|
+
return await authInternal(provider, options);
|
|
15252
|
+
} else if (error2 instanceof InvalidGrantError) {
|
|
15253
|
+
await provider.invalidateCredentials?.("tokens");
|
|
15254
|
+
return await authInternal(provider, options);
|
|
15255
|
+
}
|
|
15256
|
+
throw error2;
|
|
15257
|
+
}
|
|
15258
|
+
}
|
|
15259
|
+
async function authInternal(provider, { serverUrl, authorizationCode, scope, resourceMetadataUrl, fetchFn }) {
|
|
15260
|
+
const cachedState = await provider.discoveryState?.();
|
|
15261
|
+
let resourceMetadata;
|
|
15262
|
+
let authorizationServerUrl;
|
|
15263
|
+
let metadata;
|
|
15264
|
+
let effectiveResourceMetadataUrl = resourceMetadataUrl;
|
|
15265
|
+
if (!effectiveResourceMetadataUrl && cachedState?.resourceMetadataUrl) {
|
|
15266
|
+
effectiveResourceMetadataUrl = new URL(cachedState.resourceMetadataUrl);
|
|
15267
|
+
}
|
|
15268
|
+
if (cachedState?.authorizationServerUrl) {
|
|
15269
|
+
authorizationServerUrl = cachedState.authorizationServerUrl;
|
|
15270
|
+
resourceMetadata = cachedState.resourceMetadata;
|
|
15271
|
+
metadata = cachedState.authorizationServerMetadata ?? await discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn });
|
|
15272
|
+
if (!resourceMetadata) {
|
|
15273
|
+
try {
|
|
15274
|
+
resourceMetadata = await discoverOAuthProtectedResourceMetadata(serverUrl, { resourceMetadataUrl: effectiveResourceMetadataUrl }, fetchFn);
|
|
15275
|
+
} catch {
|
|
15276
|
+
}
|
|
15277
|
+
}
|
|
15278
|
+
if (metadata !== cachedState.authorizationServerMetadata || resourceMetadata !== cachedState.resourceMetadata) {
|
|
15279
|
+
await provider.saveDiscoveryState?.({
|
|
15280
|
+
authorizationServerUrl: String(authorizationServerUrl),
|
|
15281
|
+
resourceMetadataUrl: effectiveResourceMetadataUrl?.toString(),
|
|
15282
|
+
resourceMetadata,
|
|
15283
|
+
authorizationServerMetadata: metadata
|
|
15284
|
+
});
|
|
15285
|
+
}
|
|
15286
|
+
} else {
|
|
15287
|
+
const serverInfo = await discoverOAuthServerInfo(serverUrl, { resourceMetadataUrl: effectiveResourceMetadataUrl, fetchFn });
|
|
15288
|
+
authorizationServerUrl = serverInfo.authorizationServerUrl;
|
|
15289
|
+
metadata = serverInfo.authorizationServerMetadata;
|
|
15290
|
+
resourceMetadata = serverInfo.resourceMetadata;
|
|
15291
|
+
await provider.saveDiscoveryState?.({
|
|
15292
|
+
authorizationServerUrl: String(authorizationServerUrl),
|
|
15293
|
+
resourceMetadataUrl: effectiveResourceMetadataUrl?.toString(),
|
|
15294
|
+
resourceMetadata,
|
|
15295
|
+
authorizationServerMetadata: metadata
|
|
15296
|
+
});
|
|
15297
|
+
}
|
|
15298
|
+
const resource = await selectResourceURL(serverUrl, provider, resourceMetadata);
|
|
15299
|
+
const resolvedScope = scope || resourceMetadata?.scopes_supported?.join(" ") || provider.clientMetadata.scope;
|
|
15300
|
+
let clientInformation = await Promise.resolve(provider.clientInformation());
|
|
15301
|
+
if (!clientInformation) {
|
|
15302
|
+
if (authorizationCode !== void 0) {
|
|
15303
|
+
throw new Error("Existing OAuth client information is required when exchanging an authorization code");
|
|
15304
|
+
}
|
|
15305
|
+
const supportsUrlBasedClientId = metadata?.client_id_metadata_document_supported === true;
|
|
15306
|
+
const clientMetadataUrl = provider.clientMetadataUrl;
|
|
15307
|
+
if (clientMetadataUrl && !isHttpsUrl(clientMetadataUrl)) {
|
|
15308
|
+
throw new InvalidClientMetadataError(`clientMetadataUrl must be a valid HTTPS URL with a non-root pathname, got: ${clientMetadataUrl}`);
|
|
15309
|
+
}
|
|
15310
|
+
const shouldUseUrlBasedClientId = supportsUrlBasedClientId && clientMetadataUrl;
|
|
15311
|
+
if (shouldUseUrlBasedClientId) {
|
|
15312
|
+
clientInformation = {
|
|
15313
|
+
client_id: clientMetadataUrl
|
|
15314
|
+
};
|
|
15315
|
+
await provider.saveClientInformation?.(clientInformation);
|
|
15316
|
+
} else {
|
|
15317
|
+
if (!provider.saveClientInformation) {
|
|
15318
|
+
throw new Error("OAuth client information must be saveable for dynamic registration");
|
|
15319
|
+
}
|
|
15320
|
+
const fullInformation = await registerClient(authorizationServerUrl, {
|
|
15321
|
+
metadata,
|
|
15322
|
+
clientMetadata: provider.clientMetadata,
|
|
15323
|
+
scope: resolvedScope,
|
|
15324
|
+
fetchFn
|
|
15325
|
+
});
|
|
15326
|
+
await provider.saveClientInformation(fullInformation);
|
|
15327
|
+
clientInformation = fullInformation;
|
|
15328
|
+
}
|
|
15329
|
+
}
|
|
15330
|
+
const nonInteractiveFlow = !provider.redirectUrl;
|
|
15331
|
+
if (authorizationCode !== void 0 || nonInteractiveFlow) {
|
|
15332
|
+
const tokens2 = await fetchToken(provider, authorizationServerUrl, {
|
|
15333
|
+
metadata,
|
|
15334
|
+
resource,
|
|
15335
|
+
authorizationCode,
|
|
15336
|
+
fetchFn
|
|
15337
|
+
});
|
|
15338
|
+
await provider.saveTokens(tokens2);
|
|
15339
|
+
return "AUTHORIZED";
|
|
15340
|
+
}
|
|
15341
|
+
const tokens = await provider.tokens();
|
|
15342
|
+
if (tokens?.refresh_token) {
|
|
15343
|
+
try {
|
|
15344
|
+
const newTokens = await refreshAuthorization(authorizationServerUrl, {
|
|
15345
|
+
metadata,
|
|
15346
|
+
clientInformation,
|
|
15347
|
+
refreshToken: tokens.refresh_token,
|
|
15348
|
+
resource,
|
|
15349
|
+
addClientAuthentication: provider.addClientAuthentication,
|
|
15350
|
+
fetchFn
|
|
15351
|
+
});
|
|
15352
|
+
await provider.saveTokens(newTokens);
|
|
15353
|
+
return "AUTHORIZED";
|
|
15354
|
+
} catch (error2) {
|
|
15355
|
+
if (!(error2 instanceof OAuthError) || error2 instanceof ServerError) {
|
|
15356
|
+
} else {
|
|
15357
|
+
throw error2;
|
|
15358
|
+
}
|
|
15359
|
+
}
|
|
15360
|
+
}
|
|
15361
|
+
const state = provider.state ? await provider.state() : void 0;
|
|
15362
|
+
const { authorizationUrl, codeVerifier } = await startAuthorization(authorizationServerUrl, {
|
|
15363
|
+
metadata,
|
|
15364
|
+
clientInformation,
|
|
15365
|
+
state,
|
|
15366
|
+
redirectUrl: provider.redirectUrl,
|
|
15367
|
+
scope: resolvedScope,
|
|
15368
|
+
resource
|
|
15369
|
+
});
|
|
15370
|
+
await provider.saveCodeVerifier(codeVerifier);
|
|
15371
|
+
await provider.redirectToAuthorization(authorizationUrl);
|
|
15372
|
+
return "REDIRECT";
|
|
15373
|
+
}
|
|
15374
|
+
function isHttpsUrl(value) {
|
|
15375
|
+
if (!value)
|
|
15376
|
+
return false;
|
|
15377
|
+
try {
|
|
15378
|
+
const url2 = new URL(value);
|
|
15379
|
+
return url2.protocol === "https:" && url2.pathname !== "/";
|
|
15380
|
+
} catch {
|
|
15381
|
+
return false;
|
|
15382
|
+
}
|
|
15383
|
+
}
|
|
15384
|
+
async function selectResourceURL(serverUrl, provider, resourceMetadata) {
|
|
15385
|
+
const defaultResource = resourceUrlFromServerUrl(serverUrl);
|
|
15386
|
+
if (provider.validateResourceURL) {
|
|
15387
|
+
return await provider.validateResourceURL(defaultResource, resourceMetadata?.resource);
|
|
15388
|
+
}
|
|
15389
|
+
if (!resourceMetadata) {
|
|
15390
|
+
return void 0;
|
|
15391
|
+
}
|
|
15392
|
+
if (!checkResourceAllowed({ requestedResource: defaultResource, configuredResource: resourceMetadata.resource })) {
|
|
15393
|
+
throw new Error(`Protected resource ${resourceMetadata.resource} does not match expected ${defaultResource} (or origin)`);
|
|
15394
|
+
}
|
|
15395
|
+
return new URL(resourceMetadata.resource);
|
|
15396
|
+
}
|
|
15397
|
+
function extractWWWAuthenticateParams(res) {
|
|
15398
|
+
const authenticateHeader = res.headers.get("WWW-Authenticate");
|
|
15399
|
+
if (!authenticateHeader) {
|
|
15400
|
+
return {};
|
|
15401
|
+
}
|
|
15402
|
+
const [type, scheme] = authenticateHeader.split(" ");
|
|
15403
|
+
if (type.toLowerCase() !== "bearer" || !scheme) {
|
|
15404
|
+
return {};
|
|
15405
|
+
}
|
|
15406
|
+
const resourceMetadataMatch = extractFieldFromWwwAuth(res, "resource_metadata") || void 0;
|
|
15407
|
+
let resourceMetadataUrl;
|
|
15408
|
+
if (resourceMetadataMatch) {
|
|
15409
|
+
try {
|
|
15410
|
+
resourceMetadataUrl = new URL(resourceMetadataMatch);
|
|
15411
|
+
} catch {
|
|
15412
|
+
}
|
|
15413
|
+
}
|
|
15414
|
+
const scope = extractFieldFromWwwAuth(res, "scope") || void 0;
|
|
15415
|
+
const error2 = extractFieldFromWwwAuth(res, "error") || void 0;
|
|
15416
|
+
return {
|
|
15417
|
+
resourceMetadataUrl,
|
|
15418
|
+
scope,
|
|
15419
|
+
error: error2
|
|
15420
|
+
};
|
|
15421
|
+
}
|
|
15422
|
+
function extractFieldFromWwwAuth(response, fieldName) {
|
|
15423
|
+
const wwwAuthHeader = response.headers.get("WWW-Authenticate");
|
|
15424
|
+
if (!wwwAuthHeader) {
|
|
15425
|
+
return null;
|
|
15426
|
+
}
|
|
15427
|
+
const pattern = new RegExp(`${fieldName}=(?:"([^"]+)"|([^\\s,]+))`);
|
|
15428
|
+
const match = wwwAuthHeader.match(pattern);
|
|
15429
|
+
if (match) {
|
|
15430
|
+
return match[1] || match[2];
|
|
15431
|
+
}
|
|
15432
|
+
return null;
|
|
15433
|
+
}
|
|
15434
|
+
async function discoverOAuthProtectedResourceMetadata(serverUrl, opts, fetchFn = fetch) {
|
|
15435
|
+
const response = await discoverMetadataWithFallback(serverUrl, "oauth-protected-resource", fetchFn, {
|
|
15436
|
+
protocolVersion: opts?.protocolVersion,
|
|
15437
|
+
metadataUrl: opts?.resourceMetadataUrl
|
|
15438
|
+
});
|
|
15439
|
+
if (!response || response.status === 404) {
|
|
15440
|
+
await response?.body?.cancel();
|
|
15441
|
+
throw new Error(`Resource server does not implement OAuth 2.0 Protected Resource Metadata.`);
|
|
15442
|
+
}
|
|
15443
|
+
if (!response.ok) {
|
|
15444
|
+
await response.body?.cancel();
|
|
15445
|
+
throw new Error(`HTTP ${response.status} trying to load well-known OAuth protected resource metadata.`);
|
|
15446
|
+
}
|
|
15447
|
+
return OAuthProtectedResourceMetadataSchema.parse(await response.json());
|
|
15448
|
+
}
|
|
15449
|
+
async function fetchWithCorsRetry(url2, headers, fetchFn = fetch) {
|
|
15450
|
+
try {
|
|
15451
|
+
return await fetchFn(url2, { headers });
|
|
15452
|
+
} catch (error2) {
|
|
15453
|
+
if (error2 instanceof TypeError) {
|
|
15454
|
+
if (headers) {
|
|
15455
|
+
return fetchWithCorsRetry(url2, void 0, fetchFn);
|
|
15456
|
+
} else {
|
|
15457
|
+
return void 0;
|
|
15458
|
+
}
|
|
15459
|
+
}
|
|
15460
|
+
throw error2;
|
|
15461
|
+
}
|
|
15462
|
+
}
|
|
15463
|
+
function buildWellKnownPath(wellKnownPrefix, pathname = "", options = {}) {
|
|
15464
|
+
if (pathname.endsWith("/")) {
|
|
15465
|
+
pathname = pathname.slice(0, -1);
|
|
15466
|
+
}
|
|
15467
|
+
return options.prependPathname ? `${pathname}/.well-known/${wellKnownPrefix}` : `/.well-known/${wellKnownPrefix}${pathname}`;
|
|
15468
|
+
}
|
|
15469
|
+
async function tryMetadataDiscovery(url2, protocolVersion, fetchFn = fetch) {
|
|
15470
|
+
const headers = {
|
|
15471
|
+
"MCP-Protocol-Version": protocolVersion
|
|
15472
|
+
};
|
|
15473
|
+
return await fetchWithCorsRetry(url2, headers, fetchFn);
|
|
15474
|
+
}
|
|
15475
|
+
function shouldAttemptFallback(response, pathname) {
|
|
15476
|
+
return !response || response.status >= 400 && response.status < 500 && pathname !== "/";
|
|
15477
|
+
}
|
|
15478
|
+
async function discoverMetadataWithFallback(serverUrl, wellKnownType, fetchFn, opts) {
|
|
15479
|
+
const issuer = new URL(serverUrl);
|
|
15480
|
+
const protocolVersion = opts?.protocolVersion ?? LATEST_PROTOCOL_VERSION;
|
|
15481
|
+
let url2;
|
|
15482
|
+
if (opts?.metadataUrl) {
|
|
15483
|
+
url2 = new URL(opts.metadataUrl);
|
|
15484
|
+
} else {
|
|
15485
|
+
const wellKnownPath = buildWellKnownPath(wellKnownType, issuer.pathname);
|
|
15486
|
+
url2 = new URL(wellKnownPath, opts?.metadataServerUrl ?? issuer);
|
|
15487
|
+
url2.search = issuer.search;
|
|
15488
|
+
}
|
|
15489
|
+
let response = await tryMetadataDiscovery(url2, protocolVersion, fetchFn);
|
|
15490
|
+
if (!opts?.metadataUrl && shouldAttemptFallback(response, issuer.pathname)) {
|
|
15491
|
+
const rootUrl = new URL(`/.well-known/${wellKnownType}`, issuer);
|
|
15492
|
+
response = await tryMetadataDiscovery(rootUrl, protocolVersion, fetchFn);
|
|
15493
|
+
}
|
|
15494
|
+
return response;
|
|
15495
|
+
}
|
|
15496
|
+
function buildDiscoveryUrls(authorizationServerUrl) {
|
|
15497
|
+
const url2 = typeof authorizationServerUrl === "string" ? new URL(authorizationServerUrl) : authorizationServerUrl;
|
|
15498
|
+
const hasPath = url2.pathname !== "/";
|
|
15499
|
+
const urlsToTry = [];
|
|
15500
|
+
if (!hasPath) {
|
|
15501
|
+
urlsToTry.push({
|
|
15502
|
+
url: new URL("/.well-known/oauth-authorization-server", url2.origin),
|
|
15503
|
+
type: "oauth"
|
|
15504
|
+
});
|
|
15505
|
+
urlsToTry.push({
|
|
15506
|
+
url: new URL(`/.well-known/openid-configuration`, url2.origin),
|
|
15507
|
+
type: "oidc"
|
|
15508
|
+
});
|
|
15509
|
+
return urlsToTry;
|
|
15510
|
+
}
|
|
15511
|
+
let pathname = url2.pathname;
|
|
15512
|
+
if (pathname.endsWith("/")) {
|
|
15513
|
+
pathname = pathname.slice(0, -1);
|
|
15514
|
+
}
|
|
15515
|
+
urlsToTry.push({
|
|
15516
|
+
url: new URL(`/.well-known/oauth-authorization-server${pathname}`, url2.origin),
|
|
15517
|
+
type: "oauth"
|
|
15518
|
+
});
|
|
15519
|
+
urlsToTry.push({
|
|
15520
|
+
url: new URL(`/.well-known/openid-configuration${pathname}`, url2.origin),
|
|
15521
|
+
type: "oidc"
|
|
15522
|
+
});
|
|
15523
|
+
urlsToTry.push({
|
|
15524
|
+
url: new URL(`${pathname}/.well-known/openid-configuration`, url2.origin),
|
|
15525
|
+
type: "oidc"
|
|
15526
|
+
});
|
|
15527
|
+
return urlsToTry;
|
|
15528
|
+
}
|
|
15529
|
+
async function discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn = fetch, protocolVersion = LATEST_PROTOCOL_VERSION } = {}) {
|
|
15530
|
+
const headers = {
|
|
15531
|
+
"MCP-Protocol-Version": protocolVersion,
|
|
15532
|
+
Accept: "application/json"
|
|
15533
|
+
};
|
|
15534
|
+
const urlsToTry = buildDiscoveryUrls(authorizationServerUrl);
|
|
15535
|
+
for (const { url: endpointUrl, type } of urlsToTry) {
|
|
15536
|
+
const response = await fetchWithCorsRetry(endpointUrl, headers, fetchFn);
|
|
15537
|
+
if (!response) {
|
|
15538
|
+
continue;
|
|
15539
|
+
}
|
|
15540
|
+
if (!response.ok) {
|
|
15541
|
+
await response.body?.cancel();
|
|
15542
|
+
if (response.status >= 400 && response.status < 500) {
|
|
15543
|
+
continue;
|
|
15544
|
+
}
|
|
15545
|
+
throw new Error(`HTTP ${response.status} trying to load ${type === "oauth" ? "OAuth" : "OpenID provider"} metadata from ${endpointUrl}`);
|
|
15546
|
+
}
|
|
15547
|
+
if (type === "oauth") {
|
|
15548
|
+
return OAuthMetadataSchema.parse(await response.json());
|
|
15549
|
+
} else {
|
|
15550
|
+
return OpenIdProviderDiscoveryMetadataSchema.parse(await response.json());
|
|
15551
|
+
}
|
|
15552
|
+
}
|
|
15553
|
+
return void 0;
|
|
15554
|
+
}
|
|
15555
|
+
async function discoverOAuthServerInfo(serverUrl, opts) {
|
|
15556
|
+
let resourceMetadata;
|
|
15557
|
+
let authorizationServerUrl;
|
|
15558
|
+
try {
|
|
15559
|
+
resourceMetadata = await discoverOAuthProtectedResourceMetadata(serverUrl, { resourceMetadataUrl: opts?.resourceMetadataUrl }, opts?.fetchFn);
|
|
15560
|
+
if (resourceMetadata.authorization_servers && resourceMetadata.authorization_servers.length > 0) {
|
|
15561
|
+
authorizationServerUrl = resourceMetadata.authorization_servers[0];
|
|
15562
|
+
}
|
|
15563
|
+
} catch {
|
|
15564
|
+
}
|
|
15565
|
+
if (!authorizationServerUrl) {
|
|
15566
|
+
authorizationServerUrl = String(new URL("/", serverUrl));
|
|
15567
|
+
}
|
|
15568
|
+
const authorizationServerMetadata = await discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn: opts?.fetchFn });
|
|
15569
|
+
return {
|
|
15570
|
+
authorizationServerUrl,
|
|
15571
|
+
authorizationServerMetadata,
|
|
15572
|
+
resourceMetadata
|
|
15573
|
+
};
|
|
15574
|
+
}
|
|
15575
|
+
async function startAuthorization(authorizationServerUrl, { metadata, clientInformation, redirectUrl, scope, state, resource }) {
|
|
15576
|
+
let authorizationUrl;
|
|
15577
|
+
if (metadata) {
|
|
15578
|
+
authorizationUrl = new URL(metadata.authorization_endpoint);
|
|
15579
|
+
if (!metadata.response_types_supported.includes(AUTHORIZATION_CODE_RESPONSE_TYPE)) {
|
|
15580
|
+
throw new Error(`Incompatible auth server: does not support response type ${AUTHORIZATION_CODE_RESPONSE_TYPE}`);
|
|
15581
|
+
}
|
|
15582
|
+
if (metadata.code_challenge_methods_supported && !metadata.code_challenge_methods_supported.includes(AUTHORIZATION_CODE_CHALLENGE_METHOD)) {
|
|
15583
|
+
throw new Error(`Incompatible auth server: does not support code challenge method ${AUTHORIZATION_CODE_CHALLENGE_METHOD}`);
|
|
15584
|
+
}
|
|
15585
|
+
} else {
|
|
15586
|
+
authorizationUrl = new URL("/authorize", authorizationServerUrl);
|
|
15587
|
+
}
|
|
15588
|
+
const challenge = await pkceChallenge();
|
|
15589
|
+
const codeVerifier = challenge.code_verifier;
|
|
15590
|
+
const codeChallenge = challenge.code_challenge;
|
|
15591
|
+
authorizationUrl.searchParams.set("response_type", AUTHORIZATION_CODE_RESPONSE_TYPE);
|
|
15592
|
+
authorizationUrl.searchParams.set("client_id", clientInformation.client_id);
|
|
15593
|
+
authorizationUrl.searchParams.set("code_challenge", codeChallenge);
|
|
15594
|
+
authorizationUrl.searchParams.set("code_challenge_method", AUTHORIZATION_CODE_CHALLENGE_METHOD);
|
|
15595
|
+
authorizationUrl.searchParams.set("redirect_uri", String(redirectUrl));
|
|
15596
|
+
if (state) {
|
|
15597
|
+
authorizationUrl.searchParams.set("state", state);
|
|
15598
|
+
}
|
|
15599
|
+
if (scope) {
|
|
15600
|
+
authorizationUrl.searchParams.set("scope", scope);
|
|
15601
|
+
}
|
|
15602
|
+
if (scope?.includes("offline_access")) {
|
|
15603
|
+
authorizationUrl.searchParams.append("prompt", "consent");
|
|
15604
|
+
}
|
|
15605
|
+
if (resource) {
|
|
15606
|
+
authorizationUrl.searchParams.set("resource", resource.href);
|
|
15607
|
+
}
|
|
15608
|
+
return { authorizationUrl, codeVerifier };
|
|
15609
|
+
}
|
|
15610
|
+
function prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, redirectUri) {
|
|
15611
|
+
return new URLSearchParams({
|
|
15612
|
+
grant_type: "authorization_code",
|
|
15613
|
+
code: authorizationCode,
|
|
15614
|
+
code_verifier: codeVerifier,
|
|
15615
|
+
redirect_uri: String(redirectUri)
|
|
15616
|
+
});
|
|
15617
|
+
}
|
|
15618
|
+
async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequestParams, clientInformation, addClientAuthentication, resource, fetchFn }) {
|
|
15619
|
+
const tokenUrl = metadata?.token_endpoint ? new URL(metadata.token_endpoint) : new URL("/token", authorizationServerUrl);
|
|
15620
|
+
const headers = new Headers({
|
|
15621
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
15622
|
+
Accept: "application/json"
|
|
15623
|
+
});
|
|
15624
|
+
if (resource) {
|
|
15625
|
+
tokenRequestParams.set("resource", resource.href);
|
|
15626
|
+
}
|
|
15627
|
+
if (addClientAuthentication) {
|
|
15628
|
+
await addClientAuthentication(headers, tokenRequestParams, tokenUrl, metadata);
|
|
15629
|
+
} else if (clientInformation) {
|
|
15630
|
+
const supportedMethods = metadata?.token_endpoint_auth_methods_supported ?? [];
|
|
15631
|
+
const authMethod = selectClientAuthMethod(clientInformation, supportedMethods);
|
|
15632
|
+
applyClientAuthentication(authMethod, clientInformation, headers, tokenRequestParams);
|
|
15633
|
+
}
|
|
15634
|
+
const response = await (fetchFn ?? fetch)(tokenUrl, {
|
|
15635
|
+
method: "POST",
|
|
15636
|
+
headers,
|
|
15637
|
+
body: tokenRequestParams
|
|
15638
|
+
});
|
|
15639
|
+
if (!response.ok) {
|
|
15640
|
+
throw await parseErrorResponse(response);
|
|
15641
|
+
}
|
|
15642
|
+
return OAuthTokensSchema.parse(await response.json());
|
|
15643
|
+
}
|
|
15644
|
+
async function refreshAuthorization(authorizationServerUrl, { metadata, clientInformation, refreshToken, resource, addClientAuthentication, fetchFn }) {
|
|
15645
|
+
const tokenRequestParams = new URLSearchParams({
|
|
15646
|
+
grant_type: "refresh_token",
|
|
15647
|
+
refresh_token: refreshToken
|
|
15648
|
+
});
|
|
15649
|
+
const tokens = await executeTokenRequest(authorizationServerUrl, {
|
|
15650
|
+
metadata,
|
|
15651
|
+
tokenRequestParams,
|
|
15652
|
+
clientInformation,
|
|
15653
|
+
addClientAuthentication,
|
|
15654
|
+
resource,
|
|
15655
|
+
fetchFn
|
|
15656
|
+
});
|
|
15657
|
+
return { refresh_token: refreshToken, ...tokens };
|
|
15658
|
+
}
|
|
15659
|
+
async function fetchToken(provider, authorizationServerUrl, { metadata, resource, authorizationCode, fetchFn } = {}) {
|
|
15660
|
+
const scope = provider.clientMetadata.scope;
|
|
15661
|
+
let tokenRequestParams;
|
|
15662
|
+
if (provider.prepareTokenRequest) {
|
|
15663
|
+
tokenRequestParams = await provider.prepareTokenRequest(scope);
|
|
15664
|
+
}
|
|
15665
|
+
if (!tokenRequestParams) {
|
|
15666
|
+
if (!authorizationCode) {
|
|
15667
|
+
throw new Error("Either provider.prepareTokenRequest() or authorizationCode is required");
|
|
15668
|
+
}
|
|
15669
|
+
if (!provider.redirectUrl) {
|
|
15670
|
+
throw new Error("redirectUrl is required for authorization_code flow");
|
|
15671
|
+
}
|
|
15672
|
+
const codeVerifier = await provider.codeVerifier();
|
|
15673
|
+
tokenRequestParams = prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, provider.redirectUrl);
|
|
15674
|
+
}
|
|
15675
|
+
const clientInformation = await provider.clientInformation();
|
|
15676
|
+
return executeTokenRequest(authorizationServerUrl, {
|
|
15677
|
+
metadata,
|
|
15678
|
+
tokenRequestParams,
|
|
15679
|
+
clientInformation: clientInformation ?? void 0,
|
|
15680
|
+
addClientAuthentication: provider.addClientAuthentication,
|
|
15681
|
+
resource,
|
|
15682
|
+
fetchFn
|
|
15683
|
+
});
|
|
15684
|
+
}
|
|
15685
|
+
async function registerClient(authorizationServerUrl, { metadata, clientMetadata, scope, fetchFn }) {
|
|
15686
|
+
let registrationUrl;
|
|
15687
|
+
if (metadata) {
|
|
15688
|
+
if (!metadata.registration_endpoint) {
|
|
15689
|
+
throw new Error("Incompatible auth server: does not support dynamic client registration");
|
|
15690
|
+
}
|
|
15691
|
+
registrationUrl = new URL(metadata.registration_endpoint);
|
|
15692
|
+
} else {
|
|
15693
|
+
registrationUrl = new URL("/register", authorizationServerUrl);
|
|
15694
|
+
}
|
|
15695
|
+
const response = await (fetchFn ?? fetch)(registrationUrl, {
|
|
15696
|
+
method: "POST",
|
|
15697
|
+
headers: {
|
|
15698
|
+
"Content-Type": "application/json"
|
|
15699
|
+
},
|
|
15700
|
+
body: JSON.stringify({
|
|
15701
|
+
...clientMetadata,
|
|
15702
|
+
...scope !== void 0 ? { scope } : {}
|
|
15703
|
+
})
|
|
15704
|
+
});
|
|
15705
|
+
if (!response.ok) {
|
|
15706
|
+
throw await parseErrorResponse(response);
|
|
15707
|
+
}
|
|
15708
|
+
return OAuthClientInformationFullSchema.parse(await response.json());
|
|
15709
|
+
}
|
|
15710
|
+
|
|
15711
|
+
// ../node_modules/.pnpm/eventsource-parser@3.1.0/node_modules/eventsource-parser/dist/index.js
|
|
15712
|
+
var ParseError = class extends Error {
|
|
15713
|
+
constructor(message, options) {
|
|
15714
|
+
super(message), this.name = "ParseError", this.type = options.type, this.field = options.field, this.value = options.value, this.line = options.line;
|
|
15715
|
+
}
|
|
15716
|
+
};
|
|
15717
|
+
var LF = 10;
|
|
15718
|
+
var CR = 13;
|
|
15719
|
+
var SPACE = 32;
|
|
15720
|
+
function noop(_arg) {
|
|
15721
|
+
}
|
|
15722
|
+
function createParser(config2) {
|
|
15723
|
+
if (typeof config2 == "function")
|
|
15724
|
+
throw new TypeError(
|
|
15725
|
+
"`config` must be an object, got a function instead. Did you mean `createParser({onEvent: fn})`?"
|
|
15726
|
+
);
|
|
15727
|
+
const { onEvent = noop, onError = noop, onRetry = noop, onComment, maxBufferSize } = config2, pendingFragments = [];
|
|
15728
|
+
let pendingFragmentsLength = 0, isFirstChunk = true, id, data = "", dataLines = 0, eventType, terminated = false;
|
|
15729
|
+
function feed(chunk) {
|
|
15730
|
+
if (terminated)
|
|
15731
|
+
throw new Error(
|
|
15732
|
+
"Cannot feed parser: it was terminated after exceeding the configured max buffer size. Call `reset()` to resume parsing."
|
|
15733
|
+
);
|
|
15734
|
+
if (isFirstChunk && (isFirstChunk = false, chunk.charCodeAt(0) === 239 && chunk.charCodeAt(1) === 187 && chunk.charCodeAt(2) === 191 && (chunk = chunk.slice(3))), pendingFragments.length === 0) {
|
|
15735
|
+
const trailing2 = processLines(chunk);
|
|
15736
|
+
trailing2 !== "" && (pendingFragments.push(trailing2), pendingFragmentsLength = trailing2.length), checkBufferSize();
|
|
15737
|
+
return;
|
|
15738
|
+
}
|
|
15739
|
+
if (chunk.indexOf(`
|
|
15740
|
+
`) === -1 && chunk.indexOf("\r") === -1) {
|
|
15741
|
+
pendingFragments.push(chunk), pendingFragmentsLength += chunk.length, checkBufferSize();
|
|
15742
|
+
return;
|
|
15743
|
+
}
|
|
15744
|
+
pendingFragments.push(chunk);
|
|
15745
|
+
const input = pendingFragments.join("");
|
|
15746
|
+
pendingFragments.length = 0, pendingFragmentsLength = 0;
|
|
15747
|
+
const trailing = processLines(input);
|
|
15748
|
+
trailing !== "" && (pendingFragments.push(trailing), pendingFragmentsLength = trailing.length), checkBufferSize();
|
|
15749
|
+
}
|
|
15750
|
+
function checkBufferSize() {
|
|
15751
|
+
maxBufferSize !== void 0 && (pendingFragmentsLength + data.length <= maxBufferSize || (terminated = true, pendingFragments.length = 0, pendingFragmentsLength = 0, id = void 0, data = "", dataLines = 0, eventType = void 0, onError(
|
|
15752
|
+
new ParseError(`Buffered data exceeded max buffer size of ${maxBufferSize} characters`, {
|
|
15753
|
+
type: "max-buffer-size-exceeded"
|
|
15754
|
+
})
|
|
15755
|
+
)));
|
|
15756
|
+
}
|
|
15757
|
+
function processLines(chunk) {
|
|
15758
|
+
let searchIndex = 0;
|
|
15759
|
+
if (chunk.indexOf("\r") === -1) {
|
|
15760
|
+
let lfIndex = chunk.indexOf(`
|
|
15761
|
+
`, searchIndex);
|
|
15762
|
+
for (; lfIndex !== -1; ) {
|
|
15763
|
+
if (searchIndex === lfIndex) {
|
|
15764
|
+
dataLines > 0 && onEvent({ id, event: eventType, data }), id = void 0, data = "", dataLines = 0, eventType = void 0, searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`
|
|
15765
|
+
`, searchIndex);
|
|
15766
|
+
continue;
|
|
15767
|
+
}
|
|
15768
|
+
const firstCharCode = chunk.charCodeAt(searchIndex);
|
|
15769
|
+
if (isDataPrefix(chunk, searchIndex, firstCharCode)) {
|
|
15770
|
+
const valueStart = chunk.charCodeAt(searchIndex + 5) === SPACE ? searchIndex + 6 : searchIndex + 5, value = chunk.slice(valueStart, lfIndex);
|
|
15771
|
+
if (dataLines === 0 && chunk.charCodeAt(lfIndex + 1) === LF) {
|
|
15772
|
+
onEvent({ id, event: eventType, data: value }), id = void 0, data = "", eventType = void 0, searchIndex = lfIndex + 2, lfIndex = chunk.indexOf(`
|
|
15773
|
+
`, searchIndex);
|
|
15774
|
+
continue;
|
|
15775
|
+
}
|
|
15776
|
+
data = dataLines === 0 ? value : `${data}
|
|
15777
|
+
${value}`, dataLines++;
|
|
15778
|
+
} else isEventPrefix(chunk, searchIndex, firstCharCode) ? eventType = chunk.slice(
|
|
15779
|
+
chunk.charCodeAt(searchIndex + 6) === SPACE ? searchIndex + 7 : searchIndex + 6,
|
|
15780
|
+
lfIndex
|
|
15781
|
+
) || void 0 : parseLine(chunk, searchIndex, lfIndex);
|
|
15782
|
+
searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`
|
|
15783
|
+
`, searchIndex);
|
|
15784
|
+
}
|
|
15785
|
+
return chunk.slice(searchIndex);
|
|
15786
|
+
}
|
|
15787
|
+
for (; searchIndex < chunk.length; ) {
|
|
15788
|
+
const crIndex = chunk.indexOf("\r", searchIndex), lfIndex = chunk.indexOf(`
|
|
15789
|
+
`, searchIndex);
|
|
15790
|
+
let lineEnd = -1;
|
|
15791
|
+
if (crIndex !== -1 && lfIndex !== -1 ? lineEnd = crIndex < lfIndex ? crIndex : lfIndex : crIndex !== -1 ? crIndex === chunk.length - 1 ? lineEnd = -1 : lineEnd = crIndex : lfIndex !== -1 && (lineEnd = lfIndex), lineEnd === -1)
|
|
15792
|
+
break;
|
|
15793
|
+
parseLine(chunk, searchIndex, lineEnd), searchIndex = lineEnd + 1, chunk.charCodeAt(searchIndex - 1) === CR && chunk.charCodeAt(searchIndex) === LF && searchIndex++;
|
|
15794
|
+
}
|
|
15795
|
+
return chunk.slice(searchIndex);
|
|
15796
|
+
}
|
|
15797
|
+
function parseLine(chunk, start, end) {
|
|
15798
|
+
if (start === end) {
|
|
15799
|
+
dispatchEvent();
|
|
15800
|
+
return;
|
|
15801
|
+
}
|
|
15802
|
+
const firstCharCode = chunk.charCodeAt(start);
|
|
15803
|
+
if (isDataPrefix(chunk, start, firstCharCode)) {
|
|
15804
|
+
const valueStart = chunk.charCodeAt(start + 5) === SPACE ? start + 6 : start + 5, value2 = chunk.slice(valueStart, end);
|
|
15805
|
+
data = dataLines === 0 ? value2 : `${data}
|
|
15806
|
+
${value2}`, dataLines++;
|
|
15807
|
+
return;
|
|
15808
|
+
}
|
|
15809
|
+
if (isEventPrefix(chunk, start, firstCharCode)) {
|
|
15810
|
+
eventType = chunk.slice(chunk.charCodeAt(start + 6) === SPACE ? start + 7 : start + 6, end) || void 0;
|
|
15811
|
+
return;
|
|
15812
|
+
}
|
|
15813
|
+
if (firstCharCode === 105 && chunk.charCodeAt(start + 1) === 100 && chunk.charCodeAt(start + 2) === 58) {
|
|
15814
|
+
const value2 = chunk.slice(chunk.charCodeAt(start + 3) === SPACE ? start + 4 : start + 3, end);
|
|
15815
|
+
id = value2.includes("\0") ? void 0 : value2;
|
|
15816
|
+
return;
|
|
15817
|
+
}
|
|
15818
|
+
if (firstCharCode === 58) {
|
|
15819
|
+
if (onComment) {
|
|
15820
|
+
const line2 = chunk.slice(start, end);
|
|
15821
|
+
onComment(line2.slice(chunk.charCodeAt(start + 1) === SPACE ? 2 : 1));
|
|
15822
|
+
}
|
|
15823
|
+
return;
|
|
15824
|
+
}
|
|
15825
|
+
const line = chunk.slice(start, end), fieldSeparatorIndex = line.indexOf(":");
|
|
15826
|
+
if (fieldSeparatorIndex === -1) {
|
|
15827
|
+
processField(line, "", line);
|
|
15828
|
+
return;
|
|
15829
|
+
}
|
|
15830
|
+
const field = line.slice(0, fieldSeparatorIndex), offset = line.charCodeAt(fieldSeparatorIndex + 1) === SPACE ? 2 : 1, value = line.slice(fieldSeparatorIndex + offset);
|
|
15831
|
+
processField(field, value, line);
|
|
15832
|
+
}
|
|
15833
|
+
function processField(field, value, line) {
|
|
15834
|
+
switch (field) {
|
|
15835
|
+
case "event":
|
|
15836
|
+
eventType = value || void 0;
|
|
15837
|
+
break;
|
|
15838
|
+
case "data":
|
|
15839
|
+
data = dataLines === 0 ? value : `${data}
|
|
15840
|
+
${value}`, dataLines++;
|
|
15841
|
+
break;
|
|
15842
|
+
case "id":
|
|
15843
|
+
id = value.includes("\0") ? void 0 : value;
|
|
15844
|
+
break;
|
|
15845
|
+
case "retry":
|
|
15846
|
+
/^\d+$/.test(value) ? onRetry(parseInt(value, 10)) : onError(
|
|
15847
|
+
new ParseError(`Invalid \`retry\` value: "${value}"`, {
|
|
15848
|
+
type: "invalid-retry",
|
|
15849
|
+
value,
|
|
15850
|
+
line
|
|
15851
|
+
})
|
|
15852
|
+
);
|
|
15853
|
+
break;
|
|
15854
|
+
default:
|
|
15855
|
+
onError(
|
|
15856
|
+
new ParseError(
|
|
15857
|
+
`Unknown field "${field.length > 20 ? `${field.slice(0, 20)}\u2026` : field}"`,
|
|
15858
|
+
{ type: "unknown-field", field, value, line }
|
|
15859
|
+
)
|
|
15860
|
+
);
|
|
15861
|
+
break;
|
|
15862
|
+
}
|
|
15863
|
+
}
|
|
15864
|
+
function dispatchEvent() {
|
|
15865
|
+
dataLines > 0 && onEvent({
|
|
15866
|
+
id,
|
|
15867
|
+
event: eventType,
|
|
15868
|
+
data
|
|
15869
|
+
}), id = void 0, data = "", dataLines = 0, eventType = void 0;
|
|
15870
|
+
}
|
|
15871
|
+
function reset(options = {}) {
|
|
15872
|
+
if (options.consume && pendingFragments.length > 0) {
|
|
15873
|
+
const incompleteLine = pendingFragments.join("");
|
|
15874
|
+
parseLine(incompleteLine, 0, incompleteLine.length);
|
|
15875
|
+
}
|
|
15876
|
+
isFirstChunk = true, id = void 0, data = "", dataLines = 0, eventType = void 0, pendingFragments.length = 0, pendingFragmentsLength = 0, terminated = false;
|
|
15877
|
+
}
|
|
15878
|
+
return { feed, reset };
|
|
15879
|
+
}
|
|
15880
|
+
function isDataPrefix(chunk, i, firstCharCode) {
|
|
15881
|
+
return firstCharCode === 100 && chunk.charCodeAt(i + 1) === 97 && chunk.charCodeAt(i + 2) === 116 && chunk.charCodeAt(i + 3) === 97 && chunk.charCodeAt(i + 4) === 58;
|
|
15882
|
+
}
|
|
15883
|
+
function isEventPrefix(chunk, i, firstCharCode) {
|
|
15884
|
+
return firstCharCode === 101 && chunk.charCodeAt(i + 1) === 118 && chunk.charCodeAt(i + 2) === 101 && chunk.charCodeAt(i + 3) === 110 && chunk.charCodeAt(i + 4) === 116 && chunk.charCodeAt(i + 5) === 58;
|
|
15885
|
+
}
|
|
15886
|
+
|
|
15887
|
+
// ../node_modules/.pnpm/eventsource-parser@3.1.0/node_modules/eventsource-parser/dist/stream.js
|
|
15888
|
+
var EventSourceParserStream = class extends TransformStream {
|
|
15889
|
+
constructor({ onError, onRetry, onComment, maxBufferSize } = {}) {
|
|
15890
|
+
let parser;
|
|
15891
|
+
super({
|
|
15892
|
+
start(controller) {
|
|
15893
|
+
parser = createParser({
|
|
15894
|
+
onEvent: (event) => {
|
|
15895
|
+
controller.enqueue(event);
|
|
15896
|
+
},
|
|
15897
|
+
onError(error2) {
|
|
15898
|
+
typeof onError == "function" && onError(error2), (onError === "terminate" || error2.type === "max-buffer-size-exceeded") && controller.error(error2);
|
|
15899
|
+
},
|
|
15900
|
+
onRetry,
|
|
15901
|
+
onComment,
|
|
15902
|
+
maxBufferSize
|
|
15903
|
+
});
|
|
15904
|
+
},
|
|
15905
|
+
transform(chunk) {
|
|
15906
|
+
parser.feed(chunk);
|
|
15907
|
+
}
|
|
15908
|
+
});
|
|
15909
|
+
}
|
|
15910
|
+
};
|
|
15911
|
+
|
|
15912
|
+
// ../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js
|
|
15913
|
+
var DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS = {
|
|
15914
|
+
initialReconnectionDelay: 1e3,
|
|
15915
|
+
maxReconnectionDelay: 3e4,
|
|
15916
|
+
reconnectionDelayGrowFactor: 1.5,
|
|
15917
|
+
maxRetries: 2
|
|
15918
|
+
};
|
|
15919
|
+
var StreamableHTTPError = class extends Error {
|
|
15920
|
+
constructor(code, message) {
|
|
15921
|
+
super(`Streamable HTTP error: ${message}`);
|
|
15922
|
+
this.code = code;
|
|
15923
|
+
}
|
|
15924
|
+
};
|
|
15925
|
+
var StreamableHTTPClientTransport = class {
|
|
15926
|
+
constructor(url2, opts) {
|
|
15927
|
+
this._hasCompletedAuthFlow = false;
|
|
15928
|
+
this._url = url2;
|
|
15929
|
+
this._resourceMetadataUrl = void 0;
|
|
15930
|
+
this._scope = void 0;
|
|
15931
|
+
this._requestInit = opts?.requestInit;
|
|
15932
|
+
this._authProvider = opts?.authProvider;
|
|
15933
|
+
this._fetch = opts?.fetch;
|
|
15934
|
+
this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit);
|
|
15935
|
+
this._sessionId = opts?.sessionId;
|
|
15936
|
+
this._reconnectionOptions = opts?.reconnectionOptions ?? DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS;
|
|
15937
|
+
}
|
|
15938
|
+
async _authThenStart() {
|
|
15939
|
+
if (!this._authProvider) {
|
|
15940
|
+
throw new UnauthorizedError("No auth provider");
|
|
15941
|
+
}
|
|
15942
|
+
let result;
|
|
15943
|
+
try {
|
|
15944
|
+
result = await auth(this._authProvider, {
|
|
15945
|
+
serverUrl: this._url,
|
|
15946
|
+
resourceMetadataUrl: this._resourceMetadataUrl,
|
|
15947
|
+
scope: this._scope,
|
|
15948
|
+
fetchFn: this._fetchWithInit
|
|
15949
|
+
});
|
|
15950
|
+
} catch (error2) {
|
|
15951
|
+
this.onerror?.(error2);
|
|
15952
|
+
throw error2;
|
|
15953
|
+
}
|
|
15954
|
+
if (result !== "AUTHORIZED") {
|
|
15955
|
+
throw new UnauthorizedError();
|
|
15956
|
+
}
|
|
15957
|
+
return await this._startOrAuthSse({ resumptionToken: void 0 });
|
|
15958
|
+
}
|
|
15959
|
+
async _commonHeaders() {
|
|
15960
|
+
const headers = {};
|
|
15961
|
+
if (this._authProvider) {
|
|
15962
|
+
const tokens = await this._authProvider.tokens();
|
|
15963
|
+
if (tokens) {
|
|
15964
|
+
headers["Authorization"] = `Bearer ${tokens.access_token}`;
|
|
15965
|
+
}
|
|
15966
|
+
}
|
|
15967
|
+
if (this._sessionId) {
|
|
15968
|
+
headers["mcp-session-id"] = this._sessionId;
|
|
15969
|
+
}
|
|
15970
|
+
if (this._protocolVersion) {
|
|
15971
|
+
headers["mcp-protocol-version"] = this._protocolVersion;
|
|
15972
|
+
}
|
|
15973
|
+
const extraHeaders = normalizeHeaders(this._requestInit?.headers);
|
|
15974
|
+
return new Headers({
|
|
15975
|
+
...headers,
|
|
15976
|
+
...extraHeaders
|
|
15977
|
+
});
|
|
15978
|
+
}
|
|
15979
|
+
async _startOrAuthSse(options) {
|
|
15980
|
+
const { resumptionToken } = options;
|
|
15981
|
+
try {
|
|
15982
|
+
const headers = await this._commonHeaders();
|
|
15983
|
+
headers.set("Accept", "text/event-stream");
|
|
15984
|
+
if (resumptionToken) {
|
|
15985
|
+
headers.set("last-event-id", resumptionToken);
|
|
15986
|
+
}
|
|
15987
|
+
const response = await (this._fetch ?? fetch)(this._url, {
|
|
15988
|
+
method: "GET",
|
|
15989
|
+
headers,
|
|
15990
|
+
signal: this._abortController?.signal
|
|
15991
|
+
});
|
|
15992
|
+
if (!response.ok) {
|
|
15993
|
+
await response.body?.cancel();
|
|
15994
|
+
if (response.status === 401 && this._authProvider) {
|
|
15995
|
+
return await this._authThenStart();
|
|
15996
|
+
}
|
|
15997
|
+
if (response.status === 405) {
|
|
15998
|
+
return;
|
|
15999
|
+
}
|
|
16000
|
+
throw new StreamableHTTPError(response.status, `Failed to open SSE stream: ${response.statusText}`);
|
|
16001
|
+
}
|
|
16002
|
+
this._handleSseStream(response.body, options, true);
|
|
16003
|
+
} catch (error2) {
|
|
16004
|
+
this.onerror?.(error2);
|
|
16005
|
+
throw error2;
|
|
16006
|
+
}
|
|
16007
|
+
}
|
|
16008
|
+
/**
|
|
16009
|
+
* Calculates the next reconnection delay using backoff algorithm
|
|
16010
|
+
*
|
|
16011
|
+
* @param attempt Current reconnection attempt count for the specific stream
|
|
16012
|
+
* @returns Time to wait in milliseconds before next reconnection attempt
|
|
16013
|
+
*/
|
|
16014
|
+
_getNextReconnectionDelay(attempt) {
|
|
16015
|
+
if (this._serverRetryMs !== void 0) {
|
|
16016
|
+
return this._serverRetryMs;
|
|
16017
|
+
}
|
|
16018
|
+
const initialDelay = this._reconnectionOptions.initialReconnectionDelay;
|
|
16019
|
+
const growFactor = this._reconnectionOptions.reconnectionDelayGrowFactor;
|
|
16020
|
+
const maxDelay = this._reconnectionOptions.maxReconnectionDelay;
|
|
16021
|
+
return Math.min(initialDelay * Math.pow(growFactor, attempt), maxDelay);
|
|
16022
|
+
}
|
|
16023
|
+
/**
|
|
16024
|
+
* Schedule a reconnection attempt using server-provided retry interval or backoff
|
|
16025
|
+
*
|
|
16026
|
+
* @param lastEventId The ID of the last received event for resumability
|
|
16027
|
+
* @param attemptCount Current reconnection attempt count for this specific stream
|
|
16028
|
+
*/
|
|
16029
|
+
_scheduleReconnection(options, attemptCount = 0) {
|
|
16030
|
+
const maxRetries = this._reconnectionOptions.maxRetries;
|
|
16031
|
+
if (attemptCount >= maxRetries) {
|
|
16032
|
+
this.onerror?.(new Error(`Maximum reconnection attempts (${maxRetries}) exceeded.`));
|
|
16033
|
+
return;
|
|
16034
|
+
}
|
|
16035
|
+
const delay = this._getNextReconnectionDelay(attemptCount);
|
|
16036
|
+
this._reconnectionTimeout = setTimeout(() => {
|
|
16037
|
+
this._startOrAuthSse(options).catch((error2) => {
|
|
16038
|
+
this.onerror?.(new Error(`Failed to reconnect SSE stream: ${error2 instanceof Error ? error2.message : String(error2)}`));
|
|
16039
|
+
this._scheduleReconnection(options, attemptCount + 1);
|
|
16040
|
+
});
|
|
16041
|
+
}, delay);
|
|
16042
|
+
}
|
|
16043
|
+
_handleSseStream(stream, options, isReconnectable) {
|
|
16044
|
+
if (!stream) {
|
|
16045
|
+
return;
|
|
16046
|
+
}
|
|
16047
|
+
const { onresumptiontoken, replayMessageId } = options;
|
|
16048
|
+
let lastEventId;
|
|
16049
|
+
let hasPrimingEvent = false;
|
|
16050
|
+
let receivedResponse = false;
|
|
16051
|
+
const processStream = async () => {
|
|
16052
|
+
try {
|
|
16053
|
+
const reader = stream.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream({
|
|
16054
|
+
onRetry: (retryMs) => {
|
|
16055
|
+
this._serverRetryMs = retryMs;
|
|
16056
|
+
}
|
|
16057
|
+
})).getReader();
|
|
16058
|
+
while (true) {
|
|
16059
|
+
const { value: event, done } = await reader.read();
|
|
16060
|
+
if (done) {
|
|
16061
|
+
break;
|
|
16062
|
+
}
|
|
16063
|
+
if (event.id) {
|
|
16064
|
+
lastEventId = event.id;
|
|
16065
|
+
hasPrimingEvent = true;
|
|
16066
|
+
onresumptiontoken?.(event.id);
|
|
16067
|
+
}
|
|
16068
|
+
if (!event.data) {
|
|
16069
|
+
continue;
|
|
16070
|
+
}
|
|
16071
|
+
if (!event.event || event.event === "message") {
|
|
16072
|
+
try {
|
|
16073
|
+
const message = JSONRPCMessageSchema.parse(JSON.parse(event.data));
|
|
16074
|
+
if (isJSONRPCResultResponse(message)) {
|
|
16075
|
+
receivedResponse = true;
|
|
16076
|
+
if (replayMessageId !== void 0) {
|
|
16077
|
+
message.id = replayMessageId;
|
|
16078
|
+
}
|
|
16079
|
+
}
|
|
16080
|
+
this.onmessage?.(message);
|
|
16081
|
+
} catch (error2) {
|
|
16082
|
+
this.onerror?.(error2);
|
|
16083
|
+
}
|
|
16084
|
+
}
|
|
16085
|
+
}
|
|
16086
|
+
const canResume = isReconnectable || hasPrimingEvent;
|
|
16087
|
+
const needsReconnect = canResume && !receivedResponse;
|
|
16088
|
+
if (needsReconnect && this._abortController && !this._abortController.signal.aborted) {
|
|
16089
|
+
this._scheduleReconnection({
|
|
16090
|
+
resumptionToken: lastEventId,
|
|
16091
|
+
onresumptiontoken,
|
|
16092
|
+
replayMessageId
|
|
16093
|
+
}, 0);
|
|
16094
|
+
}
|
|
16095
|
+
} catch (error2) {
|
|
16096
|
+
this.onerror?.(new Error(`SSE stream disconnected: ${error2}`));
|
|
16097
|
+
const canResume = isReconnectable || hasPrimingEvent;
|
|
16098
|
+
const needsReconnect = canResume && !receivedResponse;
|
|
16099
|
+
if (needsReconnect && this._abortController && !this._abortController.signal.aborted) {
|
|
16100
|
+
try {
|
|
16101
|
+
this._scheduleReconnection({
|
|
16102
|
+
resumptionToken: lastEventId,
|
|
16103
|
+
onresumptiontoken,
|
|
16104
|
+
replayMessageId
|
|
16105
|
+
}, 0);
|
|
16106
|
+
} catch (error3) {
|
|
16107
|
+
this.onerror?.(new Error(`Failed to reconnect: ${error3 instanceof Error ? error3.message : String(error3)}`));
|
|
16108
|
+
}
|
|
16109
|
+
}
|
|
16110
|
+
}
|
|
16111
|
+
};
|
|
16112
|
+
processStream();
|
|
16113
|
+
}
|
|
16114
|
+
async start() {
|
|
16115
|
+
if (this._abortController) {
|
|
16116
|
+
throw new Error("StreamableHTTPClientTransport already started! If using Client class, note that connect() calls start() automatically.");
|
|
16117
|
+
}
|
|
16118
|
+
this._abortController = new AbortController();
|
|
16119
|
+
}
|
|
16120
|
+
/**
|
|
16121
|
+
* Call this method after the user has finished authorizing via their user agent and is redirected back to the MCP client application. This will exchange the authorization code for an access token, enabling the next connection attempt to successfully auth.
|
|
16122
|
+
*/
|
|
16123
|
+
async finishAuth(authorizationCode) {
|
|
16124
|
+
if (!this._authProvider) {
|
|
16125
|
+
throw new UnauthorizedError("No auth provider");
|
|
16126
|
+
}
|
|
16127
|
+
const result = await auth(this._authProvider, {
|
|
16128
|
+
serverUrl: this._url,
|
|
16129
|
+
authorizationCode,
|
|
16130
|
+
resourceMetadataUrl: this._resourceMetadataUrl,
|
|
16131
|
+
scope: this._scope,
|
|
16132
|
+
fetchFn: this._fetchWithInit
|
|
16133
|
+
});
|
|
16134
|
+
if (result !== "AUTHORIZED") {
|
|
16135
|
+
throw new UnauthorizedError("Failed to authorize");
|
|
16136
|
+
}
|
|
16137
|
+
}
|
|
16138
|
+
async close() {
|
|
16139
|
+
if (this._reconnectionTimeout) {
|
|
16140
|
+
clearTimeout(this._reconnectionTimeout);
|
|
16141
|
+
this._reconnectionTimeout = void 0;
|
|
16142
|
+
}
|
|
16143
|
+
this._abortController?.abort();
|
|
16144
|
+
this.onclose?.();
|
|
16145
|
+
}
|
|
16146
|
+
async send(message, options) {
|
|
16147
|
+
try {
|
|
16148
|
+
const { resumptionToken, onresumptiontoken } = options || {};
|
|
16149
|
+
if (resumptionToken) {
|
|
16150
|
+
this._startOrAuthSse({ resumptionToken, replayMessageId: isJSONRPCRequest(message) ? message.id : void 0 }).catch((err) => this.onerror?.(err));
|
|
16151
|
+
return;
|
|
16152
|
+
}
|
|
16153
|
+
const headers = await this._commonHeaders();
|
|
16154
|
+
headers.set("content-type", "application/json");
|
|
16155
|
+
headers.set("accept", "application/json, text/event-stream");
|
|
16156
|
+
const init = {
|
|
16157
|
+
...this._requestInit,
|
|
16158
|
+
method: "POST",
|
|
16159
|
+
headers,
|
|
16160
|
+
body: JSON.stringify(message),
|
|
16161
|
+
signal: this._abortController?.signal
|
|
16162
|
+
};
|
|
16163
|
+
const response = await (this._fetch ?? fetch)(this._url, init);
|
|
16164
|
+
const sessionId = response.headers.get("mcp-session-id");
|
|
16165
|
+
if (sessionId) {
|
|
16166
|
+
this._sessionId = sessionId;
|
|
16167
|
+
}
|
|
16168
|
+
if (!response.ok) {
|
|
16169
|
+
const text = await response.text().catch(() => null);
|
|
16170
|
+
if (response.status === 401 && this._authProvider) {
|
|
16171
|
+
if (this._hasCompletedAuthFlow) {
|
|
16172
|
+
throw new StreamableHTTPError(401, "Server returned 401 after successful authentication");
|
|
16173
|
+
}
|
|
16174
|
+
const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
|
|
16175
|
+
this._resourceMetadataUrl = resourceMetadataUrl;
|
|
16176
|
+
this._scope = scope;
|
|
16177
|
+
const result = await auth(this._authProvider, {
|
|
16178
|
+
serverUrl: this._url,
|
|
16179
|
+
resourceMetadataUrl: this._resourceMetadataUrl,
|
|
16180
|
+
scope: this._scope,
|
|
16181
|
+
fetchFn: this._fetchWithInit
|
|
16182
|
+
});
|
|
16183
|
+
if (result !== "AUTHORIZED") {
|
|
16184
|
+
throw new UnauthorizedError();
|
|
16185
|
+
}
|
|
16186
|
+
this._hasCompletedAuthFlow = true;
|
|
16187
|
+
return this.send(message);
|
|
16188
|
+
}
|
|
16189
|
+
if (response.status === 403 && this._authProvider) {
|
|
16190
|
+
const { resourceMetadataUrl, scope, error: error2 } = extractWWWAuthenticateParams(response);
|
|
16191
|
+
if (error2 === "insufficient_scope") {
|
|
16192
|
+
const wwwAuthHeader = response.headers.get("WWW-Authenticate");
|
|
16193
|
+
if (this._lastUpscopingHeader === wwwAuthHeader) {
|
|
16194
|
+
throw new StreamableHTTPError(403, "Server returned 403 after trying upscoping");
|
|
16195
|
+
}
|
|
16196
|
+
if (scope) {
|
|
16197
|
+
this._scope = scope;
|
|
16198
|
+
}
|
|
16199
|
+
if (resourceMetadataUrl) {
|
|
16200
|
+
this._resourceMetadataUrl = resourceMetadataUrl;
|
|
16201
|
+
}
|
|
16202
|
+
this._lastUpscopingHeader = wwwAuthHeader ?? void 0;
|
|
16203
|
+
const result = await auth(this._authProvider, {
|
|
16204
|
+
serverUrl: this._url,
|
|
16205
|
+
resourceMetadataUrl: this._resourceMetadataUrl,
|
|
16206
|
+
scope: this._scope,
|
|
16207
|
+
fetchFn: this._fetch
|
|
16208
|
+
});
|
|
16209
|
+
if (result !== "AUTHORIZED") {
|
|
16210
|
+
throw new UnauthorizedError();
|
|
16211
|
+
}
|
|
16212
|
+
return this.send(message);
|
|
16213
|
+
}
|
|
16214
|
+
}
|
|
16215
|
+
throw new StreamableHTTPError(response.status, `Error POSTing to endpoint: ${text}`);
|
|
16216
|
+
}
|
|
16217
|
+
this._hasCompletedAuthFlow = false;
|
|
16218
|
+
this._lastUpscopingHeader = void 0;
|
|
16219
|
+
if (response.status === 202) {
|
|
16220
|
+
await response.body?.cancel();
|
|
16221
|
+
if (isInitializedNotification(message)) {
|
|
16222
|
+
this._startOrAuthSse({ resumptionToken: void 0 }).catch((err) => this.onerror?.(err));
|
|
16223
|
+
}
|
|
16224
|
+
return;
|
|
16225
|
+
}
|
|
16226
|
+
const messages = Array.isArray(message) ? message : [message];
|
|
16227
|
+
const hasRequests = messages.filter((msg) => "method" in msg && "id" in msg && msg.id !== void 0).length > 0;
|
|
16228
|
+
const contentType = response.headers.get("content-type");
|
|
16229
|
+
if (hasRequests) {
|
|
16230
|
+
if (contentType?.includes("text/event-stream")) {
|
|
16231
|
+
this._handleSseStream(response.body, { onresumptiontoken }, false);
|
|
16232
|
+
} else if (contentType?.includes("application/json")) {
|
|
16233
|
+
const data = await response.json();
|
|
16234
|
+
const responseMessages = Array.isArray(data) ? data.map((msg) => JSONRPCMessageSchema.parse(msg)) : [JSONRPCMessageSchema.parse(data)];
|
|
16235
|
+
for (const msg of responseMessages) {
|
|
16236
|
+
this.onmessage?.(msg);
|
|
16237
|
+
}
|
|
16238
|
+
} else {
|
|
16239
|
+
await response.body?.cancel();
|
|
16240
|
+
throw new StreamableHTTPError(-1, `Unexpected content type: ${contentType}`);
|
|
16241
|
+
}
|
|
16242
|
+
} else {
|
|
16243
|
+
await response.body?.cancel();
|
|
16244
|
+
}
|
|
16245
|
+
} catch (error2) {
|
|
16246
|
+
this.onerror?.(error2);
|
|
16247
|
+
throw error2;
|
|
16248
|
+
}
|
|
16249
|
+
}
|
|
16250
|
+
get sessionId() {
|
|
16251
|
+
return this._sessionId;
|
|
16252
|
+
}
|
|
16253
|
+
/**
|
|
16254
|
+
* Terminates the current session by sending a DELETE request to the server.
|
|
16255
|
+
*
|
|
16256
|
+
* Clients that no longer need a particular session
|
|
16257
|
+
* (e.g., because the user is leaving the client application) SHOULD send an
|
|
16258
|
+
* HTTP DELETE to the MCP endpoint with the Mcp-Session-Id header to explicitly
|
|
16259
|
+
* terminate the session.
|
|
16260
|
+
*
|
|
16261
|
+
* The server MAY respond with HTTP 405 Method Not Allowed, indicating that
|
|
16262
|
+
* the server does not allow clients to terminate sessions.
|
|
16263
|
+
*/
|
|
16264
|
+
async terminateSession() {
|
|
16265
|
+
if (!this._sessionId) {
|
|
16266
|
+
return;
|
|
16267
|
+
}
|
|
16268
|
+
try {
|
|
16269
|
+
const headers = await this._commonHeaders();
|
|
16270
|
+
const init = {
|
|
16271
|
+
...this._requestInit,
|
|
16272
|
+
method: "DELETE",
|
|
16273
|
+
headers,
|
|
16274
|
+
signal: this._abortController?.signal
|
|
16275
|
+
};
|
|
16276
|
+
const response = await (this._fetch ?? fetch)(this._url, init);
|
|
16277
|
+
await response.body?.cancel();
|
|
16278
|
+
if (!response.ok && response.status !== 405) {
|
|
16279
|
+
throw new StreamableHTTPError(response.status, `Failed to terminate session: ${response.statusText}`);
|
|
16280
|
+
}
|
|
16281
|
+
this._sessionId = void 0;
|
|
16282
|
+
} catch (error2) {
|
|
16283
|
+
this.onerror?.(error2);
|
|
16284
|
+
throw error2;
|
|
16285
|
+
}
|
|
16286
|
+
}
|
|
16287
|
+
setProtocolVersion(version2) {
|
|
16288
|
+
this._protocolVersion = version2;
|
|
16289
|
+
}
|
|
16290
|
+
get protocolVersion() {
|
|
16291
|
+
return this._protocolVersion;
|
|
16292
|
+
}
|
|
16293
|
+
/**
|
|
16294
|
+
* Resume an SSE stream from a previous event ID.
|
|
16295
|
+
* Opens a GET SSE connection with Last-Event-ID header to replay missed events.
|
|
16296
|
+
*
|
|
16297
|
+
* @param lastEventId The event ID to resume from
|
|
16298
|
+
* @param options Optional callback to receive new resumption tokens
|
|
16299
|
+
*/
|
|
16300
|
+
async resumeStream(lastEventId, options) {
|
|
16301
|
+
await this._startOrAuthSse({
|
|
16302
|
+
resumptionToken: lastEventId,
|
|
16303
|
+
onresumptiontoken: options?.onresumptiontoken
|
|
16304
|
+
});
|
|
16305
|
+
}
|
|
16306
|
+
};
|
|
16307
|
+
|
|
16308
|
+
// src/tools/mcp-server-defs.ts
|
|
14668
16309
|
var import_node_fs = __toESM(require("fs"), 1);
|
|
14669
16310
|
var import_node_path = __toESM(require("path"), 1);
|
|
14670
16311
|
var HTTP_TYPES = /* @__PURE__ */ new Set(["http", "sse", "streamable_http", "streamable-http"]);
|
|
14671
|
-
function
|
|
16312
|
+
function loadMcpServerDefs(args) {
|
|
14672
16313
|
const out = [];
|
|
14673
16314
|
const seen = /* @__PURE__ */ new Set();
|
|
14674
16315
|
const sources = [...args.mcpConfigPaths, import_node_path.default.join(args.cwd, ".mcp.json")];
|
|
@@ -14679,7 +16320,7 @@ function loadCodexMcpServerDefs(args) {
|
|
|
14679
16320
|
} catch (e) {
|
|
14680
16321
|
const code = e.code;
|
|
14681
16322
|
if (code !== "ENOENT") {
|
|
14682
|
-
args.logger?.warn("
|
|
16323
|
+
args.logger?.warn("mcp config unreadable, skipped", { file, code: code ?? "parse-error" });
|
|
14683
16324
|
}
|
|
14684
16325
|
continue;
|
|
14685
16326
|
}
|
|
@@ -14690,28 +16331,34 @@ function loadCodexMcpServerDefs(args) {
|
|
|
14690
16331
|
const type = typeof def.type === "string" ? def.type.toLowerCase() : typeof def.url === "string" ? "http" : "stdio";
|
|
14691
16332
|
if (HTTP_TYPES.has(type)) {
|
|
14692
16333
|
if (typeof def.url !== "string" || !def.url) {
|
|
14693
|
-
args.logger?.warn("
|
|
16334
|
+
args.logger?.warn("mcp server http without url, skipped", { file, name });
|
|
14694
16335
|
continue;
|
|
14695
16336
|
}
|
|
14696
16337
|
if (seen.has(name)) {
|
|
14697
|
-
args.logger?.warn("
|
|
16338
|
+
args.logger?.warn("mcp server name collision, first-wins", { file, name });
|
|
14698
16339
|
continue;
|
|
14699
16340
|
}
|
|
14700
16341
|
seen.add(name);
|
|
14701
16342
|
const headers = def.headers && typeof def.headers === "object" ? Object.fromEntries(Object.entries(def.headers).filter((kv) => typeof kv[1] === "string")) : {};
|
|
14702
|
-
|
|
16343
|
+
const bearerTokenEnvVar = typeof def.bearer_token_env_var === "string" && def.bearer_token_env_var ? def.bearer_token_env_var : void 0;
|
|
16344
|
+
out.push({
|
|
16345
|
+
name,
|
|
16346
|
+
url: def.url,
|
|
16347
|
+
...Object.keys(headers).length > 0 ? { httpHeaders: headers } : {},
|
|
16348
|
+
...bearerTokenEnvVar ? { bearerTokenEnvVar } : {}
|
|
16349
|
+
});
|
|
14703
16350
|
continue;
|
|
14704
16351
|
}
|
|
14705
16352
|
if (type !== "stdio") {
|
|
14706
|
-
args.logger?.warn("
|
|
16353
|
+
args.logger?.warn("mcp server type unsupported, skipped", { file, name, type });
|
|
14707
16354
|
continue;
|
|
14708
16355
|
}
|
|
14709
16356
|
if (typeof def.command !== "string" || !def.command) {
|
|
14710
|
-
args.logger?.warn("
|
|
16357
|
+
args.logger?.warn("mcp server missing command, skipped", { file, name });
|
|
14711
16358
|
continue;
|
|
14712
16359
|
}
|
|
14713
16360
|
if (seen.has(name)) {
|
|
14714
|
-
args.logger?.warn("
|
|
16361
|
+
args.logger?.warn("mcp server name collision, first-wins", { file, name });
|
|
14715
16362
|
continue;
|
|
14716
16363
|
}
|
|
14717
16364
|
seen.add(name);
|
|
@@ -14797,6 +16444,26 @@ function isPlainObject3(v) {
|
|
|
14797
16444
|
// src/pi-mcp-bridge/extension.ts
|
|
14798
16445
|
var DEFAULT_CONNECT_TIMEOUT_MS = 15e3;
|
|
14799
16446
|
var DEFAULT_CALL_TIMEOUT_MS = 10 * 6e4;
|
|
16447
|
+
var POD_KEY_ENV = "CLAWD_POD_KEY";
|
|
16448
|
+
var CLOUD_BASE_ENV_KEYS = /* @__PURE__ */ new Set(["PATH", "HOME", "LANG", "TMPDIR"]);
|
|
16449
|
+
function mcpChildEnv(bridgeEnv, fileEnv) {
|
|
16450
|
+
const base = stringEnv(bridgeEnv);
|
|
16451
|
+
if (base[POD_KEY_ENV] === void 0) return { ...base, ...fileEnv ?? {} };
|
|
16452
|
+
const picked = {};
|
|
16453
|
+
for (const [k, v] of Object.entries(base)) {
|
|
16454
|
+
if (k === POD_KEY_ENV) continue;
|
|
16455
|
+
if (CLOUD_BASE_ENV_KEYS.has(k) || k.startsWith("CLAWD_")) picked[k] = v;
|
|
16456
|
+
}
|
|
16457
|
+
return { ...picked, ...fileEnv ?? {} };
|
|
16458
|
+
}
|
|
16459
|
+
function mcpHttpHeaders(def, bridgeEnv) {
|
|
16460
|
+
const headers = { ...def.httpHeaders ?? {} };
|
|
16461
|
+
if (!def.bearerTokenEnvVar) return { headers };
|
|
16462
|
+
const token = bridgeEnv[def.bearerTokenEnvVar];
|
|
16463
|
+
if (!token) return { headers, warn: `bearer_token_env_var ${def.bearerTokenEnvVar} is empty in bridge env, connecting without Authorization` };
|
|
16464
|
+
headers.Authorization = `Bearer ${token}`;
|
|
16465
|
+
return { headers };
|
|
16466
|
+
}
|
|
14800
16467
|
var ServerLink = class {
|
|
14801
16468
|
constructor(def, opts) {
|
|
14802
16469
|
this.def = def;
|
|
@@ -14812,17 +16479,24 @@ var ServerLink = class {
|
|
|
14812
16479
|
closedError() {
|
|
14813
16480
|
return new Error(`mcp server "${this.def.name}" closed`);
|
|
14814
16481
|
}
|
|
14815
|
-
|
|
14816
|
-
|
|
14817
|
-
|
|
14818
|
-
|
|
16482
|
+
transport() {
|
|
16483
|
+
if ("url" in this.def) {
|
|
16484
|
+
const { headers, warn } = mcpHttpHeaders(this.def, this.opts.env);
|
|
16485
|
+
if (warn) this.opts.log(`${this.def.name}: ${warn}`);
|
|
16486
|
+
return new StreamableHTTPClientTransport(new URL(this.def.url), { requestInit: { headers } });
|
|
16487
|
+
}
|
|
16488
|
+
return new StdioClientTransport({
|
|
14819
16489
|
command: this.def.command,
|
|
14820
16490
|
args: this.def.args ?? [],
|
|
14821
|
-
|
|
14822
|
-
env: { ...stringEnv(this.opts.env), ...this.def.env ?? {} },
|
|
16491
|
+
env: mcpChildEnv(this.opts.env, this.def.env),
|
|
14823
16492
|
// server 的 stderr 直通 pi 的 stderr → daemon 记成 `pi stderr` warn
|
|
14824
16493
|
stderr: "inherit"
|
|
14825
16494
|
});
|
|
16495
|
+
}
|
|
16496
|
+
/** 起 transport + initialize;超时 / 失败 / 连的过程中被 close → 把半开的 transport 收掉 */
|
|
16497
|
+
async connect() {
|
|
16498
|
+
const client = new Client({ name: "clawd-pi-mcp-bridge", version: "0.1.0" });
|
|
16499
|
+
const transport = this.transport();
|
|
14826
16500
|
client.onclose = () => {
|
|
14827
16501
|
if (this.client === client) this.client = null;
|
|
14828
16502
|
};
|
|
@@ -14889,7 +16563,7 @@ async function bridgeMcpServers(pi, options) {
|
|
|
14889
16563
|
};
|
|
14890
16564
|
let defs;
|
|
14891
16565
|
try {
|
|
14892
|
-
defs =
|
|
16566
|
+
defs = loadMcpServerDefs({
|
|
14893
16567
|
mcpConfigPaths: options.configPaths,
|
|
14894
16568
|
cwd: options.cwd,
|
|
14895
16569
|
logger: bridgeLogger(log)
|
|
@@ -14902,9 +16576,7 @@ async function bridgeMcpServers(pi, options) {
|
|
|
14902
16576
|
log(`no mcp servers to bridge (configs=${options.configPaths.length}, cwd=${options.cwd})`);
|
|
14903
16577
|
return;
|
|
14904
16578
|
}
|
|
14905
|
-
const
|
|
14906
|
-
for (const d of defs) if (!("command" in d)) log(`${d.name}: http server, pi bridge only supports stdio \u2014 skipped`);
|
|
14907
|
-
const links = stdioDefs.map((def) => new ServerLink(def, opts));
|
|
16579
|
+
const links = defs.map((def) => new ServerLink(def, opts));
|
|
14908
16580
|
pi.on("session_shutdown", async () => {
|
|
14909
16581
|
await Promise.all(links.map((l) => l.close()));
|
|
14910
16582
|
});
|
|
@@ -14978,6 +16650,9 @@ function bridgeLogger(log) {
|
|
|
14978
16650
|
}
|
|
14979
16651
|
// Annotate the CommonJS export names for ESM import in node:
|
|
14980
16652
|
0 && (module.exports = {
|
|
14981
|
-
|
|
16653
|
+
POD_KEY_ENV,
|
|
16654
|
+
bridgeMcpServers,
|
|
16655
|
+
mcpChildEnv,
|
|
16656
|
+
mcpHttpHeaders
|
|
14982
16657
|
});
|
|
14983
16658
|
module.exports = module.exports.default;
|