agentfootprint 12.0.0 → 12.1.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.
Files changed (112) hide show
  1. package/CAPABILITIES.md +1 -0
  2. package/dist/answer-account/templates.js +12 -6
  3. package/dist/answer-account/templates.js.map +1 -1
  4. package/dist/answer-validation/types.js.map +1 -1
  5. package/dist/core/agent/assessment/assess.js +94 -32
  6. package/dist/core/agent/assessment/assess.js.map +1 -1
  7. package/dist/core/agent/assessment/reasons.js +2 -2
  8. package/dist/core/agent/assessment/reasons.js.map +1 -1
  9. package/dist/core/agent/assessment/sources.js +61 -23
  10. package/dist/core/agent/assessment/sources.js.map +1 -1
  11. package/dist/core/agent/negativeClaims/delivery.js +10 -1
  12. package/dist/core/agent/negativeClaims/delivery.js.map +1 -1
  13. package/dist/esm/answer-account/templates.d.ts +1 -1
  14. package/dist/esm/answer-account/templates.js +12 -6
  15. package/dist/esm/answer-account/templates.js.map +1 -1
  16. package/dist/esm/answer-validation/types.d.ts +10 -0
  17. package/dist/esm/answer-validation/types.js.map +1 -1
  18. package/dist/esm/core/agent/assessment/assess.d.ts +6 -3
  19. package/dist/esm/core/agent/assessment/assess.js +95 -33
  20. package/dist/esm/core/agent/assessment/assess.js.map +1 -1
  21. package/dist/esm/core/agent/assessment/reasons.js +2 -2
  22. package/dist/esm/core/agent/assessment/reasons.js.map +1 -1
  23. package/dist/esm/core/agent/assessment/sources.d.ts +26 -1
  24. package/dist/esm/core/agent/assessment/sources.js +59 -22
  25. package/dist/esm/core/agent/assessment/sources.js.map +1 -1
  26. package/dist/esm/core/agent/assessment/types.d.ts +3 -1
  27. package/dist/esm/core/agent/negativeClaims/delivery.d.ts +9 -1
  28. package/dist/esm/core/agent/negativeClaims/delivery.js +10 -1
  29. package/dist/esm/core/agent/negativeClaims/delivery.js.map +1 -1
  30. package/dist/esm/identity/types.d.ts +12 -0
  31. package/dist/esm/identity/types.js.map +1 -1
  32. package/dist/esm/identity/withCredentialRetry.d.ts +5 -0
  33. package/dist/esm/identity/withCredentialRetry.js +16 -3
  34. package/dist/esm/identity/withCredentialRetry.js.map +1 -1
  35. package/dist/esm/lib/boundedJson.d.ts +27 -0
  36. package/dist/esm/lib/boundedJson.js +33 -0
  37. package/dist/esm/lib/boundedJson.js.map +1 -1
  38. package/dist/esm/mcp/callChecks.d.ts +160 -0
  39. package/dist/esm/mcp/callChecks.js +237 -0
  40. package/dist/esm/mcp/callChecks.js.map +1 -0
  41. package/dist/esm/mcp/gatewayTransport.d.ts +8 -0
  42. package/dist/esm/mcp/gatewayTransport.js +35 -2
  43. package/dist/esm/mcp/gatewayTransport.js.map +1 -1
  44. package/dist/esm/mcp/index.d.ts +3 -1
  45. package/dist/esm/mcp/index.js +7 -0
  46. package/dist/esm/mcp/index.js.map +1 -1
  47. package/dist/esm/mcp/listingGenerations.d.ts +54 -0
  48. package/dist/esm/mcp/listingGenerations.js +75 -0
  49. package/dist/esm/mcp/listingGenerations.js.map +1 -0
  50. package/dist/esm/mcp/mcpClient.js +108 -23
  51. package/dist/esm/mcp/mcpClient.js.map +1 -1
  52. package/dist/esm/mcp/toolList.d.ts +90 -0
  53. package/dist/esm/mcp/toolList.js +123 -0
  54. package/dist/esm/mcp/toolList.js.map +1 -0
  55. package/dist/esm/mcp/types.d.ts +118 -2
  56. package/dist/esm/tool-providers/index.d.ts +2 -2
  57. package/dist/esm/tool-providers/index.js +8 -0
  58. package/dist/esm/tool-providers/index.js.map +1 -1
  59. package/dist/identity/types.js.map +1 -1
  60. package/dist/identity/withCredentialRetry.js +16 -3
  61. package/dist/identity/withCredentialRetry.js.map +1 -1
  62. package/dist/lib/boundedJson.js +35 -1
  63. package/dist/lib/boundedJson.js.map +1 -1
  64. package/dist/mcp/callChecks.js +247 -0
  65. package/dist/mcp/callChecks.js.map +1 -0
  66. package/dist/mcp/gatewayTransport.js +35 -2
  67. package/dist/mcp/gatewayTransport.js.map +1 -1
  68. package/dist/mcp/index.js +10 -1
  69. package/dist/mcp/index.js.map +1 -1
  70. package/dist/mcp/listingGenerations.js +80 -0
  71. package/dist/mcp/listingGenerations.js.map +1 -0
  72. package/dist/mcp/mcpClient.js +108 -23
  73. package/dist/mcp/mcpClient.js.map +1 -1
  74. package/dist/mcp/toolList.js +128 -0
  75. package/dist/mcp/toolList.js.map +1 -0
  76. package/dist/tool-providers/index.js +9 -1
  77. package/dist/tool-providers/index.js.map +1 -1
  78. package/dist/types/answer-account/templates.d.ts +1 -1
  79. package/dist/types/answer-account/templates.d.ts.map +1 -1
  80. package/dist/types/answer-validation/types.d.ts +10 -0
  81. package/dist/types/answer-validation/types.d.ts.map +1 -1
  82. package/dist/types/core/agent/assessment/assess.d.ts +6 -3
  83. package/dist/types/core/agent/assessment/assess.d.ts.map +1 -1
  84. package/dist/types/core/agent/assessment/reasons.d.ts.map +1 -1
  85. package/dist/types/core/agent/assessment/sources.d.ts +26 -1
  86. package/dist/types/core/agent/assessment/sources.d.ts.map +1 -1
  87. package/dist/types/core/agent/assessment/types.d.ts +3 -1
  88. package/dist/types/core/agent/assessment/types.d.ts.map +1 -1
  89. package/dist/types/core/agent/negativeClaims/delivery.d.ts +9 -1
  90. package/dist/types/core/agent/negativeClaims/delivery.d.ts.map +1 -1
  91. package/dist/types/identity/types.d.ts +12 -0
  92. package/dist/types/identity/types.d.ts.map +1 -1
  93. package/dist/types/identity/withCredentialRetry.d.ts +5 -0
  94. package/dist/types/identity/withCredentialRetry.d.ts.map +1 -1
  95. package/dist/types/lib/boundedJson.d.ts +27 -0
  96. package/dist/types/lib/boundedJson.d.ts.map +1 -1
  97. package/dist/types/mcp/callChecks.d.ts +161 -0
  98. package/dist/types/mcp/callChecks.d.ts.map +1 -0
  99. package/dist/types/mcp/gatewayTransport.d.ts +8 -0
  100. package/dist/types/mcp/gatewayTransport.d.ts.map +1 -1
  101. package/dist/types/mcp/index.d.ts +3 -1
  102. package/dist/types/mcp/index.d.ts.map +1 -1
  103. package/dist/types/mcp/listingGenerations.d.ts +55 -0
  104. package/dist/types/mcp/listingGenerations.d.ts.map +1 -0
  105. package/dist/types/mcp/mcpClient.d.ts.map +1 -1
  106. package/dist/types/mcp/toolList.d.ts +91 -0
  107. package/dist/types/mcp/toolList.d.ts.map +1 -0
  108. package/dist/types/mcp/types.d.ts +118 -2
  109. package/dist/types/mcp/types.d.ts.map +1 -1
  110. package/dist/types/tool-providers/index.d.ts +2 -2
  111. package/dist/types/tool-providers/index.d.ts.map +1 -1
  112. package/package.json +1 -1
