@chrischall/office-outlook-mcp 0.3.3 → 0.3.5
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/plugin.json +1 -1
- package/README.md +2 -1
- package/dist/bundle.js +476 -101
- package/dist/version.js +1 -1
- package/package.json +5 -5
- package/server.json +2 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "MCP server for Outlook / Microsoft 365 — mail, calendar, contacts and tasks via natural language",
|
|
10
|
-
"version": "0.3.
|
|
10
|
+
"version": "0.3.5"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "Outlook (Microsoft 365)",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "MCP server for Outlook / Microsoft 365 — read mail, folders, calendar, contacts and tasks, and send mail with confirmation",
|
|
18
|
-
"version": "0.3.
|
|
18
|
+
"version": "0.3.5",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "office-outlook-mcp",
|
|
3
3
|
"displayName": "Outlook (Microsoft 365)",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.5",
|
|
5
5
|
"description": "Outlook / Microsoft 365 for Claude — read mail, folders, calendar, contacts and tasks, and send mail with confirmation, using your signed-in browser session",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Chris Hall",
|
package/README.md
CHANGED
|
@@ -148,7 +148,8 @@ a fresh preview.
|
|
|
148
148
|
|
|
149
149
|
| variable | default | |
|
|
150
150
|
|---|---|---|
|
|
151
|
-
| `MCP_CONFIRM_MODE` | `ask-user` | What a write does on a client that cannot show a confirmation prompt (claude.ai, Claude Desktop). `ask-user`: two steps — the first call does nothing and returns a preview plus a token, and the model must get your approval in chat before calling again with it. `auto`: the same two steps, but the model may use the token after reviewing the preview itself. `refuse`: writes are refused on such clients. A client that can show prompts (Claude Code) always gets the real prompt
|
|
151
|
+
| `MCP_CONFIRM_MODE` | `ask-user` | What a write does on a client that cannot show a confirmation prompt (claude.ai, Claude Desktop). `ask-user`: two steps — the first call does nothing and returns a preview plus a token, and the model must get your approval in chat before calling again with it. `auto`: the same two steps, but the model may use the token after reviewing the preview itself. `refuse`: writes are refused on such clients. A client that can show prompts (Claude Code) always gets the real prompt, unless `MCP_CONFIRM_ELICITATION=off`. An unrecognised value is treated as `refuse`. |
|
|
152
|
+
| `MCP_CONFIRM_ELICITATION` | `on` | `off` never shows a confirmation prompt, so every client gets the `MCP_CONFIRM_MODE` behaviour. Set it for a client that says it can show prompts but never does (the write hangs — opencode 2.0.x). Any other value is treated as `on`, with a warning on stderr. |
|
|
152
153
|
| `MCP_CONFIRM_TTL_SECONDS` | `600` | How long a token stays valid. |
|
|
153
154
|
| `MCP_CONFIRM_SECRET` | random per process | Signing key; set it only if tokens must survive a server restart. On mcp-host the host supplies a stable per-child key (`MCP_HOST_CONFIRM_SECRET`) and spent tokens are recorded under `MCP_DATA_DIR`, so an approval survives an idle restart. |
|
|
154
155
|
|
package/dist/bundle.js
CHANGED
|
@@ -17821,8 +17821,8 @@ function currencyCode2(_params) {
|
|
|
17821
17821
|
return _stringFormat(ZodCustomStringFormat, "currency_code", currencyCode, _params);
|
|
17822
17822
|
}
|
|
17823
17823
|
function hash(alg, params) {
|
|
17824
|
-
const
|
|
17825
|
-
const format = `${alg}_${
|
|
17824
|
+
const enc7 = params?.enc ?? "hex";
|
|
17825
|
+
const format = `${alg}_${enc7}`;
|
|
17826
17826
|
const regex = regexes_exports[format];
|
|
17827
17827
|
if (!regex)
|
|
17828
17828
|
throw new Error(`Unrecognized hash format: ${format}`);
|
|
@@ -21496,7 +21496,7 @@ var init_internal = __esm({
|
|
|
21496
21496
|
}
|
|
21497
21497
|
});
|
|
21498
21498
|
|
|
21499
|
-
// node_modules/@modelcontextprotocol/server/dist/src-
|
|
21499
|
+
// node_modules/@modelcontextprotocol/server/dist/src-Cqbh3MYc.mjs
|
|
21500
21500
|
function stampErrorBrands(instance, ctor) {
|
|
21501
21501
|
const brands = /* @__PURE__ */ new Set();
|
|
21502
21502
|
let current = ctor;
|
|
@@ -23476,7 +23476,8 @@ function build() {
|
|
|
23476
23476
|
ListResourceTemplatesResultResponseSchema: wireResultResponse(ListResourceTemplatesResultSchema$1),
|
|
23477
23477
|
ReadResourceResultResponseSchema: wireResultResponse(union([ReadResourceResultSchema$1, InputRequiredResultSchema])),
|
|
23478
23478
|
CompleteResultResponseSchema: wireResultResponse(CompleteResultSchema$1),
|
|
23479
|
-
DiscoverResultResponseSchema: wireResultResponse(DiscoverResultSchema$1)
|
|
23479
|
+
DiscoverResultResponseSchema: wireResultResponse(DiscoverResultSchema$1),
|
|
23480
|
+
SubscriptionsListenResultResponseSchema: wireResultResponse(SubscriptionsListenResultSchema$1)
|
|
23480
23481
|
};
|
|
23481
23482
|
}
|
|
23482
23483
|
function buildSchemas2026() {
|
|
@@ -23695,6 +23696,9 @@ function isSpecRequestMethod(method) {
|
|
|
23695
23696
|
function isSpecNotificationMethod(method) {
|
|
23696
23697
|
return ALL_CODECS.some((codec2) => codec2.hasNotificationMethod(method));
|
|
23697
23698
|
}
|
|
23699
|
+
function isExtensionReusedRequestMethod(method) {
|
|
23700
|
+
return method === "tasks/get" || method === "tasks/cancel";
|
|
23701
|
+
}
|
|
23698
23702
|
function isPlainObject$3(value) {
|
|
23699
23703
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
23700
23704
|
}
|
|
@@ -24269,8 +24273,8 @@ function normalizeRawShapeSchema(schema) {
|
|
|
24269
24273
|
return schema;
|
|
24270
24274
|
}
|
|
24271
24275
|
var BRANDS, OAuthError, SdkErrorCode, SdkError, SdkHttpError, FIRST_MODERN_PROTOCOL_VERSION, SUPPORTED_MODERN_PROTOCOL_VERSIONS, TOOL_RESULT_FOREIGN_FAMILY_KEYS, memo$1, REF_REWRITE_DATA_POSITION_KEYS, REF_REWRITE_NAME_MAP_KEYS, requestMethodKeys$1, notificationMethodKeys$1, resultMethodKeys, maps$1, rev2025RequestMethods, rev2025NotificationMethods, NOT_IN_ERA$1, rev2025Codec, memo2, CACHEABLE_RESULT_METHODS, RESULT_CACHE_HINT_FALLBACK, ProtocolErrorCode, ProtocolError, ResourceNotFoundError, UrlElicitationRequiredError, UnsupportedProtocolVersionError, MissingRequiredClientCapabilityError, DEFAULT_CACHE_TTL_MS, DEFAULT_CACHE_SCOPE, EXTENDED_RESULT_TYPE_METHODS, INPUT_REQUEST_METHODS_2026, maps, requestMethodKeys, notificationMethodKeys, rev2026RequestMethods, rev2026NotificationMethods, NOT_IN_ERA, REQUIRED_ENVELOPE_KEYS, rev2026Codec, wireResultSchemasMemo, MODERN_WIRE_REVISION, ALL_CODECS, schemas_exports3, isJSONRPCRequest, isJSONRPCNotification, isJSONRPCResultResponse, isJSONRPCErrorResponse, isInputRequiredResult, X_MCP_HEADER_KEY, RFC9110_TOKEN, PERMITTED_X_MCP_HEADER_TYPES, NON_REACHABLE_SUBSCHEMA_KEYWORDS, OBJECT_VALUED_SUBSCHEMA_KEYWORDS, HEADER_MISMATCH_ERROR_CODE, INBOUND_VALIDATION_LADDER, LADDER_ERROR_HTTP_STATUS, warnedZodFallback, JSON_SCHEMA_CONVERSION_TARGET, DATETIME_FRACTION_DIGITS, ANNOTATION_ONLY_JSON_SCHEMA_KEYWORDS, ROOT_KEYS, PROPERTY_KEYS_BY_TYPE, SUPPORTED_STRING_FORMATS, inputRequired, REQUEST_STATE_ONLY_LEG_PACING_MS, SPEC_SCHEMA_KEYS, authSchemas, _specTypeSchemas, _isSpecType, specTypeSchemas, isSpecType, DEFAULT_REQUEST_TIMEOUT_MSEC, RESERVED_ENVELOPE_META_KEYS, RETRY_PARAMS_KEYS, NO_REQUEST_STATE, writeNegotiatedProtocolVersion, Protocol, require_content_type, import_content_type, STDIO_DEFAULT_MAX_BUFFER_SIZE, ReadBuffer, TOOL_NAME_REGEX;
|
|
24272
|
-
var
|
|
24273
|
-
"node_modules/@modelcontextprotocol/server/dist/src-
|
|
24276
|
+
var init_src_Cqbh3MYc = __esm({
|
|
24277
|
+
"node_modules/@modelcontextprotocol/server/dist/src-Cqbh3MYc.mjs"() {
|
|
24274
24278
|
init_chunk_Br0eD_fh();
|
|
24275
24279
|
init_dialects_DoSzNhcb();
|
|
24276
24280
|
init_internal();
|
|
@@ -25370,6 +25374,8 @@ var init_src_BHSMhZ_W = __esm({
|
|
|
25370
25374
|
_transport;
|
|
25371
25375
|
_requestMessageId = 0;
|
|
25372
25376
|
_requestHandlers = /* @__PURE__ */ new Map();
|
|
25377
|
+
/** Methods registered with an explicit schema; the era gate in `_onrequest` reads it for the Tasks extension names. */
|
|
25378
|
+
_customSchemaRequestMethods = /* @__PURE__ */ new Set();
|
|
25373
25379
|
_requestHandlerAbortControllers = /* @__PURE__ */ new Map();
|
|
25374
25380
|
_notificationHandlers = /* @__PURE__ */ new Map();
|
|
25375
25381
|
_responseHandlers = /* @__PURE__ */ new Map();
|
|
@@ -25653,7 +25659,7 @@ var init_src_BHSMhZ_W = __esm({
|
|
|
25653
25659
|
return;
|
|
25654
25660
|
}
|
|
25655
25661
|
}
|
|
25656
|
-
if (isSpecRequestMethod(request.method) && !codec2.hasRequestMethod(request.method)) {
|
|
25662
|
+
if (isSpecRequestMethod(request.method) && !codec2.hasRequestMethod(request.method) && !(isExtensionReusedRequestMethod(request.method) && this._customSchemaRequestMethods.has(request.method))) {
|
|
25657
25663
|
sendErrorResponse(ProtocolErrorCode.MethodNotFound, "Method not found");
|
|
25658
25664
|
return;
|
|
25659
25665
|
}
|
|
@@ -25786,8 +25792,11 @@ var init_src_BHSMhZ_W = __esm({
|
|
|
25786
25792
|
}
|
|
25787
25793
|
request(request, schemaOrOptions, maybeOptions) {
|
|
25788
25794
|
const codec2 = this._resolveOutboundCodec(request.method);
|
|
25795
|
+
if (isStandardSchema(schemaOrOptions)) {
|
|
25796
|
+
if (!isExtensionReusedRequestMethod(request.method)) this._assertOutboundRequestInEra(codec2, request.method);
|
|
25797
|
+
return this._requestWithSchemaViaCodec(codec2, request, schemaOrOptions, maybeOptions);
|
|
25798
|
+
}
|
|
25789
25799
|
this._assertOutboundRequestInEra(codec2, request.method);
|
|
25790
|
-
if (isStandardSchema(schemaOrOptions)) return this._requestWithSchemaViaCodec(codec2, request, schemaOrOptions, maybeOptions);
|
|
25791
25800
|
const validate2 = codecResultValidator(codec2, request.method);
|
|
25792
25801
|
if (validate2 === void 0) throw new TypeError(`'${request.method}' is not a spec method; pass a result schema as the second argument to request().`);
|
|
25793
25802
|
return this._requestWithSchemaViaCodec(codec2, request, validate2, schemaOrOptions);
|
|
@@ -26031,6 +26040,8 @@ var init_src_BHSMhZ_W = __esm({
|
|
|
26031
26040
|
return maybeHandler(parsed.data, ctx);
|
|
26032
26041
|
};
|
|
26033
26042
|
else throw new TypeError("setRequestHandler: handler is required");
|
|
26043
|
+
if (typeof schemasOrHandler === "function") this._customSchemaRequestMethods.delete(method);
|
|
26044
|
+
else this._customSchemaRequestMethods.add(method);
|
|
26034
26045
|
this._requestHandlers.set(method, this._wrapHandler(method, stored));
|
|
26035
26046
|
}
|
|
26036
26047
|
/**
|
|
@@ -26060,6 +26071,7 @@ var init_src_BHSMhZ_W = __esm({
|
|
|
26060
26071
|
*/
|
|
26061
26072
|
removeRequestHandler(method) {
|
|
26062
26073
|
this._requestHandlers.delete(method);
|
|
26074
|
+
this._customSchemaRequestMethods.delete(method);
|
|
26063
26075
|
}
|
|
26064
26076
|
/**
|
|
26065
26077
|
* Asserts that a request handler has not already been set for the given method, in preparation for a new one being automatically installed.
|
|
@@ -33202,7 +33214,7 @@ var init_shimsNode = __esm({
|
|
|
33202
33214
|
}
|
|
33203
33215
|
});
|
|
33204
33216
|
|
|
33205
|
-
// node_modules/@modelcontextprotocol/server/dist/mcp-
|
|
33217
|
+
// node_modules/@modelcontextprotocol/server/dist/mcp-DIH4cS6P.mjs
|
|
33206
33218
|
function isCompletable(schema) {
|
|
33207
33219
|
return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
|
|
33208
33220
|
}
|
|
@@ -33312,6 +33324,30 @@ function serverIdentityOf(server) {
|
|
|
33312
33324
|
function discoverAdvertisedCapabilities(capabilities) {
|
|
33313
33325
|
return { ...capabilities };
|
|
33314
33326
|
}
|
|
33327
|
+
function toolInputElementCount(value, max) {
|
|
33328
|
+
let count = 0;
|
|
33329
|
+
const stack = [value];
|
|
33330
|
+
while (stack.length > 0) {
|
|
33331
|
+
const node2 = stack.pop();
|
|
33332
|
+
if (node2 === null || typeof node2 !== "object") continue;
|
|
33333
|
+
if (Array.isArray(node2)) for (const child of node2) {
|
|
33334
|
+
if (++count > max) return count;
|
|
33335
|
+
if (child !== null && typeof child === "object") stack.push(child);
|
|
33336
|
+
}
|
|
33337
|
+
else for (const key in node2) {
|
|
33338
|
+
if (!Object.prototype.hasOwnProperty.call(node2, key)) continue;
|
|
33339
|
+
if (++count > max) return count;
|
|
33340
|
+
const child = node2[key];
|
|
33341
|
+
if (child !== null && typeof child === "object") stack.push(child);
|
|
33342
|
+
}
|
|
33343
|
+
}
|
|
33344
|
+
return count;
|
|
33345
|
+
}
|
|
33346
|
+
function resolveMaxToolInputElements(value) {
|
|
33347
|
+
if (value === void 0 || value === Infinity) return void 0;
|
|
33348
|
+
if (typeof value !== "number" || Number.isNaN(value) || value < 1) throw new RangeError(`maxToolInputElements must be a number of at least 1, or Infinity, got ${String(value)}`);
|
|
33349
|
+
return value;
|
|
33350
|
+
}
|
|
33315
33351
|
function createToolExecutor(inputSchema, handler) {
|
|
33316
33352
|
if (inputSchema) {
|
|
33317
33353
|
const callback$1 = handler;
|
|
@@ -33320,6 +33356,12 @@ function createToolExecutor(inputSchema, handler) {
|
|
|
33320
33356
|
const callback = handler;
|
|
33321
33357
|
return async (_args, ctx) => callback(ctx);
|
|
33322
33358
|
}
|
|
33359
|
+
function convertListedInputSchema(name, inputSchema) {
|
|
33360
|
+
const json2 = standardSchemaToJsonSchema(inputSchema, "input");
|
|
33361
|
+
const scan = scanXMcpHeaderDeclarations(json2);
|
|
33362
|
+
if (!scan.valid) console.warn(`[mcp-sdk] tool '${name}' carries an invalid x-mcp-header declaration and will be excluded by conforming Streamable HTTP clients: ${scan.reason}`);
|
|
33363
|
+
return json2;
|
|
33364
|
+
}
|
|
33323
33365
|
function convertOutputSchemaJson(outputSchema) {
|
|
33324
33366
|
if (outputSchema === void 0) return void 0;
|
|
33325
33367
|
try {
|
|
@@ -33332,7 +33374,7 @@ function createPromptHandler(name, argsSchema, callback) {
|
|
|
33332
33374
|
if (argsSchema) {
|
|
33333
33375
|
const typedCallback = callback;
|
|
33334
33376
|
return async (args, ctx) => {
|
|
33335
|
-
const parseResult = await validateStandardSchema(argsSchema, args);
|
|
33377
|
+
const parseResult = await validateStandardSchema(argsSchema, args ?? {});
|
|
33336
33378
|
if (!parseResult.success) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid arguments for prompt ${name}: ${parseResult.error}`);
|
|
33337
33379
|
return typedCallback(parseResult.data, ctx);
|
|
33338
33380
|
};
|
|
@@ -33362,9 +33404,9 @@ function unwrapOptionalSchema(schema) {
|
|
|
33362
33404
|
return schema.def?.innerType ?? schema;
|
|
33363
33405
|
}
|
|
33364
33406
|
var COMPLETABLE_SYMBOL, MAX_TIMER_DELAY_MS, DEFAULT_MAX_SUBSCRIPTIONS, CHANGE_NOTIFICATION_METHODS, StdioListenRouter, DEFAULT_LEGACY_SHIM_MAX_ROUNDS, DEFAULT_LEGACY_SHIM_ROUND_TIMEOUT_MS, LegacyInputRequiredShim, INPUT_REQUIRED_CAPABLE_METHODS, writeClientIdentity, installDiscoverHandler, readServerIdentity, Server, McpServer, EMPTY_OBJECT_JSON_SCHEMA, EMPTY_COMPLETION_RESULT;
|
|
33365
|
-
var
|
|
33366
|
-
"node_modules/@modelcontextprotocol/server/dist/mcp-
|
|
33367
|
-
|
|
33407
|
+
var init_mcp_DIH4cS6P = __esm({
|
|
33408
|
+
"node_modules/@modelcontextprotocol/server/dist/mcp-DIH4cS6P.mjs"() {
|
|
33409
|
+
init_src_Cqbh3MYc();
|
|
33368
33410
|
init_shimsNode();
|
|
33369
33411
|
COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
|
|
33370
33412
|
MAX_TIMER_DELAY_MS = 2 ** 31 - 1;
|
|
@@ -33387,7 +33429,7 @@ var init_mcp_DYuW2ZSs = __esm({
|
|
|
33387
33429
|
_serverCapabilities;
|
|
33388
33430
|
/**
|
|
33389
33431
|
* The serving instance's identity, stamped onto the graceful-close
|
|
33390
|
-
* results' `_meta` (the spec's `
|
|
33432
|
+
* results' `_meta` (the spec's `SubscriptionsListenResultMetaObject` extends
|
|
33391
33433
|
* `ResultMetaObject`). Handed over together with the capabilities.
|
|
33392
33434
|
*/
|
|
33393
33435
|
_serverInfo;
|
|
@@ -33653,6 +33695,11 @@ var init_mcp_DYuW2ZSs = __esm({
|
|
|
33653
33695
|
if (modernProtocolVersions(this._supportedProtocolVersions).length > 0) this.setRequestHandler("server/discover", () => this._ondiscover());
|
|
33654
33696
|
if (this._capabilities.logging) this._registerLoggingHandler();
|
|
33655
33697
|
}
|
|
33698
|
+
/** Attaches to the given transport; rejects while this instance is connected to another one. */
|
|
33699
|
+
async connect(transport) {
|
|
33700
|
+
if (this.transport !== void 0) throw new SdkError(SdkErrorCode.AlreadyConnected, "Use a separate Server instance per connection: this instance is already connected to a transport. To connect it to a new transport, call close() first.");
|
|
33701
|
+
await super.connect(transport);
|
|
33702
|
+
}
|
|
33656
33703
|
/**
|
|
33657
33704
|
* Registers the built-in `logging/setLevel` request handler.
|
|
33658
33705
|
*
|
|
@@ -34208,16 +34255,12 @@ var init_mcp_DYuW2ZSs = __esm({
|
|
|
34208
34255
|
* The underlying {@linkcode Server} instance, useful for advanced operations like sending notifications.
|
|
34209
34256
|
*/
|
|
34210
34257
|
server;
|
|
34258
|
+
_maxToolInputElements;
|
|
34211
34259
|
_registeredResources = {};
|
|
34212
34260
|
_registeredResourceTemplates = {};
|
|
34213
34261
|
_registeredTools = {};
|
|
34214
34262
|
_registeredPrompts = {};
|
|
34215
|
-
/**
|
|
34216
|
-
* Per-tool JSON-converted `inputSchema`, memoized so the SEP-2243
|
|
34217
|
-
* registration-time scan and the pre-dispatch validation step share one
|
|
34218
|
-
* conversion instead of paying it twice per request under the
|
|
34219
|
-
* per-request-factory `createMcpHandler` model.
|
|
34220
|
-
*/
|
|
34263
|
+
/** Per-tool JSON-converted `inputSchema`, filled on first use by `toolInputSchemaJson()`. */
|
|
34221
34264
|
_toolInputSchemaJson = {};
|
|
34222
34265
|
/**
|
|
34223
34266
|
* The JSON-serialized `inputSchema` of a registered tool, or `undefined`
|
|
@@ -34242,6 +34285,7 @@ var init_mcp_DYuW2ZSs = __esm({
|
|
|
34242
34285
|
}
|
|
34243
34286
|
constructor(serverInfo, options) {
|
|
34244
34287
|
this.server = new Server(serverInfo, options);
|
|
34288
|
+
this._maxToolInputElements = resolveMaxToolInputElements(options?.maxToolInputElements);
|
|
34245
34289
|
if (options?.capabilities?.tools) this.setToolRequestHandlers();
|
|
34246
34290
|
if (options?.capabilities?.resources) this.setResourceRequestHandlers();
|
|
34247
34291
|
if (options?.capabilities?.prompts) this.setPromptRequestHandlers();
|
|
@@ -34314,7 +34358,7 @@ var init_mcp_DYuW2ZSs = __esm({
|
|
|
34314
34358
|
name,
|
|
34315
34359
|
title: tool.title,
|
|
34316
34360
|
description: tool.description,
|
|
34317
|
-
inputSchema: tool.inputSchema ?
|
|
34361
|
+
inputSchema: tool.inputSchema ? convertListedInputSchema(name, tool.inputSchema) : EMPTY_OBJECT_JSON_SCHEMA,
|
|
34318
34362
|
annotations: tool.annotations,
|
|
34319
34363
|
icons: tool.icons,
|
|
34320
34364
|
execution: tool.execution,
|
|
@@ -34359,6 +34403,7 @@ var init_mcp_DYuW2ZSs = __esm({
|
|
|
34359
34403
|
* Validates tool input arguments against the tool's input schema.
|
|
34360
34404
|
*/
|
|
34361
34405
|
async validateToolInput(tool, args, toolName) {
|
|
34406
|
+
if (this._maxToolInputElements !== void 0 && toolInputElementCount(args, this._maxToolInputElements) > this._maxToolInputElements) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid arguments for tool ${toolName}: arguments contain more than the maximum of ${this._maxToolInputElements} elements`);
|
|
34362
34407
|
if (!tool.inputSchema) return;
|
|
34363
34408
|
const parseResult = await validateStandardSchema(tool.inputSchema, args ?? {});
|
|
34364
34409
|
if (!parseResult.success) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Input validation error: Invalid arguments for tool ${toolName}: ${parseResult.error}`);
|
|
@@ -34633,20 +34678,19 @@ var init_mcp_DYuW2ZSs = __esm({
|
|
|
34633
34678
|
}
|
|
34634
34679
|
_createRegisteredTool(name, title, description, inputSchema, outputSchema, annotations, icons, execution, scopeChallenge, _meta, handler) {
|
|
34635
34680
|
validateAndWarnToolName(name);
|
|
34636
|
-
if (inputSchema !== void 0) try {
|
|
34637
|
-
const json2 = standardSchemaToJsonSchema(inputSchema, "input");
|
|
34638
|
-
this._toolInputSchemaJson[name] = json2;
|
|
34639
|
-
const scan = scanXMcpHeaderDeclarations(json2);
|
|
34640
|
-
if (!scan.valid) console.warn(`[mcp-sdk] tool '${name}' carries an invalid x-mcp-header declaration and will be excluded by conforming Streamable HTTP clients: ${scan.reason}`);
|
|
34641
|
-
} catch {
|
|
34642
|
-
}
|
|
34643
34681
|
let currentHandler = handler;
|
|
34682
|
+
let outputSchemaJson;
|
|
34644
34683
|
const registeredTool = {
|
|
34645
34684
|
title,
|
|
34646
34685
|
description,
|
|
34647
34686
|
inputSchema,
|
|
34648
34687
|
outputSchema,
|
|
34649
|
-
outputSchemaJson
|
|
34688
|
+
get outputSchemaJson() {
|
|
34689
|
+
return outputSchemaJson ??= convertOutputSchemaJson(registeredTool.outputSchema);
|
|
34690
|
+
},
|
|
34691
|
+
set outputSchemaJson(value) {
|
|
34692
|
+
outputSchemaJson = value;
|
|
34693
|
+
},
|
|
34650
34694
|
annotations,
|
|
34651
34695
|
icons,
|
|
34652
34696
|
execution,
|
|
@@ -35090,8 +35134,8 @@ function toError(value) {
|
|
|
35090
35134
|
var swallowsErrorsAfterClose, StdioServerTransport, DISCARD_ANSWER_TIMEOUT_MS, StdioConnectionChannel;
|
|
35091
35135
|
var init_stdio = __esm({
|
|
35092
35136
|
"node_modules/@modelcontextprotocol/server/dist/stdio.mjs"() {
|
|
35093
|
-
|
|
35094
|
-
|
|
35137
|
+
init_mcp_DIH4cS6P();
|
|
35138
|
+
init_src_Cqbh3MYc();
|
|
35095
35139
|
init_shimsNode();
|
|
35096
35140
|
swallowsErrorsAfterClose = /* @__PURE__ */ Symbol("swallowsErrorsAfterClose");
|
|
35097
35141
|
StdioServerTransport = class {
|
|
@@ -35282,8 +35326,8 @@ var init_stdio = __esm({
|
|
|
35282
35326
|
var DEFAULT_MAX_REQUEST_BODY_SIZE;
|
|
35283
35327
|
var init_dist = __esm({
|
|
35284
35328
|
"node_modules/@modelcontextprotocol/server/dist/index.mjs"() {
|
|
35285
|
-
|
|
35286
|
-
|
|
35329
|
+
init_mcp_DIH4cS6P();
|
|
35330
|
+
init_src_Cqbh3MYc();
|
|
35287
35331
|
init_shimsNode();
|
|
35288
35332
|
DEFAULT_MAX_REQUEST_BODY_SIZE = 4 * 1024 * 1024;
|
|
35289
35333
|
}
|
|
@@ -35619,6 +35663,15 @@ ${JSON.stringify(preview, null, 2)}`,
|
|
|
35619
35663
|
};
|
|
35620
35664
|
const response = inputResponse(ctx.mcpReq.inputResponses, requestKey);
|
|
35621
35665
|
const accepted = acceptedContent(ctx.mcpReq.inputResponses, requestKey, confirmationSchema);
|
|
35666
|
+
if (options.elicitation === false) {
|
|
35667
|
+
return textResult({
|
|
35668
|
+
confirmed: false,
|
|
35669
|
+
dispatched: false,
|
|
35670
|
+
action: options.action,
|
|
35671
|
+
reason: "confirmation-unsupported",
|
|
35672
|
+
note: options.unsupportedNote ? `${DISABLED_NOTE}. ${options.unsupportedNote}` : `${DISABLED_NOTE}.`
|
|
35673
|
+
});
|
|
35674
|
+
}
|
|
35622
35675
|
if (response.kind === "missing") {
|
|
35623
35676
|
if (callerAcceptsFormElicitation(ctx) === false) {
|
|
35624
35677
|
return textResult({
|
|
@@ -35649,7 +35702,7 @@ ${JSON.stringify(preview, null, 2)}`,
|
|
|
35649
35702
|
note: "Nothing was changed because the confirmation was declined, cancelled, or left unchecked."
|
|
35650
35703
|
});
|
|
35651
35704
|
}
|
|
35652
|
-
var DEFAULT_REQUEST_KEY, DEFAULT_CONFIRMATION_LABEL, UNSUPPORTED_NOTE, STATE_PREFIX;
|
|
35705
|
+
var DEFAULT_REQUEST_KEY, DEFAULT_CONFIRMATION_LABEL, UNSUPPORTED_NOTE, DISABLED_NOTE, STATE_PREFIX;
|
|
35653
35706
|
var init_confirmation = __esm({
|
|
35654
35707
|
"node_modules/@chrischall/mcp-utils/dist/server/confirmation.js"() {
|
|
35655
35708
|
init_dist();
|
|
@@ -35660,6 +35713,7 @@ var init_confirmation = __esm({
|
|
|
35660
35713
|
DEFAULT_REQUEST_KEY = "confirmation";
|
|
35661
35714
|
DEFAULT_CONFIRMATION_LABEL = "Confirm this action should proceed.";
|
|
35662
35715
|
UNSUPPORTED_NOTE = "Nothing was done because this client cannot show a confirmation prompt (it declares no MCP elicitation capability), and this action is never taken without one";
|
|
35716
|
+
DISABLED_NOTE = "Nothing was done because confirmation prompts are turned off for this server, and this action is never taken without one";
|
|
35663
35717
|
STATE_PREFIX = "mcpu.confirm.v1.";
|
|
35664
35718
|
}
|
|
35665
35719
|
});
|
|
@@ -35813,7 +35867,7 @@ async function tokenConfirmation(action, fb) {
|
|
|
35813
35867
|
}
|
|
35814
35868
|
async function requireConfirmationWithFallback(ctx, options) {
|
|
35815
35869
|
const { tokenFallback, ...confirmation } = options;
|
|
35816
|
-
if (tokenFallback && callerAcceptsFormElicitation(ctx) === false) {
|
|
35870
|
+
if (tokenFallback && (options.elicitation === false || callerAcceptsFormElicitation(ctx) === false)) {
|
|
35817
35871
|
return tokenConfirmation(options.action, tokenFallback);
|
|
35818
35872
|
}
|
|
35819
35873
|
return requireConfirmation(ctx, confirmation);
|
|
@@ -36024,6 +36078,20 @@ function readConfirmMode(env = process.env) {
|
|
|
36024
36078
|
}
|
|
36025
36079
|
return "refuse";
|
|
36026
36080
|
}
|
|
36081
|
+
function readConfirmElicitation(env = process.env) {
|
|
36082
|
+
const raw = readEnvVar("MCP_CONFIRM_ELICITATION", { env })?.trim().toLowerCase();
|
|
36083
|
+
if (!raw || raw === "on")
|
|
36084
|
+
return "on";
|
|
36085
|
+
if (raw === "off")
|
|
36086
|
+
return "off";
|
|
36087
|
+
const key = `elicitation:${raw}`;
|
|
36088
|
+
if (!warned.has(key)) {
|
|
36089
|
+
warned.add(key);
|
|
36090
|
+
process.stderr.write(`MCP_CONFIRM_ELICITATION="${raw}" is not one of on, off; treating it as on.
|
|
36091
|
+
`);
|
|
36092
|
+
}
|
|
36093
|
+
return "on";
|
|
36094
|
+
}
|
|
36027
36095
|
function readConfirmTtl(env) {
|
|
36028
36096
|
const raw = readEnvVar("MCP_CONFIRM_TTL_SECONDS", { env })?.trim();
|
|
36029
36097
|
if (!raw)
|
|
@@ -36076,10 +36144,13 @@ function confirmationFromEnv(options) {
|
|
|
36076
36144
|
const spent = callerSpent ?? spentTokenStoreFromEnv(env);
|
|
36077
36145
|
const mode = readConfirmMode(env);
|
|
36078
36146
|
const ttlSeconds = readConfirmTtl(env);
|
|
36147
|
+
const elicitationOff = readConfirmElicitation(env) === "off";
|
|
36079
36148
|
const bound = args === void 0 ? void 0 : boundArgs(args);
|
|
36080
|
-
const
|
|
36149
|
+
const bindingAdded = bound === void 0 || rest.binding ? rest : { ...rest, binding: { key: confirmKeyFromEnv(env), args: bound, ttlSeconds: ttlSeconds ?? DEFAULT_TTL_SECONDS2 } };
|
|
36150
|
+
const confirmation = elicitationOff ? { ...bindingAdded, elicitation: false } : bindingAdded;
|
|
36081
36151
|
if (mode === "refuse" || ttlSeconds === void 0) {
|
|
36082
|
-
const
|
|
36152
|
+
const reason = mode === "refuse" ? REFUSE_HINT : BAD_TTL_HINT;
|
|
36153
|
+
const hint = elicitationOff ? `${ELICITATION_OFF_HINT} ${reason}` : reason;
|
|
36083
36154
|
return {
|
|
36084
36155
|
...confirmation,
|
|
36085
36156
|
unsupportedNote: confirmation.unsupportedNote ? `${confirmation.unsupportedNote} ${hint}` : hint
|
|
@@ -36105,7 +36176,7 @@ function confirmationFromEnv(options) {
|
|
|
36105
36176
|
}
|
|
36106
36177
|
};
|
|
36107
36178
|
}
|
|
36108
|
-
var MODES, DEFAULT_TTL_SECONDS2, warned, processKey, fileStores, CONFIRM_TOKEN_AUTO_INSTRUCTION, REFUSE_HINT, BAD_TTL_HINT;
|
|
36179
|
+
var MODES, DEFAULT_TTL_SECONDS2, warned, processKey, fileStores, CONFIRM_TOKEN_AUTO_INSTRUCTION, REFUSE_HINT, ELICITATION_OFF_HINT, BAD_TTL_HINT;
|
|
36109
36180
|
var init_confirm_env = __esm({
|
|
36110
36181
|
"node_modules/@chrischall/mcp-utils/dist/server/confirm-env.js"() {
|
|
36111
36182
|
init_config();
|
|
@@ -36117,6 +36188,7 @@ var init_confirm_env = __esm({
|
|
|
36117
36188
|
fileStores = /* @__PURE__ */ new Map();
|
|
36118
36189
|
CONFIRM_TOKEN_AUTO_INSTRUCTION = "Nothing has been done yet. Review this preview; if it is what was intended, call again with the same arguments plus confirmToken. (This server runs with MCP_CONFIRM_MODE=auto, so the user's approval in chat is not required.)";
|
|
36119
36190
|
REFUSE_HINT = "Set MCP_CONFIRM_MODE=ask-user on the server to allow two-step confirmation instead.";
|
|
36191
|
+
ELICITATION_OFF_HINT = "MCP_CONFIRM_ELICITATION=off on the server turns confirmation prompts off.";
|
|
36120
36192
|
BAD_TTL_HINT = "MCP_CONFIRM_TTL_SECONDS on the server is not a positive whole number of seconds; fix it to allow two-step confirmation.";
|
|
36121
36193
|
}
|
|
36122
36194
|
});
|
|
@@ -36276,7 +36348,10 @@ function surfaceToolHints(server) {
|
|
|
36276
36348
|
));
|
|
36277
36349
|
}
|
|
36278
36350
|
async function createMcpServer(opts) {
|
|
36279
|
-
const server = new McpServer({ name: opts.name, version: opts.version }, {
|
|
36351
|
+
const server = new McpServer({ name: opts.name, version: opts.version }, {
|
|
36352
|
+
supportedProtocolVersions: [...SERVER_PROTOCOL_VERSIONS],
|
|
36353
|
+
...opts.maxToolInputElements !== void 0 ? { maxToolInputElements: opts.maxToolInputElements } : {}
|
|
36354
|
+
});
|
|
36280
36355
|
if (opts.surfaceHints !== false)
|
|
36281
36356
|
surfaceToolHints(server);
|
|
36282
36357
|
if (opts.banner !== void 0) {
|
|
@@ -36458,6 +36533,21 @@ var init_fs = __esm({
|
|
|
36458
36533
|
}
|
|
36459
36534
|
});
|
|
36460
36535
|
|
|
36536
|
+
// node_modules/@chrischall/mcp-utils/dist/internal/headers.js
|
|
36537
|
+
function responseHeader(res, name) {
|
|
36538
|
+
return getHeader(res?.headers, name);
|
|
36539
|
+
}
|
|
36540
|
+
function getHeader(headers, name) {
|
|
36541
|
+
if (!headers || typeof headers.get !== "function")
|
|
36542
|
+
return null;
|
|
36543
|
+
const value = headers.get.call(headers, name);
|
|
36544
|
+
return typeof value === "string" ? value : null;
|
|
36545
|
+
}
|
|
36546
|
+
var init_headers = __esm({
|
|
36547
|
+
"node_modules/@chrischall/mcp-utils/dist/internal/headers.js"() {
|
|
36548
|
+
}
|
|
36549
|
+
});
|
|
36550
|
+
|
|
36461
36551
|
// node_modules/@chrischall/mcp-utils/dist/internal/ascii.js
|
|
36462
36552
|
var init_ascii = __esm({
|
|
36463
36553
|
"node_modules/@chrischall/mcp-utils/dist/internal/ascii.js"() {
|
|
@@ -36708,7 +36798,7 @@ function createApiClient(opts) {
|
|
|
36708
36798
|
if (retryStatuses.includes(res.status) && attempt < retry.count) {
|
|
36709
36799
|
discard(current);
|
|
36710
36800
|
attempt += 1;
|
|
36711
|
-
const delay = retry.honorRetryAfter ? parseRetryAfterMs(res
|
|
36801
|
+
const delay = retry.honorRetryAfter ? parseRetryAfterMs(responseHeader(res, "retry-after"), {
|
|
36712
36802
|
defaultMs: retry.delayMs,
|
|
36713
36803
|
capMs: retry.maxRetryAfterMs ?? 3e4
|
|
36714
36804
|
}) : retry.delayMs;
|
|
@@ -36721,7 +36811,7 @@ function createApiClient(opts) {
|
|
|
36721
36811
|
async function unauthorizedOrEdge(attempt, method, path) {
|
|
36722
36812
|
const res = attempt.res;
|
|
36723
36813
|
let text = "";
|
|
36724
|
-
if (/json/i.test(res
|
|
36814
|
+
if (/json/i.test(responseHeader(res, "content-type") ?? "")) {
|
|
36725
36815
|
discard(attempt);
|
|
36726
36816
|
} else {
|
|
36727
36817
|
text = await readBody(attempt, (r) => r.text()).catch(() => "");
|
|
@@ -36733,14 +36823,14 @@ function createApiClient(opts) {
|
|
|
36733
36823
|
}
|
|
36734
36824
|
async function rateLimitedError(attempt, method, path) {
|
|
36735
36825
|
const res = attempt.res;
|
|
36736
|
-
const retryAfter = res
|
|
36826
|
+
const retryAfter = responseHeader(res, "retry-after");
|
|
36737
36827
|
const retryAfterMs = retryAfterToMs(retryAfter);
|
|
36738
36828
|
if (!opts.onRateLimited) {
|
|
36739
36829
|
discard(attempt);
|
|
36740
36830
|
return new RateLimitedError(service, retryAfterMs);
|
|
36741
36831
|
}
|
|
36742
36832
|
let text = "";
|
|
36743
|
-
if (/json/i.test(res
|
|
36833
|
+
if (/json/i.test(responseHeader(res, "content-type") ?? "")) {
|
|
36744
36834
|
discard(attempt);
|
|
36745
36835
|
} else {
|
|
36746
36836
|
text = await readBody(attempt, (r) => r.text()).catch(() => "");
|
|
@@ -36800,7 +36890,7 @@ function createApiClient(opts) {
|
|
|
36800
36890
|
const bytes = new Uint8Array(await readBody(attempt, (r) => r.arrayBuffer()));
|
|
36801
36891
|
return {
|
|
36802
36892
|
status: res.status,
|
|
36803
|
-
contentType: res
|
|
36893
|
+
contentType: responseHeader(res, "content-type"),
|
|
36804
36894
|
headers: res.headers,
|
|
36805
36895
|
bytes
|
|
36806
36896
|
};
|
|
@@ -36860,6 +36950,7 @@ function decodeJwtExp(token) {
|
|
|
36860
36950
|
var DEFAULT_RETRY, defaultSleep, UnauthorizedError, RateLimitedError, RequestTimeoutError, ApiError, EdgeBlockedError, EDGE_BLOCK_SCAN_MAX, EDGE_BLOCK_MARKERS;
|
|
36861
36951
|
var init_http = __esm({
|
|
36862
36952
|
"node_modules/@chrischall/mcp-utils/dist/http/index.js"() {
|
|
36953
|
+
init_headers();
|
|
36863
36954
|
init_cancel();
|
|
36864
36955
|
init_errors3();
|
|
36865
36956
|
init_scrape();
|
|
@@ -37023,6 +37114,7 @@ var init_es256 = __esm({
|
|
|
37023
37114
|
// node_modules/@chrischall/mcp-utils/dist/auth/index.js
|
|
37024
37115
|
var init_auth = __esm({
|
|
37025
37116
|
"node_modules/@chrischall/mcp-utils/dist/auth/index.js"() {
|
|
37117
|
+
init_headers();
|
|
37026
37118
|
init_config();
|
|
37027
37119
|
init_errors3();
|
|
37028
37120
|
init_http();
|
|
@@ -37056,7 +37148,7 @@ var init_version = __esm({
|
|
|
37056
37148
|
"src/version.ts"() {
|
|
37057
37149
|
"use strict";
|
|
37058
37150
|
PACKAGE_NAME = "office-outlook-mcp";
|
|
37059
|
-
VERSION = "0.3.
|
|
37151
|
+
VERSION = "0.3.5";
|
|
37060
37152
|
}
|
|
37061
37153
|
});
|
|
37062
37154
|
|
|
@@ -37308,7 +37400,7 @@ async function transcriptHash(mcpNonce, extNonce, mcpSessionPub, extSessionPub)
|
|
|
37308
37400
|
function frameAad(mcpId, seq, direction) {
|
|
37309
37401
|
return enc.encode(`fetchproxy/4/frame\0${mcpId}\0${seq}\0${direction}`);
|
|
37310
37402
|
}
|
|
37311
|
-
var PROTOCOL_VERSION, HKDF_SESSION_INFO, enc, ANSWERS_NO_EXT_SESSION, KNOWN_CAPABILITIES;
|
|
37403
|
+
var PROTOCOL_VERSION, HKDF_SESSION_INFO, enc, ANSWERS_NO_EXT_SESSION, KNOWN_CAPABILITIES, ACCOUNT_KEY_FRAME, ACCOUNT_ATTEST_FRAME, BRIDGE_ROLE_FRAME, BRIDGE_SERVE_FRAME, ROOM_PING_FRAME, ROOM_PONG_FRAME, BRIDGE_ROLE_LABEL_MAX, ROOM_FRAME_ACCEPTS;
|
|
37312
37404
|
var init_frames = __esm({
|
|
37313
37405
|
"node_modules/@fetchproxy/protocol/dist/frames.js"() {
|
|
37314
37406
|
init_crypto();
|
|
@@ -37332,6 +37424,78 @@ var init_frames = __esm({
|
|
|
37332
37424
|
"graphql",
|
|
37333
37425
|
"write_cookies"
|
|
37334
37426
|
]);
|
|
37427
|
+
ACCOUNT_KEY_FRAME = "account-key";
|
|
37428
|
+
ACCOUNT_ATTEST_FRAME = "account-attest";
|
|
37429
|
+
BRIDGE_ROLE_FRAME = "bridge-role";
|
|
37430
|
+
BRIDGE_SERVE_FRAME = "bridge-serve";
|
|
37431
|
+
ROOM_PING_FRAME = "room-ping";
|
|
37432
|
+
ROOM_PONG_FRAME = "room-pong";
|
|
37433
|
+
BRIDGE_ROLE_LABEL_MAX = 64;
|
|
37434
|
+
ROOM_FRAME_ACCEPTS = Object.freeze({
|
|
37435
|
+
[BRIDGE_ROLE_FRAME]: BRIDGE_ROLE_FRAME,
|
|
37436
|
+
[BRIDGE_SERVE_FRAME]: BRIDGE_SERVE_FRAME,
|
|
37437
|
+
[ROOM_PING_FRAME]: ROOM_PING_FRAME,
|
|
37438
|
+
[ROOM_PONG_FRAME]: ROOM_PING_FRAME
|
|
37439
|
+
});
|
|
37440
|
+
}
|
|
37441
|
+
});
|
|
37442
|
+
|
|
37443
|
+
// node_modules/@fetchproxy/protocol/dist/mcp-id.js
|
|
37444
|
+
function generateMcpId(serverName, version2) {
|
|
37445
|
+
if (serverName.includes(":")) {
|
|
37446
|
+
throw new Error(`serverName cannot contain ':': ${serverName}`);
|
|
37447
|
+
}
|
|
37448
|
+
if (version2.includes(":")) {
|
|
37449
|
+
throw new Error(`version cannot contain ':': ${version2}`);
|
|
37450
|
+
}
|
|
37451
|
+
const rand = randomHex(8);
|
|
37452
|
+
return `${serverName}:${version2}:${rand}`;
|
|
37453
|
+
}
|
|
37454
|
+
function isValidMcpId(id) {
|
|
37455
|
+
return typeof id === "string" && ID_RE.test(id);
|
|
37456
|
+
}
|
|
37457
|
+
function randomHex(bytes) {
|
|
37458
|
+
const arr = new Uint8Array(bytes);
|
|
37459
|
+
globalThis.crypto.getRandomValues(arr);
|
|
37460
|
+
return Array.from(arr, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
37461
|
+
}
|
|
37462
|
+
var ID_RE;
|
|
37463
|
+
var init_mcp_id = __esm({
|
|
37464
|
+
"node_modules/@fetchproxy/protocol/dist/mcp-id.js"() {
|
|
37465
|
+
ID_RE = /^([^:]+):([^:]+):([0-9a-f]{16})$/;
|
|
37466
|
+
}
|
|
37467
|
+
});
|
|
37468
|
+
|
|
37469
|
+
// node_modules/@fetchproxy/protocol/dist/account-attest.js
|
|
37470
|
+
var ACCOUNT_ATTEST_CONSENTS, NO_SCOPE_DIGEST, ACCOUNT_ID_RE, HEX64_RE, ACCOUNT_KID_RE, enc2;
|
|
37471
|
+
var init_account_attest = __esm({
|
|
37472
|
+
"node_modules/@fetchproxy/protocol/dist/account-attest.js"() {
|
|
37473
|
+
init_crypto();
|
|
37474
|
+
init_encoding();
|
|
37475
|
+
init_mcp_id();
|
|
37476
|
+
ACCOUNT_ATTEST_CONSENTS = Object.freeze([
|
|
37477
|
+
"silent",
|
|
37478
|
+
"confirm",
|
|
37479
|
+
"confirm-each"
|
|
37480
|
+
]);
|
|
37481
|
+
NO_SCOPE_DIGEST = "0".repeat(64);
|
|
37482
|
+
ACCOUNT_ID_RE = /^[A-Za-z0-9_.\-]{1,128}$/;
|
|
37483
|
+
HEX64_RE = /^[0-9a-f]{64}$/;
|
|
37484
|
+
ACCOUNT_KID_RE = /^[0-9a-f]{16}$/;
|
|
37485
|
+
enc2 = new TextEncoder();
|
|
37486
|
+
}
|
|
37487
|
+
});
|
|
37488
|
+
|
|
37489
|
+
// node_modules/@fetchproxy/protocol/dist/awaiting-approval.js
|
|
37490
|
+
function parseAwaitingApprovalReason(reason) {
|
|
37491
|
+
if (!reason.startsWith(AWAITING_APPROVAL_REASON_PREFIX))
|
|
37492
|
+
return null;
|
|
37493
|
+
return reason.slice(AWAITING_APPROVAL_REASON_PREFIX.length).trim();
|
|
37494
|
+
}
|
|
37495
|
+
var AWAITING_APPROVAL_REASON_PREFIX;
|
|
37496
|
+
var init_awaiting_approval = __esm({
|
|
37497
|
+
"node_modules/@fetchproxy/protocol/dist/awaiting-approval.js"() {
|
|
37498
|
+
AWAITING_APPROVAL_REASON_PREFIX = "awaiting-approval:";
|
|
37335
37499
|
}
|
|
37336
37500
|
});
|
|
37337
37501
|
|
|
@@ -37364,32 +37528,6 @@ var init_capability_availability = __esm({
|
|
|
37364
37528
|
}
|
|
37365
37529
|
});
|
|
37366
37530
|
|
|
37367
|
-
// node_modules/@fetchproxy/protocol/dist/mcp-id.js
|
|
37368
|
-
function generateMcpId(serverName, version2) {
|
|
37369
|
-
if (serverName.includes(":")) {
|
|
37370
|
-
throw new Error(`serverName cannot contain ':': ${serverName}`);
|
|
37371
|
-
}
|
|
37372
|
-
if (version2.includes(":")) {
|
|
37373
|
-
throw new Error(`version cannot contain ':': ${version2}`);
|
|
37374
|
-
}
|
|
37375
|
-
const rand = randomHex(8);
|
|
37376
|
-
return `${serverName}:${version2}:${rand}`;
|
|
37377
|
-
}
|
|
37378
|
-
function isValidMcpId(id) {
|
|
37379
|
-
return typeof id === "string" && ID_RE.test(id);
|
|
37380
|
-
}
|
|
37381
|
-
function randomHex(bytes) {
|
|
37382
|
-
const arr = new Uint8Array(bytes);
|
|
37383
|
-
globalThis.crypto.getRandomValues(arr);
|
|
37384
|
-
return Array.from(arr, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
37385
|
-
}
|
|
37386
|
-
var ID_RE;
|
|
37387
|
-
var init_mcp_id = __esm({
|
|
37388
|
-
"node_modules/@fetchproxy/protocol/dist/mcp-id.js"() {
|
|
37389
|
-
ID_RE = /^([^:]+):([^:]+):([0-9a-f]{16})$/;
|
|
37390
|
-
}
|
|
37391
|
-
});
|
|
37392
|
-
|
|
37393
37531
|
// node_modules/@fetchproxy/protocol/dist/json-pointer.js
|
|
37394
37532
|
function matchesDeclaredKey(requested, declared) {
|
|
37395
37533
|
for (const decl of declared) {
|
|
@@ -37978,6 +38116,16 @@ function validateFrame(raw) {
|
|
|
37978
38116
|
return { type: "extension-disconnected" };
|
|
37979
38117
|
if (t === "peer-gone")
|
|
37980
38118
|
return validatePeerGone(raw);
|
|
38119
|
+
if (t === ACCOUNT_KEY_FRAME)
|
|
38120
|
+
return validateAccountKey(raw);
|
|
38121
|
+
if (t === ACCOUNT_ATTEST_FRAME)
|
|
38122
|
+
return validateAccountAttest(raw);
|
|
38123
|
+
if (t === BRIDGE_ROLE_FRAME)
|
|
38124
|
+
return validateBridgeRole(raw);
|
|
38125
|
+
if (t === BRIDGE_SERVE_FRAME || t === ROOM_PING_FRAME || t === ROOM_PONG_FRAME) {
|
|
38126
|
+
assertExactFields(raw, TYPE_ONLY_FIELDS, t);
|
|
38127
|
+
return { type: t };
|
|
38128
|
+
}
|
|
37981
38129
|
throw new ProtocolError3(`unknown frame type: ${String(t)}`);
|
|
37982
38130
|
}
|
|
37983
38131
|
function validateHello(raw) {
|
|
@@ -38180,6 +38328,133 @@ function validateHelloRejected(raw) {
|
|
|
38180
38328
|
}
|
|
38181
38329
|
return { type: "hello-rejected", mcpId: raw.mcpId, reason: raw.reason };
|
|
38182
38330
|
}
|
|
38331
|
+
function assertExactFields(raw, allowed, label) {
|
|
38332
|
+
for (const k of Object.keys(raw)) {
|
|
38333
|
+
if (!allowed.includes(k)) {
|
|
38334
|
+
throw new ProtocolError3(`${label}: unexpected field ${JSON.stringify(k)}`);
|
|
38335
|
+
}
|
|
38336
|
+
}
|
|
38337
|
+
}
|
|
38338
|
+
function assertMatch(x, re, label, what) {
|
|
38339
|
+
assertString(x, label);
|
|
38340
|
+
if (!re.test(x))
|
|
38341
|
+
throw new ProtocolError3(`${label}: must be ${what}`);
|
|
38342
|
+
}
|
|
38343
|
+
function assertPositiveSafeInt(x, label) {
|
|
38344
|
+
if (typeof x !== "number" || !Number.isSafeInteger(x) || x <= 0) {
|
|
38345
|
+
throw new ProtocolError3(`${label}: expected positive safe integer`);
|
|
38346
|
+
}
|
|
38347
|
+
}
|
|
38348
|
+
function assertDisplayString(x, label, min, max) {
|
|
38349
|
+
assertString(x, label);
|
|
38350
|
+
if (x.length < min || x.length > max) {
|
|
38351
|
+
throw new ProtocolError3(`${label}: must be ${min}-${max} characters`);
|
|
38352
|
+
}
|
|
38353
|
+
if (DISPLAY_FORBIDDEN_RE.test(x)) {
|
|
38354
|
+
throw new ProtocolError3(`${label}: control or bidi-override character`);
|
|
38355
|
+
}
|
|
38356
|
+
}
|
|
38357
|
+
function validateAccountKey(raw) {
|
|
38358
|
+
const L = "account-key";
|
|
38359
|
+
assertMatch(raw.accountId, ACCOUNT_ID_RE, `${L}.accountId`, "an account id");
|
|
38360
|
+
assertMatch(raw.slug, ACCOUNT_ID_RE, `${L}.slug`, "a slug");
|
|
38361
|
+
assertDisplayString(raw.displayName, `${L}.displayName`, 0, 128);
|
|
38362
|
+
assertDisplayString(raw.confirmedBy, `${L}.confirmedBy`, 1, 256);
|
|
38363
|
+
assertMatch(raw.tokenId, ACCOUNT_ID_RE, `${L}.tokenId`, "a token id");
|
|
38364
|
+
assertMatch(raw.kid, ACCOUNT_KID_RE, `${L}.kid`, "16 lowercase hex");
|
|
38365
|
+
assertBase64Bytes(raw.publicKey, `${L}.publicKey`, 32);
|
|
38366
|
+
assertPositiveSafeInt(raw.generation, `${L}.generation`);
|
|
38367
|
+
const n = raw.bridgedRegistrations;
|
|
38368
|
+
if (typeof n !== "number" || !Number.isSafeInteger(n) || n < 0) {
|
|
38369
|
+
throw new ProtocolError3(`${L}.bridgedRegistrations: expected non-negative safe integer`);
|
|
38370
|
+
}
|
|
38371
|
+
assertExactFields(raw, ACCOUNT_KEY_FIELDS, L);
|
|
38372
|
+
return {
|
|
38373
|
+
type: ACCOUNT_KEY_FRAME,
|
|
38374
|
+
accountId: raw.accountId,
|
|
38375
|
+
slug: raw.slug,
|
|
38376
|
+
displayName: raw.displayName,
|
|
38377
|
+
confirmedBy: raw.confirmedBy,
|
|
38378
|
+
tokenId: raw.tokenId,
|
|
38379
|
+
kid: raw.kid,
|
|
38380
|
+
publicKey: raw.publicKey,
|
|
38381
|
+
generation: raw.generation,
|
|
38382
|
+
bridgedRegistrations: n
|
|
38383
|
+
};
|
|
38384
|
+
}
|
|
38385
|
+
function validateAccountAttest(raw) {
|
|
38386
|
+
const L = "account-attest";
|
|
38387
|
+
if (!isValidMcpId(raw.mcpId))
|
|
38388
|
+
throw new ProtocolError3(`${L}.mcpId: invalid format`);
|
|
38389
|
+
assertMatch(raw.accountId, ACCOUNT_ID_RE, `${L}.accountId`, "an account id");
|
|
38390
|
+
assertPositiveSafeInt(raw.generation, `${L}.generation`);
|
|
38391
|
+
assertMatch(raw.tokenId, ACCOUNT_ID_RE, `${L}.tokenId`, "a token id");
|
|
38392
|
+
assertMatch(raw.kid, ACCOUNT_KID_RE, `${L}.kid`, "16 lowercase hex");
|
|
38393
|
+
assertMatch(raw.registrationId, ACCOUNT_ID_RE, `${L}.registrationId`, "a registration id");
|
|
38394
|
+
assertMatch(raw.slug, ACCOUNT_ID_RE, `${L}.slug`, "a slug");
|
|
38395
|
+
assertMatch(raw.identityHash, HEX64_RE, `${L}.identityHash`, "64 lowercase hex");
|
|
38396
|
+
assertBase64Bytes(raw.identityEd25519Pub, `${L}.identityEd25519Pub`, 32);
|
|
38397
|
+
assertMatch(raw.scopeDigest, HEX64_RE, `${L}.scopeDigest`, "64 lowercase hex");
|
|
38398
|
+
assertString(raw.consent, `${L}.consent`);
|
|
38399
|
+
const consent = raw.consent;
|
|
38400
|
+
const known = ACCOUNT_ATTEST_CONSENTS.find((c) => c === consent);
|
|
38401
|
+
if (known === void 0) {
|
|
38402
|
+
throw new ProtocolError3(`${L}.consent: must be one of ${ACCOUNT_ATTEST_CONSENTS.join(", ")}`);
|
|
38403
|
+
}
|
|
38404
|
+
assertPositiveSafeInt(raw.notAfter, `${L}.notAfter`);
|
|
38405
|
+
assertBase64Bytes(raw.sig, `${L}.sig`, 64);
|
|
38406
|
+
assertExactFields(raw, ACCOUNT_ATTEST_FIELDS, L);
|
|
38407
|
+
return {
|
|
38408
|
+
type: ACCOUNT_ATTEST_FRAME,
|
|
38409
|
+
mcpId: raw.mcpId,
|
|
38410
|
+
accountId: raw.accountId,
|
|
38411
|
+
generation: raw.generation,
|
|
38412
|
+
tokenId: raw.tokenId,
|
|
38413
|
+
kid: raw.kid,
|
|
38414
|
+
registrationId: raw.registrationId,
|
|
38415
|
+
slug: raw.slug,
|
|
38416
|
+
identityHash: raw.identityHash,
|
|
38417
|
+
identityEd25519Pub: raw.identityEd25519Pub,
|
|
38418
|
+
scopeDigest: raw.scopeDigest,
|
|
38419
|
+
consent: known,
|
|
38420
|
+
notAfter: raw.notAfter,
|
|
38421
|
+
sig: raw.sig
|
|
38422
|
+
};
|
|
38423
|
+
}
|
|
38424
|
+
function validateBridgeRole(raw) {
|
|
38425
|
+
const L = BRIDGE_ROLE_FRAME;
|
|
38426
|
+
const role = raw.role;
|
|
38427
|
+
if (role !== "serving" && role !== "standby") {
|
|
38428
|
+
throw new ProtocolError3(`${L}.role: must be one of serving, standby`);
|
|
38429
|
+
}
|
|
38430
|
+
const canServe = raw.canServe;
|
|
38431
|
+
assertBoolean(canServe, `${L}.canServe`);
|
|
38432
|
+
assertExactFields(raw, BRIDGE_ROLE_FIELDS, L);
|
|
38433
|
+
const serving = raw.serving;
|
|
38434
|
+
if (role === "serving") {
|
|
38435
|
+
if (serving !== void 0) {
|
|
38436
|
+
throw new ProtocolError3(`${L}.serving: must be absent when role is serving`);
|
|
38437
|
+
}
|
|
38438
|
+
return { type: BRIDGE_ROLE_FRAME, role, canServe };
|
|
38439
|
+
}
|
|
38440
|
+
if (serving === void 0) {
|
|
38441
|
+
throw new ProtocolError3(`${L}.serving: required when role is standby`);
|
|
38442
|
+
}
|
|
38443
|
+
assertObject(serving, `${L}.serving`);
|
|
38444
|
+
const label = serving.label;
|
|
38445
|
+
assertDisplayString(label, `${L}.serving.label`, 1, BRIDGE_ROLE_LABEL_MAX);
|
|
38446
|
+
const since = serving.since;
|
|
38447
|
+
if (typeof since !== "number" || !Number.isSafeInteger(since) || since < 0) {
|
|
38448
|
+
throw new ProtocolError3(`${L}.serving.since: expected non-negative safe integer (Unix ms)`);
|
|
38449
|
+
}
|
|
38450
|
+
assertExactFields(serving, BRIDGE_ROLE_SERVING_FIELDS, `${L}.serving`);
|
|
38451
|
+
return {
|
|
38452
|
+
type: BRIDGE_ROLE_FRAME,
|
|
38453
|
+
role,
|
|
38454
|
+
canServe,
|
|
38455
|
+
serving: { label, since }
|
|
38456
|
+
};
|
|
38457
|
+
}
|
|
38183
38458
|
function validateInnerFrame(raw) {
|
|
38184
38459
|
assertObject(raw, "inner");
|
|
38185
38460
|
const t = raw.type;
|
|
@@ -38641,12 +38916,13 @@ function validateInnerResponse(raw) {
|
|
|
38641
38916
|
}
|
|
38642
38917
|
throw new ProtocolError3(`inner.ok: must be boolean, got ${typeof raw.ok}`);
|
|
38643
38918
|
}
|
|
38644
|
-
var ProtocolError3, FORBIDDEN_KEYS, BASE64_RE, SCOPE_KEY_RE, SCOPE_KEY_GLOB_RE, HEADER_NAME_RE, HOSTNAME_RE, CAPTURE_PATH_RE, DOM_SELECTOR_RE, DOM_ATTRIBUTE_RE, GRAPHQL_OP_NAME_RE, PAIR_CODE_RE, KNOWN_RESPONSE_OPS;
|
|
38919
|
+
var ProtocolError3, FORBIDDEN_KEYS, BASE64_RE, SCOPE_KEY_RE, SCOPE_KEY_GLOB_RE, HEADER_NAME_RE, HOSTNAME_RE, CAPTURE_PATH_RE, DOM_SELECTOR_RE, DOM_ATTRIBUTE_RE, GRAPHQL_OP_NAME_RE, PAIR_CODE_RE, DISPLAY_FORBIDDEN_RE, ACCOUNT_KEY_FIELDS, ACCOUNT_ATTEST_FIELDS, TYPE_ONLY_FIELDS, BRIDGE_ROLE_FIELDS, BRIDGE_ROLE_SERVING_FIELDS, KNOWN_RESPONSE_OPS;
|
|
38645
38920
|
var init_validate = __esm({
|
|
38646
38921
|
"node_modules/@fetchproxy/protocol/dist/validate.js"() {
|
|
38647
38922
|
init_frames();
|
|
38648
38923
|
init_capability_availability();
|
|
38649
38924
|
init_mcp_id();
|
|
38925
|
+
init_account_attest();
|
|
38650
38926
|
init_json_pointer();
|
|
38651
38927
|
init_public_suffix();
|
|
38652
38928
|
ProtocolError3 = class extends Error {
|
|
@@ -38666,6 +38942,38 @@ var init_validate = __esm({
|
|
|
38666
38942
|
DOM_ATTRIBUTE_RE = /^[A-Za-z_:][A-Za-z0-9_:.\-]{0,127}$/;
|
|
38667
38943
|
GRAPHQL_OP_NAME_RE = /^[_A-Za-z][_0-9A-Za-z]{0,127}$/;
|
|
38668
38944
|
PAIR_CODE_RE = /^\d{4}-\d{4}$/;
|
|
38945
|
+
DISPLAY_FORBIDDEN_RE = /[\u0000-\u001f\u007f-\u009f\u200e\u200f\u202a-\u202e\u2066-\u2069]/;
|
|
38946
|
+
ACCOUNT_KEY_FIELDS = [
|
|
38947
|
+
"type",
|
|
38948
|
+
"accountId",
|
|
38949
|
+
"slug",
|
|
38950
|
+
"displayName",
|
|
38951
|
+
"confirmedBy",
|
|
38952
|
+
"tokenId",
|
|
38953
|
+
"kid",
|
|
38954
|
+
"publicKey",
|
|
38955
|
+
"generation",
|
|
38956
|
+
"bridgedRegistrations"
|
|
38957
|
+
];
|
|
38958
|
+
ACCOUNT_ATTEST_FIELDS = [
|
|
38959
|
+
"type",
|
|
38960
|
+
"mcpId",
|
|
38961
|
+
"accountId",
|
|
38962
|
+
"generation",
|
|
38963
|
+
"tokenId",
|
|
38964
|
+
"kid",
|
|
38965
|
+
"registrationId",
|
|
38966
|
+
"slug",
|
|
38967
|
+
"identityHash",
|
|
38968
|
+
"identityEd25519Pub",
|
|
38969
|
+
"scopeDigest",
|
|
38970
|
+
"consent",
|
|
38971
|
+
"notAfter",
|
|
38972
|
+
"sig"
|
|
38973
|
+
];
|
|
38974
|
+
TYPE_ONLY_FIELDS = ["type"];
|
|
38975
|
+
BRIDGE_ROLE_FIELDS = ["type", "role", "canServe", "serving"];
|
|
38976
|
+
BRIDGE_ROLE_SERVING_FIELDS = ["label", "since"];
|
|
38669
38977
|
KNOWN_RESPONSE_OPS = /* @__PURE__ */ new Set([
|
|
38670
38978
|
...KNOWN_CAPABILITIES,
|
|
38671
38979
|
"graphql_query"
|
|
@@ -38673,9 +38981,17 @@ var init_validate = __esm({
|
|
|
38673
38981
|
}
|
|
38674
38982
|
});
|
|
38675
38983
|
|
|
38984
|
+
// node_modules/@fetchproxy/protocol/dist/room-frames.js
|
|
38985
|
+
var init_room_frames = __esm({
|
|
38986
|
+
"node_modules/@fetchproxy/protocol/dist/room-frames.js"() {
|
|
38987
|
+
init_frames();
|
|
38988
|
+
init_validate();
|
|
38989
|
+
}
|
|
38990
|
+
});
|
|
38991
|
+
|
|
38676
38992
|
// node_modules/@fetchproxy/protocol/dist/pair-code.js
|
|
38677
38993
|
async function pairTranscript(mcpIdentityPub, extIdentityPub, mcpNonce, extNonce, mcpSessionPub) {
|
|
38678
|
-
const label =
|
|
38994
|
+
const label = enc3.encode(PAIR_LABEL);
|
|
38679
38995
|
const parts = [mcpIdentityPub, extIdentityPub, mcpNonce, extNonce, mcpSessionPub];
|
|
38680
38996
|
const out = new Uint8Array(label.length + 1 + parts.reduce((n, p) => n + p.length, 0));
|
|
38681
38997
|
out.set(label, 0);
|
|
@@ -38694,11 +39010,11 @@ function digits(hash2) {
|
|
|
38694
39010
|
const s = (n % 100000000n).toString().padStart(8, "0");
|
|
38695
39011
|
return `${s.slice(0, 4)}-${s.slice(4)}`;
|
|
38696
39012
|
}
|
|
38697
|
-
var
|
|
39013
|
+
var enc3, PAIR_LABEL;
|
|
38698
39014
|
var init_pair_code = __esm({
|
|
38699
39015
|
"node_modules/@fetchproxy/protocol/dist/pair-code.js"() {
|
|
38700
39016
|
init_crypto();
|
|
38701
|
-
|
|
39017
|
+
enc3 = new TextEncoder();
|
|
38702
39018
|
PAIR_LABEL = "fetchproxy/4/pair";
|
|
38703
39019
|
}
|
|
38704
39020
|
});
|
|
@@ -38713,14 +39029,14 @@ function base64Length(byteLength) {
|
|
|
38713
39029
|
return Math.ceil(byteLength / 3) * 4;
|
|
38714
39030
|
}
|
|
38715
39031
|
function encodeInnerFrame(inner) {
|
|
38716
|
-
return
|
|
39032
|
+
return enc4.encode(JSON.stringify(inner));
|
|
38717
39033
|
}
|
|
38718
39034
|
function plaintextOf(inner) {
|
|
38719
39035
|
return inner instanceof Uint8Array ? inner : encodeInnerFrame(inner);
|
|
38720
39036
|
}
|
|
38721
39037
|
function sealedFrameWireBytes(mcpId, seq, inner) {
|
|
38722
39038
|
const plaintext = plaintextOf(inner).length;
|
|
38723
|
-
const envelope =
|
|
39039
|
+
const envelope = enc4.encode(JSON.stringify({ type: "frame", mcpId, seq, iv: "", ciphertext: "" })).length;
|
|
38724
39040
|
return envelope + IV_B64_BYTES + base64Length(plaintext + AES_GCM_TAG_BYTES);
|
|
38725
39041
|
}
|
|
38726
39042
|
async function sealInnerFrame(sessionKey, mcpId, seq, inner, direction) {
|
|
@@ -38758,14 +39074,14 @@ async function openEncryptedFrameDetailed(sessionKey, frame, direction) {
|
|
|
38758
39074
|
return { stage: "validation-failed", error: error62, recoveredId };
|
|
38759
39075
|
}
|
|
38760
39076
|
}
|
|
38761
|
-
var
|
|
39077
|
+
var enc4, dec, AES_GCM_TAG_BYTES, IV_B64_BYTES, MAX_FRAME_BYTES;
|
|
38762
39078
|
var init_seal = __esm({
|
|
38763
39079
|
"node_modules/@fetchproxy/protocol/dist/seal.js"() {
|
|
38764
39080
|
init_crypto();
|
|
38765
39081
|
init_encoding();
|
|
38766
39082
|
init_frames();
|
|
38767
39083
|
init_validate();
|
|
38768
|
-
|
|
39084
|
+
enc4 = new TextEncoder();
|
|
38769
39085
|
dec = new TextDecoder();
|
|
38770
39086
|
AES_GCM_TAG_BYTES = 16;
|
|
38771
39087
|
IV_B64_BYTES = 16;
|
|
@@ -38777,8 +39093,11 @@ var init_seal = __esm({
|
|
|
38777
39093
|
var init_dist3 = __esm({
|
|
38778
39094
|
"node_modules/@fetchproxy/protocol/dist/index.js"() {
|
|
38779
39095
|
init_frames();
|
|
39096
|
+
init_account_attest();
|
|
39097
|
+
init_awaiting_approval();
|
|
38780
39098
|
init_capability_availability();
|
|
38781
39099
|
init_validate();
|
|
39100
|
+
init_room_frames();
|
|
38782
39101
|
init_crypto();
|
|
38783
39102
|
init_mcp_id();
|
|
38784
39103
|
init_pair_code();
|
|
@@ -41177,11 +41496,23 @@ var require_websocket = __commonJS({
|
|
|
41177
41496
|
this._isServer = false;
|
|
41178
41497
|
this._redirects = 0;
|
|
41179
41498
|
if (protocols === void 0) {
|
|
41180
|
-
protocols
|
|
41499
|
+
if (!options || options.protocols === void 0) {
|
|
41500
|
+
protocols = [];
|
|
41501
|
+
} else if (Array.isArray(options.protocols)) {
|
|
41502
|
+
protocols = options.protocols;
|
|
41503
|
+
} else {
|
|
41504
|
+
protocols = [options.protocols];
|
|
41505
|
+
}
|
|
41181
41506
|
} else if (!Array.isArray(protocols)) {
|
|
41182
41507
|
if (typeof protocols === "object" && protocols !== null) {
|
|
41183
41508
|
options = protocols;
|
|
41184
|
-
protocols
|
|
41509
|
+
if (options.protocols === void 0) {
|
|
41510
|
+
protocols = [];
|
|
41511
|
+
} else if (Array.isArray(options.protocols)) {
|
|
41512
|
+
protocols = options.protocols;
|
|
41513
|
+
} else {
|
|
41514
|
+
protocols = [options.protocols];
|
|
41515
|
+
}
|
|
41185
41516
|
} else {
|
|
41186
41517
|
protocols = [protocols];
|
|
41187
41518
|
}
|
|
@@ -41378,7 +41709,6 @@ var require_websocket = __commonJS({
|
|
|
41378
41709
|
}
|
|
41379
41710
|
return;
|
|
41380
41711
|
}
|
|
41381
|
-
this._readyState = _WebSocket.CLOSING;
|
|
41382
41712
|
this._sender.close(code2, data, !this._isServer, (err) => {
|
|
41383
41713
|
if (err) return;
|
|
41384
41714
|
this._closeFrameSent = true;
|
|
@@ -41386,6 +41716,7 @@ var require_websocket = __commonJS({
|
|
|
41386
41716
|
this._socket.end();
|
|
41387
41717
|
}
|
|
41388
41718
|
});
|
|
41719
|
+
this._readyState = _WebSocket.CLOSING;
|
|
41389
41720
|
setCloseTimer(this);
|
|
41390
41721
|
}
|
|
41391
41722
|
/**
|
|
@@ -41610,6 +41941,7 @@ var require_websocket = __commonJS({
|
|
|
41610
41941
|
socketPath: void 0,
|
|
41611
41942
|
hostname: void 0,
|
|
41612
41943
|
protocol: void 0,
|
|
41944
|
+
protocols: void 0,
|
|
41613
41945
|
timeout: void 0,
|
|
41614
41946
|
method: "GET",
|
|
41615
41947
|
host: void 0,
|
|
@@ -42815,14 +43147,23 @@ var init_session_ready = __esm({
|
|
|
42815
43147
|
platform;
|
|
42816
43148
|
/**
|
|
42817
43149
|
* #418: the remedy, when the reason is one this package knows how to
|
|
42818
|
-
* explain —
|
|
42819
|
-
*
|
|
43150
|
+
* explain — `unsupported-capability`, which blames the browser rather than
|
|
43151
|
+
* the MCP, and (D12) `awaiting-approval`, which says to approve in the
|
|
43152
|
+
* browser. `null` otherwise.
|
|
42820
43153
|
*/
|
|
42821
43154
|
hint;
|
|
43155
|
+
/**
|
|
43156
|
+
* D12: `true` only for an `awaiting-approval:` refusal — the extension has
|
|
43157
|
+
* queued an approval card and nobody is at the browser yet, so the same call
|
|
43158
|
+
* succeeds once the person approves. Every other refusal is the extension's
|
|
43159
|
+
* final answer, and retrying unchanged is refused the same way.
|
|
43160
|
+
*/
|
|
43161
|
+
retryable;
|
|
42822
43162
|
constructor(info) {
|
|
42823
43163
|
const unavailable = parseUnsupportedCapabilityReason(info.reason);
|
|
43164
|
+
const awaiting = parseAwaitingApprovalReason(info.reason);
|
|
42824
43165
|
const platform = info.platform ?? null;
|
|
42825
|
-
const hint = unavailable !== null ? `${platform ? `this browser (${platform})` : "this browser"} cannot serve any of the capabilities this MCP needs (${unavailable.join(", ")}) \u2014 ContextMint Bridge checked for the browser APIs and they are missing. Nothing is wrong with the MCP or your pairing, and updating will not change it: use this MCP from a browser that provides them (for example Chrome).` : null;
|
|
43166
|
+
const hint = awaiting !== null ? `The extension is waiting for you to approve this MCP` + (awaiting !== "" ? ` (${awaiting})` : "") + ` \u2014 open ContextMint Bridge in your browser, approve it there, then retry. Nothing is wrong with the MCP or your sign-in.` : unavailable !== null ? `${platform ? `this browser (${platform})` : "this browser"} cannot serve any of the capabilities this MCP needs (${unavailable.join(", ")}) \u2014 ContextMint Bridge checked for the browser APIs and they are missing. Nothing is wrong with the MCP or your pairing, and updating will not change it: use this MCP from a browser that provides them (for example Chrome).` : null;
|
|
42826
43167
|
super(`fetchproxy: the extension refused the connection for "${info.mcpId}": ${info.reason}. ` + (hint !== null ? hint : `This is the extension's own reason \u2014 it is not a timeout, and retrying unchanged will be refused the same way.`));
|
|
42827
43168
|
this.name = "FetchproxyHelloRejectedError";
|
|
42828
43169
|
this.mcpId = info.mcpId;
|
|
@@ -42830,6 +43171,7 @@ var init_session_ready = __esm({
|
|
|
42830
43171
|
this.unavailableCapabilities = unavailable ?? [];
|
|
42831
43172
|
this.platform = platform;
|
|
42832
43173
|
this.hint = hint;
|
|
43174
|
+
this.retryable = awaiting !== null;
|
|
42833
43175
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
42834
43176
|
}
|
|
42835
43177
|
};
|
|
@@ -43442,10 +43784,20 @@ async function startHost(opts) {
|
|
|
43442
43784
|
let resolveOwnSession;
|
|
43443
43785
|
let rejectOwnSession;
|
|
43444
43786
|
let ownSessionReady;
|
|
43787
|
+
let ownRetryableRefusal = false;
|
|
43788
|
+
let ownSessionSettled = false;
|
|
43445
43789
|
function resetSessionPromise() {
|
|
43790
|
+
ownRetryableRefusal = false;
|
|
43791
|
+
ownSessionSettled = false;
|
|
43446
43792
|
ownSessionReady = new Promise((resolve2, reject) => {
|
|
43447
|
-
resolveOwnSession =
|
|
43448
|
-
|
|
43793
|
+
resolveOwnSession = (st) => {
|
|
43794
|
+
ownSessionSettled = true;
|
|
43795
|
+
resolve2(st);
|
|
43796
|
+
};
|
|
43797
|
+
rejectOwnSession = (e) => {
|
|
43798
|
+
ownSessionSettled = true;
|
|
43799
|
+
reject(e);
|
|
43800
|
+
};
|
|
43449
43801
|
});
|
|
43450
43802
|
ownSessionReady.catch(() => {
|
|
43451
43803
|
});
|
|
@@ -43712,13 +44064,15 @@ async function startHost(opts) {
|
|
|
43712
44064
|
const extPub = fromB64(frame.extensionSessionPub);
|
|
43713
44065
|
const shared = await ecdhX25519(held.priv, extPub);
|
|
43714
44066
|
const salt = await transcriptHash(held.nonce, extNonce, held.pub, extPub);
|
|
43715
|
-
const key = await hkdfSha256(shared, salt,
|
|
44067
|
+
const key = await hkdfSha256(shared, salt, enc5.encode(HKDF_SESSION_INFO), 32);
|
|
43716
44068
|
if (extensionWs !== ws)
|
|
43717
44069
|
return;
|
|
43718
44070
|
ownSession = new SessionState(key);
|
|
43719
44071
|
ownSessionInfo = sessionInfoFromHello(verifiedHello);
|
|
43720
44072
|
ownDecryptFailures = 0;
|
|
43721
44073
|
ownPendingPairCode = null;
|
|
44074
|
+
if (ownRetryableRefusal)
|
|
44075
|
+
resetSessionPromise();
|
|
43722
44076
|
resolveOwnSession(ownSession);
|
|
43723
44077
|
} else {
|
|
43724
44078
|
const slot = peers.get(frame.mcpId);
|
|
@@ -43787,11 +44141,17 @@ async function startHost(opts) {
|
|
|
43787
44141
|
}
|
|
43788
44142
|
if (frame.type === "hello-rejected" && identified === "extension") {
|
|
43789
44143
|
if (frame.mcpId === opts.ownMcpId) {
|
|
43790
|
-
|
|
44144
|
+
const refusal = new FetchproxyHelloRejectedError({
|
|
43791
44145
|
mcpId: frame.mcpId,
|
|
43792
44146
|
reason: frame.reason,
|
|
43793
44147
|
platform: extensionHello?.platform ?? null
|
|
43794
|
-
})
|
|
44148
|
+
});
|
|
44149
|
+
if (ownRetryableRefusal)
|
|
44150
|
+
resetSessionPromise();
|
|
44151
|
+
const settlesPending = !ownSessionSettled;
|
|
44152
|
+
rejectOwnSession(refusal);
|
|
44153
|
+
if (refusal.retryable && settlesPending)
|
|
44154
|
+
ownRetryableRefusal = true;
|
|
43795
44155
|
} else {
|
|
43796
44156
|
const slot = peers.get(frame.mcpId);
|
|
43797
44157
|
if (slot?.helloFrame.accepts?.includes("hello-rejected")) {
|
|
@@ -43904,7 +44264,7 @@ async function startHost(opts) {
|
|
|
43904
44264
|
sessionInfo: () => ownSession !== null ? ownSessionInfo : null
|
|
43905
44265
|
};
|
|
43906
44266
|
}
|
|
43907
|
-
var HTTP_ORIGIN_RE, PUBLIC_ORIGIN_RE, EXTENSION_ORIGIN_RE, OPAQUE_ORIGIN, ALLOW_LOCAL_ORIGINS_ENV, HANDSHAKE_TIMEOUT_MS, MAX_PAYLOAD_BYTES,
|
|
44267
|
+
var HTTP_ORIGIN_RE, PUBLIC_ORIGIN_RE, EXTENSION_ORIGIN_RE, OPAQUE_ORIGIN, ALLOW_LOCAL_ORIGINS_ENV, HANDSHAKE_TIMEOUT_MS, MAX_PAYLOAD_BYTES, enc5, OWN_DECRYPT_FAILURES_BEFORE_REHANDSHAKE;
|
|
43908
44268
|
var init_host = __esm({
|
|
43909
44269
|
"node_modules/@fetchproxy/server/dist/host.js"() {
|
|
43910
44270
|
init_wrapper();
|
|
@@ -43923,7 +44283,7 @@ var init_host = __esm({
|
|
|
43923
44283
|
ALLOW_LOCAL_ORIGINS_ENV = "FETCHPROXY_ALLOW_LOCAL_ORIGINS";
|
|
43924
44284
|
HANDSHAKE_TIMEOUT_MS = 15e3;
|
|
43925
44285
|
MAX_PAYLOAD_BYTES = MAX_FRAME_BYTES;
|
|
43926
|
-
|
|
44286
|
+
enc5 = new TextEncoder();
|
|
43927
44287
|
OWN_DECRYPT_FAILURES_BEFORE_REHANDSHAKE = 3;
|
|
43928
44288
|
}
|
|
43929
44289
|
});
|
|
@@ -44028,7 +44388,9 @@ async function startPeer(opts) {
|
|
|
44028
44388
|
let rejectFirstReady;
|
|
44029
44389
|
let sessionPromise;
|
|
44030
44390
|
let sessionPromiseSettled = false;
|
|
44391
|
+
let retryableRefusal = false;
|
|
44031
44392
|
function resetSessionPromise() {
|
|
44393
|
+
retryableRefusal = false;
|
|
44032
44394
|
sessionPromiseSettled = false;
|
|
44033
44395
|
sessionPromise = new Promise((resolve2, reject) => {
|
|
44034
44396
|
resolveFirstReady = (st) => {
|
|
@@ -44125,6 +44487,8 @@ async function startPeer(opts) {
|
|
|
44125
44487
|
raw = JSON.parse(data.toString());
|
|
44126
44488
|
const frame = validateFrame(raw);
|
|
44127
44489
|
if (frame.type === "hello" && frame.role === "extension") {
|
|
44490
|
+
if (retryableRefusal)
|
|
44491
|
+
resetSessionPromise();
|
|
44128
44492
|
extensionHello = frame;
|
|
44129
44493
|
const mintedKeypair = await generateSessionKeypair();
|
|
44130
44494
|
const mintedHello = await buildServerHello({
|
|
@@ -44154,6 +44518,8 @@ async function startPeer(opts) {
|
|
|
44154
44518
|
session = null;
|
|
44155
44519
|
if (sessionPromiseSettled)
|
|
44156
44520
|
resetSessionPromise();
|
|
44521
|
+
} else if (retryableRefusal) {
|
|
44522
|
+
resetSessionPromise();
|
|
44157
44523
|
}
|
|
44158
44524
|
extensionDisconnectListeners.forEach((cb) => cb());
|
|
44159
44525
|
return;
|
|
@@ -44175,7 +44541,7 @@ async function startPeer(opts) {
|
|
|
44175
44541
|
const extNonce = fromB64(authenticated.sessionNonce);
|
|
44176
44542
|
const shared = await ecdhX25519(held.priv, extPub);
|
|
44177
44543
|
const salt = await transcriptHash(held.nonce, extNonce, held.pub, extPub);
|
|
44178
|
-
const sessionKey = await hkdfSha256(shared, salt,
|
|
44544
|
+
const sessionKey = await hkdfSha256(shared, salt, enc6.encode(HKDF_SESSION_INFO), 32);
|
|
44179
44545
|
if (sessionEphemeral !== held) {
|
|
44180
44546
|
console.warn(`[fetchproxy] ${opts.serverName}: dropping a session derived against an ephemeral that was superseded while it was being derived`);
|
|
44181
44547
|
return;
|
|
@@ -44188,16 +44554,24 @@ async function startPeer(opts) {
|
|
|
44188
44554
|
if (isRenegotiation) {
|
|
44189
44555
|
renegotiateListeners.forEach((cb) => cb());
|
|
44190
44556
|
} else {
|
|
44557
|
+
if (retryableRefusal)
|
|
44558
|
+
resetSessionPromise();
|
|
44191
44559
|
resolveFirstReady(session);
|
|
44192
44560
|
}
|
|
44193
44561
|
return;
|
|
44194
44562
|
}
|
|
44195
44563
|
if (frame.type === "hello-rejected" && frame.mcpId === opts.mcpId) {
|
|
44196
|
-
|
|
44564
|
+
const refusal = new FetchproxyHelloRejectedError({
|
|
44197
44565
|
mcpId: frame.mcpId,
|
|
44198
44566
|
reason: frame.reason,
|
|
44199
44567
|
platform: extensionHello?.platform ?? null
|
|
44200
|
-
})
|
|
44568
|
+
});
|
|
44569
|
+
if (retryableRefusal)
|
|
44570
|
+
resetSessionPromise();
|
|
44571
|
+
const settlesPending = !sessionPromiseSettled;
|
|
44572
|
+
rejectFirstReady(refusal);
|
|
44573
|
+
if (refusal.retryable && settlesPending)
|
|
44574
|
+
retryableRefusal = true;
|
|
44201
44575
|
}
|
|
44202
44576
|
if (frame.type === "pair-pending" && frame.mcpId === opts.mcpId) {
|
|
44203
44577
|
const hello2 = extensionHello;
|
|
@@ -44327,7 +44701,7 @@ async function startPeer(opts) {
|
|
|
44327
44701
|
};
|
|
44328
44702
|
return handle;
|
|
44329
44703
|
}
|
|
44330
|
-
var PEER_DIAL_TIMEOUT_MS,
|
|
44704
|
+
var PEER_DIAL_TIMEOUT_MS, enc6;
|
|
44331
44705
|
var init_peer = __esm({
|
|
44332
44706
|
"node_modules/@fetchproxy/server/dist/peer.js"() {
|
|
44333
44707
|
init_wrapper();
|
|
@@ -44341,7 +44715,7 @@ var init_peer = __esm({
|
|
|
44341
44715
|
init_extension_trust();
|
|
44342
44716
|
init_extension_pins();
|
|
44343
44717
|
PEER_DIAL_TIMEOUT_MS = 5e3;
|
|
44344
|
-
|
|
44718
|
+
enc6 = new TextEncoder();
|
|
44345
44719
|
}
|
|
44346
44720
|
});
|
|
44347
44721
|
|
|
@@ -44383,8 +44757,9 @@ var init_error_kind = __esm({
|
|
|
44383
44757
|
|
|
44384
44758
|
// node_modules/@fetchproxy/server/dist/classify-bridge-error.js
|
|
44385
44759
|
function classifyBridgeError(err) {
|
|
44386
|
-
if (err instanceof FetchproxyHelloRejectedError)
|
|
44387
|
-
return "hello_rejected";
|
|
44760
|
+
if (err instanceof FetchproxyHelloRejectedError) {
|
|
44761
|
+
return err.retryable ? "awaiting_approval" : "hello_rejected";
|
|
44762
|
+
}
|
|
44388
44763
|
if (err instanceof FetchproxySessionNotReadyError)
|
|
44389
44764
|
return "session_not_ready";
|
|
44390
44765
|
if (err instanceof FetchproxyTimeoutError)
|
|
@@ -48796,7 +49171,7 @@ await runMcp({
|
|
|
48796
49171
|
});
|
|
48797
49172
|
/*! Bundled license information:
|
|
48798
49173
|
|
|
48799
|
-
@modelcontextprotocol/server/dist/src-
|
|
49174
|
+
@modelcontextprotocol/server/dist/src-Cqbh3MYc.mjs:
|
|
48800
49175
|
(*!
|
|
48801
49176
|
* content-type
|
|
48802
49177
|
* Copyright(c) 2015 Douglas Christopher Wilson
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chrischall/office-outlook-mcp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"mcpName": "io.github.chrischall/office-outlook-mcp",
|
|
5
5
|
"description": "Outlook / Microsoft 365 MCP server for Claude — developed and maintained by AI (Claude Code)",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
|
@@ -45,14 +45,14 @@
|
|
|
45
45
|
"typecheck": "tsc -p tsconfig.check.json"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@chrischall/mcp-utils": "^2.
|
|
49
|
-
"@fetchproxy/server": "^3.
|
|
50
|
-
"@modelcontextprotocol/server": "^2.
|
|
48
|
+
"@chrischall/mcp-utils": "^2.15.0",
|
|
49
|
+
"@fetchproxy/server": "^3.6.0",
|
|
50
|
+
"@modelcontextprotocol/server": "^2.3.0",
|
|
51
51
|
"dotenv": "^18.0.1",
|
|
52
52
|
"zod": "^4.6.5"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@modelcontextprotocol/client": "^2.
|
|
55
|
+
"@modelcontextprotocol/client": "^2.3.0",
|
|
56
56
|
"@types/node": "^26.0.0",
|
|
57
57
|
"@vitest/coverage-v8": "^5.0.0",
|
|
58
58
|
"esbuild": "^0.28.1",
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/chrischall/office-outlook-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.5",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@chrischall/office-outlook-mcp",
|
|
14
|
-
"version": "0.3.
|
|
14
|
+
"version": "0.3.5",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|