@agentcomms/resend 0.16.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,7 @@ Generated by scripts/third-party-licenses.mjs from the 31 packages the bundler p
8
8
 
9
9
 
10
10
  ----------------------------------------------------------------------------------------------------
11
- @modelcontextprotocol/client@2.0.0 — MIT
11
+ @modelcontextprotocol/client@2.3.1 — Apache-2.0
12
12
  https://modelcontextprotocol.io
13
13
  ----------------------------------------------------------------------------------------------------
14
14
  The MCP project is undergoing a licensing transition from the MIT License to the Apache License, Version 2.0 ("Apache-2.0"). All new code and specification contributions to the project are licensed under Apache-2.0. Documentation contributions (excluding specifications) are licensed under CC-BY-4.0.
@@ -228,7 +228,7 @@ Documentation in this project (excluding specifications) is licensed under
228
228
  CC-BY-4.0. See https://creativecommons.org/licenses/by/4.0/legalcode for
229
229
  the full license text.
230
230
  ----------------------------------------------------------------------------------------------------
231
- @modelcontextprotocol/core@2.0.0 — MIT
231
+ @modelcontextprotocol/core@2.3.1 — Apache-2.0
232
232
  https://modelcontextprotocol.io
233
233
  ----------------------------------------------------------------------------------------------------
234
234
  The MCP project is undergoing a licensing transition from the MIT License to the Apache License, Version 2.0 ("Apache-2.0"). All new code and specification contributions to the project are licensed under Apache-2.0. Documentation contributions (excluding specifications) are licensed under CC-BY-4.0.
@@ -448,7 +448,7 @@ Documentation in this project (excluding specifications) is licensed under
448
448
  CC-BY-4.0. See https://creativecommons.org/licenses/by/4.0/legalcode for
449
449
  the full license text.
450
450
  ----------------------------------------------------------------------------------------------------
451
- @modelcontextprotocol/server@2.0.0 — MIT
451
+ @modelcontextprotocol/server@2.3.1 — Apache-2.0
452
452
  https://modelcontextprotocol.io
453
453
  ----------------------------------------------------------------------------------------------------
454
454
  The MCP project is undergoing a licensing transition from the MIT License to the Apache License, Version 2.0 ("Apache-2.0"). All new code and specification contributions to the project are licensed under Apache-2.0. Documentation contributions (excluding specifications) are licensed under CC-BY-4.0.
@@ -936,10 +936,10 @@ deal in the Software without restriction, including without limitation the
936
936
  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
937
937
  sell copies of the Software, and to permit persons to whom the Software is
938
938
  furnished to do so, subject to the following conditions:
939
-
939
+
940
940
  The above copyright notice and this permission notice shall be included in
941
941
  all copies or substantial portions of the Software.
942
-
942
+
943
943
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
944
944
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
945
945
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -957,10 +957,10 @@ deal in the Software without restriction, including without limitation the
957
957
  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
958
958
  sell copies of the Software, and to permit persons to whom the Software is
959
959
  furnished to do so, subject to the following conditions:
960
-
960
+
961
961
  The above copyright notice and this permission notice shall be included in
962
962
  all copies or substantial portions of the Software.
963
-
963
+
964
964
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
965
965
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
966
966
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -1080,7 +1080,7 @@ pkce-challenge@5.0.1 — MIT
1080
1080
  ----------------------------------------------------------------------------------------------------
1081
1081
  MIT License
1082
1082
 
1083
- Copyright (c) 2019
1083
+ Copyright (c) 2019
1084
1084
 
1085
1085
  Permission is hereby granted, free of charge, to any person obtaining a copy
1086
1086
  of this software and associated documentation files (the "Software"), to deal
@@ -1100,7 +1100,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1100
1100
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1101
1101
  SOFTWARE.
1102
1102
  ----------------------------------------------------------------------------------------------------
1103
- postal-mime@3.0.0 — MIT-0
1103
+ postal-mime@4.0.5 — MIT-0
1104
1104
  https://postal-mime.postalsys.com
