@openrouter/mcp 0.0.1 → 1.0.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 (64) hide show
  1. package/README.md +156 -6
  2. package/esm/auth/auth-resolver.d.ts +1 -1
  3. package/esm/auth/auth-resolver.d.ts.map +1 -1
  4. package/esm/auth/auth-types.d.ts +9 -1
  5. package/esm/auth/auth-types.d.ts.map +1 -1
  6. package/esm/auth/auth-types.js.map +1 -1
  7. package/esm/build-tools.d.ts +4 -2
  8. package/esm/build-tools.d.ts.map +1 -1
  9. package/esm/build-tools.js +3 -0
  10. package/esm/build-tools.js.map +1 -1
  11. package/esm/cache/cache-types.d.ts +17 -0
  12. package/esm/cache/cache-types.d.ts.map +1 -1
  13. package/esm/cache/cache-types.js +11 -3
  14. package/esm/cache/cache-types.js.map +1 -1
  15. package/esm/cache/serialize.d.ts +4 -4
  16. package/esm/cache/serialize.d.ts.map +1 -1
  17. package/esm/cache/serialize.js +17 -6
  18. package/esm/cache/serialize.js.map +1 -1
  19. package/esm/close-quietly.d.ts +24 -0
  20. package/esm/close-quietly.d.ts.map +1 -0
  21. package/esm/close-quietly.js +30 -0
  22. package/esm/close-quietly.js.map +1 -0
  23. package/esm/create-mcp-tools.d.ts.map +1 -1
  24. package/esm/create-mcp-tools.js +23 -2
  25. package/esm/create-mcp-tools.js.map +1 -1
  26. package/esm/elicitation.d.ts +1 -1
  27. package/esm/elicitation.d.ts.map +1 -1
  28. package/esm/errors.d.ts +47 -0
  29. package/esm/errors.d.ts.map +1 -1
  30. package/esm/errors.js +41 -0
  31. package/esm/errors.js.map +1 -1
  32. package/esm/handle.d.ts +25 -0
  33. package/esm/handle.d.ts.map +1 -1
  34. package/esm/handle.js +116 -14
  35. package/esm/handle.js.map +1 -1
  36. package/esm/index.d.ts +3 -3
  37. package/esm/index.d.ts.map +1 -1
  38. package/esm/index.js +1 -1
  39. package/esm/index.js.map +1 -1
  40. package/esm/mcp-connection.d.ts +114 -7
  41. package/esm/mcp-connection.d.ts.map +1 -1
  42. package/esm/mcp-connection.js +364 -34
  43. package/esm/mcp-connection.js.map +1 -1
  44. package/esm/rehydrate.d.ts +40 -5
  45. package/esm/rehydrate.d.ts.map +1 -1
  46. package/esm/rehydrate.js +381 -55
  47. package/esm/rehydrate.js.map +1 -1
  48. package/esm/resource-tools.d.ts +1 -1
  49. package/esm/resource-tools.d.ts.map +1 -1
  50. package/esm/resource-tools.js +24 -2
  51. package/esm/resource-tools.js.map +1 -1
  52. package/esm/tool-wrapper.d.ts +17 -2
  53. package/esm/tool-wrapper.d.ts.map +1 -1
  54. package/esm/tool-wrapper.js +16 -3
  55. package/esm/tool-wrapper.js.map +1 -1
  56. package/esm/transport-types.d.ts +43 -1
  57. package/esm/transport-types.d.ts.map +1 -1
  58. package/esm/types.d.ts +56 -7
  59. package/esm/types.d.ts.map +1 -1
  60. package/esm/version.d.ts +3 -0
  61. package/esm/version.d.ts.map +1 -0
  62. package/esm/version.js +5 -0
  63. package/esm/version.js.map +1 -0
  64. package/package.json +13 -9
