@chrischall/office-outlook-mcp 0.6.0 → 0.6.2
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/mcp.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +11 -6
- package/dist/auth-fetchproxy.js +26 -122
- package/dist/bundle.js +603 -259
- package/dist/client.js +45 -84
- package/dist/token-cache.js +2 -11
- package/dist/tools/writes.js +41 -41
- package/dist/version.js +1 -1
- package/package.json +3 -3
- package/server.json +2 -2
package/dist/bundle.js
CHANGED
|
@@ -248,6 +248,7 @@ __export(util_exports, {
|
|
|
248
248
|
required: () => required,
|
|
249
249
|
safeExtend: () => safeExtend,
|
|
250
250
|
shallowClone: () => shallowClone,
|
|
251
|
+
sizeCaps: () => sizeCaps,
|
|
251
252
|
slugify: () => slugify,
|
|
252
253
|
stringifyPrimitive: () => stringifyPrimitive,
|
|
253
254
|
toZod: () => toZod,
|
|
@@ -671,6 +672,18 @@ function prefixIssues(path, issues) {
|
|
|
671
672
|
function unwrapMessage(message) {
|
|
672
673
|
return typeof message === "string" ? message : message?.message;
|
|
673
674
|
}
|
|
675
|
+
function sizeCaps(defChecks) {
|
|
676
|
+
const caps = [];
|
|
677
|
+
for (const ch of defChecks ?? []) {
|
|
678
|
+
const d = ch._zod.def;
|
|
679
|
+
if (!/_(length|size)$|_equals$/.test(d.check))
|
|
680
|
+
break;
|
|
681
|
+
const max = d.maximum ?? d.length ?? d.size;
|
|
682
|
+
if (max >= 0)
|
|
683
|
+
caps.push([max, ch]);
|
|
684
|
+
}
|
|
685
|
+
return caps;
|
|
686
|
+
}
|
|
674
687
|
function attachSchema(issues, start, inst) {
|
|
675
688
|
var _a3;
|
|
676
689
|
for (let i = start; i < issues.length; i++) {
|
|
@@ -2234,7 +2247,7 @@ var init_versions = __esm({
|
|
|
2234
2247
|
version = {
|
|
2235
2248
|
major: 4,
|
|
2236
2249
|
minor: 6,
|
|
2237
|
-
patch:
|
|
2250
|
+
patch: 7
|
|
2238
2251
|
};
|
|
2239
2252
|
}
|
|
2240
2253
|
});
|
|
@@ -2396,6 +2409,28 @@ function isValidJWT(token, algorithm = null) {
|
|
|
2396
2409
|
return false;
|
|
2397
2410
|
}
|
|
2398
2411
|
}
|
|
2412
|
+
function capSize(inst, size) {
|
|
2413
|
+
const caps = sizeCaps(inst._zod.def.checks);
|
|
2414
|
+
if (!caps.length)
|
|
2415
|
+
return;
|
|
2416
|
+
const cap = Math.min(...caps.map((c) => c[0]));
|
|
2417
|
+
const parse3 = inst._zod.parse;
|
|
2418
|
+
inst._zod.parse = (payload, ctx) => {
|
|
2419
|
+
const n = size(payload.value);
|
|
2420
|
+
if (n > cap && !ctx?.skipChecks && ctx?.direction !== "backward") {
|
|
2421
|
+
for (const [max, ch] of sizeCaps(inst._zod.def.checks)) {
|
|
2422
|
+
if (n > max && ch._zod.def.when(payload)) {
|
|
2423
|
+
const start = payload.issues.length;
|
|
2424
|
+
ch._zod.check(payload);
|
|
2425
|
+
payload.issues[start].continue = false;
|
|
2426
|
+
attachSchema(payload.issues, start, inst);
|
|
2427
|
+
return payload;
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
return parse3(payload, ctx);
|
|
2432
|
+
};
|
|
2433
|
+
}
|
|
2399
2434
|
function handleArrayResult(result, final, index) {
|
|
2400
2435
|
if (result.issues.length) {
|
|
2401
2436
|
final.issues.push(...prefixIssues(index, result.issues));
|
|
@@ -2896,7 +2931,7 @@ function handleRefineResult(result, payload, input2, inst) {
|
|
|
2896
2931
|
payload.issues.push(issue(_iss));
|
|
2897
2932
|
}
|
|
2898
2933
|
}
|
|
2899
|
-
var $ZodType, toStandardResult, $ZodString, $ZodStringFormat, $ZodGUID, $ZodUUID, $ZodEmail, URL_BAD_FORMAT, URL_UNPARSEABLE, asciiTabOrNewline, $ZodURL, $ZodEmoji, $ZodNanoID, $ZodCUID, $ZodCUID2, $ZodULID, $ZodXID, $ZodKSUID, $ZodISODateTime, $ZodISODate, $ZodISOTime, $ZodISODuration, $ZodIPv4, ipv6Alphabet, $ZodIPv6, $ZodMAC, $ZodCIDRv4, $ZodCIDRv6, base64Charset, $ZodBase64, base64urlCharset, $ZodBase64URL, $ZodE164, CC_SANITIZE, $ZodCreditCard, $ZodIBAN, $ZodJWT, $ZodCustomStringFormat, $ZodNumber, $ZodNumberFormat, $ZodBoolean, $ZodBigInt, $ZodBigIntFormat, $ZodSymbol, $ZodUndefined, $ZodNull, $ZodAny, $ZodUnknown, $ZodNever, $ZodVoid, $ZodDate, $ZodArray, NO_SYMBOL_KEYS, $ZodObject, $ZodObjectJIT, $ZodUnion, $ZodXor, $ZodDiscriminatedUnion, $ZodIntersection, $ZodTuple, $ZodRecord, $ZodMap, $ZodSet, $ZodEnum, $ZodLiteral, $ZodFile, $ZodTransform, $ZodOptional, $ZodExactOptional, $ZodNullable, $ZodDefault, $ZodPrefault, $ZodNonOptional, $ZodSuccess, $ZodCatch, $ZodNaN, $ZodPipe, $ZodCodec, $ZodPreprocess, $ZodReadonly, $ZodTemplateLiteral, $ZodFunction, $ZodPromise, $ZodLazy, $ZodCustom;
|
|
2934
|
+
var $ZodType, toStandardResult, $ZodString, $ZodStringFormat, $ZodGUID, $ZodUUID, $ZodEmail, URL_BAD_FORMAT, URL_UNPARSEABLE, asciiTabOrNewline, $ZodURL, $ZodEmoji, $ZodNanoID, $ZodCUID, $ZodCUID2, $ZodULID, $ZodXID, $ZodKSUID, $ZodISODateTime, $ZodISODate, $ZodISOTime, $ZodISODuration, $ZodIPv4, ipv6Alphabet, $ZodIPv6, $ZodMAC, $ZodCIDRv4, $ZodCIDRv6, base64Charset, $ZodBase64, base64urlCharset, $ZodBase64URL, $ZodE164, CC_SANITIZE, $ZodCreditCard, $ZodIBAN, $ZodJWT, $ZodCustomStringFormat, $ZodNumber, $ZodNumberFormat, $ZodBoolean, $ZodBigInt, $ZodBigIntFormat, $ZodSymbol, $ZodUndefined, $ZodNull, $ZodAny, $ZodUnknown, $ZodNever, $ZodVoid, $ZodDate, arraySize, mapSize, setSize, $ZodArray, NO_SYMBOL_KEYS, $ZodObject, $ZodObjectJIT, $ZodUnion, $ZodXor, $ZodDiscriminatedUnion, $ZodIntersection, $ZodTuple, $ZodRecord, $ZodMap, $ZodSet, $ZodEnum, $ZodLiteral, $ZodFile, $ZodTransform, $ZodOptional, $ZodExactOptional, $ZodNullable, $ZodDefault, $ZodPrefault, $ZodNonOptional, $ZodSuccess, $ZodCatch, $ZodNaN, $ZodPipe, $ZodCodec, $ZodPreprocess, $ZodReadonly, $ZodTemplateLiteral, $ZodFunction, $ZodPromise, $ZodLazy, $ZodCustom;
|
|
2900
2935
|
var init_schemas = __esm({
|
|
2901
2936
|
"node_modules/zod/v4/core/schemas.js"() {
|
|
2902
2937
|
init_checks();
|
|
@@ -3503,6 +3538,9 @@ var init_schemas = __esm({
|
|
|
3503
3538
|
return payload;
|
|
3504
3539
|
};
|
|
3505
3540
|
});
|
|
3541
|
+
arraySize = (input2) => Array.isArray(input2) ? input2.length : -1;
|
|
3542
|
+
mapSize = (input2) => input2 instanceof Map ? input2.size : -1;
|
|
3543
|
+
setSize = (input2) => input2 instanceof Set ? input2.size : -1;
|
|
3506
3544
|
$ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
|
|
3507
3545
|
$ZodType.init(inst, def);
|
|
3508
3546
|
const memo3 = globalConfig.memoizer;
|
|
@@ -3540,6 +3578,7 @@ var init_schemas = __esm({
|
|
|
3540
3578
|
}
|
|
3541
3579
|
return payload;
|
|
3542
3580
|
};
|
|
3581
|
+
capSize(inst, arraySize);
|
|
3543
3582
|
});
|
|
3544
3583
|
NO_SYMBOL_KEYS = [];
|
|
3545
3584
|
$ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
@@ -4178,6 +4217,7 @@ var init_schemas = __esm({
|
|
|
4178
4217
|
return Promise.all(proms).then(() => payload);
|
|
4179
4218
|
return payload;
|
|
4180
4219
|
};
|
|
4220
|
+
capSize(inst, mapSize);
|
|
4181
4221
|
});
|
|
4182
4222
|
$ZodSet = /* @__PURE__ */ $constructor("$ZodSet", (inst, def) => {
|
|
4183
4223
|
$ZodType.init(inst, def);
|
|
@@ -4214,6 +4254,7 @@ var init_schemas = __esm({
|
|
|
4214
4254
|
return Promise.all(proms).then(() => payload);
|
|
4215
4255
|
return payload;
|
|
4216
4256
|
};
|
|
4257
|
+
capSize(inst, setSize);
|
|
4217
4258
|
});
|
|
4218
4259
|
$ZodEnum = /* @__PURE__ */ $constructor("$ZodEnum", (inst, def) => {
|
|
4219
4260
|
$ZodType.init(inst, def);
|
|
@@ -14003,9 +14044,15 @@ function generateNullableCheck(doc, ctx, schema, accessor, buildsValue = true) {
|
|
|
14003
14044
|
doc.write(`}`);
|
|
14004
14045
|
return outputVar;
|
|
14005
14046
|
}
|
|
14047
|
+
function generateSizeGate(doc, schema, size) {
|
|
14048
|
+
for (const [max, check2] of sizeCaps(schema._zod.def.checks)) {
|
|
14049
|
+
doc.write(`if (${size} > ${numericOperand(max, check2._zod.def.check)}) return INVALID;`);
|
|
14050
|
+
}
|
|
14051
|
+
}
|
|
14006
14052
|
function generateArrayCheck(doc, ctx, schema, accessor, buildsValue = true) {
|
|
14007
14053
|
const def = schema._zod.def;
|
|
14008
14054
|
doc.write(`if (!Array.isArray(${accessor})) return INVALID;`);
|
|
14055
|
+
generateSizeGate(doc, schema, `${accessor}.length`);
|
|
14009
14056
|
const outputVar = buildsValue ? newVar(ctx) : null;
|
|
14010
14057
|
const iVar = newVar(ctx);
|
|
14011
14058
|
const elemVar = newVar(ctx);
|
|
@@ -14405,6 +14452,7 @@ function literalPropertyKey(ctx, key) {
|
|
|
14405
14452
|
function generateMapCheck(doc, ctx, schema, accessor) {
|
|
14406
14453
|
const def = schema._zod.def;
|
|
14407
14454
|
doc.write(`if (!(${accessor} instanceof Map)) return INVALID;`);
|
|
14455
|
+
generateSizeGate(doc, schema, `${accessor}.size`);
|
|
14408
14456
|
const outputVar = newVar(ctx);
|
|
14409
14457
|
const kVar = newVar(ctx);
|
|
14410
14458
|
const valVar = newVar(ctx);
|
|
@@ -14421,6 +14469,7 @@ function generateMapCheck(doc, ctx, schema, accessor) {
|
|
|
14421
14469
|
function generateSetCheck(doc, ctx, schema, accessor) {
|
|
14422
14470
|
const def = schema._zod.def;
|
|
14423
14471
|
doc.write(`if (!(${accessor} instanceof Set)) return INVALID;`);
|
|
14472
|
+
generateSizeGate(doc, schema, `${accessor}.size`);
|
|
14424
14473
|
const outputVar = newVar(ctx);
|
|
14425
14474
|
const valVar = newVar(ctx);
|
|
14426
14475
|
doc.write(`const ${outputVar} = new Set();`);
|
|
@@ -35372,10 +35421,33 @@ function redactJsonCookie(quote) {
|
|
|
35372
35421
|
function redactSecrets(text) {
|
|
35373
35422
|
return text.replace(BEARER_RE, "$1[REDACTED]").replace(BASIC_AUTH_RE, "$1[REDACTED]").replace(SET_COOKIE_RE, "$1$2=[REDACTED]").replace(COOKIE_HEADER_RE, (_m, prefix, pairs) => `${prefix}${pairs.replace(/=[^;,\s]*/g, "=[REDACTED]")}`).replace(API_KEY_RE, "[REDACTED]").replace(GOOGLE_OAUTH_TOKEN_RE, "[REDACTED]").replace(HEADER_SECRET_RE, "$1[REDACTED]").replace(QUERY_SECRET_RE, "$1[REDACTED]").replace(OAUTH_CODE_RE, "$1[REDACTED]").replace(FORM_PASSWORD_RE, "$1[REDACTED]").replace(AWS_SIGV4_RE, "$1[REDACTED]").replace(JSON_COOKIE_DQ_RE, redactJsonCookie('"')).replace(JSON_COOKIE_SQ_RE, redactJsonCookie("'")).replace(JSON_SECRET_DQ_RE, "$1[REDACTED]$2").replace(JSON_SECRET_SQ_RE, "$1[REDACTED]$2").replace(JSON_SECRET_NUM_RE, "$1[REDACTED]").replace(JWT_RE, "[REDACTED]");
|
|
35374
35423
|
}
|
|
35375
|
-
function
|
|
35424
|
+
function redactValues(text, values, opts = {}) {
|
|
35425
|
+
const placeholder = opts.placeholder ?? "[REDACTED]";
|
|
35426
|
+
const minLength = Math.max(1, opts.minLength ?? 1);
|
|
35427
|
+
const needles = /* @__PURE__ */ new Set();
|
|
35428
|
+
for (const value of values) {
|
|
35429
|
+
if (typeof value !== "string" || value.length < minLength)
|
|
35430
|
+
continue;
|
|
35431
|
+
needles.add(value);
|
|
35432
|
+
if (opts.jsonEscaped !== false) {
|
|
35433
|
+
const escaped = JSON.stringify(value).slice(1, -1);
|
|
35434
|
+
if (escaped !== value && escaped.length >= minLength)
|
|
35435
|
+
needles.add(escaped);
|
|
35436
|
+
}
|
|
35437
|
+
}
|
|
35438
|
+
let out = String(text ?? "");
|
|
35439
|
+
for (const needle of [...needles].sort((a, b) => b.length - a.length)) {
|
|
35440
|
+
if (out.includes(needle))
|
|
35441
|
+
out = out.split(needle).join(placeholder);
|
|
35442
|
+
}
|
|
35443
|
+
return out;
|
|
35444
|
+
}
|
|
35445
|
+
function truncateErrorMessage(text, max = DEFAULT_ERROR_MESSAGE_MAX, opts = {}) {
|
|
35376
35446
|
const str = text === null || text === void 0 ? "" : String(text);
|
|
35377
35447
|
const cap = Math.max(ERROR_REDACTION_INPUT_MAX, max);
|
|
35378
|
-
const
|
|
35448
|
+
const capped = str.length > cap ? str.slice(0, cap) : str;
|
|
35449
|
+
const scrubbed = opts.values !== void 0 ? redactValues(capped, opts.values, opts.placeholder !== void 0 ? { placeholder: opts.placeholder } : {}) : capped;
|
|
35450
|
+
const redacted = redactSecrets(scrubbed);
|
|
35379
35451
|
if (redacted.length <= max)
|
|
35380
35452
|
return redacted;
|
|
35381
35453
|
return `${redacted.slice(0, max)}\u2026 [truncated]`;
|
|
@@ -35482,7 +35554,7 @@ var init_errors3 = __esm({
|
|
|
35482
35554
|
// webhook signing secret (Stripe-style)
|
|
35483
35555
|
].map((p) => `\\b${p}`).join("|"), "g");
|
|
35484
35556
|
GOOGLE_OAUTH_TOKEN_RE = /(?<![A-Za-z0-9+/])(?:ya29\.|1\/\/)[A-Za-z0-9._-]{8,}/g;
|
|
35485
|
-
QUERY_SECRET_RE = new RegExp(`([
|
|
35557
|
+
QUERY_SECRET_RE = new RegExp(`([?&#;](?:(?:access|refresh|id|auth|session|csrf|xsrf|api)[_-]?token|client[_-]?secret|api[_-]?secret|api[_-]?key|password|passwd|signature|secret|token|auth|key|sig|(?:code[_-]?)?verifier|(?:php|j)?sess(?:ion)?[_-]?id|sid|x[-_]${HEADER_NAME_RUN}?(?:api[-_]?key|token|secret|auth)${HEADER_NAME_RUN})=)[^&#\\s"'<>\`]+`, "gi");
|
|
35486
35558
|
OAUTH_CODE_RE = /([?&]code=)(?=[^&#\s"'<>`]{16,})[^&#\s"'<>`]+/gi;
|
|
35487
35559
|
FORM_PASSWORD_RE = /((?:^|[\s,;:"'(\[{])(?:password|passwd)=)[^&#\s"'<>`]+/gim;
|
|
35488
35560
|
HEADER_SECRET_RE = new RegExp(`(\\b(?:x[-_]${HEADER_NAME_RUN}?(?:api[-_]?key|token|secret|auth)${HEADER_NAME_RUN}|api[-_]?key)\\s*:\\s*)[^\\s,;"'<>\`]+`, "gi");
|
|
@@ -35493,6 +35565,8 @@ var init_errors3 = __esm({
|
|
|
35493
35565
|
"api[_-]?secret",
|
|
35494
35566
|
"(?:x[_-])?api[_-]?key",
|
|
35495
35567
|
"private[_-]?key",
|
|
35568
|
+
"aws[_-]?secret[_-]?access[_-]?key",
|
|
35569
|
+
// fleet-audit#1297
|
|
35496
35570
|
"code[_-]?verifier",
|
|
35497
35571
|
// PKCE; a bare `verifier` key is too generic for JSON
|
|
35498
35572
|
`x[_-]${HEADER_NAME_RUN}?(?:api[_-]?key|token|secret|auth)${HEADER_NAME_RUN}`,
|
|
@@ -35522,6 +35596,16 @@ var init_zod = __esm({
|
|
|
35522
35596
|
}
|
|
35523
35597
|
});
|
|
35524
35598
|
|
|
35599
|
+
// node_modules/@chrischall/mcp-utils/dist/response/media.js
|
|
35600
|
+
var MEDIA_NOUN, MEDIA_QUALIFIER, MEDIA_KEY;
|
|
35601
|
+
var init_media = __esm({
|
|
35602
|
+
"node_modules/@chrischall/mcp-utils/dist/response/media.js"() {
|
|
35603
|
+
MEDIA_NOUN = "(?:avatar|picture|photo|thumbnail|thumb|image|icon|banner|profile_pic(?:ture)?|logo)";
|
|
35604
|
+
MEDIA_QUALIFIER = "(?:primary|secondary|main|default|cover|hero|profile|master|rendered|small|medium|large|full|original|tall)";
|
|
35605
|
+
MEDIA_KEY = new RegExp(`^(?:(?:${MEDIA_QUALIFIER}|${MEDIA_NOUN})[_-]?)?${MEDIA_NOUN}s?(?:[_-]?(?:link|uri|url|src)s?)?$`, "i");
|
|
35606
|
+
}
|
|
35607
|
+
});
|
|
35608
|
+
|
|
35525
35609
|
// node_modules/@chrischall/mcp-utils/dist/response/view.js
|
|
35526
35610
|
function viewParam(honoured, opts = {}) {
|
|
35527
35611
|
if (honoured.length < 2) {
|
|
@@ -35560,6 +35644,7 @@ var VIEWS, DEFAULT_VIEW, BLURB;
|
|
|
35560
35644
|
var init_view = __esm({
|
|
35561
35645
|
"node_modules/@chrischall/mcp-utils/dist/response/view.js"() {
|
|
35562
35646
|
init_zod();
|
|
35647
|
+
init_media();
|
|
35563
35648
|
VIEWS = ["compact", "full", "raw"];
|
|
35564
35649
|
DEFAULT_VIEW = "compact";
|
|
35565
35650
|
BLURB = {
|
|
@@ -35570,16 +35655,6 @@ var init_view = __esm({
|
|
|
35570
35655
|
}
|
|
35571
35656
|
});
|
|
35572
35657
|
|
|
35573
|
-
// node_modules/@chrischall/mcp-utils/dist/response/media.js
|
|
35574
|
-
var MEDIA_NOUN, MEDIA_QUALIFIER, MEDIA_KEY;
|
|
35575
|
-
var init_media = __esm({
|
|
35576
|
-
"node_modules/@chrischall/mcp-utils/dist/response/media.js"() {
|
|
35577
|
-
MEDIA_NOUN = "(?:avatar|picture|photo|thumbnail|thumb|image|icon|banner|profile_pic(?:ture)?|logo)";
|
|
35578
|
-
MEDIA_QUALIFIER = "(?:primary|secondary|main|default|cover|hero|profile|master|rendered|small|medium|large|full|original|tall)";
|
|
35579
|
-
MEDIA_KEY = new RegExp(`^(?:(?:${MEDIA_QUALIFIER}|${MEDIA_NOUN})[_-]?)?${MEDIA_NOUN}s?(?:[_-]?(?:link|uri|url|src)s?)?$`, "i");
|
|
35580
|
-
}
|
|
35581
|
-
});
|
|
35582
|
-
|
|
35583
35658
|
// node_modules/@chrischall/mcp-utils/dist/response/untrusted.js
|
|
35584
35659
|
function isPlainObject3(value) {
|
|
35585
35660
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
@@ -36651,6 +36726,9 @@ var init_headers = __esm({
|
|
|
36651
36726
|
});
|
|
36652
36727
|
|
|
36653
36728
|
// node_modules/@chrischall/mcp-utils/dist/internal/ascii.js
|
|
36729
|
+
function asciiLower(s) {
|
|
36730
|
+
return s.replace(/[A-Z]+/g, (m) => m.toLowerCase());
|
|
36731
|
+
}
|
|
36654
36732
|
var init_ascii = __esm({
|
|
36655
36733
|
"node_modules/@chrischall/mcp-utils/dist/internal/ascii.js"() {
|
|
36656
36734
|
}
|
|
@@ -36662,16 +36740,42 @@ var init_code_point = __esm({
|
|
|
36662
36740
|
}
|
|
36663
36741
|
});
|
|
36664
36742
|
|
|
36743
|
+
// node_modules/@chrischall/mcp-utils/dist/internal/tags.js
|
|
36744
|
+
var init_tags = __esm({
|
|
36745
|
+
"node_modules/@chrischall/mcp-utils/dist/internal/tags.js"() {
|
|
36746
|
+
}
|
|
36747
|
+
});
|
|
36748
|
+
|
|
36665
36749
|
// node_modules/@chrischall/mcp-utils/dist/scrape/index.js
|
|
36666
36750
|
function isCloudflareChallenge(html) {
|
|
36667
|
-
return
|
|
36751
|
+
return html.includes("_cf_chl_opt") || hasJustAMomentTitle(html);
|
|
36752
|
+
}
|
|
36753
|
+
function hasJustAMomentTitle(html) {
|
|
36754
|
+
const lower2 = asciiLower(html);
|
|
36755
|
+
let i = 0;
|
|
36756
|
+
for (; ; ) {
|
|
36757
|
+
const open2 = lower2.indexOf("<title", i);
|
|
36758
|
+
if (open2 < 0)
|
|
36759
|
+
return false;
|
|
36760
|
+
const gt = lower2.indexOf(">", open2 + 6);
|
|
36761
|
+
if (gt < 0)
|
|
36762
|
+
return false;
|
|
36763
|
+
let j = gt + 1;
|
|
36764
|
+
while (j < lower2.length && /\s/.test(lower2[j]))
|
|
36765
|
+
j++;
|
|
36766
|
+
if (lower2.startsWith(JUST_A_MOMENT, j))
|
|
36767
|
+
return true;
|
|
36768
|
+
i = gt + 1;
|
|
36769
|
+
}
|
|
36668
36770
|
}
|
|
36669
|
-
var NEXT_DATA_MAX_CHARS;
|
|
36771
|
+
var NEXT_DATA_MAX_CHARS, JUST_A_MOMENT;
|
|
36670
36772
|
var init_scrape = __esm({
|
|
36671
36773
|
"node_modules/@chrischall/mcp-utils/dist/scrape/index.js"() {
|
|
36672
36774
|
init_ascii();
|
|
36673
36775
|
init_code_point();
|
|
36776
|
+
init_tags();
|
|
36674
36777
|
NEXT_DATA_MAX_CHARS = 16 * 1024 * 1024;
|
|
36778
|
+
JUST_A_MOMENT = "just a moment";
|
|
36675
36779
|
}
|
|
36676
36780
|
});
|
|
36677
36781
|
|
|
@@ -36707,7 +36811,7 @@ var init_net_atoms = __esm({
|
|
|
36707
36811
|
// node_modules/@chrischall/mcp-utils/dist/http/body-limit.js
|
|
36708
36812
|
async function readBytesCapped(res, maxBytes, service, bounded) {
|
|
36709
36813
|
if (maxBytes !== void 0) {
|
|
36710
|
-
const declared = Number(res
|
|
36814
|
+
const declared = Number(responseHeader(res, "content-length") ?? NaN);
|
|
36711
36815
|
if (Number.isFinite(declared) && declared > maxBytes) {
|
|
36712
36816
|
cancelStream(res.body);
|
|
36713
36817
|
throw new ResponseTooLargeError(service, maxBytes);
|
|
@@ -36752,6 +36856,7 @@ var ResponseTooLargeError;
|
|
|
36752
36856
|
var init_body_limit = __esm({
|
|
36753
36857
|
"node_modules/@chrischall/mcp-utils/dist/http/body-limit.js"() {
|
|
36754
36858
|
init_errors3();
|
|
36859
|
+
init_headers();
|
|
36755
36860
|
ResponseTooLargeError = class extends McpToolError {
|
|
36756
36861
|
maxBytes;
|
|
36757
36862
|
constructor(service, maxBytes) {
|
|
@@ -36811,6 +36916,126 @@ var init_url_safety = __esm({
|
|
|
36811
36916
|
}
|
|
36812
36917
|
});
|
|
36813
36918
|
|
|
36919
|
+
// node_modules/@chrischall/mcp-utils/dist/http/transport-failure.js
|
|
36920
|
+
function codeOf(e) {
|
|
36921
|
+
if (e === null || typeof e !== "object")
|
|
36922
|
+
return void 0;
|
|
36923
|
+
const code2 = e.code;
|
|
36924
|
+
return typeof code2 === "string" && code2 !== "" ? code2 : void 0;
|
|
36925
|
+
}
|
|
36926
|
+
function causes(err) {
|
|
36927
|
+
const out = [];
|
|
36928
|
+
let at = err;
|
|
36929
|
+
for (let depth = 0; depth < MAX_CAUSE_DEPTH && at !== void 0 && at !== null; depth++) {
|
|
36930
|
+
out.push(at);
|
|
36931
|
+
if (at instanceof AggregateError)
|
|
36932
|
+
out.push(...at.errors);
|
|
36933
|
+
at = at.cause;
|
|
36934
|
+
}
|
|
36935
|
+
return out;
|
|
36936
|
+
}
|
|
36937
|
+
function transportCauseCode(err) {
|
|
36938
|
+
for (const e of causes(err)) {
|
|
36939
|
+
const code2 = codeOf(e);
|
|
36940
|
+
if (code2 !== void 0)
|
|
36941
|
+
return code2;
|
|
36942
|
+
}
|
|
36943
|
+
return void 0;
|
|
36944
|
+
}
|
|
36945
|
+
function causeMessage(err) {
|
|
36946
|
+
const chain = causes(err).slice(1);
|
|
36947
|
+
for (let i = chain.length - 1; i >= 0; i--) {
|
|
36948
|
+
const e = chain[i];
|
|
36949
|
+
if (e instanceof Error && e.message !== "")
|
|
36950
|
+
return e.message;
|
|
36951
|
+
}
|
|
36952
|
+
return void 0;
|
|
36953
|
+
}
|
|
36954
|
+
function isFetchFailedError(err) {
|
|
36955
|
+
return err instanceof TypeError && err.message === "fetch failed";
|
|
36956
|
+
}
|
|
36957
|
+
function proxyRefusalStatus(err) {
|
|
36958
|
+
for (const e of causes(err)) {
|
|
36959
|
+
if (codeOf(e) === "ERR_PROXY_TUNNEL") {
|
|
36960
|
+
const m = /\b(\d{3})\b/.exec(e instanceof Error ? e.message.slice(0, 500) : "");
|
|
36961
|
+
return m ? Number(m[1]) : "unknown";
|
|
36962
|
+
}
|
|
36963
|
+
if (e instanceof Error) {
|
|
36964
|
+
const m = /^Proxy response \((\d{3})\) !== 200 when HTTP Tunneling/.exec(e.message);
|
|
36965
|
+
if (m)
|
|
36966
|
+
return Number(m[1]);
|
|
36967
|
+
}
|
|
36968
|
+
}
|
|
36969
|
+
return void 0;
|
|
36970
|
+
}
|
|
36971
|
+
function classify(err, code2) {
|
|
36972
|
+
const refused = proxyRefusalStatus(err);
|
|
36973
|
+
if (refused !== void 0) {
|
|
36974
|
+
return { cls: refused === 403 || refused === 407 || refused === "unknown" ? "egress" : "proxy", proxyStatus: refused };
|
|
36975
|
+
}
|
|
36976
|
+
if (code2 !== void 0 && DNS_CODES.has(code2))
|
|
36977
|
+
return { cls: "dns" };
|
|
36978
|
+
if (code2 !== void 0 && CERT_CODES.has(code2))
|
|
36979
|
+
return { cls: "tls" };
|
|
36980
|
+
if (code2 !== void 0 && CONNECT_CODES.has(code2))
|
|
36981
|
+
return { cls: "connect" };
|
|
36982
|
+
return { cls: "other" };
|
|
36983
|
+
}
|
|
36984
|
+
function describeTransportFailure(err, url2, service, opts = {}) {
|
|
36985
|
+
if (!isFetchFailedError(err))
|
|
36986
|
+
return void 0;
|
|
36987
|
+
let host;
|
|
36988
|
+
try {
|
|
36989
|
+
host = new URL(url2).hostname;
|
|
36990
|
+
} catch {
|
|
36991
|
+
host = "(unknown host)";
|
|
36992
|
+
}
|
|
36993
|
+
const code2 = transportCauseCode(err);
|
|
36994
|
+
const detail = [code2, causeMessage(err)].filter((s) => s !== void 0);
|
|
36995
|
+
const why = detail.length > 0 ? ` (${[...new Set(detail)].join(": ")})` : "";
|
|
36996
|
+
const { cls, proxyStatus } = classify(err, code2);
|
|
36997
|
+
const ctx = { host, service, code: code2, ...proxyStatus !== void 0 ? { proxyStatus } : {} };
|
|
36998
|
+
const hint = (opts.hints?.[cls] ?? DEFAULT_HINTS[cls])(host, ctx);
|
|
36999
|
+
return new McpToolError(`Could not reach ${service} at ${host}${why}.`, { kind: "transport", hint, cause: err });
|
|
37000
|
+
}
|
|
37001
|
+
var MAX_CAUSE_DEPTH, DNS_CODES, CONNECT_CODES, CERT_CODES, DEFAULT_HINTS;
|
|
37002
|
+
var init_transport_failure = __esm({
|
|
37003
|
+
"node_modules/@chrischall/mcp-utils/dist/http/transport-failure.js"() {
|
|
37004
|
+
init_errors3();
|
|
37005
|
+
MAX_CAUSE_DEPTH = 5;
|
|
37006
|
+
DNS_CODES = /* @__PURE__ */ new Set(["ENOTFOUND", "EAI_AGAIN", "EAI_FAIL", "EAI_NONAME"]);
|
|
37007
|
+
CONNECT_CODES = /* @__PURE__ */ new Set([
|
|
37008
|
+
"ECONNREFUSED",
|
|
37009
|
+
"ECONNRESET",
|
|
37010
|
+
"ETIMEDOUT",
|
|
37011
|
+
"ENETUNREACH",
|
|
37012
|
+
"EHOSTUNREACH",
|
|
37013
|
+
"EPIPE",
|
|
37014
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
37015
|
+
"UND_ERR_SOCKET",
|
|
37016
|
+
"UND_ERR_HEADERS_TIMEOUT"
|
|
37017
|
+
]);
|
|
37018
|
+
CERT_CODES = /* @__PURE__ */ new Set([
|
|
37019
|
+
"UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
|
|
37020
|
+
"UNABLE_TO_GET_ISSUER_CERT",
|
|
37021
|
+
"UNABLE_TO_VERIFY_LEAF_SIGNATURE",
|
|
37022
|
+
"SELF_SIGNED_CERT_IN_CHAIN",
|
|
37023
|
+
"DEPTH_ZERO_SELF_SIGNED_CERT",
|
|
37024
|
+
"CERT_HAS_EXPIRED",
|
|
37025
|
+
"CERT_NOT_YET_VALID",
|
|
37026
|
+
"ERR_TLS_CERT_ALTNAME_INVALID"
|
|
37027
|
+
]);
|
|
37028
|
+
DEFAULT_HINTS = {
|
|
37029
|
+
egress: (host) => `The outbound proxy this server runs behind refused the connection to ${host}: its egress policy does not allow that host. On a hosted (mcp-host) registration, the host must be on the registration's egress allow-list \u2014 the owner accepts the manifest's egress proposal (or adds the host) on the registration, then retries. Elsewhere, ask whoever runs the proxy to allow it.`,
|
|
37030
|
+
proxy: (host, ctx) => `The outbound proxy this server runs behind could not open a connection to ${host} (it answered ${String(ctx.proxyStatus)}). Retry; if it persists, check the proxy can reach the host.`,
|
|
37031
|
+
dns: (host) => `This machine could not resolve ${host}. Check DNS and VPN: a split-tunnel VPN that resolves some of a service's hosts but not others fails exactly like this. \`nslookup ${host}\` on the machine running this server tells you which.`,
|
|
37032
|
+
tls: (host) => `Node did not trust the TLS certificate ${host} presented. On a corporate network this is usually TLS inspection: export your proxy's root CA as PEM and start this server with NODE_EXTRA_CA_CERTS=/path/to/ca.pem (Node does not read the system keychain). If the certificate is expired or not yet valid, also check the machine's clock.`,
|
|
37033
|
+
connect: (host, ctx) => `The connection to ${host} was refused, reset or timed out before ${ctx.service} answered \u2014 usually a firewall, or a network that only lets traffic out through a proxy. Node's fetch ignores proxy settings unless told: start this server with HTTPS_PROXY=<your proxy URL> and NODE_USE_ENV_PROXY=1 (Node 22.21+ / 24.5+), or allow the host through the firewall.`,
|
|
37034
|
+
other: (host) => `No response from ${host}. Check this machine can reach it (VPN, proxy, firewall); \`curl -sI https://${host}/\` from the same machine is a quick test.`
|
|
37035
|
+
};
|
|
37036
|
+
}
|
|
37037
|
+
});
|
|
37038
|
+
|
|
36814
37039
|
// node_modules/@chrischall/mcp-utils/dist/internal/retry-after.js
|
|
36815
37040
|
function retryAfterToMs(header, now = Date.now()) {
|
|
36816
37041
|
if (header == null)
|
|
@@ -36831,6 +37056,27 @@ var init_retry_after = __esm({
|
|
|
36831
37056
|
});
|
|
36832
37057
|
|
|
36833
37058
|
// node_modules/@chrischall/mcp-utils/dist/http/index.js
|
|
37059
|
+
function withoutCredentials(headers, tokenHeader) {
|
|
37060
|
+
const drop = new Set(CROSS_ORIGIN_DROPPED_HEADERS);
|
|
37061
|
+
if (tokenHeader !== void 0)
|
|
37062
|
+
drop.add(tokenHeader.toLowerCase());
|
|
37063
|
+
const out = {};
|
|
37064
|
+
for (const [k, v] of Object.entries(headers))
|
|
37065
|
+
if (!drop.has(k.toLowerCase()))
|
|
37066
|
+
out[k] = v;
|
|
37067
|
+
return out;
|
|
37068
|
+
}
|
|
37069
|
+
function joinQuery(path, query) {
|
|
37070
|
+
if (!query)
|
|
37071
|
+
return path;
|
|
37072
|
+
const hashAt = path.indexOf("#");
|
|
37073
|
+
const head = hashAt < 0 ? path : path.slice(0, hashAt);
|
|
37074
|
+
const fragment = hashAt < 0 ? "" : path.slice(hashAt);
|
|
37075
|
+
if (!head.includes("?"))
|
|
37076
|
+
return `${head}${query}${fragment}`;
|
|
37077
|
+
const sep = head.endsWith("?") || head.endsWith("&") ? "" : "&";
|
|
37078
|
+
return `${head}${sep}${query.slice(1)}${fragment}`;
|
|
37079
|
+
}
|
|
36834
37080
|
function cancelBody(res) {
|
|
36835
37081
|
try {
|
|
36836
37082
|
const body = res.body;
|
|
@@ -36839,6 +37085,27 @@ function cancelBody(res) {
|
|
|
36839
37085
|
} catch {
|
|
36840
37086
|
}
|
|
36841
37087
|
}
|
|
37088
|
+
function writeOutcomeStatus(err) {
|
|
37089
|
+
const status = err.cause?.status;
|
|
37090
|
+
return typeof status === "number" ? status : void 0;
|
|
37091
|
+
}
|
|
37092
|
+
function unknownOutcomeReason(err, opts = {}) {
|
|
37093
|
+
if (err.timedOut)
|
|
37094
|
+
return "it did not answer in time";
|
|
37095
|
+
const status = writeOutcomeStatus(err);
|
|
37096
|
+
if (status !== void 0)
|
|
37097
|
+
return `it answered HTTP ${status} after ${opts.sent ?? "the request"} was sent`;
|
|
37098
|
+
return "the connection dropped";
|
|
37099
|
+
}
|
|
37100
|
+
async function writeOrUnknown(run, onUnknown) {
|
|
37101
|
+
try {
|
|
37102
|
+
return { ok: true, value: await run() };
|
|
37103
|
+
} catch (err) {
|
|
37104
|
+
if (!(err instanceof WriteOutcomeUnknownError))
|
|
37105
|
+
throw err;
|
|
37106
|
+
return { ok: false, result: await onUnknown(err, unknownOutcomeReason(err)) };
|
|
37107
|
+
}
|
|
37108
|
+
}
|
|
36842
37109
|
function headerOf(headers, name) {
|
|
36843
37110
|
if (headers === void 0)
|
|
36844
37111
|
return void 0;
|
|
@@ -36959,7 +37226,9 @@ function createApiClient(opts) {
|
|
|
36959
37226
|
const retryStatuses = retry.statuses ?? [429];
|
|
36960
37227
|
const timeoutMs = opts.timeout === false ? 0 : opts.timeout ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
36961
37228
|
const redirectMode = opts.redirect;
|
|
36962
|
-
const
|
|
37229
|
+
const stripCrossOrigin = redirectMode === void 0 && opts.tokenHeader !== void 0;
|
|
37230
|
+
const manualRedirects = redirectMode === "same-origin" || stripCrossOrigin;
|
|
37231
|
+
const maxRedirects = opts.maxRedirects ?? (stripCrossOrigin ? FETCH_MAX_REDIRECTS : DEFAULT_MAX_REDIRECTS);
|
|
36963
37232
|
const reportWriteOutcome = opts.writeOutcomeUnknown !== false;
|
|
36964
37233
|
const defaultMaxBytes = checkMaxBytes("maxResponseBytes", opts.maxResponseBytes);
|
|
36965
37234
|
if (!Number.isSafeInteger(maxRedirects) || maxRedirects < 0) {
|
|
@@ -37061,7 +37330,7 @@ function createApiClient(opts) {
|
|
|
37061
37330
|
`Refusing request to ${service}: path ${JSON.stringify(path.split(/[?#]/, 1)[0])} contains a ${hazard}, which URL normalisation would rewrite. Build paths with apiPath\`...\` so each value is one encoded segment.`
|
|
37062
37331
|
);
|
|
37063
37332
|
}
|
|
37064
|
-
const url2 = `${base}${path
|
|
37333
|
+
const url2 = `${base}${joinQuery(path, query)}`;
|
|
37065
37334
|
if (baseOrigin === void 0)
|
|
37066
37335
|
return url2;
|
|
37067
37336
|
let parsed;
|
|
@@ -37075,14 +37344,21 @@ function createApiClient(opts) {
|
|
|
37075
37344
|
}
|
|
37076
37345
|
return url2;
|
|
37077
37346
|
}
|
|
37078
|
-
function
|
|
37079
|
-
let next;
|
|
37347
|
+
function resolveLocation(location, from) {
|
|
37080
37348
|
try {
|
|
37081
|
-
|
|
37349
|
+
return new URL(location, from).href;
|
|
37082
37350
|
} catch {
|
|
37083
37351
|
throw new RedirectRefusedError(`Refusing redirect from ${service}: the Location header is not a valid URL.`);
|
|
37084
37352
|
}
|
|
37085
|
-
|
|
37353
|
+
}
|
|
37354
|
+
function onBaseOrigin(href) {
|
|
37355
|
+
const next = new URL(href);
|
|
37356
|
+
return baseOrigin !== void 0 && next.origin === baseOrigin && next.username === baseParts?.username && next.password === baseParts?.password;
|
|
37357
|
+
}
|
|
37358
|
+
function sameOriginHop(location, from) {
|
|
37359
|
+
const href = resolveLocation(location, from);
|
|
37360
|
+
const next = new URL(href);
|
|
37361
|
+
if (!onBaseOrigin(href)) {
|
|
37086
37362
|
throw new RedirectRefusedError(`Refusing redirect from ${service} to ${next.origin}: it leaves the base origin ${baseOrigin ?? "(unparseable)"}, and following it would re-send the credential there.`);
|
|
37087
37363
|
}
|
|
37088
37364
|
return next.href;
|
|
@@ -37092,20 +37368,21 @@ function createApiClient(opts) {
|
|
|
37092
37368
|
const query = opt.query ? buildQueryString(opt.query) : "";
|
|
37093
37369
|
const url2 = resolveUrl(path, query);
|
|
37094
37370
|
const bodyInit = reqBody !== void 0 ? { body: reqBody } : {};
|
|
37095
|
-
const fetchHop = (hopUrl, hopMethod, withBody, token, signal) => {
|
|
37371
|
+
const fetchHop = (hopUrl, hopMethod, withBody, token, signal, credentialed = true) => {
|
|
37096
37372
|
if (!signal?.aborted)
|
|
37097
37373
|
dispatch.sent = true;
|
|
37374
|
+
const headers = {
|
|
37375
|
+
Accept: "application/json",
|
|
37376
|
+
...withBody && contentType !== void 0 ? { "Content-Type": contentType } : {},
|
|
37377
|
+
...typeof opts.baseHeaders === "function" ? opts.baseHeaders() : opts.baseHeaders,
|
|
37378
|
+
...authHeader(token || void 0),
|
|
37379
|
+
...opt.headers
|
|
37380
|
+
};
|
|
37098
37381
|
return doFetch(hopUrl, {
|
|
37099
37382
|
method: hopMethod,
|
|
37100
|
-
headers:
|
|
37101
|
-
Accept: "application/json",
|
|
37102
|
-
...withBody && contentType !== void 0 ? { "Content-Type": contentType } : {},
|
|
37103
|
-
...opts.baseHeaders,
|
|
37104
|
-
...authHeader(token || void 0),
|
|
37105
|
-
...opt.headers
|
|
37106
|
-
},
|
|
37383
|
+
headers: credentialed ? headers : withoutCredentials(headers, opts.tokenHeader),
|
|
37107
37384
|
...signal ? { signal } : {},
|
|
37108
|
-
...
|
|
37385
|
+
...manualRedirects ? { redirect: "manual" } : redirectMode !== void 0 ? { redirect: redirectMode } : {},
|
|
37109
37386
|
...withBody ? bodyInit : {}
|
|
37110
37387
|
}).catch((err) => {
|
|
37111
37388
|
markTransportFailure(err);
|
|
@@ -37113,13 +37390,14 @@ function createApiClient(opts) {
|
|
|
37113
37390
|
});
|
|
37114
37391
|
};
|
|
37115
37392
|
const fetchWith = async (token, signal) => {
|
|
37116
|
-
if (
|
|
37393
|
+
if (!manualRedirects)
|
|
37117
37394
|
return fetchHop(url2, method, true, token, signal);
|
|
37118
37395
|
let hopUrl = url2;
|
|
37119
37396
|
let hopMethod = method;
|
|
37120
37397
|
let withBody = true;
|
|
37398
|
+
let credentialed = true;
|
|
37121
37399
|
for (let hops = 0; ; hops += 1) {
|
|
37122
|
-
const res = await fetchHop(hopUrl, hopMethod, withBody, token, signal);
|
|
37400
|
+
const res = await fetchHop(hopUrl, hopMethod, withBody, token, signal, credentialed);
|
|
37123
37401
|
const location = REDIRECT_STATUSES.has(res.status) ? responseHeader(res, "location") : void 0;
|
|
37124
37402
|
if (location === void 0 || location === null)
|
|
37125
37403
|
return res;
|
|
@@ -37127,7 +37405,13 @@ function createApiClient(opts) {
|
|
|
37127
37405
|
if (hops >= maxRedirects) {
|
|
37128
37406
|
throw new RedirectRefusedError(`Refusing request to ${service}: too many redirects (more than ${maxRedirects}).`);
|
|
37129
37407
|
}
|
|
37130
|
-
|
|
37408
|
+
if (stripCrossOrigin) {
|
|
37409
|
+
hopUrl = resolveLocation(location, hopUrl);
|
|
37410
|
+
if (credentialed && !onBaseOrigin(hopUrl))
|
|
37411
|
+
credentialed = false;
|
|
37412
|
+
} else {
|
|
37413
|
+
hopUrl = sameOriginHop(location, hopUrl);
|
|
37414
|
+
}
|
|
37131
37415
|
if (res.status === 303 || (res.status === 301 || res.status === 302) && hopMethod === "POST") {
|
|
37132
37416
|
if (hopMethod !== "HEAD")
|
|
37133
37417
|
hopMethod = "GET";
|
|
@@ -37204,24 +37488,62 @@ function createApiClient(opts) {
|
|
|
37204
37488
|
throw err;
|
|
37205
37489
|
}
|
|
37206
37490
|
}
|
|
37207
|
-
|
|
37208
|
-
|
|
37209
|
-
|
|
37491
|
+
function withIdempotency(opt) {
|
|
37492
|
+
const name = opts.idempotencyHeader;
|
|
37493
|
+
if (name === void 0 || name === "")
|
|
37494
|
+
return opt;
|
|
37495
|
+
const lower2 = name.toLowerCase();
|
|
37496
|
+
if (opt.headers && Object.keys(opt.headers).some((k) => k.toLowerCase() === lower2))
|
|
37497
|
+
return opt;
|
|
37498
|
+
const key = opt.idempotencyKey ?? globalThis.crypto.randomUUID();
|
|
37499
|
+
return { ...opt, headers: { ...opt.headers, [name]: key } };
|
|
37500
|
+
}
|
|
37501
|
+
async function errorFor(res, text, method, path, retried) {
|
|
37502
|
+
const edge = detectEdgeBlock({ body: text, headers: res.headers, status: res.status });
|
|
37503
|
+
if (edge)
|
|
37504
|
+
return new EdgeBlockedError(res.status, edge.vendor, { service, method, path });
|
|
37505
|
+
if (opts.onErrorResponse) {
|
|
37506
|
+
const decision = await opts.onErrorResponse({ status: res.status, method, path, headers: res.headers, body: text, retried });
|
|
37507
|
+
if (decision instanceof Error)
|
|
37508
|
+
return decision;
|
|
37509
|
+
if (decision === "retry" && !retried)
|
|
37510
|
+
return "retry";
|
|
37511
|
+
}
|
|
37512
|
+
return httpError(res, text, method, path, service);
|
|
37513
|
+
}
|
|
37514
|
+
const fetchJson = (method, path, opt = {}) => {
|
|
37515
|
+
const o = withIdempotency(opt);
|
|
37516
|
+
return guardWrite(method, o, (dispatch) => fetchJsonOnce(method, path, o, dispatch));
|
|
37517
|
+
};
|
|
37518
|
+
const fetchHtml = (method, path, opt = {}) => {
|
|
37519
|
+
const o = withIdempotency(opt);
|
|
37520
|
+
return guardWrite(method, o, (dispatch) => fetchHtmlOnce(method, path, o, dispatch));
|
|
37521
|
+
};
|
|
37522
|
+
const fetchRaw = (method, path, opt = {}) => {
|
|
37523
|
+
const o = withIdempotency(opt);
|
|
37524
|
+
return guardWrite(method, o, (dispatch) => fetchRawOnce(method, path, o, dispatch));
|
|
37525
|
+
};
|
|
37210
37526
|
async function fetchJsonOnce(method, path, opt, dispatch) {
|
|
37211
37527
|
const maxBytes = capOf(opt);
|
|
37212
|
-
|
|
37213
|
-
|
|
37214
|
-
|
|
37215
|
-
|
|
37216
|
-
|
|
37217
|
-
|
|
37218
|
-
|
|
37219
|
-
|
|
37220
|
-
|
|
37221
|
-
|
|
37222
|
-
|
|
37223
|
-
|
|
37528
|
+
let attempt;
|
|
37529
|
+
for (let retried = false; ; retried = true) {
|
|
37530
|
+
attempt = await send(method, path, opt, dispatch);
|
|
37531
|
+
const res2 = attempt.res;
|
|
37532
|
+
if (res2.status === 401)
|
|
37533
|
+
throw await unauthorizedOrEdge(attempt, method, path, maxBytes);
|
|
37534
|
+
if (res2.status === 429)
|
|
37535
|
+
throw await rateLimitedError(attempt, method, path, maxBytes);
|
|
37536
|
+
if (res2.status === 204) {
|
|
37537
|
+
discard(attempt);
|
|
37538
|
+
return parseJsonBody("", { expect: opt.expect, service, method, path, status: 204 });
|
|
37539
|
+
}
|
|
37540
|
+
if (res2.ok)
|
|
37541
|
+
break;
|
|
37542
|
+
const failure2 = await errorFor(res2, await readErrorText(attempt, maxBytes), method, path, retried);
|
|
37543
|
+
if (failure2 !== "retry")
|
|
37544
|
+
throw failure2;
|
|
37224
37545
|
}
|
|
37546
|
+
const res = attempt.res;
|
|
37225
37547
|
const text = await readText(attempt, maxBytes);
|
|
37226
37548
|
return parseJsonBody(text, {
|
|
37227
37549
|
expect: opt.expect,
|
|
@@ -37235,34 +37557,43 @@ function createApiClient(opts) {
|
|
|
37235
37557
|
async function fetchHtmlOnce(method, path, opt, dispatch) {
|
|
37236
37558
|
const maxBytes = capOf(opt);
|
|
37237
37559
|
const headers = { Accept: "text/html,*/*", ...opt.headers };
|
|
37238
|
-
|
|
37239
|
-
|
|
37240
|
-
|
|
37241
|
-
|
|
37242
|
-
|
|
37243
|
-
|
|
37244
|
-
|
|
37245
|
-
|
|
37560
|
+
for (let retried = false; ; retried = true) {
|
|
37561
|
+
const attempt = await send(method, path, { ...opt, headers }, dispatch);
|
|
37562
|
+
const res = attempt.res;
|
|
37563
|
+
if (res.status === 401)
|
|
37564
|
+
throw await unauthorizedOrEdge(attempt, method, path, maxBytes);
|
|
37565
|
+
if (res.status === 429)
|
|
37566
|
+
throw await rateLimitedError(attempt, method, path, maxBytes);
|
|
37567
|
+
if (res.ok)
|
|
37568
|
+
return readText(attempt, maxBytes);
|
|
37569
|
+
const failure2 = await errorFor(res, await readErrorText(attempt, maxBytes), method, path, retried);
|
|
37570
|
+
if (failure2 !== "retry")
|
|
37571
|
+
throw failure2;
|
|
37246
37572
|
}
|
|
37247
|
-
return readText(attempt, maxBytes);
|
|
37248
37573
|
}
|
|
37249
37574
|
async function fetchRawOnce(method, path, opt, dispatch) {
|
|
37250
37575
|
const maxBytes = capOf(opt);
|
|
37251
37576
|
const headers = { Accept: "*/*", ...opt.headers };
|
|
37252
|
-
|
|
37253
|
-
|
|
37254
|
-
|
|
37255
|
-
|
|
37256
|
-
|
|
37257
|
-
|
|
37258
|
-
|
|
37577
|
+
let attempt;
|
|
37578
|
+
for (let retried = false; ; retried = true) {
|
|
37579
|
+
attempt = await send(method, path, { ...opt, headers }, dispatch);
|
|
37580
|
+
const res2 = attempt.res;
|
|
37581
|
+
if (res2.status === 401)
|
|
37582
|
+
throw await unauthorizedOrEdge(attempt, method, path, maxBytes);
|
|
37583
|
+
if (res2.status === 429)
|
|
37584
|
+
throw await rateLimitedError(attempt, method, path, maxBytes);
|
|
37585
|
+
if (res2.ok)
|
|
37586
|
+
break;
|
|
37259
37587
|
const text = await readText(attempt, maxBytes).catch((err) => {
|
|
37260
37588
|
if (err instanceof RequestTimeoutError)
|
|
37261
37589
|
throw err;
|
|
37262
37590
|
return "";
|
|
37263
37591
|
});
|
|
37264
|
-
|
|
37592
|
+
const failure2 = await errorFor(res2, text, method, path, retried);
|
|
37593
|
+
if (failure2 !== "retry")
|
|
37594
|
+
throw failure2;
|
|
37265
37595
|
}
|
|
37596
|
+
const res = attempt.res;
|
|
37266
37597
|
const bytes = await readBytes(attempt, maxBytes);
|
|
37267
37598
|
return {
|
|
37268
37599
|
status: res.status,
|
|
@@ -37331,7 +37662,7 @@ function decodeJwtExp(token) {
|
|
|
37331
37662
|
}
|
|
37332
37663
|
return exp;
|
|
37333
37664
|
}
|
|
37334
|
-
var DEFAULT_RETRY, defaultSleep, DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_MAX_REDIRECTS, REDIRECT_STATUSES, UnauthorizedError, RateLimitedError, RequestTimeoutError, DEFAULT_WRITE_OUTCOME_HINT, WriteOutcomeUnknownError, SAFE_METHODS, ApiError, EdgeBlockedError, EDGE_BLOCK_SCAN_MAX, EDGE_BLOCK_MARKERS;
|
|
37665
|
+
var DEFAULT_RETRY, defaultSleep, DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_MAX_REDIRECTS, FETCH_MAX_REDIRECTS, CROSS_ORIGIN_DROPPED_HEADERS, REDIRECT_STATUSES, UnauthorizedError, RateLimitedError, RequestTimeoutError, DEFAULT_WRITE_OUTCOME_HINT, WriteOutcomeUnknownError, SAFE_METHODS, ApiError, EdgeBlockedError, EDGE_BLOCK_SCAN_MAX, EDGE_BLOCK_MARKERS;
|
|
37335
37666
|
var init_http = __esm({
|
|
37336
37667
|
"node_modules/@chrischall/mcp-utils/dist/http/index.js"() {
|
|
37337
37668
|
init_headers();
|
|
@@ -37343,6 +37674,7 @@ var init_http = __esm({
|
|
|
37343
37674
|
init_net_atoms();
|
|
37344
37675
|
init_fetch_bounded();
|
|
37345
37676
|
init_url_safety();
|
|
37677
|
+
init_transport_failure();
|
|
37346
37678
|
init_body_limit();
|
|
37347
37679
|
init_net_atoms();
|
|
37348
37680
|
init_url_safety();
|
|
@@ -37351,6 +37683,8 @@ var init_http = __esm({
|
|
|
37351
37683
|
defaultSleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
37352
37684
|
DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
37353
37685
|
DEFAULT_MAX_REDIRECTS = 5;
|
|
37686
|
+
FETCH_MAX_REDIRECTS = 20;
|
|
37687
|
+
CROSS_ORIGIN_DROPPED_HEADERS = ["authorization", "cookie", "proxy-authorization"];
|
|
37354
37688
|
REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
37355
37689
|
UnauthorizedError = class extends Error {
|
|
37356
37690
|
status = 401;
|
|
@@ -37588,7 +37922,7 @@ var init_version = __esm({
|
|
|
37588
37922
|
"src/version.ts"() {
|
|
37589
37923
|
"use strict";
|
|
37590
37924
|
PACKAGE_NAME = "office-outlook-mcp";
|
|
37591
|
-
VERSION = "0.6.
|
|
37925
|
+
VERSION = "0.6.2";
|
|
37592
37926
|
}
|
|
37593
37927
|
});
|
|
37594
37928
|
|
|
@@ -38143,6 +38477,21 @@ var init_public_suffix = __esm({
|
|
|
38143
38477
|
}
|
|
38144
38478
|
});
|
|
38145
38479
|
|
|
38480
|
+
// node_modules/@fetchproxy/protocol/dist/ip-literal.js
|
|
38481
|
+
function isIpLiteralHost(host) {
|
|
38482
|
+
if (host.includes(":") || host.startsWith("["))
|
|
38483
|
+
return true;
|
|
38484
|
+
const labels = host.split(".");
|
|
38485
|
+
if (labels.length > 1 && labels[labels.length - 1] === "")
|
|
38486
|
+
labels.pop();
|
|
38487
|
+
const last = labels[labels.length - 1] ?? "";
|
|
38488
|
+
return /^[0-9]+$/.test(last) || /^0x[0-9a-f]*$/i.test(last);
|
|
38489
|
+
}
|
|
38490
|
+
var init_ip_literal = __esm({
|
|
38491
|
+
"node_modules/@fetchproxy/protocol/dist/ip-literal.js"() {
|
|
38492
|
+
}
|
|
38493
|
+
});
|
|
38494
|
+
|
|
38146
38495
|
// node_modules/@fetchproxy/protocol/dist/validate.js
|
|
38147
38496
|
function assertObject(x, label) {
|
|
38148
38497
|
if (typeof x !== "object" || x === null || Array.isArray(x)) {
|
|
@@ -38592,6 +38941,9 @@ function validateHello(raw) {
|
|
|
38592
38941
|
if (!HOSTNAME_RE.test(d)) {
|
|
38593
38942
|
throw new ProtocolError3(`hello.domains: invalid hostname ${JSON.stringify(d)}`);
|
|
38594
38943
|
}
|
|
38944
|
+
if (isIpLiteralHost(d)) {
|
|
38945
|
+
throw new ProtocolError3(`hello.domains: ${JSON.stringify(d)} is an IP address \u2014 declare the site's DNS hostname; IP-literal origins (LAN, loopback, link-local) are not reachable through the bridge`);
|
|
38946
|
+
}
|
|
38595
38947
|
if (isPublicSuffix(d)) {
|
|
38596
38948
|
throw new ProtocolError3(`hello.domains: ${JSON.stringify(d)} is a public suffix \u2014 declare a registrable domain (e.g. "example.${d}"), not the suffix every site under it shares`);
|
|
38597
38949
|
}
|
|
@@ -39365,6 +39717,7 @@ var init_validate = __esm({
|
|
|
39365
39717
|
init_account_attest();
|
|
39366
39718
|
init_json_pointer();
|
|
39367
39719
|
init_public_suffix();
|
|
39720
|
+
init_ip_literal();
|
|
39368
39721
|
ProtocolError3 = class extends Error {
|
|
39369
39722
|
constructor(message) {
|
|
39370
39723
|
super(message);
|
|
@@ -39544,6 +39897,7 @@ var init_dist3 = __esm({
|
|
|
39544
39897
|
init_seal();
|
|
39545
39898
|
init_encoding();
|
|
39546
39899
|
init_public_suffix();
|
|
39900
|
+
init_ip_literal();
|
|
39547
39901
|
init_json_pointer();
|
|
39548
39902
|
}
|
|
39549
39903
|
});
|
|
@@ -44514,7 +44868,7 @@ async function startHost(opts) {
|
|
|
44514
44868
|
if (ownRetryableRefusal)
|
|
44515
44869
|
resetSessionPromise();
|
|
44516
44870
|
resolveOwnSession(ownSession);
|
|
44517
|
-
} else {
|
|
44871
|
+
} else if (identified === "extension" && extensionWs === ws) {
|
|
44518
44872
|
const slot = peers.get(frame.mcpId);
|
|
44519
44873
|
if (slot)
|
|
44520
44874
|
slot.ws.send(JSON.stringify(frame));
|
|
@@ -45602,6 +45956,9 @@ var init_ws_server = __esm({
|
|
|
45602
45956
|
throw new Error("FetchproxyServer: opts.domains must be a non-empty array of hostnames");
|
|
45603
45957
|
}
|
|
45604
45958
|
for (const d of opts.domains) {
|
|
45959
|
+
if (typeof d === "string" && isIpLiteralHost(d)) {
|
|
45960
|
+
throw new Error(`FetchproxyServer: opts.domains entry ${JSON.stringify(d)} is an IP address \u2014 declare the site's DNS hostname; IP-literal origins (LAN, loopback, link-local) are not reachable through the bridge`);
|
|
45961
|
+
}
|
|
45605
45962
|
if (typeof d === "string" && isPublicSuffix(d)) {
|
|
45606
45963
|
throw new Error(`FetchproxyServer: opts.domains entry ${JSON.stringify(d)} is a public suffix \u2014 declare a registrable domain (e.g. "example.${d}"), not the suffix every site under it shares`);
|
|
45607
45964
|
}
|
|
@@ -47547,8 +47904,10 @@ var init_bulk = __esm({
|
|
|
47547
47904
|
});
|
|
47548
47905
|
|
|
47549
47906
|
// node_modules/@fetchproxy/server/dist/bot-wall.js
|
|
47907
|
+
var CLOUDFLARE_TITLE_SCAN_MAX;
|
|
47550
47908
|
var init_bot_wall = __esm({
|
|
47551
47909
|
"node_modules/@fetchproxy/server/dist/bot-wall.js"() {
|
|
47910
|
+
CLOUDFLARE_TITLE_SCAN_MAX = 64 * 1024;
|
|
47552
47911
|
}
|
|
47553
47912
|
});
|
|
47554
47913
|
|
|
@@ -47909,6 +48268,71 @@ function createBootstrapOpts(args) {
|
|
|
47909
48268
|
...nonEmpty(b.domSelectors) ? { domSelectors: b.domSelectors } : {}
|
|
47910
48269
|
};
|
|
47911
48270
|
}
|
|
48271
|
+
function stripBearer(raw) {
|
|
48272
|
+
const m = /^\s*Bearer\s+(.+)$/i.exec(raw);
|
|
48273
|
+
return (m?.[1] ?? raw).trim();
|
|
48274
|
+
}
|
|
48275
|
+
async function raceCaptures(attempts, windowMs) {
|
|
48276
|
+
for (const a of attempts)
|
|
48277
|
+
a.catch(() => {
|
|
48278
|
+
});
|
|
48279
|
+
let timer;
|
|
48280
|
+
const expiry = new Promise((_resolve, reject) => {
|
|
48281
|
+
timer = setTimeout(() => reject(new Error(`timed out after ${Math.round(windowMs / 1e3)}s waiting for the page to make a request we could read`)), windowMs);
|
|
48282
|
+
});
|
|
48283
|
+
try {
|
|
48284
|
+
return await Promise.race([
|
|
48285
|
+
Promise.any(attempts).catch((e) => {
|
|
48286
|
+
throw new Error(e instanceof AggregateError ? e.errors.map((x) => messageOf(x)).join("; ") : messageOf(e));
|
|
48287
|
+
}),
|
|
48288
|
+
expiry
|
|
48289
|
+
]);
|
|
48290
|
+
} finally {
|
|
48291
|
+
clearTimeout(timer);
|
|
48292
|
+
}
|
|
48293
|
+
}
|
|
48294
|
+
async function captureBearerHeader(opts) {
|
|
48295
|
+
if (opts.captures.length === 0)
|
|
48296
|
+
throw new Error("captureBearerHeader: at least one capture declaration is required.");
|
|
48297
|
+
const minLength = opts.minLength ?? 100;
|
|
48298
|
+
const normalise = opts.normalise ?? stripBearer;
|
|
48299
|
+
const domains = opts.domains ?? [...new Set(opts.captures.map((c) => c.host))];
|
|
48300
|
+
const build2 = opts.createTransport ?? ((o) => createFetchproxyTransport(o));
|
|
48301
|
+
const transport = build2({
|
|
48302
|
+
...opts.transportOptions,
|
|
48303
|
+
...createBootstrapOpts({ domains: [...domains], bootstrap: { captureHeaders: opts.captures.map((c) => ({ ...c })) } }),
|
|
48304
|
+
...opts.port !== void 0 ? { port: opts.port } : {},
|
|
48305
|
+
// Both: the explicit deadline for every bridge version, and the declared
|
|
48306
|
+
// window so the transport's own derivation agrees with it.
|
|
48307
|
+
fetchTimeoutMs: deadlineForCaptureWindow(void 0, opts.windowMs) ?? SERVER_DEFAULT_FETCH_TIMEOUT_MS,
|
|
48308
|
+
captureWindowMs: opts.windowMs,
|
|
48309
|
+
serverName: opts.serverName,
|
|
48310
|
+
version: opts.version
|
|
48311
|
+
});
|
|
48312
|
+
const one = async (decl) => {
|
|
48313
|
+
const raw = await transport.server.captureRequestHeader({ ...decl, timeoutMs: opts.windowMs });
|
|
48314
|
+
if (typeof raw !== "string")
|
|
48315
|
+
throw new Error(`${decl.host}: capture returned no header`);
|
|
48316
|
+
const token = normalise(raw);
|
|
48317
|
+
if (token.length < minLength) {
|
|
48318
|
+
throw new Error(`${decl.host}: ${decl.headerName} header was present but too short to be a token (${token.length} chars)`);
|
|
48319
|
+
}
|
|
48320
|
+
return token;
|
|
48321
|
+
};
|
|
48322
|
+
try {
|
|
48323
|
+
await transport.start();
|
|
48324
|
+
try {
|
|
48325
|
+
return opts.captures.length === 1 ? await one(opts.captures[0]) : await raceCaptures(opts.captures.map(one), opts.windowMs);
|
|
48326
|
+
} catch (e) {
|
|
48327
|
+
throw new Error(`could not capture ${opts.what} from the browser (${messageOf(e)}). ${opts.guidance}`);
|
|
48328
|
+
}
|
|
48329
|
+
} finally {
|
|
48330
|
+
try {
|
|
48331
|
+
await transport.close();
|
|
48332
|
+
} catch {
|
|
48333
|
+
}
|
|
48334
|
+
}
|
|
48335
|
+
}
|
|
47912
48336
|
var PLACEHOLDER_RE2, SERVER_DEFAULT_FETCH_TIMEOUT_MS, CAPTURE_DEADLINE_MARGIN_MS;
|
|
47913
48337
|
var init_fetchproxy = __esm({
|
|
47914
48338
|
"node_modules/@chrischall/mcp-utils/dist/fetchproxy/index.js"() {
|
|
@@ -47937,97 +48361,26 @@ __export(auth_fetchproxy_exports, {
|
|
|
47937
48361
|
function getWsPort() {
|
|
47938
48362
|
return readPortEnv("OUTLOOK_WS_PORT", DEFAULT_WS_PORT);
|
|
47939
48363
|
}
|
|
47940
|
-
function withFetch(opts) {
|
|
47941
|
-
const derived2 = opts.capabilities ?? [];
|
|
47942
|
-
return {
|
|
47943
|
-
...opts,
|
|
47944
|
-
capabilities: derived2.includes("fetch") ? derived2 : [...derived2, "fetch"]
|
|
47945
|
-
};
|
|
47946
|
-
}
|
|
47947
|
-
async function raceCaptures(attempts, windowMs) {
|
|
47948
|
-
for (const a of attempts) a.catch(() => {
|
|
47949
|
-
});
|
|
47950
|
-
let timer;
|
|
47951
|
-
const expiry = new Promise((_, reject) => {
|
|
47952
|
-
timer = setTimeout(
|
|
47953
|
-
() => reject(
|
|
47954
|
-
new Error(
|
|
47955
|
-
`timed out after ${Math.round(windowMs / 1e3)}s waiting for the page to make a request we could read`
|
|
47956
|
-
)
|
|
47957
|
-
),
|
|
47958
|
-
windowMs
|
|
47959
|
-
);
|
|
47960
|
-
});
|
|
47961
|
-
try {
|
|
47962
|
-
return await Promise.race([
|
|
47963
|
-
Promise.any(attempts).catch((e) => {
|
|
47964
|
-
throw new Error(
|
|
47965
|
-
e instanceof AggregateError ? e.errors.map((x) => x.message).join("; ") : e.message
|
|
47966
|
-
);
|
|
47967
|
-
}),
|
|
47968
|
-
expiry
|
|
47969
|
-
]);
|
|
47970
|
-
} finally {
|
|
47971
|
-
clearTimeout(timer);
|
|
47972
|
-
}
|
|
47973
|
-
}
|
|
47974
|
-
function stripBearer(raw) {
|
|
47975
|
-
const m = /^\s*Bearer\s+(.+)$/i.exec(raw);
|
|
47976
|
-
return (m ? m[1] : raw).trim();
|
|
47977
|
-
}
|
|
47978
48364
|
async function captureTokenViaFetchproxy() {
|
|
47979
|
-
|
|
47980
|
-
|
|
47981
|
-
|
|
47982
|
-
|
|
47983
|
-
bootstrap: {
|
|
47984
|
-
captureHeaders: [{ ...CAPTURE_DECL_CLOUD }, { ...CAPTURE_DECL_OFFICE }]
|
|
47985
|
-
}
|
|
47986
|
-
})
|
|
47987
|
-
),
|
|
48365
|
+
return captureBearerHeader({
|
|
48366
|
+
captures: [CAPTURE_DECL_CLOUD, CAPTURE_DECL_OFFICE],
|
|
48367
|
+
domains: TRUST_DOMAINS,
|
|
48368
|
+
windowMs: CAPTURE_TIMEOUT_MS,
|
|
47988
48369
|
port: getWsPort(),
|
|
47989
|
-
fetchTimeoutMs: BRIDGE_DEADLINE_MS,
|
|
47990
48370
|
serverName: PACKAGE_NAME,
|
|
47991
|
-
version: VERSION
|
|
48371
|
+
version: VERSION,
|
|
48372
|
+
what: "an Outlook token",
|
|
48373
|
+
guidance: "Open a signed-in Outlook tab (outlook.cloud.microsoft or outlook.office.com), leave it in the foreground for a moment so the page makes a request, and retry."
|
|
47992
48374
|
});
|
|
47993
|
-
try {
|
|
47994
|
-
await transport.start();
|
|
47995
|
-
const attempts = [CAPTURE_DECL_CLOUD, CAPTURE_DECL_OFFICE].map(
|
|
47996
|
-
(decl) => transport.server.captureRequestHeader({ ...decl, timeoutMs: CAPTURE_TIMEOUT_MS }).then((raw) => {
|
|
47997
|
-
if (typeof raw !== "string") {
|
|
47998
|
-
throw new Error(`${decl.host}: capture returned no header`);
|
|
47999
|
-
}
|
|
48000
|
-
const token = stripBearer(raw);
|
|
48001
|
-
if (token.length < MIN_TOKEN_LENGTH) {
|
|
48002
|
-
throw new Error(
|
|
48003
|
-
`${decl.host}: authorization header was present but too short to be a token (${token.length} chars)`
|
|
48004
|
-
);
|
|
48005
|
-
}
|
|
48006
|
-
return token;
|
|
48007
|
-
})
|
|
48008
|
-
);
|
|
48009
|
-
try {
|
|
48010
|
-
return await raceCaptures(attempts, CAPTURE_TIMEOUT_MS);
|
|
48011
|
-
} catch (e) {
|
|
48012
|
-
const detail = e.message;
|
|
48013
|
-
throw new Error(
|
|
48014
|
-
`could not capture an Outlook token from the browser (${detail}). Open a signed-in Outlook tab (outlook.cloud.microsoft or outlook.office.com), leave it in the foreground for a moment so the page makes a request, and retry.`
|
|
48015
|
-
);
|
|
48016
|
-
}
|
|
48017
|
-
} finally {
|
|
48018
|
-
try {
|
|
48019
|
-
await transport.close();
|
|
48020
|
-
} catch {
|
|
48021
|
-
}
|
|
48022
|
-
}
|
|
48023
48375
|
}
|
|
48024
|
-
var DEFAULT_WS_PORT, CAPTURE_DECL_CLOUD, CAPTURE_DECL_OFFICE, CAPTURE_HOSTS, TRUST_DOMAINS, CAPTURE_TIMEOUT_MS
|
|
48376
|
+
var DEFAULT_WS_PORT, CAPTURE_DECL_CLOUD, CAPTURE_DECL_OFFICE, CAPTURE_HOSTS, TRUST_DOMAINS, CAPTURE_TIMEOUT_MS;
|
|
48025
48377
|
var init_auth_fetchproxy = __esm({
|
|
48026
48378
|
"src/auth-fetchproxy.ts"() {
|
|
48027
48379
|
"use strict";
|
|
48028
48380
|
init_fetchproxy();
|
|
48029
48381
|
init_dist2();
|
|
48030
48382
|
init_version();
|
|
48383
|
+
init_fetchproxy();
|
|
48031
48384
|
DEFAULT_WS_PORT = 37149;
|
|
48032
48385
|
CAPTURE_DECL_CLOUD = {
|
|
48033
48386
|
host: "outlook.cloud.microsoft",
|
|
@@ -48042,8 +48395,6 @@ var init_auth_fetchproxy = __esm({
|
|
|
48042
48395
|
CAPTURE_HOSTS = [CAPTURE_DECL_CLOUD.host, CAPTURE_DECL_OFFICE.host];
|
|
48043
48396
|
TRUST_DOMAINS = [...CAPTURE_HOSTS];
|
|
48044
48397
|
CAPTURE_TIMEOUT_MS = readTtlMsEnv("OUTLOOK_CAPTURE_TIMEOUT", 3e4);
|
|
48045
|
-
BRIDGE_DEADLINE_MS = Math.max(CAPTURE_TIMEOUT_MS + 15e3, 3e4);
|
|
48046
|
-
MIN_TOKEN_LENGTH = 100;
|
|
48047
48398
|
}
|
|
48048
48399
|
});
|
|
48049
48400
|
|
|
@@ -48625,6 +48976,46 @@ var TokenManager = class {
|
|
|
48625
48976
|
return res;
|
|
48626
48977
|
}
|
|
48627
48978
|
};
|
|
48979
|
+
var RECAPTURE_SENTINEL = "fetchproxy:recapture";
|
|
48980
|
+
var UNKNOWN_CAPTURED_TOKEN_TTL_MS = 10 * 60 * 1e3;
|
|
48981
|
+
function capturedBearerTokens(accessToken, opts = {}) {
|
|
48982
|
+
const now = opts.now ?? Date.now;
|
|
48983
|
+
let expiresAt;
|
|
48984
|
+
try {
|
|
48985
|
+
expiresAt = decodeJwtExp(accessToken) * 1e3;
|
|
48986
|
+
} catch {
|
|
48987
|
+
expiresAt = now() + (opts.unknownTtlMs ?? UNKNOWN_CAPTURED_TOKEN_TTL_MS);
|
|
48988
|
+
}
|
|
48989
|
+
return { accessToken, refreshToken: RECAPTURE_SENTINEL, expiresAt };
|
|
48990
|
+
}
|
|
48991
|
+
function createCapturedTokenManager(opts) {
|
|
48992
|
+
const { direct } = opts;
|
|
48993
|
+
const wrap = (token) => capturedBearerTokens(token, {
|
|
48994
|
+
...opts.unknownTtlMs !== void 0 ? { unknownTtlMs: opts.unknownTtlMs } : {},
|
|
48995
|
+
...opts.now !== void 0 ? { now: opts.now } : {}
|
|
48996
|
+
});
|
|
48997
|
+
const persistence = direct === void 0 ? opts.persistence ?? void 0 : void 0;
|
|
48998
|
+
return new TokenManager({
|
|
48999
|
+
initial: async () => wrap(direct ?? await opts.capture()),
|
|
49000
|
+
refresh: async () => {
|
|
49001
|
+
if (direct !== void 0) {
|
|
49002
|
+
throw opts.onDirectRejected ? opts.onDirectRejected() : new McpToolError("The directly supplied access token was rejected (401).", {
|
|
49003
|
+
status: 401,
|
|
49004
|
+
kind: "credential_rejected",
|
|
49005
|
+
hint: "A directly supplied token cannot be refreshed automatically. Replace it with a current one, or unset it to capture from a signed-in browser tab instead."
|
|
49006
|
+
});
|
|
49007
|
+
}
|
|
49008
|
+
return wrap(await opts.capture());
|
|
49009
|
+
},
|
|
49010
|
+
...persistence !== void 0 ? { persistence } : {},
|
|
49011
|
+
// Never fatal: the token is in hand and re-capturable.
|
|
49012
|
+
onPersistError: (err) => {
|
|
49013
|
+
opts.onPersistError?.(err);
|
|
49014
|
+
},
|
|
49015
|
+
...opts.skewMs !== void 0 ? { skewMs: opts.skewMs } : {},
|
|
49016
|
+
...opts.now !== void 0 ? { now: opts.now } : {}
|
|
49017
|
+
});
|
|
49018
|
+
}
|
|
48628
49019
|
|
|
48629
49020
|
// src/token-cache.ts
|
|
48630
49021
|
init_dist2();
|
|
@@ -48636,11 +49027,6 @@ function tokenCachePath(env = process.env) {
|
|
|
48636
49027
|
fileName: "token.json"
|
|
48637
49028
|
});
|
|
48638
49029
|
}
|
|
48639
|
-
function isToken(raw) {
|
|
48640
|
-
if (raw === null || typeof raw !== "object") return false;
|
|
48641
|
-
const t = raw;
|
|
48642
|
-
return typeof t.accessToken === "string" && t.accessToken !== "" && typeof t.expiresAt === "number" && (t.refreshToken === void 0 || typeof t.refreshToken === "string");
|
|
48643
|
-
}
|
|
48644
49030
|
function bindingFor(env) {
|
|
48645
49031
|
if (readEnvVar("OUTLOOK_ACCESS_TOKEN", { env }) !== void 0) return null;
|
|
48646
49032
|
if (parseBoolEnv("OUTLOOK_DISABLE_FETCHPROXY", { env })) return null;
|
|
@@ -48653,7 +49039,7 @@ function createTokenCache(env = process.env) {
|
|
|
48653
49039
|
return createFileStatePersistence({
|
|
48654
49040
|
filePath: tokenCachePath(env),
|
|
48655
49041
|
boundTo,
|
|
48656
|
-
validate: (raw) =>
|
|
49042
|
+
validate: (raw) => isBearerTokens(raw) ? raw : null
|
|
48657
49043
|
});
|
|
48658
49044
|
}
|
|
48659
49045
|
function reportCacheWriteFailure(err) {
|
|
@@ -48669,16 +49055,9 @@ async function captureTokenLazily() {
|
|
|
48669
49055
|
return mod.captureTokenViaFetchproxy();
|
|
48670
49056
|
}
|
|
48671
49057
|
var DEFAULT_API_BASE = "https://outlook.office.com/api/v2.0";
|
|
48672
|
-
|
|
48673
|
-
|
|
48674
|
-
|
|
48675
|
-
let expiresAt;
|
|
48676
|
-
try {
|
|
48677
|
-
expiresAt = decodeJwtExp(accessToken) * 1e3;
|
|
48678
|
-
} catch {
|
|
48679
|
-
expiresAt = Date.now() + UNKNOWN_TOKEN_TTL_MS;
|
|
48680
|
-
}
|
|
48681
|
-
return { accessToken, refreshToken: RECAPTURE_SENTINEL, expiresAt };
|
|
49058
|
+
function urlOf(input2) {
|
|
49059
|
+
if (typeof input2 === "string") return input2;
|
|
49060
|
+
return input2 instanceof URL ? input2.href : input2.url;
|
|
48682
49061
|
}
|
|
48683
49062
|
function isCredentialFailure(e) {
|
|
48684
49063
|
const kind = errorKindOf(e);
|
|
@@ -48703,7 +49082,14 @@ var OutlookClient = class {
|
|
|
48703
49082
|
constructor(opts = {}) {
|
|
48704
49083
|
this.#env = opts.env ?? process.env;
|
|
48705
49084
|
this.#capture = opts.captureToken ?? captureTokenLazily;
|
|
48706
|
-
|
|
49085
|
+
const fetchImpl = opts.fetchImpl ?? ((input2, init) => fetch(input2, init));
|
|
49086
|
+
this.#fetchImpl = async (input2, init) => {
|
|
49087
|
+
try {
|
|
49088
|
+
return await fetchImpl(input2, init);
|
|
49089
|
+
} catch (e) {
|
|
49090
|
+
throw describeTransportFailure(e, urlOf(input2), "Outlook") ?? e;
|
|
49091
|
+
}
|
|
49092
|
+
};
|
|
48707
49093
|
this.#baseUrl = readEnvVar("OUTLOOK_API_BASE", { env: this.#env }) ?? DEFAULT_API_BASE;
|
|
48708
49094
|
const direct = readEnvVar("OUTLOOK_ACCESS_TOKEN", { env: this.#env });
|
|
48709
49095
|
const bridgeOff = parseBoolEnv("OUTLOOK_DISABLE_FETCHPROXY", { env: this.#env });
|
|
@@ -48726,51 +49112,17 @@ var OutlookClient = class {
|
|
|
48726
49112
|
if (this.#configError) throw this.#configError;
|
|
48727
49113
|
}
|
|
48728
49114
|
#tokenManager() {
|
|
48729
|
-
if (this.#tokens) return this.#tokens;
|
|
48730
49115
|
const direct = readEnvVar("OUTLOOK_ACCESS_TOKEN", { env: this.#env });
|
|
48731
|
-
|
|
48732
|
-
|
|
48733
|
-
|
|
48734
|
-
|
|
48735
|
-
|
|
48736
|
-
|
|
48737
|
-
|
|
48738
|
-
|
|
48739
|
-
|
|
48740
|
-
|
|
48741
|
-
// and on a machine with no bridge it just hangs for the capture window on
|
|
48742
|
-
// every 401. Say what is wrong instead.
|
|
48743
|
-
refresh: async () => {
|
|
48744
|
-
if (direct !== void 0) {
|
|
48745
|
-
throw new McpToolError("OUTLOOK_ACCESS_TOKEN was rejected by Outlook.", {
|
|
48746
|
-
hint: "A directly-supplied token cannot be refreshed automatically. Replace OUTLOOK_ACCESS_TOKEN with a current one, or unset it to capture from a signed-in Outlook browser tab instead.",
|
|
48747
|
-
status: 401,
|
|
48748
|
-
kind: "credential_rejected"
|
|
48749
|
-
});
|
|
48750
|
-
}
|
|
48751
|
-
return toBearerTokens(await this.#capture());
|
|
48752
|
-
},
|
|
48753
|
-
// A failed cache write must not fail the call that triggered it: the
|
|
48754
|
-
// token is in hand and re-capturable, so a read-only data dir should cost
|
|
48755
|
-
// the next cold start a capture, not this request.
|
|
48756
|
-
...persistence ? {
|
|
48757
|
-
persistence: {
|
|
48758
|
-
load: () => persistence.load(),
|
|
48759
|
-
save: (t) => {
|
|
48760
|
-
try {
|
|
48761
|
-
persistence.save(t);
|
|
48762
|
-
} catch (e) {
|
|
48763
|
-
reportCacheWriteFailure(e);
|
|
48764
|
-
}
|
|
48765
|
-
},
|
|
48766
|
-
clear: () => {
|
|
48767
|
-
try {
|
|
48768
|
-
persistence.clear();
|
|
48769
|
-
} catch {
|
|
48770
|
-
}
|
|
48771
|
-
}
|
|
48772
|
-
}
|
|
48773
|
-
} : {}
|
|
49116
|
+
this.#tokens ??= createCapturedTokenManager({
|
|
49117
|
+
capture: () => this.#capture(),
|
|
49118
|
+
direct,
|
|
49119
|
+
onDirectRejected: () => new McpToolError("OUTLOOK_ACCESS_TOKEN was rejected by Outlook.", {
|
|
49120
|
+
hint: "A directly-supplied token cannot be refreshed automatically. Replace OUTLOOK_ACCESS_TOKEN with a current one, or unset it to capture from a signed-in Outlook browser tab instead.",
|
|
49121
|
+
status: 401,
|
|
49122
|
+
kind: "credential_rejected"
|
|
49123
|
+
}),
|
|
49124
|
+
persistence: direct === void 0 ? createTokenCache(this.#env) : null,
|
|
49125
|
+
onPersistError: reportCacheWriteFailure
|
|
48774
49126
|
});
|
|
48775
49127
|
return this.#tokens;
|
|
48776
49128
|
}
|
|
@@ -49928,6 +50280,9 @@ function messageBody(subject, body, html) {
|
|
|
49928
50280
|
}
|
|
49929
50281
|
var TEAMS = { IsOnlineMeeting: true, OnlineMeetingProvider: "TeamsForBusiness" };
|
|
49930
50282
|
var teamsMeetingParam = external_exports.boolean().optional().describe("Attach a Microsoft Teams meeting (default true). false leaves it off.");
|
|
50283
|
+
var addTeamsMeetingParam = external_exports.boolean().optional().describe(
|
|
50284
|
+
"true adds a Microsoft Teams meeting to an event that lacks one (default false: the way people join is left as it is)."
|
|
50285
|
+
);
|
|
49931
50286
|
var EVENT_STATE_SELECT = "Id,Subject,IsOrganizer,Start,End,Location,Attendees,IsOnlineMeeting,OnlineMeetingProvider,OnlineMeeting";
|
|
49932
50287
|
function attendee(Address, Type) {
|
|
49933
50288
|
return { Type, EmailAddress: { Address } };
|
|
@@ -49949,19 +50304,14 @@ function dateTimeTimeZone2(value, zone) {
|
|
|
49949
50304
|
return { DateTime: value, TimeZone: zone };
|
|
49950
50305
|
}
|
|
49951
50306
|
var TIMEOUT_SENTENCE = 'If Outlook does not answer in time (or the connection drops) the result has status "unknown": the write may well have gone through, so check before retrying \u2014 never resend blindly.';
|
|
49952
|
-
|
|
49953
|
-
|
|
49954
|
-
|
|
49955
|
-
|
|
49956
|
-
|
|
49957
|
-
|
|
49958
|
-
|
|
49959
|
-
|
|
49960
|
-
status: "unknown",
|
|
49961
|
-
warning: `Outlook did not confirm this write (${e.timedOut ? "it did not answer in time" : "the connection dropped"}), so it may already have happened. Check ${checkWhere} before retrying; do not resend blindly.`
|
|
49962
|
-
})
|
|
49963
|
-
};
|
|
49964
|
-
}
|
|
50307
|
+
function writeOrUnknown2(run, checkWhere) {
|
|
50308
|
+
return writeOrUnknown(
|
|
50309
|
+
run,
|
|
50310
|
+
(e) => minifiedResult({
|
|
50311
|
+
status: "unknown",
|
|
50312
|
+
warning: `Outlook did not confirm this write (${unknownOutcomeReason(e)}), so it may already have happened. Check ${checkWhere} before retrying; do not resend blindly.`
|
|
50313
|
+
})
|
|
50314
|
+
);
|
|
49965
50315
|
}
|
|
49966
50316
|
var INVITE_EVENT_SELECT = "Id,Subject,IsOrganizer,IsCancelled,Start,End,Organizer,ResponseStatus";
|
|
49967
50317
|
var DELETE_EVENT_SELECT = "Id,Subject,IsOrganizer,IsCancelled,ResponseStatus,Type,SeriesMasterId,Start,End,Organizer,Attendees";
|
|
@@ -50069,7 +50419,7 @@ function registerWriteTools(server, client2) {
|
|
|
50069
50419
|
confirmToken
|
|
50070
50420
|
});
|
|
50071
50421
|
if (gate) return gate;
|
|
50072
|
-
const sent = await
|
|
50422
|
+
const sent = await writeOrUnknown2(() => client2.write("POST", "/me/sendmail", payload), "Sent Items");
|
|
50073
50423
|
if (!sent.ok) return sent.result;
|
|
50074
50424
|
return minifiedResult({ sent: true, subject, recipients: recipients || null });
|
|
50075
50425
|
}
|
|
@@ -50077,39 +50427,30 @@ function registerWriteTools(server, client2) {
|
|
|
50077
50427
|
server.registerTool(
|
|
50078
50428
|
"outlook_create_draft",
|
|
50079
50429
|
{
|
|
50080
|
-
description: "Create a draft message in the Drafts folder without sending it. Returns the created draft, which can be reviewed and sent from Outlook. " +
|
|
50081
|
-
|
|
50430
|
+
description: "Create a draft message in the Drafts folder without sending it. Returns the created draft, which can be reviewed and sent from Outlook. It does not ask to confirm: a draft reaches nobody until it is sent from Outlook. Calling it twice leaves two drafts. " + TIMEOUT_SENTENCE,
|
|
50431
|
+
// Self-only and additive, like outlook_reply with draftOnly: nothing is
|
|
50432
|
+
// overwritten or sent. Not idempotent: a repeat creates a second draft.
|
|
50433
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
50082
50434
|
inputSchema: external_exports.object({
|
|
50083
50435
|
to: recipientList,
|
|
50084
50436
|
cc: recipientList,
|
|
50085
50437
|
subject: external_exports.string().describe("Subject line"),
|
|
50086
50438
|
body: external_exports.string().describe("Message body"),
|
|
50087
|
-
html: external_exports.boolean().optional().describe("Compose the body as HTML (default: plain text)")
|
|
50088
|
-
confirmToken: confirmTokenParam
|
|
50439
|
+
html: external_exports.boolean().optional().describe("Compose the body as HTML (default: plain text)")
|
|
50089
50440
|
})
|
|
50090
50441
|
},
|
|
50091
|
-
async ({ to, cc, subject, body, html
|
|
50442
|
+
async ({ to, cc, subject, body, html }) => {
|
|
50092
50443
|
const payload = {
|
|
50093
50444
|
...messageBody(subject, body, html),
|
|
50094
50445
|
ToRecipients: toRecipients(to),
|
|
50095
50446
|
...cc?.length ? { CcRecipients: toRecipients(cc) } : {}
|
|
50096
50447
|
};
|
|
50097
|
-
const
|
|
50098
|
-
|
|
50099
|
-
|
|
50100
|
-
message: "Review and confirm this draft:",
|
|
50101
|
-
summary: `Create draft "${subject}"`,
|
|
50102
|
-
// One signed-in mailbox per server process.
|
|
50103
|
-
account: void 0,
|
|
50104
|
-
request: { method: "POST", path: "/me/messages", body: payload },
|
|
50105
|
-
confirmToken
|
|
50106
|
-
});
|
|
50107
|
-
if (gate) return gate;
|
|
50108
|
-
const created = await client2.write(
|
|
50109
|
-
"POST",
|
|
50110
|
-
"/me/messages",
|
|
50111
|
-
payload
|
|
50448
|
+
const create = await writeOrUnknown2(
|
|
50449
|
+
() => client2.write("POST", "/me/messages", payload),
|
|
50450
|
+
"Drafts"
|
|
50112
50451
|
);
|
|
50452
|
+
if (!create.ok) return create.result;
|
|
50453
|
+
const created = create.value;
|
|
50113
50454
|
return minifiedResult({ created: true, Id: created?.Id, WebLink: created?.WebLink });
|
|
50114
50455
|
}
|
|
50115
50456
|
);
|
|
@@ -50300,7 +50641,7 @@ function registerWriteTools(server, client2) {
|
|
|
50300
50641
|
confirmToken
|
|
50301
50642
|
});
|
|
50302
50643
|
if (gate) return gate;
|
|
50303
|
-
const write = await
|
|
50644
|
+
const write = await writeOrUnknown2(
|
|
50304
50645
|
() => client2.write("POST", "/me/events", payload),
|
|
50305
50646
|
"the calendar (outlook_list_events)"
|
|
50306
50647
|
);
|
|
@@ -50326,7 +50667,7 @@ function registerWriteTools(server, client2) {
|
|
|
50326
50667
|
server.registerTool(
|
|
50327
50668
|
"outlook_update_event",
|
|
50328
50669
|
{
|
|
50329
|
-
description: "Update a meeting you organize: retitle, move, relocate, edit the description, or add/remove attendees. Moving only `start` keeps the meeting's length.
|
|
50670
|
+
description: "Update a meeting you organize: retitle, move, relocate, edit the description, or add/remove attendees. Moving only `start` keeps the meeting's length. It does not add a Microsoft Teams meeting unless you pass `teamsMeeting: true` (on an event that lacks one). Attendees are sent an updated invitation. Only the organizer can update a meeting \u2014 an attendee's edit would change their own copy alone, so it is refused. The result is verified by re-reading the event. " + CONFIRM_FLOW_SENTENCE + " " + CONFIRM_INJECTION_RULE,
|
|
50330
50671
|
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true },
|
|
50331
50672
|
inputSchema: external_exports.object({
|
|
50332
50673
|
id: external_exports.string().min(1).describe("Event Id from outlook_list_events or outlook_get_event"),
|
|
@@ -50339,7 +50680,7 @@ function registerWriteTools(server, client2) {
|
|
|
50339
50680
|
addAttendees: recipientList.describe("Required attendees to add"),
|
|
50340
50681
|
addOptionalAttendees: recipientList.describe("Optional attendees to add"),
|
|
50341
50682
|
removeAttendees: recipientList.describe("Attendees to remove"),
|
|
50342
|
-
teamsMeeting:
|
|
50683
|
+
teamsMeeting: addTeamsMeetingParam,
|
|
50343
50684
|
confirmToken: confirmTokenParam
|
|
50344
50685
|
})
|
|
50345
50686
|
},
|
|
@@ -50392,18 +50733,21 @@ function registerWriteTools(server, client2) {
|
|
|
50392
50733
|
}
|
|
50393
50734
|
payload.Attendees = next;
|
|
50394
50735
|
}
|
|
50395
|
-
const addTeams = args.teamsMeeting
|
|
50736
|
+
const addTeams = args.teamsMeeting === true && !(current && isTeams(current));
|
|
50396
50737
|
if (addTeams) Object.assign(payload, TEAMS);
|
|
50397
50738
|
if (Object.keys(payload).length === 0) {
|
|
50398
50739
|
throw new McpToolError("Nothing to update.", {
|
|
50399
|
-
hint: "Pass at least one of subject, start, end, location, body, or
|
|
50740
|
+
hint: "Pass at least one of subject, start, end, location, body, attendee changes, or teamsMeeting: true."
|
|
50400
50741
|
});
|
|
50401
50742
|
}
|
|
50402
50743
|
const gate = await confirmWrite(ctx, {
|
|
50403
50744
|
tool: "outlook_update_event",
|
|
50404
50745
|
action: "calendar.update_event",
|
|
50405
|
-
message: "Review and confirm this change (attendees are sent an updated invitation):",
|
|
50406
|
-
summary: `Update "${current?.Subject ?? args.id}": ${
|
|
50746
|
+
message: addTeams ? "Review and confirm this change (attendees are sent an updated invitation). This will also make it a Microsoft Teams meeting: attendees get a Teams join link." : "Review and confirm this change (attendees are sent an updated invitation):",
|
|
50747
|
+
summary: `Update "${current?.Subject ?? args.id}": ${[
|
|
50748
|
+
Object.keys(payload).filter((k) => !(k in TEAMS)).join(", "),
|
|
50749
|
+
addTeams ? "this will also make it a Microsoft Teams meeting" : ""
|
|
50750
|
+
].filter((part) => part !== "").join("; ")}`,
|
|
50407
50751
|
// One signed-in mailbox per server process.
|
|
50408
50752
|
account: void 0,
|
|
50409
50753
|
target: args.id,
|
|
@@ -50518,7 +50862,7 @@ function registerWriteTools(server, client2) {
|
|
|
50518
50862
|
});
|
|
50519
50863
|
if (gate) return gate;
|
|
50520
50864
|
}
|
|
50521
|
-
const write = await
|
|
50865
|
+
const write = await writeOrUnknown2(
|
|
50522
50866
|
() => client2.write("POST", path, payload),
|
|
50523
50867
|
"the event's response (outlook_get_event)"
|
|
50524
50868
|
);
|
|
@@ -50601,7 +50945,7 @@ function registerWriteTools(server, client2) {
|
|
|
50601
50945
|
});
|
|
50602
50946
|
if (gate) return gate;
|
|
50603
50947
|
}
|
|
50604
|
-
const write = await
|
|
50948
|
+
const write = await writeOrUnknown2(
|
|
50605
50949
|
() => client2.write("DELETE", path),
|
|
50606
50950
|
"the calendar (outlook_get_event)"
|
|
50607
50951
|
);
|
|
@@ -50654,7 +50998,7 @@ function registerWriteTools(server, client2) {
|
|
|
50654
50998
|
const base = `/me/messages/${encodeURIComponent(messageId)}`;
|
|
50655
50999
|
const forwardTo = mode === "forward" ? { ToRecipients: toRecipients(to) } : {};
|
|
50656
51000
|
if (draftOnly === true) {
|
|
50657
|
-
const create = await
|
|
51001
|
+
const create = await writeOrUnknown2(
|
|
50658
51002
|
() => client2.write(
|
|
50659
51003
|
"POST",
|
|
50660
51004
|
`${base}/${draft}`,
|
|
@@ -50721,7 +51065,7 @@ function registerWriteTools(server, client2) {
|
|
|
50721
51065
|
confirmToken
|
|
50722
51066
|
});
|
|
50723
51067
|
if (gate) return gate;
|
|
50724
|
-
const sent = await
|
|
51068
|
+
const sent = await writeOrUnknown2(() => client2.write("POST", path, payload), "Sent Items");
|
|
50725
51069
|
if (!sent.ok) return sent.result;
|
|
50726
51070
|
return mailboxUntrusted({
|
|
50727
51071
|
sent: true,
|