1105
1105
  ----------------------------------------------------------------------------------------------------
1106
1106
  Copyright (c) 2021-2025 Andris Reinman
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { A as removeAccountChange, At as updateGateAtTerminal, C as inspectKey, Ct as runUpdateCheckChild, D as policyChange, Dt as terminalUpdateHooks, E as policyApprovalRefusal, Ft as writeResult, G as SEND_LOOKUP, H as CommsError, Ht as VERSION, J as approvalsOf, K as UPDATE_CHECK_CHILD_COMMAND, Lt as RESEND_CALLER, M as showAccount, Nt as waitForApproval, O as policyReport, P as ResendContext, Pt as wholeNumber, R as checkNewName, S as addAccountChange, St as runCommand, T as modeOf, Tt as serverPruneChange, U as EXIT_CODES, V as CHANNEL_SERVERS, W as PATH_OPTIONS, X as approveRefusedHint, Y as approveChangeAtTerminal, Z as canPrompt, _ as showSentEmail, _t as refuseUnclaimedApproval, a as revokeSendApproval, at as exemptFromUpdateGate, bt as renderPrune, c as downloadReceived, ct as handoffSentence, d as listReceived, dt as kindOf, et as cliHandoffs, f as listScheduled, g as showReceived, gt as pathOverridesFromCliOptions, ht as paint, i as prepareSend, it as escapeForDisplay, j as sendPolicyOf, k as policyWanted, kt as truncateDisplay, l as getMetrics, lt as handoffSentenceToFill, m as listSuppressions, mt as openCore, n as executeSend, nt as commandPathOf, o as sendStatus, p as listSentEmails, q as agentMarker, r as finishSendApproval, rt as describeFenceReport, s as cancelScheduledChange, st as gatedChangeAtTerminal, t as beginSendApproval, tt as colorEnabled, u as listDomains, ut as installExitStatus, vt as renderApprovalWait, w as listAccounts, wt as serverInstallChange, x as runDoctor, xt as resolvePaths, yt as renderInstall } from "./send-BwyJM23a.mjs";
2
+ import { A as removeAccountChange, At as updateGateAtTerminal, C as inspectKey, Ct as runUpdateCheckChild, D as policyChange, Dt as terminalUpdateHooks, E as policyApprovalRefusal, Ft as writeResult, G as SEND_LOOKUP, H as CommsError, Ht as VERSION, J as approvalsOf, K as UPDATE_CHECK_CHILD_COMMAND, Lt as RESEND_CALLER, M as showAccount, Nt as waitForApproval, O as policyReport, P as ResendContext, Pt as wholeNumber, R as checkNewName, S as addAccountChange, St as runCommand, T as modeOf, Tt as serverPruneChange, U as EXIT_CODES, V as CHANNEL_SERVERS, W as PATH_OPTIONS, X as approveRefusedHint, Y as approveChangeAtTerminal, Z as canPrompt, _ as showSentEmail, _t as refuseUnclaimedApproval, a as revokeSendApproval, at as exemptFromUpdateGate, bt as renderPrune, c as downloadReceived, ct as handoffSentence, d as listReceived, dt as kindOf, et as cliHandoffs, f as listScheduled, g as showReceived, gt as pathOverridesFromCliOptions, ht as paint, i as prepareSend, it as escapeForDisplay, j as sendPolicyOf, k as policyWanted, kt as truncateDisplay, l as getMetrics, lt as handoffSentenceToFill, m as listSuppressions, mt as openCore, n as executeSend, nt as commandPathOf, o as sendStatus, p as listSentEmails, q as agentMarker, r as finishSendApproval, rt as describeFenceReport, s as cancelScheduledChange, st as gatedChangeAtTerminal, t as beginSendApproval, tt as colorEnabled, u as listDomains, ut as installExitStatus, vt as renderApprovalWait, w as listAccounts, wt as serverInstallChange, x as runDoctor, xt as resolvePaths, yt as renderInstall } from "./send-D-SXJezp.mjs";
3
3
  import path from "node:path";