package/README.md CHANGED
@@ -9,11 +9,15 @@ Expose the tools of a remote [Model Context Protocol](https://modelcontextprotoc
9
9
  - Faithful JSON Schema → Zod conversion so the model sees real parameters.
10
10
  - Serializable, rehydratable cache so you can skip re-listing (and, opt-in, re-authenticating).
11
11
  - Progress streaming, `tools/list_changed` auto-refresh, cancellation, resources, and elicitation.
12
+ - Speaks both MCP protocol revisions (`2025-11-25` and `2026-07-28`), negotiated per server.
12
13
 
13
14
  > stdio servers are intentionally out of scope.
14
15
 
15
16
  ## Install
16
17
 
18
+ Requires **Node 20+** (inherited from `@modelcontextprotocol/client@2`, which declares
19
+ `engines.node: >=20`; this package declares the same).
20
+
17
21
  ```bash
18
22
  pnpm add @openrouter/mcp @openrouter/agent
19
23
  ```
@@ -55,8 +59,8 @@ auth: { kind: 'headers', headers: { 'X-API-Key': key } }
55
59
  auth: { kind: 'oauth', provider }
56
60
  ```
57
61
 
58
- Prefer an `OAuthClientProvider` over caching static tokens — the transport refreshes through it
59
- automatically.
62
+ Prefer an OAuth provider over caching static tokens — the transport refreshes through it
63
+ automatically. Type yours with `MCPOAuthClientProvider`, re-exported from this package.
60
64
 
61
65
  ## Caching & rehydration
62
66
 
@@ -86,9 +90,44 @@ const mcp = await createMCPTools({
86
90
  });
87
91
  ```
88
92
 
93
+ `staleness.maxAgeMs` is honoured by `rehydrateMCPTools()` as well as by `createMCPTools()`'s
94
+ cache-hit path, and on every path — including `reconnectOnExpiry: false`, which opts out of
95
+ rebuilding the transport, not out of bounded-age tools. An over-age snapshot re-lists over
96
+ the replayed connection. If that re-list fails, the call rejects with `MCPStaleSnapshotError`
97
+ rather than quietly serving tools you declared too old; catch it to opt back in:
98
+
99
+ ```ts
100
+ import { rehydrateMCPTools, MCPStaleSnapshotError } from '@openrouter/mcp';
101
+
102
+ try {
103
+ return await rehydrateMCPTools({
104
+ snapshot,
105
+ staleness: { maxAgeMs: 60_000 },
106
+ reconnectOnExpiry: false,
107
+ });
108
+ } catch (err) {
109
+ if (err instanceof MCPStaleSnapshotError) {
110
+ // Connection was fine, only the re-list failed — take the cached tool set.
111
+ return await rehydrateMCPTools({ snapshot, reconnectOnExpiry: false });
112
+ }
113
+ throw err;
114
+ }
115
+ ```
116
+
117
+ It subclasses `MCPCacheError`, so existing `catch (e instanceof MCPCacheError)` sites keep
118
+ working. Note that a successful replay does not write to the store — the snapshot it would
119
+ write is the one just read. Seeding a store from a snapshot obtained elsewhere means writing
120
+ it yourself or calling `handle.refresh()` after rehydrating. Writing a snapshot back to your store is best-effort: a store outage leaves you with a
121
+ working handle and a stale cache entry rather than a failed call. Catch `MCPCacheWriteError`
122
+ from `handle.refresh()` if you would rather treat that as fatal. `handle.refresh()` also always reaches the server: SDK v2 caches `tools/list` per
123
+ client up to the server's `ttlMs`, and every internal list read bypasses that so a refresh
124
+ cannot hand back the previous tool set.
125
+
89
126
  > **Security:** `cacheCredentials` is `false` by default. When enabled, snapshots contain bearer
90
127
  > tokens/headers — treat the store as a secret store and namespace cache keys by principal in
91
- > multi-tenant setups.
128
+ > multi-tenant setups. Session ids are never persisted: an `Mcp-Session-Id` is
129
+ > bearer-equivalent to an authenticated server session, and nothing reads it back, so it would
130
+ > be attack surface for no functionality. A `sessionId` found in an old snapshot is ignored.
92
131
 
93
132
  ## Multiple servers
94
133
 
@@ -110,7 +149,9 @@ const result = callModel(client, {
110
149
  | Option | Description |
111
150
  | --- | --- |
112
151
  | `url` | Remote MCP server endpoint. |
113
- | `transport` | `'streamableHttp'` (default, falls back to SSE) or `'sse'`. |
152
+ | `transport` | `'streamableHttp'` (default, falls back to SSE) or `'sse'` (deprecated upstream). |
153
+ | `protocolNegotiation` | `'auto'` (default), `'legacy'`, or `{ pin }`. See Protocol revisions. |
154
+ | `probeTimeoutMs` | Ceiling on the `server/discover` probe (default 30000). |
114
155
  | `auth` | Bearer token, headers, or an `OAuthClientProvider`. |
115
156
  | `toolNamePrefix` | Prefix every wrapped tool name. |
116
157
  | `includeTools` / `excludeTools` | Allow/deny lists by MCP tool name. |
@@ -119,8 +160,117 @@ const result = callModel(client, {
119
160
  | `resources` | Expose synthetic `list_resources` / `read_resource` tools (default on). |
120
161
  | `emitProgress` | Stream MCP progress as generator-tool events (default on). |
121
162
  | `autoRefreshOnListChanged` | Re-list on `tools/list_changed` (default on). |
122
- | `onElicitation` | Handle server elicitation requests; auto-declines when omitted. |
123
- | `signal` | Abort signal threaded into every tool call. |
163
+ | `onElicitation` | Handle elicitation requests (both revisions); auto-declines when omitted. |
164
+ | `signal` | Aborts every tool call and the connection itself (connect, probe, legacy retry, reconnects). |
165
+
166
+ ## Client identity
167
+
168
+ The client identifies itself to every server it connects to via MCP `clientInfo`
169
+ (`{ name, version }`). Pass `clientInfo` in options to override it; otherwise the default
170
+ is `@openrouter/mcp` at this package's version.
171
+
172
+ That version is **generated** into `src/version.ts` from `package.json`, which is the
173
+ single source of truth. `build` regenerates it, so a changesets version bump is picked up
174
+ automatically before publish. To regenerate by hand:
175
+
176
+ ```bash
177
+ pnpm --filter @openrouter/mcp gen:version
178
+ ```
179
+
180
+ The generated file is committed rather than gitignored, because CI's lint, typecheck, and
181
+ unit-test jobs compile `src` without running a build. `tests/unit/version.test.ts` fails
182
+ if the committed constant drifts from `package.json`, so a stale value cannot merge.
183
+
184
+ ## Protocol revisions
185
+
186
+ Both current MCP revisions are supported, and the right one is chosen for you. Point this
187
+ at any server and it works:
188
+
189
+ ```ts
190
+ const mcp = await createMCPTools({ url: 'https://mcp.example.com/mcp' });
191
+ ```
192
+
193
+ By default (`protocolNegotiation: 'auto'`) the client probes with `server/discover` and
194
+ then speaks whichever revision the server offers:
195
+
196
+ | Server | What goes on the wire |
197
+ | --- | --- |
198
+ | **`2026-07-28`** | `server/discover`, then requests carrying the per-request `_meta` envelope and `Mcp-Method` / `Mcp-Name` headers. No `initialize` — the handshake is removed in this revision (SEP-2575). |
199
+ | **`2025-11-25`** and earlier | `server/discover`, then a fallback to the classic `initialize` + `notifications/initialized` handshake, byte-equivalent to a 2025-only client. |
200
+
201
+ A probe is a new request, and some infrastructure dislikes new requests — a proxy, WAF, or
202
+ strict gateway may hang or 5xx on an unknown method. **You don't need to configure anything
203
+ for that case.** When you have not set `protocolNegotiation`, a failed connect is retried
204
+ once with `'legacy'`, so such a server connects exactly as it did before this package
205
+ probed at all. That covers the pinned `transport: 'sse'` path and the Streamable HTTP → SSE
206
+ fallback too, since all three share one client factory.
207
+
208
+ Override when you need to:
209
+
210
+ ```ts
211
+ // Skip the probe. A performance choice, not a compatibility one: saves the extra
212
+ // round trip when you already know the server is 2025-era.
213
+ await createMCPTools({ url, protocolNegotiation: 'legacy' });
214
+
215
+ // Require a specific revision; fail loudly rather than falling back.
216
+ await createMCPTools({ url, protocolNegotiation: { pin: '2026-07-28' } });
217
+ ```
218
+
219
+ > Setting `protocolNegotiation` at all — **including to `'auto'`** — opts out of the
220
+ > automatic legacy retry. Naming a mode means you want that mode's failures too, and
221
+ > silently overriding a `{ pin }` would defeat the point of pinning.
222
+
223
+ The probe is bounded at 30s; pass `probeTimeoutMs` to change it. Without a bound the SDK gives
224
+ the probe the full 60s request timeout, so a black-holing gateway takes minutes to fail. The
225
+ ceiling is not tighter because a probe timeout is *not* recoverable — on HTTP it counts as an
226
+ outage, and the legacy retry speaks a handshake that `2026-07-28` removed — so a modern-only
227
+ server slower than the ceiling would fail outright rather than just take longer. Lower it when
228
+ you control the server and want to fail fast; raise it for known-slow cold starts.
229
+
230
+ `'auto'` costs one extra round trip against legacy servers. When a connect fails, the retry
231
+ re-walks the same transport ladder under `'legacy'`, so an unreachable server is dialled up to
232
+ four times before erroring — the price of guaranteeing that a legacy server reachable only
233
+ over SSE still connects when its probe is refused.
234
+
235
+ An auth failure skips the retry: the SDK's `UnauthorizedError`, or — when an OAuth provider is
236
+ configured — a **401** status from the probe (which the SDK reports as an `SdkHttpError`
237
+ rather than routing through the OAuth flow), from any attempt, not only the last. A **403**
238
+ never skips it, even under OAuth: the SDK's PKCE side effects occur only on 401, so a 403
239
+ retry re-drives nothing, while gateways commonly answer unknown methods with 403 — the exact
240
+ case the retry exists to rescue. Rejected credentials are not something a different protocol
241
+ revision fixes, and retrying a 401 would drive an OAuth authorization flow twice and overwrite
242
+ the saved PKCE verifier.
243
+
244
+ `MCPConnectionError` exposes every underlying failure on `errors` (like `AggregateError`), flat
245
+ and in attempt order across both negotiation passes, so nothing is hidden behind `cause` —
246
+ which holds only the last attempt.
247
+
248
+ There are no hardcoded protocol version strings in this package — negotiation is delegated to
249
+ `@modelcontextprotocol/client`.
250
+
251
+ ### What differs between the revisions
252
+
253
+ Mostly nothing you need to care about, with three exceptions:
254
+
255
+ | Surface | Behavior |
256
+ | --- | --- |
257
+ | `onElicitation` | **Works on both.** On 2025-era servers it handles `elicitation/create`; on 2026-07-28 that request is gone, but the SDK's multi-round-trip driver (SEP-2322) routes `input_required` results through the same handler and retries the call. |
258
+ | `sessionId` | 2025-era only. Protocol sessions and `Mcp-Session-Id` are removed in 2026-07-28 (SEP-2567), so it is `undefined` there. Snapshots keep the field so older ones still deserialize. |
259
+ | `transport: 'sse'` | Still supported for legacy servers, but HTTP+SSE is reclassified Deprecated (SEP-2596). Prefer `streamableHttp`. |
260
+
261
+ Sampling and Roots are deprecated in the new revision and were never implemented here, so
262
+ there is nothing to migrate.
263
+
264
+ The SDK also keeps its own per-client response cache (24h ceiling), independent of the
265
+ `MCPCacheStore` described above. The two are unrelated: `MCPCacheStore` persists a tool
266
+ snapshot across processes and, opt-in, credentials.
267
+
268
+ ### OAuth provider types
269
+
270
+ If you pass `{ kind: 'oauth', provider }`, type your provider with
271
+ `MCPOAuthClientProvider` from this package rather than importing from
272
+ `@modelcontextprotocol/client` — that import path is an implementation detail and has
273
+ changed once already.
124
274
 
125
275
  ## License
126
276
 
@@ -1,4 +1,4 @@
1
- import type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
1
+ import type { OAuthClientProvider } from '@modelcontextprotocol/client';
2
2
  import type { MCPAuth } from './auth-types.js';
3
3
  /**
4
4
  * The transport-level pieces derived from an {@link MCPAuth}: static headers to
@@ -1 +1 @@
1
- {"version":3,"file":"auth-resolver.d.ts","sourceRoot":"","sources":["../../src/auth/auth-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,YAAY,CAyBnE"}
1
+ {"version":3,"file":"auth-resolver.d.ts","sourceRoot":"","sources":["../../src/auth/auth-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,YAAY,CAyBnE"}
@@ -1,4 +1,12 @@
1
- import type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
1
+ import type { OAuthClientProvider } from '@modelcontextprotocol/client';
2
+ /**
3
+ * The OAuth provider contract expected by {@link MCPAuth}'s `oauth` variant.
4
+ *
5
+ * Re-exported under our own name so consumers can type their provider without
6
+ * importing from `@modelcontextprotocol/client` directly — that import path is
7
+ * an implementation detail of this package and has changed once already.
8
+ */
9
+ export type MCPOAuthClientProvider = OAuthClientProvider;
2
10
  /**
3
11
  * Authentication for a remote MCP server. Supplied once and reused by the
4
12
  * connected client for tool discovery and every subsequent tool call.
@@ -1 +1 @@
1
- {"version":3,"file":"auth-types.d.ts","sourceRoot":"","sources":["../../src/auth/auth-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAEpF;;;;;;;;GAQG;AACH,MAAM,MAAM,OAAO,GACf;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC3C,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,mBAAmB,CAAC;CAC/B,CAAC;AAEN,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,IAAI;IAC9D,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,mBAAmB,CAAC;CAC/B,CAEA"}
1
+ {"version":3,"file":"auth-types.d.ts","sourceRoot":"","sources":["../../src/auth/auth-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE;;;;;;GAMG;AACH,MAAM,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;AAEzD;;;;;;;;GAQG;AACH,MAAM,MAAM,OAAO,GACf;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC3C,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,mBAAmB,CAAC;CAC/B,CAAC;AAEN,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,IAAI;IAC9D,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,mBAAmB,CAAC;CAC/B,CAEA"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth-types.js","sourceRoot":"","sources":["../../src/auth/auth-types.ts"],"names":[],"mappings":"AAyBA,MAAM,UAAU,WAAW,CAAC,IAAyB;IAInD,OAAO,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"auth-types.js","sourceRoot":"","sources":["../../src/auth/auth-types.ts"],"names":[],"mappings":"AAkCA,MAAM,UAAU,WAAW,CAAC,IAAyB;IAInD,OAAO,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;AAChC,CAAC"}
@@ -1,5 +1,5 @@
1
- import type { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
- import type { Tool } from '@openrouter/agent/tool-types';
1
+ import type { Client } from '@modelcontextprotocol/client';
2
+ import type { Tool, ToolLoopKey } from '@openrouter/agent/tool-types';
3
3
  import type { UnconvertibleSchemaMode } from './schema/json-schema-to-zod.js';
4
4
  import type { McpToolDef } from './tool-wrapper.js';
5
5
  import type { ResourcesOption } from './types.js';
@@ -11,6 +11,8 @@ export interface BuildToolsOptions {
11
11
  excludeTools?: readonly string[];
12
12
  schemaMode?: UnconvertibleSchemaMode;
13
13
  emitProgress?: boolean;
14
+ /** Per-tool doom-loop identities, keyed by unprefixed MCP tool name. */
15
+ loopKeys?: Readonly<Record<string, ToolLoopKey<Record<string, unknown>>>>;
14
16
  signal?: AbortSignal;
15
17
  resources?: ResourcesOption;
16
18
  /** Whether the server advertised the resources capability. */
@@ -1 +1 @@
1
- {"version":3,"file":"build-tools.d.ts","sourceRoot":"","sources":["../src/build-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAGzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,8DAA8D;IAC9D,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AASD,mEAAmE;AACnE,wBAAgB,cAAc,CAC5B,IAAI,EAAE,SAAS,UAAU,EAAE,EAC3B,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,EAChC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,GAC/B,UAAU,EAAE,CASd;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,EAAE,CAqC7D"}
1
+ {"version":3,"file":"build-tools.d.ts","sourceRoot":"","sources":["../src/build-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,8DAA8D;IAC9D,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AASD,mEAAmE;AACnE,wBAAgB,cAAc,CAC5B,IAAI,EAAE,SAAS,UAAU,EAAE,EAC3B,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,EAChC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,GAC/B,UAAU,EAAE,CASd;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,EAAE,CAwC7D"}
@@ -36,6 +36,9 @@ export function buildTools(options) {
36
36
  ...(options.emitProgress !== undefined && {
37
37
  emitProgress: options.emitProgress,
38
38
  }),
39
+ ...(options.loopKeys !== undefined && {
40
+ loopKeys: options.loopKeys,
41
+ }),
39
42
  ...(options.signal !== undefined && {
40
43
  signal: options.signal,
41
44
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"build-tools.js","sourceRoot":"","sources":["../src/build-tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build-tools.js","sourceRoot":"","sources":["../src/build-tools.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,8 @@ export interface SerializedMCPToolDef {
5
5
  description?: string;
6
6
  inputSchema: Readonly<Record<string, unknown>>;
7
7
  outputSchema?: Readonly<Record<string, unknown>>;
8
+ /** Server-advertised doom-loop identity (field list or `false`), if any. */
9
+ loopKey?: readonly string[] | false;
8
10
  }
9
11
  /** OAuth/bearer token material, persisted only when `cacheCredentials` is on. */
10
12
  export interface SerializedTokenSet {
@@ -29,6 +31,21 @@ export interface SerializedMCPServer {
29
31
  version?: string;
30
32
  };
31
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
+ */
32
49
  sessionId?: string;
33
50
  tools: SerializedMCPToolDef[];
34
51
  auth?: {
@@ -1 +1 @@
1
- {"version":3,"file":"cache-types.d.ts","sourceRoot":"","sources":["../../src/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;CAClD;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,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;AAUD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAelF"}
1
+ {"version":3,"file":"cache-types.d.ts","sourceRoot":"","sources":["../../src/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"}
@@ -13,9 +13,17 @@ export function isFiniteEpoch(value) {
13
13
  return typeof value === 'number' && Number.isFinite(value) && value >= 0;
14
14
  }
15
15
  function isSerializedToolDef(value) {
16
- return (isJsonSchemaObject(value) &&
17
- typeof value['name'] === 'string' &&
18
- isJsonSchemaObject(value['inputSchema']));
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);
19
27
  }
20
28
  /**
21
29
  * Validate an untrusted value as a {@link SerializedMCPServer}. Cache stores may
@@ -1 +1 @@
1
- {"version":3,"file":"cache-types.js","sourceRoot":"","sources":["../../src/cache/cache-types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AA4CrE,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,OAAO,CACL,kBAAkB,CAAC,KAAK,CAAC;QACzB,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,QAAQ;QACjC,kBAAkB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CACzC,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"}
1
+ {"version":3,"file":"cache-types.js","sourceRoot":"","sources":["../../src/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"}
@@ -11,15 +11,15 @@ export interface SerializeInput {
11
11
  version?: string;
12
12
  };
13
13
  capabilities?: Readonly<Record<string, unknown>>;
14
- sessionId?: string;
15
14
  auth?: MCPAuth;
16
15
  cacheCredentials: boolean;
17
16
  cachedAt: number;
18
17
  }
19
18
  /**
20
- * Build a serializable snapshot. Credentials (tokens/headers, session id) are
21
- * included only when `cacheCredentials` is true; otherwise the snapshot holds
22
- * just the structural data needed to rebuild the tool set after a fresh auth.
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
23
  */
24
24
  export declare function serializeServer(input: SerializeInput): Promise<SerializedMCPServer>;
25
25
  //# sourceMappingURL=serialize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/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,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAgDD;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAqCzF"}
1
+ {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/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"}
@@ -1,5 +1,7 @@
1
1
  import { resolveAuth } from '../auth/auth-resolver.js';
2
2
  import { isFiniteEpoch } from './cache-types.js';
3
+ const _expiresInStillRelative = true;
4
+ void _expiresInStillRelative;
3
5
  /** Pull a serializable token set from an OAuth provider, if it has tokens. */
4
6
  async function tokensFromProvider(provider) {
5
7
  const tokens = await provider.tokens();
@@ -43,9 +45,10 @@ async function buildAuthBlock(auth) {
43
45
  : undefined;
44
46
  }
45
47
  /**
46
- * Build a serializable snapshot. Credentials (tokens/headers, session id) are
47
- * included only when `cacheCredentials` is true; otherwise the snapshot holds
48
- * just the structural data needed to rebuild the tool set after a fresh auth.
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.
49
52
  */
50
53
  export async function serializeServer(input) {
51
54
  const tools = input.toolDefs.map((def) => ({
@@ -57,6 +60,9 @@ export async function serializeServer(input) {
57
60
  ...(def.outputSchema !== undefined && {
58
61
  outputSchema: def.outputSchema,
59
62
  }),
63
+ ...(def.loopKey !== undefined && {
64
+ loopKey: def.loopKey,
65
+ }),
60
66
  }));
61
67
  const snapshot = {
62
68
  version: 1,
@@ -76,9 +82,14 @@ export async function serializeServer(input) {
76
82
  if (auth !== undefined) {
77
83
  snapshot.auth = auth;
78
84
  }
79
- if (input.sessionId !== undefined) {
80
- snapshot.sessionId = input.sessionId;
81
- }
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.
82
93
  }
83
94
  return snapshot;
84
95
  }
@@ -1 +1 @@
1
- {"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../src/cache/serialize.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../src/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/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/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"}
@@ -1 +1 @@
1
- {"version":3,"file":"create-mcp-tools.d.ts","sourceRoot":"","sources":["../src/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;AA8DD,YAAY,EAAE,mBAAmB,EAAE,CAAC"}
1
+ {"version":3,"file":"create-mcp-tools.d.ts","sourceRoot":"","sources":["../src/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;AAkFD,YAAY,EAAE,mBAAmB,EAAE,CAAC"}
@@ -23,7 +23,9 @@ export async function createMCPTools(options) {
23
23
  }
24
24
  // Option keys forwarded verbatim from a cache-hit `createMCPTools` call into
25
25
  // `rehydrateMCPTools`, so a warm handle applies the same auth, filters, prefix,
26
- // and credential-caching behavior as a cold one.
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.
27
29
  const FORWARDED_REHYDRATE_KEYS = [
28
30
  'auth',
29
31
  'fetch',
@@ -36,8 +38,12 @@ const FORWARDED_REHYDRATE_KEYS = [
36
38
  'excludeTools',
37
39
  'resources',
38
40
  'emitProgress',
41
+ 'loopKeys',
39
42
  'autoRefreshOnListChanged',
40
43
  'cacheCredentials',
44
+ 'protocolNegotiation',
45
+ 'probeTimeoutMs',
46
+ 'staleness',
41
47
  ];
42
48
  /** Copy the defined forwarded options from `createMCPTools` into a rehydrate base. */
43
49
  function forwardedRehydrateOptions(options) {
@@ -53,7 +59,22 @@ function forwardedRehydrateOptions(options) {
53
59
  return out;
54
60
  }
55
61
  async function tryCacheHit(options, store, cacheKey) {
56
- const snapshot = await store.get(cacheKey);
62
+ // A failed read is a miss, not a failure. The cache exists to skip a
63
+ // listTools() round trip; a store blip on the lookup must not reject a call
64
+ // that a plain miss would have served via a fresh connect. This mirrors the
65
+ // write side, which is best-effort everywhere — without it, "a store outage
66
+ // leaves you with a working handle" only held if the outage arrived after
67
+ // the read. Wrapped in try/catch rather than `.catch()`: `MCPCacheStore.get`
68
+ // may return synchronously, and a synchronous throw would bypass a
69
+ // promise-level handler — the exact hole `closeQuietly` exists to plug on
70
+ // the teardown side.
71
+ let snapshot;
72
+ try {
73
+ snapshot = await store.get(cacheKey);
74
+ }
75
+ catch {
76
+ snapshot = undefined;
77
+ }
57
78
  if (snapshot === null || snapshot === undefined || !isSerializedMCPServer(snapshot)) {
58
79
  return undefined;
59
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"create-mcp-tools.js","sourceRoot":"","sources":["../src/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,iDAAiD;AACjD,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,0BAA0B;IAC1B,kBAAkB;CAC0E,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,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3C,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"}
1
+ {"version":3,"file":"create-mcp-tools.js","sourceRoot":"","sources":["../src/create-mcp-tools.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { ElicitRequest, ElicitResult } from '@modelcontextprotocol/sdk/types.js';
1
+ import type { ElicitRequest, ElicitResult } from '@modelcontextprotocol/client';
2
2
  import type { ElicitationHandler } from './types.js';
3
3
  /**
4
4
  * Build the `elicitation/create` request handler registered on the MCP client.
@@ -1 +1 @@
1
- {"version":3,"file":"elicitation.d.ts","sourceRoot":"","sources":["../src/elicitation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAEtF,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"}
1
+ {"version":3,"file":"elicitation.d.ts","sourceRoot":"","sources":["../src/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"}