@@ -79,6 +79,18 @@ export interface CredentialRequest {
79
79
  readonly request?: RequestContext;
80
80
  /** Force a fresh authorization, bypassing any cached/refresh token. */
81
81
  readonly forceReauth?: boolean;
82
+ /**
83
+ * The abort signal of the request this credential is for — present when the
84
+ * caller has one, as `gatewayTransport` does for every request it vends for.
85
+ *
86
+ * A provider that does work of its own (a token endpoint, a vault, an SDK
87
+ * call) should hand it on and stop when it fires: the request it would serve
88
+ * has been cancelled or ran out of time. Ignoring it is safe, never a leak:
89
+ * the caller stops waiting at the abort and never uses a credential that
90
+ * arrives after it. It is a live object, not data: never put it in a cache
91
+ * key, a log line or an error message.
92
+ */
93
+ readonly signal?: AbortSignal;
82
94
  }
83
95
  /**
84
96
  * A credential, ready to apply to a downstream request. It carries its `kind`
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/identity/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,oFAAoF;AACpF,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,8FAA8F;IAC9F,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACnC,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;IAClC,uEAAuE;IACvE,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,UAAU;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,uFAAuF;AACvF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;oFACoF;AACpF,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;IAC1C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,GAAG,+BAA+B,CAAC;AAElF;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAClE;AAED,yEAAyE;AACzE,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,gBAAgB,GAAG,CAAC,IAAI,gBAAgB,CAE7E;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;0DAEsD;IACtD,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CACpC;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,IAAI,kBAAkB,CAanE"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/identity/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,oFAAoF;AACpF,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,8FAA8F;IAC9F,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACnC,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;IAClC,uEAAuE;IACvE,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,UAAU;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,uFAAuF;AACvF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;oFACoF;AACpF,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;IAC1C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,GAAG,+BAA+B,CAAC;AAElF;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAClE;AAED,yEAAyE;AACzE,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,gBAAgB,GAAG,CAAC,IAAI,gBAAgB,CAE7E;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;0DAEsD;IACtD,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CACpC;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,IAAI,kBAAkB,CAanE"}
@@ -25,6 +25,11 @@
25
25
  * `issued` is success; `authorization-required` is a HUMAN flow (3LO
26
26
  * consent), not a transient fault — retrying it would hammer the IdP
27
27
  * without the user having authorized anything.
28
+ * • The request's `signal` (`CredentialRequest.signal`) is passed through to
29
+ * the wrapped provider, ends the backoff wait, and is checked immediately
30
+ * before every attempt, the first included: a request whose signal has
31
+ * fired never asks the provider (again), and the call rejects with the
32
+ * abort. An attempt already running is the provider's to stop.
28
33
  * • After retries exhaust, the LAST error is rethrown — the call site
29
34
  * behaves byte-identically to an unwrapped provider (fail-closed:
30
35
  * `agentfootprint.credential.failed` emit + error tool result; the tool
@@ -1 +1 @@
1
- {"version":3,"file":"withCredentialRetry.d.ts","sourceRoot":"","sources":["../../../src/identity/withCredentialRetry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAGH,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACvF,OAAO,KAAK,EAAE,kBAAkB,EAAuC,MAAM,YAAY,CAAC;AAE1F;;;;GAIG;AACH,MAAM,MAAM,0BAA0B,GAAG,gBAAgB,CAAC;AAE1D;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,GAAE,0BAA+B,GACvC,kBAAkB,CAkCpB"}
1
+ {"version":3,"file":"withCredentialRetry.d.ts","sourceRoot":"","sources":["../../../src/identity/withCredentialRetry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAIH,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACvF,OAAO,KAAK,EAAE,kBAAkB,EAAuC,MAAM,YAAY,CAAC;AAE1F;;;;GAIG;AACH,MAAM,MAAM,0BAA0B,GAAG,gBAAgB,CAAC;AAE1D;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,GAAE,0BAA+B,GACvC,kBAAkB,CAyCpB"}
@@ -1,4 +1,31 @@
1
1
  export declare function ownData(value: unknown, allowed?: readonly string[]): Record<string, unknown>;
2
+ /** A list as {@link readOwnList} read it. */
3
+ export interface OwnList {
4
+ /** The entries read, in index order — a hole or an accessor entry is `undefined` (its getter never called). */
5
+ readonly entries: readonly unknown[];
6
+ /** How many entries the list holds past the bound — counted, never read. */
7
+ readonly unread: number;
8
+ }
9
+ /**
10
+ * Read a list the way {@link copyJson} reads an array — a plain array only
11
+ * (`Array.prototype`), its own `length`, the own DATA property at each index —
12
+ * as a READER that never refuses: at most `maxEntries` entries, a hole or an
13
+ * accessor entry read as `undefined` (the getter is never called), and the
14
+ * entries past the bound counted in `unread`, never walked. It never calls the
15
+ * list's iterator, a getter or a method, so a list from a record the library
16
+ * did not build cannot hide its entries or run code inside the reader.
17
+ * `undefined` when `value` is not a plain array: the caller says what that
18
+ * means for its own question, the conservative way.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const list = ['a'];
23
+ * list.length = 3; // a hole at 1 and 2
24
+ * Object.defineProperty(list, Symbol.iterator, { value: function* () {} }); // never called
25
+ * readOwnList(list, 2); // { entries: ['a', undefined], unread: 1 }
26
+ * ```
27
+ */
28
+ export declare function readOwnList(value: unknown, maxEntries: number): OwnList | undefined;
2
29
  /** JSON copy without invoking toJSON/getters or silently dropping data. */
