@openrouter/agent 0.9.0 → 0.10.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 (136) hide show
  1. package/README.md +249 -2
  2. package/THIRD_PARTY_NOTICES.md +25 -0
  3. package/esm/index.d.ts +3 -3
  4. package/esm/index.d.ts.map +1 -1
  5. package/esm/index.js +1 -1
  6. package/esm/index.js.map +1 -1
  7. package/esm/inner-loop/call-model.d.ts.map +1 -1
  8. package/esm/inner-loop/call-model.js +25 -7
  9. package/esm/inner-loop/call-model.js.map +1 -1
  10. package/esm/lib/agent-tool.d.ts +1 -1
  11. package/esm/lib/agent-tool.d.ts.map +1 -1
  12. package/esm/lib/agent-tool.js.map +1 -1
  13. package/esm/lib/async-params.d.ts +14 -0
  14. package/esm/lib/async-params.d.ts.map +1 -1
  15. package/esm/lib/async-params.js +25 -1
  16. package/esm/lib/async-params.js.map +1 -1
  17. package/esm/lib/model-result.d.ts +3 -3
  18. package/esm/lib/model-result.d.ts.map +1 -1
  19. package/esm/lib/model-result.js +45 -21
  20. package/esm/lib/model-result.js.map +1 -1
  21. package/esm/lib/next-turn-params.d.ts.map +1 -1
  22. package/esm/lib/next-turn-params.js +3 -1
  23. package/esm/lib/next-turn-params.js.map +1 -1
  24. package/esm/lib/next-turn-params.test.js +72 -0
  25. package/esm/lib/next-turn-params.test.js.map +1 -1
  26. package/esm/lib/stream-transformers.d.ts +1 -1
  27. package/esm/lib/stream-transformers.d.ts.map +1 -1
  28. package/esm/lib/stream-transformers.js.map +1 -1
  29. package/esm/lib/tool-set-types.d.ts +298 -0
  30. package/esm/lib/tool-set-types.d.ts.map +1 -0
  31. package/esm/lib/tool-set-types.js +2 -0
  32. package/esm/lib/tool-set-types.js.map +1 -0
  33. package/esm/lib/tool-set.d.ts +157 -0
  34. package/esm/lib/tool-set.d.ts.map +1 -0
  35. package/esm/lib/tool-set.js +473 -0
  36. package/esm/lib/tool-set.js.map +1 -0
  37. package/esm/lib/tool-types.d.ts +198 -28
  38. package/esm/lib/tool-types.d.ts.map +1 -1
  39. package/esm/lib/tool-types.js.map +1 -1
  40. package/esm/lib/tool.d.ts +47 -21
  41. package/esm/lib/tool.d.ts.map +1 -1
  42. package/esm/lib/tool.js +13 -3
  43. package/esm/lib/tool.js.map +1 -1
  44. package/esm/mcp/auth/auth-resolver.d.ts +14 -0
  45. package/esm/mcp/auth/auth-resolver.d.ts.map +1 -0
  46. package/esm/mcp/auth/auth-resolver.js +27 -0
  47. package/esm/mcp/auth/auth-resolver.js.map +1 -0
  48. package/esm/mcp/auth/auth-types.d.ts +33 -0
  49. package/esm/mcp/auth/auth-types.d.ts.map +1 -0
  50. package/esm/mcp/auth/auth-types.js +4 -0
  51. package/esm/mcp/auth/auth-types.js.map +1 -0
  52. package/esm/mcp/build-tools.d.ts +29 -0
  53. package/esm/mcp/build-tools.d.ts.map +1 -0
  54. package/esm/mcp/build-tools.js +80 -0
  55. package/esm/mcp/build-tools.js.map +1 -0
  56. package/esm/mcp/cache/cache-store.d.ts +24 -0
  57. package/esm/mcp/cache/cache-store.d.ts.map +1 -0
  58. package/esm/mcp/cache/cache-store.js +20 -0
  59. package/esm/mcp/cache/cache-store.js.map +1 -0
  60. package/esm/mcp/cache/cache-types.d.ts +71 -0
  61. package/esm/mcp/cache/cache-types.d.ts.map +1 -0
  62. package/esm/mcp/cache/cache-types.js +49 -0
  63. package/esm/mcp/cache/cache-types.js.map +1 -0
  64. package/esm/mcp/cache/serialize.d.ts +25 -0
  65. package/esm/mcp/cache/serialize.d.ts.map +1 -0
  66. package/esm/mcp/cache/serialize.js +96 -0
  67. package/esm/mcp/cache/serialize.js.map +1 -0
  68. package/esm/mcp/close-quietly.d.ts +24 -0
  69. package/esm/mcp/close-quietly.d.ts.map +1 -0
  70. package/esm/mcp/close-quietly.js +30 -0
  71. package/esm/mcp/close-quietly.js.map +1 -0
  72. package/esm/mcp/create-mcp-tools.d.ts +13 -0
  73. package/esm/mcp/create-mcp-tools.d.ts.map +1 -0
  74. package/esm/mcp/create-mcp-tools.js +87 -0
  75. package/esm/mcp/create-mcp-tools.js.map +1 -0
  76. package/esm/mcp/elicitation.d.ts +11 -0
  77. package/esm/mcp/elicitation.d.ts.map +1 -0
  78. package/esm/mcp/elicitation.js +51 -0
  79. package/esm/mcp/elicitation.js.map +1 -0
  80. package/esm/mcp/errors.d.ts +91 -0
  81. package/esm/mcp/errors.d.ts.map +1 -0
  82. package/esm/mcp/errors.js +91 -0
  83. package/esm/mcp/errors.js.map +1 -0
  84. package/esm/mcp/handle.d.ts +66 -0
  85. package/esm/mcp/handle.d.ts.map +1 -0
  86. package/esm/mcp/handle.js +323 -0
  87. package/esm/mcp/handle.js.map +1 -0
  88. package/esm/mcp/index.d.ts +13 -0
  89. package/esm/mcp/index.d.ts.map +1 -0
  90. package/esm/mcp/index.js +11 -0
  91. package/esm/mcp/index.js.map +1 -0
  92. package/esm/mcp/mcp-connection.d.ts +150 -0
  93. package/esm/mcp/mcp-connection.d.ts.map +1 -0
  94. package/esm/mcp/mcp-connection.js +478 -0
  95. package/esm/mcp/mcp-connection.js.map +1 -0
  96. package/esm/mcp/mcp-sdk.d.ts +10 -0
  97. package/esm/mcp/mcp-sdk.d.ts.map +1 -0
  98. package/esm/mcp/mcp-sdk.js +37 -0
  99. package/esm/mcp/mcp-sdk.js.map +1 -0
  100. package/esm/mcp/rehydrate.d.ts +76 -0
  101. package/esm/mcp/rehydrate.d.ts.map +1 -0
  102. package/esm/mcp/rehydrate.js +505 -0
  103. package/esm/mcp/rehydrate.js.map +1 -0
  104. package/esm/mcp/resource-tools.d.ts +17 -0
  105. package/esm/mcp/resource-tools.d.ts.map +1 -0
  106. package/esm/mcp/resource-tools.js +155 -0
  107. package/esm/mcp/resource-tools.js.map +1 -0
  108. package/esm/mcp/result-mapper.d.ts +19 -0
  109. package/esm/mcp/result-mapper.d.ts.map +1 -0
  110. package/esm/mcp/result-mapper.js +40 -0
  111. package/esm/mcp/result-mapper.js.map +1 -0
  112. package/esm/mcp/schema/json-schema-guards.d.ts +14 -0
  113. package/esm/mcp/schema/json-schema-guards.d.ts.map +1 -0
  114. package/esm/mcp/schema/json-schema-guards.js +19 -0
  115. package/esm/mcp/schema/json-schema-guards.js.map +1 -0
  116. package/esm/mcp/schema/json-schema-to-zod.d.ts +20 -0
  117. package/esm/mcp/schema/json-schema-to-zod.d.ts.map +1 -0
  118. package/esm/mcp/schema/json-schema-to-zod.js +72 -0
  119. package/esm/mcp/schema/json-schema-to-zod.js.map +1 -0
  120. package/esm/mcp/tool-wrapper.d.ts +41 -0
  121. package/esm/mcp/tool-wrapper.d.ts.map +1 -0
  122. package/esm/mcp/tool-wrapper.js +131 -0
  123. package/esm/mcp/tool-wrapper.js.map +1 -0
  124. package/esm/mcp/transport-types.d.ts +45 -0
  125. package/esm/mcp/transport-types.d.ts.map +1 -0
  126. package/esm/mcp/transport-types.js +2 -0
  127. package/esm/mcp/transport-types.js.map +1 -0
  128. package/esm/mcp/types.d.ts +119 -0
  129. package/esm/mcp/types.d.ts.map +1 -0
  130. package/esm/mcp/types.js +2 -0
  131. package/esm/mcp/types.js.map +1 -0
  132. package/esm/mcp/version.d.ts +3 -0
  133. package/esm/mcp/version.d.ts.map +1 -0
  134. package/esm/mcp/version.js +5 -0
  135. package/esm/mcp/version.js.map +1 -0
  136. package/package.json +44 -7