4
4
  import { createInterface } from "node:readline/promises";
5
5
  import { stripVTControlCharacters } from "node:util";
@@ -3424,15 +3424,23 @@ is out: update first, or put it off (the stop names both commands) · 64 usage
3424
3424
  });
3425
3425
  writeResult(prepared, output(), renderPrepared, streams);
3426
3426
  }));
3427
- accountOption(send.command("execute <approvalId>")).description("send a prepared email, once. Refuses unless the approval, the content and the recipients all match").requiredOption("--expect-to <addresses>", "the To list you believe it goes to, comma-separated, or none").requiredOption("--expect-cc <addresses>", "the Cc list, or none").requiredOption("--expect-bcc <addresses>", "the Bcc list, or none").requiredOption("--expect-subject <subject>", "the subject").action(act(async (context, _options, approvalId, flags) => {
3427
+ accountOption(send.command("execute <approvalId>")).description("send a prepared email by approval id; optional legacy expectations are checked exactly").option("--expect-to <addresses>", "legacy exact check: To list, comma-separated, or none").option("--expect-cc <addresses>", "legacy exact check: Cc list, or none").option("--expect-bcc <addresses>", "legacy exact check: Bcc list, or none").option("--expect-subject <subject>", "legacy exact check: subject").action(act(async (context, _options, approvalId, flags) => {
3428
+ const expectation = [
3429
+ flags.expectTo,
3430
+ flags.expectCc,
3431
+ flags.expectBcc,
3432
+ flags.expectSubject
3433
+ ];
3434
+ const hasExpect = expectation.some((value) => value !== void 0);
3435
+ if (hasExpect && expectation.some((value) => value === void 0)) throw new CommsError("USAGE", "give all four --expect-* options together, or leave all four out");
3428
3436
  const sent = await executeSend(context, String(flags.account), {
3429
3437
  approvalId,
3430
- expect: {
3438
+ ...hasExpect ? { expect: {
3431
3439
  to: expectList(flags.expectTo, "--expect-to"),
3432
3440
  cc: expectList(flags.expectCc, "--expect-cc"),
3433
3441
  bcc: expectList(flags.expectBcc, "--expect-bcc"),
3434
3442
  subject: String(flags.expectSubject)
3435
- }
3443
+ } } : {}
3436
3444
  });
3437
3445
  writeResult(sent, output(), renderSent, streams);
3438
3446
  }));
@@ -3497,7 +3505,7 @@ is out: update first, or put it off (the stop names both commands) · 64 usage
3497
3505
  }));