3
30
  export declare function copyJson(value: unknown, maxBytes: number, freeze: boolean, maxDepth?: number): unknown;
4
31
  //# sourceMappingURL=boundedJson.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"boundedJson.d.ts","sourceRoot":"","sources":["../../../src/lib/boundedJson.ts"],"names":[],"mappings":"AAGA,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkB5F;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CACtB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,EACf,QAAQ,SAAM,GACb,OAAO,CA0ET"}
1
+ {"version":3,"file":"boundedJson.d.ts","sourceRoot":"","sources":["../../../src/lib/boundedJson.ts"],"names":[],"mappings":"AAGA,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkB5F;AAED,6CAA6C;AAC7C,MAAM,WAAW,OAAO;IACtB,+GAA+G;IAC/G,QAAQ,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,CAAC;IACrC,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAWnF;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CACtB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,EACf,QAAQ,SAAM,GACb,OAAO,CA0ET"}
@@ -0,0 +1,161 @@
1
+ /**
2
+ * callChecks — a listing never makes a callable tool lose its checks.
3
+ *
4
+ * Pattern: the SDK's three per-tool call checks, carried by every tool the
5
+ * library hands out, plus one typed refusal.
6
+ * Role: The MCP SDK's `Client` runs three checks inside `callTool`, and it
7
+ * keeps them only for the tools of its most recent `tools/list`
8
+ * answer (1.32: `cacheToolMetadata` replaces them on every answer):
9
+ *
10
+ * 1. a tool with `execution.taskSupport: 'required'` is refused before a
11
+ * plain `tools/call` is sent;
12
+ * 2. a tool with an `outputSchema` must answer with `structuredContent`,
13
+ * unless the answer is an error;
14
+ * 3. that `structuredContent` must match the schema.
15
+ *
16
+ * So a tool that declares any of them carries them itself, as the listing it
17
+ * came from declared them. The library leaves them to the SDK only for a tool
18
+ * of a ONE-page list whose answer is still the latest, with no list request
19
+ * out (`listingGenerations.ts`), both when the call starts and when its answer
20
+ * comes in: the one-page normal case, which runs exactly as it always did.
21
+ * Every other call runs the tool's own checks, at the SDK's moments — the first
22
+ * before sending, the other two once the answer is in, before anything reads it
23
+ * — and raises the SDK's error: its own `McpError` where this arm loaded the
24
+ * SDK, otherwise an error with the same name, code and message. Those calls
25
+ * are to a tool of a paged list, a tool whose list a later answer replaced (a
26
+ * refresh that failed or succeeded; a reference held across it), and any call
27
+ * made while a list is being read.
28
+ *
29
+ * All of this covers the lists the library reads (`tools()`, `refresh()`); a
30
+ * listing it does not send — the SDK client's own automatic refresh, a
31
+ * `listTools` call of the caller's — is not seen (`listingGenerations.ts`).
32
+ *
33
+ * The output checks need a JSON Schema validator equal to the client's: the
34
+ * SDK's default (`AjvJsonSchemaValidator`, loaded with the SDK on the Node
35
+ * loader arm), or the caller's `jsonSchemaValidator`. Where neither exists — an
36
+ * `sdk` or `connection` arm given none — an answer under these rules is never
37
+ * returned unchecked (`McpOutputUncheckedError`):
38
+ *
39
+ * - a call under the tool's own checks from the start, to a tool that
40
+ * declares an `outputSchema`, is refused before it is sent (`sent: false`);
41
+ * - a call that started under the SDK's checks is refused once its answer is
42
+ * in, unread, when the library sent a `tools/list` request while the call
43
+ * was out (`sent: true`): the SDK may have checked it against another list.
44
+ *
45
+ * A schema is compiled when a tool's own checks first need it, never before:
46
+ * the one-page normal case compiles nothing twice.
47
+ */
48
+ import type { McpCallToolResult, McpJsonSchemaValidator, McpListedTool } from './types.js';
49
+ import type { ListingGenerations } from './listingGenerations.js';
50
+ /** The SDK's `McpError` constructor, as `@modelcontextprotocol/sdk/types.js` exports it. */
51
+ export type McpErrorClass = new (code: number, message: string, data?: unknown) => Error;
52
+ /** A compiled output check, as the SDK's validator returns one. */
53
+ type Validate = (input: unknown) => {
54
+ readonly valid: boolean;
55
+ readonly errorMessage?: string;
56
+ };
57
+ /**
58
+ * What one connection checks its tools' calls with: a validator equal to its
59
+ * client's, the SDK's own error class where the library loaded the SDK, and
60
+ * which `tools/list` answer the SDK holds its checks for.
61
+ */
62
+ export interface CallCheckKit {
63
+ /** The client's name, as its refusals name it. */
64
+ readonly server: string;
65
+ /** The validator; created on first use. `undefined` when none is reachable. */
66
+ validator(): McpJsonSchemaValidator | undefined;
67
+ /** The SDK's own `McpError`, when this arm loaded the SDK. */
68
+ readonly McpError?: McpErrorClass;
69
+ /** This connection's list requests, counted (`listingGenerations.ts` · `listingsOf`). */
70
+ readonly listings: ListingGenerations;
71
+ }
72
+ /**
73
+ * The kit for one connection, named `server`, whose list requests `listings`
74
+ * counts (`listingsOf(connection)`, shared by every client over it). `given` is
75
+ * the caller's `jsonSchemaValidator`; `loaded` holds what the library loaded
76
+ * with the SDK on the Node loader arm — the SDK's default validator class and
77
+ * its `McpError` — each `undefined` where it is not a constructor (another arm,
78
+ * or an SDK without it).
79
+ */
80
+ export declare function callCheckKit(server: string, listings: ListingGenerations, given: McpJsonSchemaValidator | undefined, loaded?: {
81
+ readonly Validator?: unknown;
82
+ readonly McpError?: unknown;
83
+ }): CallCheckKit;
84
+ /**
85
+ * `value` as a validator, or `undefined` when it was not given. Refused by name
86
+ * when it is something else, before anything connects.
87
+ */
88
+ export declare function validatorOption(value: unknown, at: string): McpJsonSchemaValidator | undefined;
89
+ /** The checks one listed tool carries, as the listing it came from declared them. */
90
+ export interface CallChecks {
91
+ readonly server: string;
92
+ readonly tool: string;
93
+ /** `execution.taskSupport: 'required'`: only ever run as a task. */
94
+ readonly taskRequired: boolean;
95
+ /** The tool declares an `outputSchema`. */
96
+ readonly outputDeclared: boolean;
97
+ /**
98
+ * True while the SDK's `Client` holds this tool's checks: the tool came from
99
+ * a one-page list whose answer is still the latest, and no list request is
100
+ * out. Then the SDK checks the call, and nothing here runs.
101
+ */
102
+ heldBySdk(): boolean;
103
+ /**
104
+ * The compiled output check, compiled from the declared schema on first use.
105
+ * `undefined` when no output is declared or no validator is reachable.
106
+ */
107
+ validate(): Validate | undefined;
108
+ /** Raise an SDK error, as this arm can: the SDK's class, or its exact shape. */
109
+ fail(code: number, message: string): Error;
110
+ }
111
+ /**
112
+ * The checks `listed` carries — `undefined` when it declares none. `generation`
113
+ * is the one answer its list was read in, when it was read in one
114
+ * (`toolList.ts` · `ToolListing`); a paged list's tools have none, so the SDK
115
+ * never holds all of them.
116
+ */
117
+ export declare function checksFor(listed: McpListedTool, kit: CallCheckKit, generation: number | undefined): CallChecks | undefined;
118
+ /**
119
+ * True when this call's output cannot be checked here: it runs under the
120
+ * tool's own checks, the tool declares an `outputSchema`, no validator is
121
+ * reachable, and it is not refused as a required task anyway (that refusal is
122
+ * the SDK's, and comes first). The call is then refused before it is sent.
123
+ */
124
+ export declare function outputUnchecked(checks: CallChecks): boolean;
125
+ /** The SDK's task refusal, word for word, before anything is sent. */
126
+ export declare function refuseRequiredTask(checks: CallChecks): void;
127
+ /**
128
+ * The SDK's two output checks, in its order and with its sentences, once the
129
+ * answer is in and before anything reads it. An answer no validator here can
130
+ * check is never returned: it is refused, unread, as sent.
131
+ */
132
+ export declare function checkOutput(checks: CallChecks, result: McpCallToolResult): void;
133
+ /**
134
+ * A tool call whose output this connection cannot check, refused. The tool
135
+ * declares an `outputSchema`, the MCP SDK no longer holds the checks of the
136
+ * tool list it came from, and this connection has no JSON Schema validator to
137
+ * check it with — so its answer is never returned:
138
+ *
139
+ * - `sent: false` — refused before it was sent: nothing reached the server.
140
+ * The tool came from a paged list, from a list a later answer replaced, or
141
+ * the call was made while a list was being read.
142
+ * - `sent: true` — the call was sent, and a `tools/list` request went out
143
+ * before its answer came in: the SDK may have checked that answer against
144
+ * the other list, so it is refused unread. The tool may have run.
145
+ *
146
+ * Pass `jsonSchemaValidator` — the validator your client uses — to `mcpClient`.
147
+ * Names the server and the tool, never an argument or an answer.
148
+ */
149
+ export declare class McpOutputUncheckedError extends Error {
150
+ readonly server: string;
151
+ readonly tool: string;
152
+ /** Whether the request left the client: `false` when the refusal came before it. */
153
+ readonly sent: boolean;
154
+ readonly code: "ERR_MCP_OUTPUT_UNCHECKED";
155
+ readonly reason: "output-unchecked";
156
+ constructor(server: string, tool: string,
157
+ /** Whether the request left the client: `false` when the refusal came before it. */
158
+ sent: boolean);
159
+ }
160
+ export {};
161
+ //# sourceMappingURL=callChecks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callChecks.d.ts","sourceRoot":"","sources":["../../../src/mcp/callChecks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,4FAA4F;AAC5F,MAAM,MAAM,aAAa,GAAG,KAAK,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,KAAK,CAAC;AAMzF,mEAAmE;AACnE,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhG;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,kDAAkD;IAClD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,SAAS,IAAI,sBAAsB,GAAG,SAAS,CAAC;IAChD,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC;IAClC,yFAAyF;IACzF,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;CACvC;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,sBAAsB,GAAG,SAAS,EACzC,MAAM,GAAE;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GACzE,YAAY,CAcd;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS,CAY9F;AAED,qFAAqF;AACrF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,2CAA2C;IAC3C,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;;;;OAIG;IACH,SAAS,IAAI,OAAO,CAAC;IACrB;;;OAGG;IACH,QAAQ,IAAI,QAAQ,GAAG,SAAS,CAAC;IACjC,gFAAgF;IAChF,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC;CAC5C;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,YAAY,EACjB,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,UAAU,GAAG,SAAS,CAoBxB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAE3D;AAED,sEAAsE;AACtE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAO3D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,iBAAiB,GAAG,IAAI,CA2B/E;AA+BD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAK9C,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,OAAO;IAPxB,QAAQ,CAAC,IAAI,6BAAuC;IACpD,QAAQ,CAAC,MAAM,qBAA+B;gBAGnC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM;IACrB,oFAAoF;IAC3E,IAAI,EAAE,OAAO;CASzB"}
@@ -146,6 +146,14 @@ export type FetchLike = (input: string | URL | Request, init?: RequestInit) => P
146
146
  * Build the `fetch` the MCP SDK will use: one that vends a credential, applies