@@ -0,0 +1,71 @@
1
+ import type { MCPTransportKind } from '../transport-types.js';
2
+ /** A discovered tool definition as stored in a cache snapshot. */
3
+ export interface SerializedMCPToolDef {
4
+ name: string;
5
+ description?: string;
6
+ inputSchema: Readonly<Record<string, unknown>>;
7
+ outputSchema?: Readonly<Record<string, unknown>>;
8
+ /** Server-advertised doom-loop identity (field list or `false`), if any. */
9
+ loopKey?: readonly string[] | false;
10
+ }
11
+ /** OAuth/bearer token material, persisted only when `cacheCredentials` is on. */
12
+ export interface SerializedTokenSet {
13
+ accessToken: string;
14
+ tokenType?: string;
15
+ refreshToken?: string;
16
+ /** Epoch ms; absence means unknown/no declared expiry. */
17
+ expiresAt?: number;
18
+ scope?: string;
19
+ }
20
+ /**
21
+ * Serializable snapshot of a connected MCP server: enough to rebuild the tool
22
+ * set (and, opt-in, reconnect with cached credentials) without re-listing or
23
+ * re-authenticating.
24
+ */
25
+ export interface SerializedMCPServer {
26
+ version: 1;
27
+ url: string;
28
+ transport: MCPTransportKind;
29
+ serverInfo?: {
30
+ name?: string;
31
+ version?: string;
32
+ };
33
+ capabilities?: Readonly<Record<string, unknown>>;
34
+ /**
35
+ * Streamable HTTP session id, replayed on reconnect.
36
+ *
37
+ * @deprecated No longer written, and never read back. Protocol-level sessions
38
+ * and the `Mcp-Session-Id` header are removed in revision 2026-07-28
39
+ * (SEP-2567), where cross-call state moves to server-minted handles passed as
40
+ * ordinary tool arguments.
41
+ *
42
+ * The field remains only so snapshots written by older versions keep
43
+ * deserializing — a validator that rejected it would turn every existing cache
44
+ * entry into a hard failure. Nothing populates it now: it is bearer-equivalent
45
+ * to an authenticated server session, so persisting it to an external store was
46
+ * attack surface for no functionality once the replay path stopped forwarding
47
+ * it. Treat any value found here as untrusted legacy data. See the README.
48
+ */
49
+ sessionId?: string;
50
+ tools: SerializedMCPToolDef[];
51
+ auth?: {
52
+ headers?: Readonly<Record<string, string>>;
53
+ tokens?: SerializedTokenSet;
54
+ };
55
+ cachedAt: number;
56
+ }
57
+ /**
58
+ * The shared "valid `cachedAt`" rule: a finite, non-negative epoch (ms).
59
+ * Consumed by both the read-side snapshot validator and the write-side
60
+ * serializer so the two can't drift. Rejecting negatives keeps the invariant
61
+ * honest at the boundary rather than relying on downstream maxAge arithmetic to
62
+ * fail-safe on a clock-skewed or garbage value.
63
+ */
64
+ export declare function isFiniteEpoch(value: unknown): value is number;
65
+ /**
66
+ * Validate an untrusted value as a {@link SerializedMCPServer}. Cache stores may
67
+ * be backed by a DB or another org member's data, so snapshots are checked
68
+ * structurally before use — never trusted by shape alone.
69
+ */
70
+ export declare function isSerializedMCPServer(value: unknown): value is SerializedMCPServer;
71
+ //# sourceMappingURL=cache-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-types.d.ts","sourceRoot":"","sources":["../../../src/mcp/cache/cache-types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,kEAAkE;AAClE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACjD,4EAA4E;IAC5E,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,CAAC;CACrC;AAED,iFAAiF;AACjF,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,CAAC,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,gBAAgB,CAAC;IAC5B,UAAU,CAAC,EAAE;QACX,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACjD;;;;;;;;;;;;;;OAcG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,EAAE,kBAAkB,CAAC;KAC7B,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAMD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE7D;AAmBD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAelF"}
@@ -0,0 +1,49 @@
1
+ import { isJsonSchemaObject } from '../schema/json-schema-guards.js';
2
+ function isTransportKind(value) {
3
+ return value === 'streamableHttp' || value === 'sse';
4
+ }
5
+ /**
6
+ * The shared "valid `cachedAt`" rule: a finite, non-negative epoch (ms).
7
+ * Consumed by both the read-side snapshot validator and the write-side
8
+ * serializer so the two can't drift. Rejecting negatives keeps the invariant
9
+ * honest at the boundary rather than relying on downstream maxAge arithmetic to
10
+ * fail-safe on a clock-skewed or garbage value.
11
+ */
12
+ export function isFiniteEpoch(value) {
13
+ return typeof value === 'number' && Number.isFinite(value) && value >= 0;
14
+ }
15
+ function isSerializedToolDef(value) {
16
+ if (!isJsonSchemaObject(value)) {
17
+ return false;
18
+ }
19
+ const loopKey = value['loopKey'];
20
+ // Absent is valid (the field is optional); present must be `false` or a
21
+ // string array. Anything else — a truthy scalar, a mixed array, a nested
22
+ // object — is a poisoned or stale snapshot and rejects the whole entry.
23
+ const hasValidLoopKey = loopKey === undefined ||
24
+ loopKey === false ||
25
+ (Array.isArray(loopKey) && loopKey.every((field) => typeof field === 'string'));
26
+ return (typeof value['name'] === 'string' && isJsonSchemaObject(value['inputSchema']) && hasValidLoopKey);
27
+ }
28
+ /**
29
+ * Validate an untrusted value as a {@link SerializedMCPServer}. Cache stores may
30
+ * be backed by a DB or another org member's data, so snapshots are checked
31
+ * structurally before use — never trusted by shape alone.
32
+ */
33
+ export function isSerializedMCPServer(value) {
34
+ if (!isJsonSchemaObject(value)) {
35
+ return false;
36
+ }
37
+ if (value['version'] !== 1) {
38
+ return false;
39
+ }
40
+ if (typeof value['url'] !== 'string' || !isTransportKind(value['transport'])) {
41
+ return false;
42
+ }
43
+ if (!isFiniteEpoch(value['cachedAt'])) {
44
+ return false;
45
+ }
46
+ const { tools } = value;
47
+ return Array.isArray(tools) && tools.every(isSerializedToolDef);
48
+ }
49
+ //# sourceMappingURL=cache-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-types.js","sourceRoot":"","sources":["../../../src/mcp/cache/cache-types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AA6DrE,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,KAAK,KAAK,gBAAgB,IAAI,KAAK,KAAK,KAAK,CAAC;AACvD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAc;IACzC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;IACjC,wEAAwE;IACxE,yEAAyE;IACzE,wEAAwE;IACxE,MAAM,eAAe,GACnB,OAAO,KAAK,SAAS;QACrB,OAAO,KAAK,KAAK;QACjB,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC;IAClF,OAAO,CACL,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,QAAQ,IAAI,kBAAkB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,IAAI,eAAe,CACjG,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,QAAQ,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;QAC7E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IACxB,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;AAClE,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { MCPAuth } from '../auth/auth-types.js';
2
+ import type { McpToolDef } from '../tool-wrapper.js';
3
+ import type { MCPTransportKind } from '../types.js';
4
+ import type { SerializedMCPServer } from './cache-types.js';
5
+ export interface SerializeInput {
6
+ url: string;
7
+ transport: MCPTransportKind;
8
+ toolDefs: readonly McpToolDef[];
9
+ serverInfo?: {
10
+ name?: string;
11
+ version?: string;
12
+ };
13
+ capabilities?: Readonly<Record<string, unknown>>;
14
+ auth?: MCPAuth;
15
+ cacheCredentials: boolean;
16
+ cachedAt: number;
17
+ }
18
+ /**
19
+ * Build a serializable snapshot. Credentials (tokens/headers) are included only
20
+ * when `cacheCredentials` is true; otherwise the snapshot holds just the
21
+ * structural data needed to rebuild the tool set after a fresh auth. Session ids
22
+ * are never included — see the note in the `cacheCredentials` branch.
23
+ */
24
+ export declare function serializeServer(input: SerializeInput): Promise<SerializedMCPServer>;
25
+ //# sourceMappingURL=serialize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../../src/mcp/cache/serialize.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAsB,MAAM,kBAAkB,CAAC;AAGhF,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE;QACX,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACjD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAuED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA6CzF"}
@@ -0,0 +1,96 @@
1
+ import { resolveAuth } from '../auth/auth-resolver.js';
2
+ import { isFiniteEpoch } from './cache-types.js';
3
+ const _expiresInStillRelative = true;
4
+ void _expiresInStillRelative;
5
+ /** Pull a serializable token set from an OAuth provider, if it has tokens. */
6
+ async function tokensFromProvider(provider) {
7
+ const tokens = await provider.tokens();
8
+ if (tokens === undefined) {
9
+ return undefined;
10
+ }
11
+ const expiresInMs = typeof tokens.expires_in === 'number' ? tokens.expires_in * 1000 : undefined;
12
+ return {
13
+ accessToken: tokens.access_token,
14
+ ...(typeof tokens.token_type === 'string' && {
15
+ tokenType: tokens.token_type,
16
+ }),
17
+ ...(typeof tokens.refresh_token === 'string' && {
18
+ refreshToken: tokens.refresh_token,
19
+ }),
20
+ ...(typeof tokens.scope === 'string' && {
21
+ scope: tokens.scope,
22
+ }),
23
+ ...(expiresInMs !== undefined && {
24
+ expiresAt: Date.now() + expiresInMs,
25
+ }),
26
+ };
27
+ }
28
+ async function buildAuthBlock(auth) {
29
+ if (auth === undefined) {
30
+ return undefined;
31
+ }
32
+ if (auth.kind === 'oauth') {
33
+ const tokens = await tokensFromProvider(auth.provider);
34
+ return tokens !== undefined
35
+ ? {
36
+ tokens,
37
+ }
38
+ : undefined;
39
+ }
40
+ const { headers } = resolveAuth(auth);
41
+ return Object.keys(headers).length > 0
42
+ ? {
43
+ headers,
44
+ }
45
+ : undefined;
46
+ }
47
+ /**
48
+ * Build a serializable snapshot. Credentials (tokens/headers) are included only
49
+ * when `cacheCredentials` is true; otherwise the snapshot holds just the
50
+ * structural data needed to rebuild the tool set after a fresh auth. Session ids
51
+ * are never included — see the note in the `cacheCredentials` branch.
52
+ */
53
+ export async function serializeServer(input) {
54
+ const tools = input.toolDefs.map((def) => ({
55
+ name: def.name,
56
+ ...(def.description !== undefined && {
57
+ description: def.description,
58
+ }),
59
+ inputSchema: def.inputSchema,
60
+ ...(def.outputSchema !== undefined && {
61
+ outputSchema: def.outputSchema,
62
+ }),
63
+ ...(def.loopKey !== undefined && {
64
+ loopKey: def.loopKey,
65
+ }),
66
+ }));
67
+ const snapshot = {
68
+ version: 1,
69
+ url: input.url,
70
+ transport: input.transport,
71
+ ...(input.serverInfo !== undefined && {
72
+ serverInfo: input.serverInfo,
73
+ }),
74
+ ...(input.capabilities !== undefined && {
75
+ capabilities: input.capabilities,
76
+ }),
77
+ tools,
78
+ cachedAt: isFiniteEpoch(input.cachedAt) ? input.cachedAt : Date.now(),
79
+ };
80
+ if (input.cacheCredentials) {
81
+ const auth = await buildAuthBlock(input.auth);
82
+ if (auth !== undefined) {
83
+ snapshot.auth = auth;
84
+ }
85
+ // `sessionId` is deliberately NOT persisted. A Streamable HTTP
86
+ // `Mcp-Session-Id` is a bearer-equivalent handle to an authenticated server
87
+ // session, and nothing reads it back: the replay path stopped forwarding it
88
+ // once we found that a transport reporting a sessionId makes SDK v2 skip
89
+ // negotiation entirely, silently losing server capabilities. Writing it to an
90
+ // external store (Redis, a database, a file) would be attack surface for no
91
+ // functionality. That it was gated behind `cacheCredentials` at all reflects
92
+ // that it was always credential-grade.
93
+ }
94
+ return snapshot;
95
+ }
96
+ //# sourceMappingURL=serialize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../../src/mcp/cache/serialize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Release something closeable on a path that is already failing, swallowing
3
+ * whatever `close()` does on the way out.
4
+ *
5
+ * The `try` matters as much as the `catch`: `close()` is not guaranteed to
6
+ * return a rejected promise on failure, and a *synchronous* throw never
7
+ * produces one — so `x.close().catch(() => {})` throws before `.catch()` is
8
+ * ever attached. On an unwinding path that is actively harmful in two ways: it
9
+ * replaces the real error (a useful "couldn't reach the server" becomes an
10
+ * opaque teardown failure), and it skips whatever recovery followed the close —
11
+ * a fallback that used to self-heal starts rejecting instead.
12
+ *
13
+ * Every teardown-on-failure site in this package goes through here, so the
14
+ * guarantee holds uniformly rather than depending on each caller remembering
15
+ * the distinction.
16
+ *
17
+ * Deliberately not exported from the package entrypoint: callers close through
18
+ * `MCPToolsHandle.close()` / `MCPConnection.close()`, which report failures
19
+ * rather than swallowing them. This is only for teardown during error unwinding.
20
+ */
21
+ export declare function closeQuietly(closeable: {
22
+ close(): Promise<void>;
23
+ }): Promise<void>;
24
+ //# sourceMappingURL=close-quietly.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"close-quietly.d.ts","sourceRoot":"","sources":["../../src/mcp/close-quietly.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE;IAAE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvF"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Release something closeable on a path that is already failing, swallowing
3
+ * whatever `close()` does on the way out.
4
+ *
5
+ * The `try` matters as much as the `catch`: `close()` is not guaranteed to
6
+ * return a rejected promise on failure, and a *synchronous* throw never
7
+ * produces one — so `x.close().catch(() => {})` throws before `.catch()` is
8
+ * ever attached. On an unwinding path that is actively harmful in two ways: it
9
+ * replaces the real error (a useful "couldn't reach the server" becomes an
10
+ * opaque teardown failure), and it skips whatever recovery followed the close —
11
+ * a fallback that used to self-heal starts rejecting instead.
12
+ *
13
+ * Every teardown-on-failure site in this package goes through here, so the
14
+ * guarantee holds uniformly rather than depending on each caller remembering
15
+ * the distinction.
16
+ *
17
+ * Deliberately not exported from the package entrypoint: callers close through
18
+ * `MCPToolsHandle.close()` / `MCPConnection.close()`, which report failures
19
+ * rather than swallowing them. This is only for teardown during error unwinding.
20
+ */
21
+ export async function closeQuietly(closeable) {
22
+ try {
23
+ await closeable.close();
24
+ }
25
+ catch {
26
+ // Nothing actionable: we are already unwinding a failure, and the close
27
+ // outcome is never the error the caller needs to see.
28
+ }
29
+ }
30
+ //# sourceMappingURL=close-quietly.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"close-quietly.js","sourceRoot":"","sources":["../../src/mcp/close-quietly.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAqC;IACtE,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,wEAAwE;QACxE,sDAAsD;IACxD,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { SerializedMCPServer } from './cache/cache-types.js';
2
+ import type { CreateMCPToolsOptions, MCPToolsHandle } from './types.js';
3
+ /**
4
+ * Connect to a remote MCP server, discover its tools, and return a handle whose
5
+ * `.tools` can be passed straight into `callModel({ tools })`. Auth is supplied
6
+ * once and reused for discovery and every subsequent tool call.
7
+ *
8
+ * When `cache` is provided, a valid non-stale snapshot is rehydrated instead of
9
+ * re-listing; otherwise the fresh result is written back to the cache.
10
+ */
11
+ export declare function createMCPTools(options: CreateMCPToolsOptions): Promise<MCPToolsHandle>;
12
+ export type { SerializedMCPServer };
13
+ //# sourceMappingURL=create-mcp-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-mcp-tools.d.ts","sourceRoot":"","sources":["../../src/mcp/create-mcp-tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAKlE,OAAO,KAAK,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAExE;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CAY5F;AAyED,YAAY,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,87 @@
1
+ import { defaultCacheKey } from './cache/cache-store.js';
2
+ import { isSerializedMCPServer } from './cache/cache-types.js';
3
+ import { freshConnect, normalizeUrl } from './handle.js';
4
+ import { rehydrateMCPTools } from './rehydrate.js';
5
+ /**
6
+ * Connect to a remote MCP server, discover its tools, and return a handle whose
7
+ * `.tools` can be passed straight into `callModel({ tools })`. Auth is supplied
8
+ * once and reused for discovery and every subsequent tool call.
9
+ *
10
+ * When `cache` is provided, a valid non-stale snapshot is rehydrated instead of
11
+ * re-listing; otherwise the fresh result is written back to the cache.
12
+ */
13
+ export async function createMCPTools(options) {
14
+ const url = normalizeUrl(options.url);
15
+ const cacheKey = options.cache?.key ?? defaultCacheKey(url.href);
16
+ if (options.cache !== undefined) {
17
+ const hit = await tryCacheHit(options, options.cache.store, cacheKey);
18
+ if (hit !== undefined) {
19
+ return hit;
20
+ }
21
+ }
22
+ return freshConnect(options, url, cacheKey);
23
+ }
24
+ // Option keys forwarded verbatim from a cache-hit `createMCPTools` call into
25
+ // `rehydrateMCPTools`, so a warm handle applies the same auth, filters, prefix,
26
+ // loop identities, and credential-caching behavior as a cold one. Anything
27
+ // omitted here is SILENTLY DROPPED on a cache hit — when adding an option to
28
+ // `CreateMCPToolsOptions` that rehydrate also honors, add it here too.
29
+ const FORWARDED_REHYDRATE_KEYS = [
30
+ 'auth',
31
+ 'fetch',
32
+ 'clientInfo',
33
+ 'onUnconvertibleSchema',
34
+ 'onElicitation',
35
+ 'signal',
36
+ 'toolNamePrefix',
37
+ 'includeTools',
38
+ 'excludeTools',
39
+ 'resources',
40
+ 'emitProgress',
41
+ 'loopKeys',
42
+ 'autoRefreshOnListChanged',
43
+ 'cacheCredentials',
44
+ 'protocolNegotiation',
45
+ 'probeTimeoutMs',
46
+ 'staleness',
47
+ ];
48
+ /** Copy the defined forwarded options from `createMCPTools` into a rehydrate base. */
49
+ function forwardedRehydrateOptions(options) {
50
+ const out = {};
51
+ for (const key of FORWARDED_REHYDRATE_KEYS) {
52
+ const value = options[key];
53
+ if (value !== undefined) {
54
+ Object.assign(out, {
55
+ [key]: value,
56
+ });
57
+ }
58
+ }
59
+ return out;
60
+ }
61
+ async function tryCacheHit(options, store, cacheKey) {
62
+ let snapshot;
63
+ try {
64
+ snapshot = await store.get(cacheKey);
65
+ }
66
+ catch {
67
+ snapshot = undefined;
68
+ }
69
+ if (snapshot === null || snapshot === undefined || !isSerializedMCPServer(snapshot)) {
70
+ return undefined;
71
+ }
72
+ const maxAge = options.staleness?.maxAgeMs;
73
+ if (maxAge !== undefined && Date.now() - snapshot.cachedAt > maxAge) {
74
+ return undefined;
75
+ }
76
+ // Defer to rehydrate, which reconnects and falls back to a fresh connect on
77
+ // expiry.
78
+ return rehydrateMCPTools({
79
+ snapshot,
80
+ ...forwardedRehydrateOptions(options),
81
+ cache: {
82
+ store,
83
+ key: cacheKey,
84
+ },
85
+ });
86
+ }
87
+ //# sourceMappingURL=create-mcp-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-mcp-tools.js","sourceRoot":"","sources":["../../src/mcp/create-mcp-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGnD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAA8B;IACjE,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAEjE,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACtE,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC;IAED,OAAO,YAAY,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED,6EAA6E;AAC7E,gFAAgF;AAChF,2EAA2E;AAC3E,6EAA6E;AAC7E,uEAAuE;AACvE,MAAM,wBAAwB,GAAG;IAC/B,MAAM;IACN,OAAO;IACP,YAAY;IACZ,uBAAuB;IACvB,eAAe;IACf,QAAQ;IACR,gBAAgB;IAChB,cAAc;IACd,cAAc;IACd,WAAW;IACX,cAAc;IACd,UAAU;IACV,0BAA0B;IAC1B,kBAAkB;IAClB,qBAAqB;IACrB,gBAAgB;IAChB,WAAW;CACiF,CAAC;AAE/F,sFAAsF;AACtF,SAAS,yBAAyB,CAChC,OAA8B;IAE9B,MAAM,GAAG,GAAsC,EAAE,CAAC;IAClD,KAAK,MAAM,GAAG,IAAI,wBAAwB,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE;gBACjB,CAAC,GAAG,CAAC,EAAE,KAAK;aACb,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,OAA8B,EAC9B,KAAoB,EACpB,QAAgB;IAEhB,IAAI,QAA+D,CAAC;IACpE,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,QAAQ,GAAG,SAAS,CAAC;IACvB,CAAC;IACD,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC;IAC3C,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,QAAQ,GAAG,MAAM,EAAE,CAAC;QACpE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,4EAA4E;IAC5E,UAAU;IACV,OAAO,iBAAiB,CAAC;QACvB,QAAQ;QACR,GAAG,yBAAyB,CAAC,OAAO,CAAC;QACrC,KAAK,EAAE;YACL,KAAK;YACL,GAAG,EAAE,QAAQ;SACd;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { ElicitRequest, ElicitResult } from '@modelcontextprotocol/client';
2
+ import type { ElicitationHandler } from './types.js';
3
+ /**
4
+ * Build the `elicitation/create` request handler registered on the MCP client.
5
+ * Delegates to the caller's {@link ElicitationHandler}; when none is supplied,
6
+ * auto-declines so a tool call awaiting input fails gracefully instead of
7
+ * hanging. The MCP spec forbids eliciting sensitive/PII data — that contract is
8
+ * the server's responsibility; callers should treat requested fields as such.
9
+ */
10
+ export declare function makeElicitationRequestHandler(handler: ElicitationHandler | undefined): (request: ElicitRequest) => Promise<ElicitResult>;
11
+ //# sourceMappingURL=elicitation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elicitation.d.ts","sourceRoot":"","sources":["../../src/mcp/elicitation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEhF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA4BrD;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,kBAAkB,GAAG,SAAS,GACtC,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,CA2BnD"}
@@ -0,0 +1,51 @@
1
+ import { isJsonSchemaObject } from './schema/json-schema-guards.js';
2
+ /** A form-mode elicitation request carries a `requestedSchema`. */
3
+ function hasRequestedSchema(params) {
4
+ return 'requestedSchema' in params;
5
+ }
6
+ /** Narrow handler-returned content to the primitive record the spec allows. */
7
+ function toElicitContent(content) {
8
+ const out = {};
9
+ for (const [key, value] of Object.entries(content)) {
10
+ if (typeof value === 'string' ||
11
+ typeof value === 'number' ||
12
+ typeof value === 'boolean' ||
13
+ (Array.isArray(value) && value.every((v) => typeof v === 'string'))) {
14
+ out[key] = value;
15
+ }
16
+ }
17
+ return out;
18
+ }
19
+ /**
20
+ * Build the `elicitation/create` request handler registered on the MCP client.
21
+ * Delegates to the caller's {@link ElicitationHandler}; when none is supplied,
22
+ * auto-declines so a tool call awaiting input fails gracefully instead of
23
+ * hanging. The MCP spec forbids eliciting sensitive/PII data — that contract is
24
+ * the server's responsibility; callers should treat requested fields as such.
25
+ */
26
+ export function makeElicitationRequestHandler(handler) {
27
+ return async (request) => {
28
+ if (handler === undefined) {
29
+ return {
30
+ action: 'decline',
31
+ };
32
+ }
33
+ const { params } = request;
34
+ const requestedSchema = hasRequestedSchema(params) ? params.requestedSchema : undefined;
35
+ const schema = isJsonSchemaObject(requestedSchema) ? requestedSchema : {};
36
+ const response = await handler({
37
+ message: params.message,
38
+ requestedSchema: schema,
39
+ });
40
+ if (response.action === 'accept') {
41
+ return {
42
+ action: 'accept',
43
+ content: toElicitContent(response.content),
44
+ };
45
+ }
46
+ return {
47
+ action: response.action,
48
+ };
49
+ };
50
+ }
51
+ //# sourceMappingURL=elicitation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elicitation.js","sourceRoot":"","sources":["../../src/mcp/elicitation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAMpE,mEAAmE;AACnE,SAAS,kBAAkB,CAAC,MAA+B;IAGzD,OAAO,iBAAiB,IAAI,MAAM,CAAC;AACrC,CAAC;AAED,+EAA+E;AAC/E,SAAS,eAAe,CAAC,OAAgC;IACvD,MAAM,GAAG,GAAuC,EAAE,CAAC;IACnD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,IACE,OAAO,KAAK,KAAK,QAAQ;YACzB,OAAO,KAAK,KAAK,QAAQ;YACzB,OAAO,KAAK,KAAK,SAAS;YAC1B,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,EAChF,CAAC;YACD,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAC3C,OAAuC;IAEvC,OAAO,KAAK,EAAE,OAAsB,EAAyB,EAAE;QAC7D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO;gBACL,MAAM,EAAE,SAAS;aAClB,CAAC;QACJ,CAAC;QAED,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAC3B,MAAM,eAAe,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC;QACxF,MAAM,MAAM,GAAG,kBAAkB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;QAE1E,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;YAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,eAAe,EAAE,MAAM;SACxB,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACjC,OAAO;gBACL,MAAM,EAAE,QAAQ;gBAChB,OAAO,EAAE,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC;aAC3C,CAAC;QACJ,CAAC;QACD,OAAO;YACL,MAAM,EAAE,QAAQ,CAAC,MAAM;SACxB,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Base error for all @openrouter/agent/mcp failures.
3
+ */
4
+ export declare class MCPError extends Error {
5
+ constructor(message: string, options?: {
6
+ cause?: unknown;
7
+ });
8
+ }
9
+ /**
10
+ * Raised when an MCP tool call returns `isError: true` or when the result
11
+ * cannot be mapped to a usable model output.
12
+ */
13
+ export declare class MCPToolCallError extends MCPError {
14
+ readonly toolName: string;
15
+ constructor(toolName: string, message: string, options?: {
16
+ cause?: unknown;
17
+ });
18
+ }
19
+ /**
20
+ * Raised when a cached snapshot cannot be validated or rehydrated.
21
+ */
22
+ export declare class MCPCacheError extends MCPError {
23
+ constructor(message: string, options?: {
24
+ cause?: unknown;
25
+ });
26
+ }
27
+ /**
28
+ * Raised when the tool list was read successfully but writing the snapshot back
29
+ * to the caller's `MCPCacheStore` failed.
30
+ *
31
+ * Distinct from the read failing, because the consequences differ completely: the
32
+ * connection is live and its tools are current, so the only thing lost is a cache
33
+ * entry. Callers who treat a store outage as fatal can catch this; callers who
34
+ * would rather keep working with a warm handle can ignore it.
35
+ *
36
+ * Subclasses {@link MCPCacheError}, so existing catch sites keep working.
37
+ */
38
+ export declare class MCPCacheWriteError extends MCPCacheError {
39
+ constructor(message: string, options?: {
40
+ cause?: unknown;
41
+ });
42
+ }
43
+ /**
44
+ * Raised when a snapshot is older than `staleness.maxAgeMs` and the re-list that
45
+ * would have refreshed it failed — so the only tools available are ones the
46
+ * caller declared too old to use.
47
+ *
48
+ * Subclasses {@link MCPCacheError}, so existing `catch (e instanceof
49
+ * MCPCacheError)` sites keep working. Catch this specifically to fall back to
50
+ * stale-but-usable tools instead of failing.
51
+ */
52
+ export declare class MCPStaleSnapshotError extends MCPCacheError {
53
+ constructor(message: string, options?: {
54
+ cause?: unknown;
55
+ });
56
+ }
57
+ /**
58
+ * Raised when connecting to the MCP server fails across all attempted transports.
59
+ */
60
+ export declare class MCPConnectionError extends MCPError {
61
+ /**
62
+ * Every failure behind this one, in attempt order.
63
+ *
64
+ * `cause` holds only the last attempt, which loses information: an
65
+ * `UnauthorizedError` from the Streamable HTTP attempt matters even when the
66
+ * SSE fallback then failed for an unrelated reason (a URL that simply isn't an
67
+ * SSE endpoint answering 404). Named `errors` to match `AggregateError`, so it
68
+ * reads the way callers expect rather than as a bespoke field.
69
+ *
70
+ * Always populated: a single-attempt failure contributes its one underlying
71
+ * error, so `errors[errors.length - 1]` and `cause` agree and a caller can
72
+ * iterate `errors` alone without special-casing the single-attempt shape —
73
+ * which matters most on the auth short-circuit, where exactly one attempt was
74
+ * made and its rejection is the thing worth finding.
75
+ */
76
+ readonly errors: readonly unknown[];
77
+ constructor(message: string, options?: {
78
+ cause?: unknown;
79
+ errors?: readonly unknown[];
80
+ });
81
+ }
82
+ /**
83
+ * Raised when MCP support is used without its optional SDK peer installed.
84
+ */
85
+ export declare class MCPMissingPeerDependencyError extends MCPConnectionError {
86
+ readonly packageName = "@modelcontextprotocol/client";
87
+ constructor(options?: {
88
+ cause?: unknown;
89
+ });
90
+ }
91
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/mcp/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;gBAE/B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;CAKJ;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAGxB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;CAMJ;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,QAAQ;gBAEvC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;CAKJ;AAED;;;;;;;;;;GAUG;AACH,qBAAa,kBAAmB,SAAQ,aAAa;gBAEjD,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;CAKJ;AAED;;;;;;;;GAQG;AACH,qBAAa,qBAAsB,SAAQ,aAAa;gBAEpD,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;CAKJ;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,QAAQ;IAC9C;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC;gBAGlC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;KAC7B;CAcJ;AAED;;GAEG;AACH,qBAAa,6BAA8B,SAAQ,kBAAkB;IACnE,QAAQ,CAAC,WAAW,kCAAkC;gBAE1C,OAAO,CAAC,EAAE;QACpB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB;CAQF"}