3498
3506
  const mcp = program.command("mcp").description("run the MCP server on stdio, for a coding agent to connect to").option("--account <name>", "pin the server to one account; every tool then acts on it and no other").action(async (flags) => {
3499
3507
  ran = true;
3500
- const startResendStdioServer = deps.startMcp ?? (await import("./stdio-entry-BGq1Q5V_.mjs")).startResendStdioServer;
3508
+ const startResendStdioServer = deps.startMcp ?? (await import("./stdio-entry-DcVZBKOq.mjs")).startResendStdioServer;
3501
3509
  const core = coreForInvocation();
3502
3510
  await startResendStdioServer({
3503
3511
  ...deps,
@@ -1,5 +1,5 @@
1
- import { A as stampErrorBrands, C as mergeCapabilities, D as runInputRequiredFlow, E as resolveInputRequiredDriverConfig, M as ListChangedOptionsBaseSchema, N as SERVER_INFO_META_KEY, O as scanXMcpHeaderDeclarations, P as SUBSCRIPTION_ID_META_KEY, S as legacyProtocolVersions, T as parseSchema, _ as isJSONRPCErrorResponse, b as isModernProtocolVersion, c as SdkErrorCode, d as __commonJSMin, f as __toESM, g as declaredDialect, h as codecForVersion, i as ProtocolErrorCode, j as DiscoverResultSchema, l as SdkHttpError, m as buildMcpParamHeaders, n as Protocol, o as SUPPORTED_MODERN_PROTOCOL_VERSIONS, p as brandedHasInstance, r as ProtocolError, s as SdkError, t as MODERN_WIRE_REVISION, u as UnsupportedProtocolVersionError, v as isJSONRPCRequest, w as modernProtocolVersions, x as isSpecType, y as isJSONRPCResultResponse } from "./src-D_zzAWoS-BhK0GFdq-oo-8IJem.mjs";
2
- //#region ../core/dist/dist-COPefvtq.mjs
1
+ import { A as stampErrorBrands, C as mergeCapabilities, D as runInputRequiredFlow, E as resolveInputRequiredDriverConfig, M as ListChangedOptionsBaseSchema, N as SERVER_INFO_META_KEY, O as scanXMcpHeaderDeclarations, P as SUBSCRIPTION_ID_META_KEY, S as legacyProtocolVersions, T as parseSchema, _ as isJSONRPCErrorResponse, b as isModernProtocolVersion, c as SdkErrorCode, d as __commonJSMin, f as __toESM, g as declaredDialect, h as codecForVersion, i as ProtocolErrorCode, j as DiscoverResultSchema, l as SdkHttpError, m as buildMcpParamHeaders, n as Protocol, o as SUPPORTED_MODERN_PROTOCOL_VERSIONS, p as brandedHasInstance, r as ProtocolError, s as SdkError, t as MODERN_WIRE_REVISION, u as UnsupportedProtocolVersionError, v as isJSONRPCRequest, w as modernProtocolVersions, x as isSpecType, y as isJSONRPCResultResponse } from "./src-WCy6ifGf-DXrNj-15-D0oRtifb.mjs";
2
+ //#region ../core/dist/dist-C7DG2LdL.mjs
3
3
  var require_code$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.regexpCode = exports.getEsmExportName = exports.getProperty = exports.safeStringify = exports.stringify = exports.strConcat = exports.addCodeArg = exports.str = exports._ = exports.nil = exports._Code = exports.Name = exports.IDENTIFIER = exports._CodeOrName = void 0;
@@ -7241,10 +7241,12 @@ var RegistrationRejectedError = class extends OAuthClientFlowError {
7241
7241
  };
7242
7242
  /**
7243
7243
  * Thrown by the token-exchange and refresh paths when the resolved token
7244
- * endpoint is not `https:` and is not a loopback host (SEP-2207). This is a
7245
- * configuration error — re-authorizing cannot fix it — so it intentionally does
7246
- * **not** extend `OAuthError` and `auth()`'s refresh branch rethrows it instead
7247
- * of falling through to a fresh `/authorize` redirect.
7244
+ * endpoint is not `https:` and is not a loopback host. The MCP authorization
7245
+ * specification requires authorization server endpoints to use HTTPS; loopback
7246
+ * hosts are exempt here for local development. This is a configuration error —
7247
+ * re-authorizing cannot fix it — so it intentionally does **not** extend
7248
+ * `OAuthError` and `auth()`'s refresh branch rethrows it instead of falling
7249
+ * through to a fresh `/authorize` redirect.
7248
7250
  */
7249
7251
  var InsecureTokenEndpointError = class extends OAuthClientFlowError {
7250
7252
  static {
@@ -7253,7 +7255,7 @@ var InsecureTokenEndpointError = class extends OAuthClientFlowError {
7253
7255
  /** The token endpoint URL that was rejected. */
7254
7256
  tokenEndpoint;
7255
7257
  constructor(tokenEndpoint) {
7256
- super(`Refusing to send credentials to non-https token endpoint '${tokenEndpoint}'. OAuth token requests MUST use TLS (localhost / 127.0.0.1 / ::1 are exempt).`);
7258
+ super(`Refusing to send credentials to non-https token endpoint '${tokenEndpoint}'. OAuth token requests MUST use TLS (localhost / *.localhost / 127.0.0.1 / ::1 are exempt).`);
7257
7259
  this.tokenEndpoint = tokenEndpoint;
7258
7260
  }
7259
7261
  };
@@ -7278,21 +7280,25 @@ var InsecureTokenEndpointError = class extends OAuthClientFlowError {
7278
7280
  * `requiredScope`, which appears in the error message).
7279
7281
  */
7280
7282
  /**
7281
- * Thrown by `auth()` on the authorization-code callback leg when the
7282
- * authorization server resolved by discovery differs from the one recorded in
7283
- * `discoveryState()` at redirect time. The `authorization_code` and PKCE
7284
- * `code_verifier` are bound to the AS that minted the code (RFC 7636); sending
7285
- * them to a different AS's token endpoint is a credential-exfiltration vector.
7283
+ * Thrown by `auth()` and `fetchToken()` when the authorization server in use differs
7284
+ * from the one a credential is bound to and the flow cannot simply start over:
7286
7285
  *
7287
- * This is the only runtime check left in the SEP-2352 model — stored tokens and
7288
- * client credentials are protected structurally by the `issuer` stamp instead.
7286
+ * - on the authorization-code callback leg, when it differs from the one recorded
7287
+ * in `discoveryState()` at redirect time — the `authorization_code` and PKCE
7288
+ * `code_verifier` are bound to the AS that minted the code (RFC 7636);
7289
+ * - for client information whose `issuer` stamp names a different authorization
7290
+ * server on a provider that cannot re-register (no `saveClientInformation()`,
7291
+ * e.g. the bundled static-credential providers); `fetchToken()` throws for any provider.
7292
+ *
7293
+ * Stored tokens and re-registrable client information are protected structurally
7294
+ * by the `issuer` stamp instead (they read back as absent).
7289
7295
  */
7290
7296
  var AuthorizationServerMismatchError = class extends OAuthClientFlowError {
7291
7297
  static {
7292
7298
  Object.defineProperty(this, "mcpBrand", { value: "mcp.AuthorizationServerMismatchError" });
7293
7299
  }
7294
7300
  constructor(recordedIssuer, currentIssuer) {
7295
- super(`Authorization server changed between redirect and callback (redirected to ${JSON.stringify(recordedIssuer)}, callback resolved ${JSON.stringify(currentIssuer)}); refusing to send authorization_code/code_verifier to a different token endpoint`);
7301
+ super(`Authorization server mismatch: credentials are bound to ${JSON.stringify(recordedIssuer)} but this call resolved ${JSON.stringify(currentIssuer)}; refusing to present them to a different authorization server`);
7296
7302
  this.recordedIssuer = recordedIssuer;
7297
7303
  this.currentIssuer = currentIssuer;
7298
7304
  }
@@ -7902,6 +7908,10 @@ function classifyProbeOutcome(outcome, context) {
7902
7908
  case "rpc-error": return classifyRpcError(outcome, context);
7903
7909
  case "http-error": return classifyHttpError(outcome, context);
7904
7910
  case "network-error": return classifyNetworkError(outcome.error, context);
7911
+ case "unusable-reply": return {
7912
+ kind: "error",
7913
+ error: new SdkError(SdkErrorCode.EraNegotiationFailed, `Version negotiation probe failed: the server answered with an unusable reply (${describeError(outcome.error)})`, { cause: outcome.error }, { cause: outcome.error })
7914
+ };
7905
7915
  case "auth-required": return {
7906
7916
  kind: "error",
7907
7917
  error: outcome.error
@@ -7992,7 +8002,7 @@ function classifyNetworkError(error, context) {
7992
8002
  if (context.environment === "browser" && isOpaqueFetchTypeError(error)) return { kind: "legacy" };
7993
8003
  return {
7994
8004
  kind: "error",
7995
- error: new SdkError(SdkErrorCode.EraNegotiationFailed, `Version negotiation probe failed: ${describeError(error)}`, { cause: error })
8005
+ error: new SdkError(SdkErrorCode.EraNegotiationFailed, `Version negotiation probe failed: ${describeError(error)}`, { cause: error }, { cause: error })
7996
8006
  };
7997
8007
  }
7998
8008
  function isOpaqueFetchTypeError(error) {
@@ -8236,6 +8246,11 @@ function buildProbeRequest(id, protocolVersion, clientInfo, capabilities) {
8236
8246
  }) }
8237
8247
  };
8238
8248
  }
8249
+ /** True for what the transport throws when the probe was answered 2xx without a usable reply. */
8250
+ function isUnusableReplyError(error) {
8251
+ if (error instanceof SdkError && error.code === SdkErrorCode.ClientHttpUnexpectedContent) return true;
8252
+ return error instanceof Error && error.name === "SyntaxError";
8253
+ }
8239
8254
  function normalizeReply(reply, timeoutMs) {
8240
8255
  switch (reply.kind) {
8241
8256
  case "response": return reply.error === void 0 ? {
@@ -8260,6 +8275,10 @@ function normalizeReply(reply, timeoutMs) {
8260
8275
  statusText: error.data.statusText
8261
8276
  };
8262
8277
  }
8278
+ if (isUnusableReplyError(error)) return {
8279
+ kind: "unusable-reply",
8280
+ error
8281
+ };
8263
8282
  return {
8264
8283
  kind: "network-error",
8265
8284
  error
@@ -9142,7 +9161,7 @@ var Client = class extends Protocol {
9142
9161
  }, options);
9143
9162
  const hit = await this._serveFromCache("prompts/list", void 0, options);
9144
9163
  if (hit !== void 0) return hit;
9145
- return this._listAllPages("prompts/list", params, options, (acc, page) => acc.prompts.push(...page.prompts));
9164
+ return this._listAllPages("prompts/list", params, options, (r) => r.prompts);
9146
9165
  }
9147
9166
  /**
9148
9167
  * Lists available resources.
@@ -9181,7 +9200,7 @@ var Client = class extends Protocol {
9181
9200
  }, options);
9182
9201
  const hit = await this._serveFromCache("resources/list", void 0, options);
9183
9202
  if (hit !== void 0) return hit;
9184
- return this._listAllPages("resources/list", params, options, (acc, page) => acc.resources.push(...page.resources));
9203
+ return this._listAllPages("resources/list", params, options, (r) => r.resources);
9185
9204
  }
9186
9205
  /**
9187
9206
  * Lists available resource URI templates for dynamic resources.
@@ -9206,7 +9225,7 @@ var Client = class extends Protocol {
9206
9225
  }, options);
9207
9226
  const hit = await this._serveFromCache("resources/templates/list", void 0, options);
9208
9227
  if (hit !== void 0) return hit;
9209
- return this._listAllPages("resources/templates/list", params, options, (acc, page) => acc.resourceTemplates.push(...page.resourceTemplates));
9228
+ return this._listAllPages("resources/templates/list", params, options, (r) => r.resourceTemplates);
9210
9229
  }
9211
9230
  /**
9212
9231
  * Walk every page of a paginated list verb, aggregate, and write ONE
@@ -9214,8 +9233,7 @@ var Client = class extends Protocol {
9214
9233
  * methods' no-`cursor` auto-aggregate path. Page 1's result object is
9215
9234
  * mutated in place (its items array is extended; `nextCursor` is
9216
9235
  * cleared); page-1 metadata (`ttlMs`, `cacheScope`, `_meta`) is preserved.
9217
- * A `nextCursor` that repeats stops the walk (defence against a
9218
- * non-converging server, mcp.d's `drainList` guard);
9236
+ * A page with the same items and `nextCursor` as the previous page ends the walk;
9219
9237
  * {@linkcode ClientOptions.listMaxPages} is a hard cap — hitting it
9220
9238
  * throws, so a partial aggregate is never cached. The
9221
9239
  * captured-generation guard skips the write when a `list_changed` landed
@@ -9230,7 +9248,7 @@ var Client = class extends Protocol {
9230
9248
  * trace context) supplied to the public `list*()` reaches every wire
9231
9249
  * request the walk issues.
9232
9250
  */
9233
- async _listAllPages(method, baseParams, options, append, finalize) {
9251
+ async _listAllPages(method, baseParams, options, items, finalize) {
9234
9252
  const bypass = options?.cacheMode === "bypass";
9235
9253
  const generation = this._cache.captureGeneration(method);
9236
9254
  const acc = await this.request({
@@ -9238,14 +9256,13 @@ var Client = class extends Protocol {
9238
9256
  ...baseParams && { params: { ...baseParams } }
9239
9257
  }, options);
9240
9258
  let cursor = acc.nextCursor;
9241
- const seen = /* @__PURE__ */ new Set();
9259
+ let previous = acc;
9242
9260
  let pages = 1;
9243
- while (cursor !== void 0 && !seen.has(cursor)) {
9261
+ while (cursor !== void 0) {
9244
9262
  if (this._listMaxPages !== 0 && pages >= this._listMaxPages) throw new SdkError(SdkErrorCode.ListPaginationExceeded, `${method}: exceeded listMaxPages (${this._listMaxPages}); server pagination did not terminate`, {
9245
9263
  method,
9246
9264
  listMaxPages: this._listMaxPages
9247
9265
  });
9248
- seen.add(cursor);
9249
9266
  const page = await this.request({
9250
9267
  method,
9251
9268
  params: {
@@ -9253,7 +9270,9 @@ var Client = class extends Protocol {
9253
9270
  cursor
9254
9271
  }
9255
9272
  }, options);
9256
- append(acc, page);
9273
+ if (page.nextCursor === cursor && JSON.stringify(items(page)) === JSON.stringify(items(previous))) break;
9274
+ items(acc).push(...items(page));
9275
+ previous = page;
9257
9276
  cursor = page.nextCursor;
9258
9277
  pages++;
9259
9278
  }
@@ -9514,19 +9533,22 @@ var Client = class extends Protocol {
9514
9533
  notifications: filter
9515
9534
  }
9516
9535
  };
9536
+ const routeSendFailure = (error) => {
9537
+ settle({
9538
+ cause: "remote",
9539
+ error: error instanceof Error ? error : new Error(String(error))
9540
+ });
9541
+ };
9517
9542
  try {
9518
- await this.transport.send(jsonrpcRequest, {
9543
+ this.transport.send(jsonrpcRequest, {
9519
9544
  requestSignal: requestAbort.signal,
9520
9545
  onRequestStreamEnd: () => settle({
9521
9546
  cause: "remote",
9522
9547
  error: /* @__PURE__ */ new Error("subscriptions/listen: stream ended")
9523
9548
  })
9524
- });
9549
+ }).catch(routeSendFailure);
9525
9550
  } catch (error) {
9526
- settle({
9527
- cause: "remote",
9528
- error: error instanceof Error ? error : new Error(String(error))
9529
- });
9551
+ routeSendFailure(error);
9530
9552
  }
9531
9553
  return {
9532
9554
  honoredFilter: await opening,
@@ -9778,7 +9800,7 @@ var Client = class extends Protocol {
9778
9800
  }
9779
9801
  const hit = await this._serveFromCache("tools/list", void 0, options);
9780
9802
  if (hit !== void 0) return hit;
9781
- return this._listAllPages("tools/list", params, options, (acc, page) => acc.tools.push(...page.tools), (acc) => this._excludeInvalidXMcpHeaderTools(acc));
9803
+ return this._listAllPages("tools/list", params, options, (r) => r.tools, (acc) => this._excludeInvalidXMcpHeaderTools(acc));
9782
9804
  }
9783
9805
  /**
9784
9806
  * SEP-2243 (protocol revision 2026-07-28): a Streamable HTTP client MUST