147
147
  * it to this one request, and keeps nothing.
148
148
  *
149
+ * The vend is a wait, and it honours the request's abort signal — resolved as
150
+ * fetch resolves it (`init.signal`, else a Request input's own): the provider
151
+ * is handed it (`CredentialRequest.signal`), the wait ends at the abort with the
152
+ * abort, and the signal is checked again once the credential arrives. So an
153
+ * aborted or timed-out request is never sent: the gateway stops waiting and
154
+ * never uses a late credential. A provider that ignores cancellation may still
155
+ * finish its own work.
156
+ *
149
157
  * Exported for tests — the secrecy invariant is asserted against this function
150
158
  * directly, because that is where a leak would happen and driving a whole SDK
151
159
  * to reach it would test less while looking like it tested more.
@@ -1 +1 @@
1
- {"version":3,"file":"gatewayTransport.d.ts","sourceRoot":"","sources":["../../../src/mcp/gatewayTransport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,4CAA4C;AAC5C,MAAM,WAAW,uBAAuB;IACtC,4BAA4B;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;IACzC;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,mFAAmF;IACnF,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkDG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;CAC5B;AAID;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,mBAAmB,CAatF;AAED;;;;;;GAMG;AACH,qBAAa,iCAAkC,SAAQ,KAAK;IAC1D,QAAQ,CAAC,IAAI,uCAAiD;IAC9D,sCAAsC;IACtC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;gBAEtB,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM;CAUtD;AAED,0FAA0F;AAC1F,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEjG;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,mBAAmB,EAC9B,SAAS,GAAE,SAA6C,GACvD,SAAS,CAuBX"}
1
+ {"version":3,"file":"gatewayTransport.d.ts","sourceRoot":"","sources":["../../../src/mcp/gatewayTransport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAEnF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,4CAA4C;AAC5C,MAAM,WAAW,uBAAuB;IACtC,4BAA4B;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;IACzC;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,mFAAmF;IACnF,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkDG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;CAC5B;AAID;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,mBAAmB,CAatF;AAED;;;;;;GAMG;AACH,qBAAa,iCAAkC,SAAQ,KAAK;IAC1D,QAAQ,CAAC,IAAI,uCAAiD;IAC9D,sCAAsC;IACtC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;gBAEtB,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM;CAUtD;AAgBD,0FAA0F;AAC1F,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEjG;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,mBAAmB,EAC9B,SAAS,GAAE,SAA6C,GACvD,SAAS,CAuCX"}
@@ -13,5 +13,7 @@ export { retryingFetch } from './throttleRetry.js';
13
13
  export type { RetryOnThrottle, ThrottleFetch, ThrottleRetryInfo, ThrottleRetryOptions, } from './throttleRetry.js';
14
14
  export type { McpReplayDeduplication, McpReplayKind, McpReplayOptions, McpReplayPolicy, McpReplayTool, } from './replay.js';
15
15
  export { McpReplayUnavailableError, type McpReplayUnavailableReason } from './replayUnavailable.js';
16
- export type { McpCallToolResult, McpClient, McpClientOptions, McpConnection, McpConnectionOptions, McpSdk, McpGatewayTransport, McpHttpTransport, McpStdioTransport, McpTransport, McpSdkClient, McpServeOptions, McpServeHandle, McpServeTransport, McpHttpServeTransport, McpStdioServeTransport, McpSdkServer, } from './types.js';
16
+ export { McpToolListIncompleteError, type McpToolListIncompleteReason } from './toolList.js';
17
+ export { McpOutputUncheckedError } from './callChecks.js';
18
+ export type { McpCallToolResult, McpClient, McpClientOptions, McpConnection, McpConnectionOptions, McpJsonSchemaValidator, McpSdk, McpGatewayTransport, McpHttpTransport, McpStdioTransport, McpTransport, McpSdkClient, McpServeOptions, McpServeHandle, McpServeTransport, McpHttpServeTransport, McpStdioServeTransport, McpSdkServer, } from './types.js';
17
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChG,OAAO,EACL,gBAAgB,EAChB,iCAAiC,EACjC,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EACV,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EACV,sBAAsB,EACtB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,aAAa,GACd,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,yBAAyB,EAAE,KAAK,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACpG,YAAY,EACV,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,oBAAoB,EACpB,MAAM,EACN,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,GACb,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChG,OAAO,EACL,gBAAgB,EAChB,iCAAiC,EACjC,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EACV,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EACV,sBAAsB,EACtB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,aAAa,GACd,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,yBAAyB,EAAE,KAAK,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAGpG,OAAO,EAAE,0BAA0B,EAAE,KAAK,2BAA2B,EAAE,MAAM,eAAe,CAAC;AAI7F,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,YAAY,EACV,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,MAAM,EACN,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,GACb,MAAM,YAAY,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * listingGenerations — which `tools/list` answer the MCP SDK's `Client` holds
3
+ * its per-tool call checks for, as far as one connection can tell.
4
+ *
5
+ * Pattern: a count of the list requests one connection sent and settled.
6
+ * Role: The SDK's `Client` keeps its per-tool call checks (`callChecks.ts`)
7
+ * for the tools of the last `tools/list` answer it received: every
8
+ * answer replaces them. A request that FAILED can replace them too: the
9
+ * SDK caches an answer before it returns it, and caching can throw after
10
+ * the old checks are cleared (1.32: an `outputSchema` its validator
11
+ * cannot compile). The library cannot see inside the SDK, but it sends
12
+ * every list request it makes. So it counts them:
13
+ *
14
+ * - a request is OUT from the moment it is sent until it settles, because the
15
+ * SDK replaces its checks before the library sees the answer;
16
+ * - each request that settles, answered or failed, starts a new GENERATION.
17
+ *
18
+ * The SDK holds the checks of a listing's one answer only while the generation
19
+ * that answer settled at is the latest and no request is out. The SDK keeps one
20
+ * set of checks per client, so there is one count per connection object: every
21
+ * `mcpClient` over the same client shares it (`listingsOf`). A `tools/list`
22
+ * request the library did not send — your own code calling `listTools` on a
23
+ * client passed as `connection`, or that client's own automatic refresh
24
+ * (`listChanged.tools` with `autoRefresh`) — is not counted: the library cannot
25
+ * see it, and a tool it handed out goes on leaving its checks to an SDK that no
26
+ * longer holds them. That limit is documented, and pinned by
27
+ * `test/mcp/listingKeepsChecks.limits.test.ts`.
28
+ */
29
+ /** One settled `tools/list` request's answer, and the generation it settled at. */
30
+ export interface SettledListing<T> {
31
+ readonly answer: T;
32
+ readonly generation: number;
33
+ }
34
+ /** The `tools/list` requests one connection has out, and the generations they settled at. */
35
+ export declare class ListingGenerations {
36
+ private settled;
37
+ private out;
38
+ /**
39
+ * Send one `tools/list` request with `send`, counted as out from the moment it
40
+ * is sent until it settles. Settling starts a new generation, answered or not.
41
+ *
42
+ * @throws whatever `send` rejects with, as it rejected
43
+ */
44
+ ask<T>(send: () => Promise<T>): Promise<SettledListing<T>>;
45
+ /** True while `generation` is the latest settled one and no request is out. */
46
+ isLatest(generation: number): boolean;
47
+ private settle;
48
+ }
49
+ /**
50
+ * The count for `connection`: the same one for every `mcpClient` that adapts
51
+ * the same client, because the SDK keeps one set of checks per client and a
52
+ * listing by any of them replaces it.
53
+ */
54
+ export declare function listingsOf(connection: object): ListingGenerations;
55
+ //# sourceMappingURL=listingGenerations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listingGenerations.d.ts","sourceRoot":"","sources":["../../../src/mcp/listingGenerations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,mFAAmF;AACnF,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACnB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,6FAA6F;AAC7F,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,GAAG,CAAK;IAEhB;;;;;OAKG;IACG,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAWhE,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAIrC,OAAO,CAAC,MAAM;CAKf;AAKD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,CAOjE"}
@@ -1 +1 @@
1
- {"version":3,"file":"mcpClient.d.ts","sourceRoot":"","sources":["../../../src/mcp/mcpClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAKH,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAEhB,oBAAoB,EAKrB,MAAM,YAAY,CAAC;AAiCpB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC,CA8DjG"}
1
+ {"version":3,"file":"mcpClient.d.ts","sourceRoot":"","sources":["../../../src/mcp/mcpClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAKH,OAAO,KAAK,EAEV,SAAS,EACT,gBAAgB,EAEhB,oBAAoB,EAMrB,MAAM,YAAY,CAAC;AA8CpB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC,CAoFjG"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * toolList — every page of a server's `tools/list` answer, or a typed refusal
3
+ * that says the list is incomplete.
4
+ *
5
+ * Pattern: one bounded loop + one typed refusal.
6
+ * Role: MCP pages a tool list: a page carries `nextCursor` while the server
7
+ * has more, and the next page is asked for with `{ cursor }`. Reading
8
+ * only the first page cut a paginating server's catalogue short in
9
+ * silence — the agent saw part of it and nothing said so. This reads
10
+ * until the server sends no cursor, within a bound, and when it cannot
11
+ * finish the list it says why:
12
+ *
13
+ * - `'page-limit'` — the list did not end within {@link MAX_TOOL_LIST_PAGES}
14
+ * pages;
15
+ * - `'cursor-repeated'` — a page named a cursor this listing already sent, so
16
+ * following it would loop.
17
+ *
18
+ * The first page is asked exactly as before pagination was followed: no params
19
+ * (and, with no signal, no arguments at all). The client's signal rides every
20
+ * page in the SDK's trailing options, and it is checked immediately before each
21
+ * page is asked for and again when each answer arrives (`lib/abort.ts`): once
22
+ * it has fired, nothing more is asked for and no page is accepted, the last one
23
+ * included. An abort is the caller's word, so it wins over an incomplete list.
24
+ * What it cannot do is settle a page a connection that ignores the signal is
25
+ * still holding: that promise settles when the connection says.
26
+ *
27
+ * Every page request is counted from the moment it is sent until it settles
28
+ * (`listingGenerations.ts`): the MCP SDK's `Client` replaces its per-tool call
29
+ * checks with each answer, so a tool's checks depend on which answer is the
30
+ * latest (`callChecks.ts`).
31
+ */
32
+ import type { Tool } from '../tools/tools.js';
33
+ import type { ListingGenerations } from './listingGenerations.js';
34
+ import type { McpConnection, McpListedTool } from './types.js';
35
+ /**
36
+ * The most `tools/list` requests one listing sends. A bound on REQUESTS, not on
37
+ * the catalogue's size: a page may hold any number of tools. A server that
38
+ * keeps paging past it is reported as incomplete rather than read without end.
39
+ */
40
+ export declare const MAX_TOOL_LIST_PAGES = 100;
41
+ /** Why a server's tool list could not be read to its end. */
42
+ export type McpToolListIncompleteReason = 'page-limit' | 'cursor-repeated';
43
+ /** What a listing read: every tool its pages held, how many pages, and whether it ended. */
44
+ export interface ToolListing {
45
+ readonly tools: readonly McpListedTool[];
46
+ readonly pages: number;
47
+ /**
48
+ * For a list read in ONE answer, the generation that answer settled at: the
49
+ * MCP SDK's `Client` holds its tools' checks while it stays the latest
50
+ * (`listingGenerations.ts`). Absent for a paged list: no one answer holds all
51
+ * of its tools.
52
+ */
53
+ readonly generation?: number;
54
+ /** Absent when the server's list ended: the last page carried no cursor. */
55
+ readonly incomplete?: McpToolListIncompleteReason;
56
+ }
57
+ /**
58
+ * Read the server's tool list, page by page, until a page carries no cursor —
59
+ * or until it cannot be finished, which the result says (`incomplete`).
60
+ *
61
+ * @param listings the connection's count of list requests, which every page
62
+ * request joins (`listingGenerations.ts`)
63
+ * @throws the abort, when `signal` has fired before a page is asked for or by
64
+ * the time its answer arrives; and whatever the connection rejects a page
65
+ * with, as it always did
66
+ */
67
+ export declare function listEveryPage(connection: McpConnection, signal: AbortSignal | undefined, listings: ListingGenerations): Promise<ToolListing>;
68
+ /**
69
+ * A server's tool list that could not be read to its end. `tools()` and
70
+ * `refresh()` reject with it rather than return a list cut short: an agent
71
+ * handed part of a catalogue cannot know what it was not offered.
72
+ *
73
+ * `tools` holds what WAS listed — wrapped and callable, exactly as `tools()`
74
+ * would have returned them — for a caller that decides to use an incomplete
75
+ * list knowingly. Names the server, the reason and the count, never a cursor.
76
+ */
77
+ export declare class McpToolListIncompleteError extends Error {
78
+ readonly reason: McpToolListIncompleteReason;
79
+ readonly server: string;
80
+ /** The pages read before the listing stopped. */
81
+ readonly pages: number;
82
+ /** The tools those pages listed, in page order. */
83
+ readonly tools: readonly Tool[];
84
+ readonly code: "ERR_MCP_TOOL_LIST_INCOMPLETE";
85
+ constructor(reason: McpToolListIncompleteReason, server: string,
86
+ /** The pages read before the listing stopped. */
87
+ pages: number,
88
+ /** The tools those pages listed, in page order. */
89
+ tools: readonly Tool[]);
90
+ }
91
+ //# sourceMappingURL=toolList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolList.d.ts","sourceRoot":"","sources":["../../../src/mcp/toolList.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE/D;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,6DAA6D;AAC7D,MAAM,MAAM,2BAA2B,GAAG,YAAY,GAAG,iBAAiB,CAAC;AAE3E,4FAA4F;AAC5F,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,CAAC,EAAE,2BAA2B,CAAC;CACnD;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,aAAa,EACzB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAAC,WAAW,CAAC,CA0BtB;AAwBD;;;;;;;;GAQG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;IAIjD,QAAQ,CAAC,MAAM,EAAE,2BAA2B;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE;IARjC,QAAQ,CAAC,IAAI,iCAA2C;gBAG7C,MAAM,EAAE,2BAA2B,EACnC,MAAM,EAAE,MAAM;IACvB,iDAAiD;IACxC,KAAK,EAAE,MAAM;IACtB,mDAAmD;IAC1C,KAAK,EAAE,SAAS,IAAI,EAAE;CASlC"}
@@ -307,6 +307,25 @@ export interface McpClientOptions {
307
307
  * @see McpSdk for the two static imports that produce it.
308
308
  */
309
309
  readonly sdk?: McpSdk;
310
+ /**
311
+ * The JSON Schema validator a tool's `outputSchema` is checked with — the MCP
312
+ * SDK's own validator interface (`new AjvJsonSchemaValidator()` from
313
+ * `@modelcontextprotocol/sdk/validation/ajv`, `new CfWorkerJsonSchemaValidator()`,
314
+ * or your own).
315
+ *
316
+ * Why it exists: the SDK's `Client` checks a tool's output only for the tools
317
+ * of its most recent `tools/list` answer, so every tool the library hands out
318
+ * carries its own checks, and runs them whenever the SDK no longer holds its
319
+ * list: a paged list, a list a later answer replaced, a call made while a list
320
+ * is read — of the lists `tools()` and `refresh()` read (see
321
+ * `McpClient.tools()`; the client the library builds here never lists by
322
+ * itself). The client the library builds is handed this same validator, so
323
+ * one validator checks every call. Omit it and the library uses the SDK's
324
+ * default, loaded with the SDK itself; with `sdk`, where the library never
325
+ * touches its Node loader, such a call to a tool that declares an
326
+ * `outputSchema` is refused (`McpOutputUncheckedError`) unless you pass one.
327
+ */
328
+ readonly jsonSchemaValidator?: McpJsonSchemaValidator;
310
329
  /** @see McpConnectionOptions — never set on this arm. */
311
330
  readonly connection?: undefined;
312
331
  /**
@@ -346,10 +365,35 @@ export interface McpConnectionOptions {
346
365
  /**
347
366
  * A connection you already opened. The library never calls `connect()` on it;
348
367
  * `close()` on the returned client closes it exactly once.
368
+ *
369
+ * Leave its tool discovery to `mcpClient`: the per-tool checks hold only for
370
+ * the lists `tools()` and `refresh()` read (see `McpClient.tools()`). Do not
371
+ * let the SDK client refresh itself (`listChanged.tools` with `autoRefresh`,
372
+ * which is on by default once `listChanged.tools` is given): set
373
+ * `autoRefresh: false` and call `refresh()` from `onChanged`, or give
374
+ * `mcpClient` a connection of its own.
349
375
  */
350
376
  readonly connection: McpConnection;
351
377
  /** Abort the list / call paths. Rides the SDK's request options. */
352
378
  readonly signal?: AbortSignal;
379
+ /**
380
+ * The JSON Schema validator your client checks tool output with — pass the
381
+ * SAME one you gave its constructor (`jsonSchemaValidator`), or the SDK's
382
+ * default, `new AjvJsonSchemaValidator()`.
383
+ *
384
+ * The SDK's `Client` checks a tool's output only for the tools of its most
385
+ * recent `tools/list` answer, so the library checks a tool itself, with this,
386
+ * whenever the SDK no longer holds its list: a paged list, a list a later
387
+ * answer replaced, a call made while a list is read. Without it, such a call
388
+ * to a tool that declares an `outputSchema` is refused
389
+ * (`McpOutputUncheckedError`); a one-page catalogue that is still the latest
390
+ * answer never needs it. It covers only the lists `tools()` and `refresh()`
391
+ * read: when the SDK client's cache is replaced some other way (its own
392
+ * automatic refresh, a `listTools` call of yours), the library still leaves
393
+ * the call to the SDK, and this validator is never asked (see
394
+ * `McpClient.tools()`).
395
+ */
396
+ readonly jsonSchemaValidator?: McpJsonSchemaValidator;
353
397
  /** @see McpClientOptions — never set on this arm. */
354
398
  readonly transport?: undefined;
355
399
  /** @see McpClientOptions — never set on this arm. */
@@ -376,12 +420,52 @@ export interface McpClient {
376
420
  * after `mcpClient(...)` is the snapshot used to register on the
377
421
  * agent; subsequent calls re-fetch (cheap, in-memory cached by the
378
422
  * SDK between fetches).
423
+ *
424
+ * Every page of the server's `tools/list` answer is read: the client
425
+ * follows `nextCursor` until a page carries none, sending at most 100
426
+ * `tools/list` requests (a bound on requests, not on the catalogue's size).
427
+ * A list that does not end within them, or that names a cursor it already
428
+ * sent (a loop), is never returned cut short: the call rejects with
429
+ * `McpToolListIncompleteError`, whose `reason` says which and whose `tools`
430
+ * holds what was listed. `signal` rides every page and is checked before
431
+ * each page is asked for and when each answer arrives: once it has fired,
432
+ * nothing more is asked for and no page is accepted.
433
+ *
434
+ * Every tool keeps its checks, whatever `tools()` and `refresh()` list later —
435
+ * those of any `mcpClient` over the same client included. That holds only
436
+ * while all tool discovery on the client runs through them; see below. The
437
+ * SDK's `Client` checks a tool's call (a required task refused before
438
+ * sending; `structuredContent` required by an `outputSchema`, and matched
439
+ * against it) only for the tools of its most recent `tools/list` answer, so
440
+ * every tool returned here carries those checks itself. They are left to the
441
+ * SDK only for a tool of a one-page list whose answer is still the latest,
442
+ * with no list request out. Every other call runs the tool's own and fails
443
+ * with the same error: a paged list's tools, a tool held across a later
444
+ * `refresh()` (failed or not), a call made while a list is read. Where no JSON
445
+ * Schema validator is reachable (`jsonSchemaValidator` on the `sdk` and
446
+ * `connection` arms), such a call to a tool that declares an `outputSchema` is
447
+ * refused with `McpOutputUncheckedError`: before it is sent, or, when a list
448
+ * was read while it was out, once its answer is in, unread.
449
+ *
450
+ * What it does not cover: a listing the library does not send. Your own
451
+ * `listTools` calls, the SDK client's automatic discovery (`listChanged.tools`
452
+ * with `autoRefresh`, on by default once `listChanged.tools` is given), or any
453
+ * other replacement of the SDK client's cache leave a tool handed out here
454
+ * believing the SDK still holds its checks — so neither its output checks nor
455
+ * its required-task refusal run, even with `jsonSchemaValidator`. The client
456
+ * the library builds (the `transport` and `sdk` arms) never lists by itself;
457
+ * on a client you pass as `connection`, set `autoRefresh: false` and call
458
+ * `refresh()` from `onChanged`, or give `mcpClient` a connection of its own.
379
459
  */
380
460
  tools(): Promise<readonly Tool[]>;
381
461
  /**
382
462
  * Force a refresh from the server. Use when you suspect the server
383
463
  * has dynamically added/removed tools mid-session (e.g., after the
384
- * server processes a config update).
464
+ * server processes a config update). Reads every page, as `tools()` does.
465
+ * When it fails it rejects, and `tools()` keeps serving the catalogue it
466
+ * had: those tools keep their own checks (see `tools()`). Route the server's
467
+ * list-changed notice here, rather than letting the SDK client refresh
468
+ * itself: a listing the library does not send is not covered.
385
469
  */
386
470
  refresh(): Promise<readonly Tool[]>;
387
471
  /** Close the underlying transport. After `close()` the client is unusable. */
@@ -412,8 +496,17 @@ export interface McpClient {
412
496
  * convenience version of it.
413
497
  */
414
498
  export interface McpConnection {
415
- listTools(params?: undefined, options?: McpRequestOptions): Promise<{
499
+ /**
500
+ * One page of the server's tool list. The first page is asked with no params;
501
+ * each later page with the `nextCursor` the page before it returned, as
502
+ * `{ cursor }`. A connection that never pages returns no `nextCursor`.
503
+ */
504
+ listTools(params?: {
505
+ readonly cursor?: string;
506
+ }, options?: McpRequestOptions): Promise<{
416
507
  readonly tools: ReadonlyArray<McpListedTool>;
508
+ /** Present while the server has more tools: what to ask for the next page with. */
509
+ readonly nextCursor?: string;
417
510
  }>;
418
511
  callTool(params: {
419
512
  readonly name: string;
@@ -510,6 +603,29 @@ export interface McpListedTool {
510
603
  readonly inputSchema: Readonly<Record<string, unknown>>;
511
604
  /** MCP's extensibility bag. Absent from most servers' tools. */
512
605
  readonly _meta?: Readonly<Record<string, unknown>>;
606
+ /**
607
+ * What the tool's `structuredContent` must match. Read for the one reason the
608
+ * SDK's `Client` reads it: a tool that declares one must answer with
609
+ * matching `structuredContent` (see `McpClient.tools()` for a paged list).
610
+ */
611
+ readonly outputSchema?: Readonly<Record<string, unknown>>;
612
+ /** How the tool may run: `taskSupport: 'required'` means only as a task, never a plain `tools/call`. */
613
+ readonly execution?: {
614
+ readonly taskSupport?: string;
615
+ };
616
+ }
617
+ /**
618
+ * A JSON Schema validator, as the MCP SDK's `Client` takes one
619
+ * (`jsonSchemaValidator`): `getValidator(schema)` compiles a schema once and
620
+ * returns a function that checks one value against it. Typed STRUCTURALLY so
621
+ * this declaration never references the optional peer; the SDK's own
622
+ * `AjvJsonSchemaValidator` and `CfWorkerJsonSchemaValidator` satisfy it.
623
+ */
624
+ export interface McpJsonSchemaValidator {
625
+ getValidator(schema: object): (input: unknown) => {
626
+ readonly valid: boolean;
627
+ readonly errorMessage?: string;
628
+ };
513
629
  }
514
630
  /**
515
631
  * What `tools/call` can answer with — **a union, because the protocol is one.**