@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.
@@ -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.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.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.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. An unrecognised value is treated as `refuse`. |
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 enc6 = params?.enc ?? "hex";
17825
- const format = `${alg}_${enc6}`;
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-BHSMhZ_W.mjs
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 init_src_BHSMhZ_W = __esm({
24273
- "node_modules/@modelcontextprotocol/server/dist/src-BHSMhZ_W.mjs"() {
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-DYuW2ZSs.mjs
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 init_mcp_DYuW2ZSs = __esm({
33366
- "node_modules/@modelcontextprotocol/server/dist/mcp-DYuW2ZSs.mjs"() {
33367
- init_src_BHSMhZ_W();
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 `SubscriptionsListenResultMeta` extends
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 ? standardSchemaToJsonSchema(tool.inputSchema, "input") : EMPTY_OBJECT_JSON_SCHEMA,
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: convertOutputSchemaJson(outputSchema),
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
- init_mcp_DYuW2ZSs();
35094
- init_src_BHSMhZ_W();
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
- init_mcp_DYuW2ZSs();
35286
- init_src_BHSMhZ_W();
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 confirmation = bound === void 0 || rest.binding ? rest : { ...rest, binding: { key: confirmKeyFromEnv(env), args: bound, ttlSeconds: ttlSeconds ?? DEFAULT_TTL_SECONDS2 } };
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 hint = mode === "refuse" ? REFUSE_HINT : BAD_TTL_HINT;
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 }, { supportedProtocolVersions: [...SERVER_PROTOCOL_VERSIONS] });
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.headers.get("retry-after"), {
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.headers.get("content-type") ?? "")) {
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.headers.get("retry-after");
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.headers.get("content-type") ?? "")) {
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.headers.get("content-type"),
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.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 = enc2.encode(PAIR_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 enc2, PAIR_LABEL;
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
- enc2 = new TextEncoder();
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 enc3.encode(JSON.stringify(inner));
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 = enc3.encode(JSON.stringify({ type: "frame", mcpId, seq, iv: "", ciphertext: "" })).length;
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 enc3, dec, AES_GCM_TAG_BYTES, IV_B64_BYTES, MAX_FRAME_BYTES;
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
- enc3 = new TextEncoder();
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 — today only `unsupported-capability`, which blames the browser
42819
- * rather than the MCP. `null` otherwise.
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 = resolve2;
43448
- rejectOwnSession = reject;
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, enc4.encode(HKDF_SESSION_INFO), 32);
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
- rejectOwnSession(new FetchproxyHelloRejectedError({
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, enc4, OWN_DECRYPT_FAILURES_BEFORE_REHANDSHAKE;
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
- enc4 = new TextEncoder();
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, enc5.encode(HKDF_SESSION_INFO), 32);
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
- rejectFirstReady(new FetchproxyHelloRejectedError({
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, enc5;
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
- enc5 = new TextEncoder();
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-BHSMhZ_W.mjs:
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
@@ -10,4 +10,4 @@
10
10
  * line below and nowhere else — not even in prose.
11
11
  */
12
12
  export const PACKAGE_NAME = 'office-outlook-mcp';
13
- export const VERSION = '0.3.3'; // x-release-please-version
13
+ export const VERSION = '0.3.5'; // x-release-please-version
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chrischall/office-outlook-mcp",
3
- "version": "0.3.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.13.0",
49
- "@fetchproxy/server": "^3.4.1",
50
- "@modelcontextprotocol/server": "^2.2.0",
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.2.0",
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.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.3",
14
+ "version": "0.3.5",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },