@openrouter/mcp 1.0.0 → 1.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.
- package/README.md +40 -159
- package/esm/cache.d.ts +7 -0
- package/esm/cache.d.ts.map +1 -0
- package/esm/cache.js +2 -0
- package/esm/cache.js.map +1 -0
- package/esm/create-mcp-tools.d.ts +4 -10
- package/esm/create-mcp-tools.d.ts.map +1 -1
- package/esm/create-mcp-tools.js +3 -93
- package/esm/create-mcp-tools.js.map +1 -1
- package/esm/index.d.ts +8 -12
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -10
- package/esm/index.js.map +1 -1
- package/esm/schema.d.ts +7 -0
- package/esm/schema.d.ts.map +1 -0
- package/esm/schema.js +2 -0
- package/esm/schema.js.map +1 -0
- package/esm/types.d.ts +3 -150
- package/esm/types.d.ts.map +1 -1
- package/package.json +9 -12
- package/esm/auth/auth-resolver.d.ts +0 -14
- package/esm/auth/auth-resolver.d.ts.map +0 -1
- package/esm/auth/auth-resolver.js +0 -27
- package/esm/auth/auth-resolver.js.map +0 -1
- package/esm/auth/auth-types.d.ts +0 -33
- package/esm/auth/auth-types.d.ts.map +0 -1
- package/esm/auth/auth-types.js +0 -4
- package/esm/auth/auth-types.js.map +0 -1
- package/esm/build-tools.d.ts +0 -29
- package/esm/build-tools.d.ts.map +0 -1
- package/esm/build-tools.js +0 -80
- package/esm/build-tools.js.map +0 -1
- package/esm/cache/cache-store.d.ts +0 -24
- package/esm/cache/cache-store.d.ts.map +0 -1
- package/esm/cache/cache-store.js +0 -20
- package/esm/cache/cache-store.js.map +0 -1
- package/esm/cache/cache-types.d.ts +0 -71
- package/esm/cache/cache-types.d.ts.map +0 -1
- package/esm/cache/cache-types.js +0 -49
- package/esm/cache/cache-types.js.map +0 -1
- package/esm/cache/serialize.d.ts +0 -25
- package/esm/cache/serialize.d.ts.map +0 -1
- package/esm/cache/serialize.js +0 -96
- package/esm/cache/serialize.js.map +0 -1
- package/esm/close-quietly.d.ts +0 -24
- package/esm/close-quietly.d.ts.map +0 -1
- package/esm/close-quietly.js +0 -30
- package/esm/close-quietly.js.map +0 -1
- package/esm/elicitation.d.ts +0 -11
- package/esm/elicitation.d.ts.map +0 -1
- package/esm/elicitation.js +0 -51
- package/esm/elicitation.js.map +0 -1
- package/esm/errors.d.ts +0 -82
- package/esm/errors.d.ts.map +0 -1
- package/esm/errors.js +0 -80
- package/esm/errors.js.map +0 -1
- package/esm/handle.d.ts +0 -66
- package/esm/handle.d.ts.map +0 -1
- package/esm/handle.js +0 -323
- package/esm/handle.js.map +0 -1
- package/esm/mcp-connection.d.ts +0 -142
- package/esm/mcp-connection.d.ts.map +0 -1
- package/esm/mcp-connection.js +0 -477
- package/esm/mcp-connection.js.map +0 -1
- package/esm/rehydrate.d.ts +0 -76
- package/esm/rehydrate.d.ts.map +0 -1
- package/esm/rehydrate.js +0 -499
- package/esm/rehydrate.js.map +0 -1
- package/esm/resource-tools.d.ts +0 -17
- package/esm/resource-tools.d.ts.map +0 -1
- package/esm/resource-tools.js +0 -155
- package/esm/resource-tools.js.map +0 -1
- package/esm/result-mapper.d.ts +0 -19
- package/esm/result-mapper.d.ts.map +0 -1
- package/esm/result-mapper.js +0 -40
- package/esm/result-mapper.js.map +0 -1
- package/esm/schema/json-schema-guards.d.ts +0 -14
- package/esm/schema/json-schema-guards.d.ts.map +0 -1
- package/esm/schema/json-schema-guards.js +0 -19
- package/esm/schema/json-schema-guards.js.map +0 -1
- package/esm/schema/json-schema-to-zod.d.ts +0 -20
- package/esm/schema/json-schema-to-zod.d.ts.map +0 -1
- package/esm/schema/json-schema-to-zod.js +0 -72
- package/esm/schema/json-schema-to-zod.js.map +0 -1
- package/esm/tool-wrapper.d.ts +0 -41
- package/esm/tool-wrapper.d.ts.map +0 -1
- package/esm/tool-wrapper.js +0 -131
- package/esm/tool-wrapper.js.map +0 -1
- package/esm/transport-types.d.ts +0 -45
- package/esm/transport-types.d.ts.map +0 -1
- package/esm/transport-types.js +0 -2
- package/esm/transport-types.js.map +0 -1
- package/esm/version.d.ts +0 -3
- package/esm/version.d.ts.map +0 -1
- package/esm/version.js +0 -5
- package/esm/version.js.map +0 -1
package/esm/rehydrate.js
DELETED
|
@@ -1,499 +0,0 @@
|
|
|
1
|
-
import { resolveAuth } from './auth/auth-resolver.js';
|
|
2
|
-
import { isOAuthAuth } from './auth/auth-types.js';
|
|
3
|
-
import { defaultCacheKey } from './cache/cache-store.js';
|
|
4
|
-
import { isSerializedMCPServer } from './cache/cache-types.js';
|
|
5
|
-
import { closeQuietly } from './close-quietly.js';
|
|
6
|
-
import { MCPCacheError, MCPCacheWriteError, MCPStaleSnapshotError } from './errors.js';
|
|
7
|
-
import { freshConnect, makeHandle } from './handle.js';
|
|
8
|
-
import { connect, isAuthFailure } from './mcp-connection.js';
|
|
9
|
-
/** Clock skew (ms) treated as "already expired" when checking cached tokens. */
|
|
10
|
-
const EXPIRY_SKEW_MS = 30000;
|
|
11
|
-
function snapshotToToolDefs(snapshot) {
|
|
12
|
-
return snapshot.tools.map((t) => ({
|
|
13
|
-
name: t.name,
|
|
14
|
-
...(t.description !== undefined && {
|
|
15
|
-
description: t.description,
|
|
16
|
-
}),
|
|
17
|
-
inputSchema: {
|
|
18
|
-
...t.inputSchema,
|
|
19
|
-
},
|
|
20
|
-
...(t.outputSchema !== undefined && {
|
|
21
|
-
outputSchema: {
|
|
22
|
-
...t.outputSchema,
|
|
23
|
-
},
|
|
24
|
-
}),
|
|
25
|
-
...(t.loopKey !== undefined && {
|
|
26
|
-
loopKey: t.loopKey,
|
|
27
|
-
}),
|
|
28
|
-
}));
|
|
29
|
-
}
|
|
30
|
-
/** A snapshot older than `maxAgeMs` should be re-listed rather than replayed. */
|
|
31
|
-
function snapshotIsStale(snapshot, maxAgeMs) {
|
|
32
|
-
if (maxAgeMs === undefined) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
return Date.now() - snapshot.cachedAt > maxAgeMs;
|
|
36
|
-
}
|
|
37
|
-
/** Cached tokens are unusable if they have a known expiry within the skew window. */
|
|
38
|
-
function tokensExpired(snapshot) {
|
|
39
|
-
const expiresAt = snapshot.auth?.tokens?.expiresAt;
|
|
40
|
-
if (expiresAt === undefined) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
return expiresAt - Date.now() <= EXPIRY_SKEW_MS;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Reconstruct an {@link MCPAuth} from credentials persisted in a snapshot (only
|
|
47
|
-
* present when it was serialized with `cacheCredentials: true`). Prefer static
|
|
48
|
-
* headers when present; otherwise fall back to the OAuth/bearer access token.
|
|
49
|
-
* Returns undefined when the snapshot carries no usable credentials.
|
|
50
|
-
*/
|
|
51
|
-
function authFromSnapshot(snapshot) {
|
|
52
|
-
const auth = snapshot.auth;
|
|
53
|
-
if (auth === undefined) {
|
|
54
|
-
return undefined;
|
|
55
|
-
}
|
|
56
|
-
if (auth.headers !== undefined && Object.keys(auth.headers).length > 0) {
|
|
57
|
-
return {
|
|
58
|
-
kind: 'headers',
|
|
59
|
-
headers: auth.headers,
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
if (auth.tokens?.accessToken !== undefined) {
|
|
63
|
-
return {
|
|
64
|
-
kind: 'bearer',
|
|
65
|
-
token: auth.tokens.accessToken,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
return undefined;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Options copied straight from a rehydrate call onto the `createMCPTools`
|
|
72
|
-
* options used for the fresh-connect fallback. `satisfies` keeps this honest:
|
|
73
|
-
* a key that isn't on both types fails to compile rather than silently
|
|
74
|
-
* dropping.
|
|
75
|
-
*
|
|
76
|
-
* `staleness` is deliberately absent — it compares a snapshot's age, and the
|
|
77
|
-
* fallback path has no snapshot to compare.
|
|
78
|
-
*/
|
|
79
|
-
const PASS_THROUGH_CREATE_KEYS = [
|
|
80
|
-
'fetch',
|
|
81
|
-
'onUnconvertibleSchema',
|
|
82
|
-
'onElicitation',
|
|
83
|
-
'protocolNegotiation',
|
|
84
|
-
'probeTimeoutMs',
|
|
85
|
-
'signal',
|
|
86
|
-
'clientInfo',
|
|
87
|
-
'toolNamePrefix',
|
|
88
|
-
'includeTools',
|
|
89
|
-
'excludeTools',
|
|
90
|
-
'resources',
|
|
91
|
-
'emitProgress',
|
|
92
|
-
'loopKeys',
|
|
93
|
-
'autoRefreshOnListChanged',
|
|
94
|
-
'cacheCredentials',
|
|
95
|
-
'cache',
|
|
96
|
-
];
|
|
97
|
-
function toCreateOptions(options, snapshot, effectiveAuth) {
|
|
98
|
-
const out = {
|
|
99
|
-
url: snapshot.url,
|
|
100
|
-
transport: snapshot.transport,
|
|
101
|
-
...(effectiveAuth !== undefined && {
|
|
102
|
-
auth: effectiveAuth,
|
|
103
|
-
}),
|
|
104
|
-
};
|
|
105
|
-
// Copy every defined pass-through key in one pass. Written as a loop rather
|
|
106
|
-
// than a spread per key so adding an option doesn't push this function's
|
|
107
|
-
// cyclomatic complexity past the structural gate's ceiling; it also mirrors
|
|
108
|
-
// `forwardedRehydrateOptions` in create-mcp-tools.ts, which forwards the same
|
|
109
|
-
// set in the opposite direction.
|
|
110
|
-
for (const key of PASS_THROUGH_CREATE_KEYS) {
|
|
111
|
-
const value = options[key];
|
|
112
|
-
if (value !== undefined) {
|
|
113
|
-
Object.assign(out, {
|
|
114
|
-
[key]: value,
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return out;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Connect options for the snapshot-replay path.
|
|
122
|
-
*
|
|
123
|
-
* Distinct from {@link toCreateOptions}, which builds the *fallback*
|
|
124
|
-
* `createMCPTools` options: this one carries the snapshot's own `transport` and
|
|
125
|
-
* `sessionId` because the point is to re-establish the connection the snapshot
|
|
126
|
-
* describes, and it deliberately omits the tool-shaping keys, which are applied
|
|
127
|
-
* by `makeHandle` rather than at connect time.
|
|
128
|
-
*/
|
|
129
|
-
function toReplayConnectOptions(args) {
|
|
130
|
-
const { options, snapshot, url, effectiveAuth } = args;
|
|
131
|
-
return {
|
|
132
|
-
url,
|
|
133
|
-
transport: snapshot.transport,
|
|
134
|
-
...(effectiveAuth !== undefined && {
|
|
135
|
-
auth: effectiveAuth,
|
|
136
|
-
}),
|
|
137
|
-
...(options.fetch !== undefined && {
|
|
138
|
-
fetch: options.fetch,
|
|
139
|
-
}),
|
|
140
|
-
...(options.clientInfo !== undefined && {
|
|
141
|
-
clientInfo: options.clientInfo,
|
|
142
|
-
}),
|
|
143
|
-
// `sessionId` is deliberately NOT forwarded. When a transport reports one,
|
|
144
|
-
// SDK v2 skips negotiation entirely — no `server/discover` probe and no
|
|
145
|
-
// `initialize` — and returns with `getProtocolEra()`,
|
|
146
|
-
// `getServerCapabilities()` and `getServerVersion()` all left undefined. It
|
|
147
|
-
// does not error, which is what makes it dangerous: `serverHasResources()`
|
|
148
|
-
// reads those capabilities, so a snapshot carrying a `sessionId` would
|
|
149
|
-
// silently replay with resource tools missing and no server info. Sessions
|
|
150
|
-
// are also removed outright in 2026-07-28 (SEP-2567), so a fresh handshake
|
|
151
|
-
// is both correct and cheap — one round trip on a path that already opens a
|
|
152
|
-
// connection.
|
|
153
|
-
...(options.onElicitation !== undefined && {
|
|
154
|
-
onElicitation: options.onElicitation,
|
|
155
|
-
}),
|
|
156
|
-
...(options.protocolNegotiation !== undefined && {
|
|
157
|
-
protocolNegotiation: options.protocolNegotiation,
|
|
158
|
-
}),
|
|
159
|
-
...(options.probeTimeoutMs !== undefined && {
|
|
160
|
-
probeTimeoutMs: options.probeTimeoutMs,
|
|
161
|
-
}),
|
|
162
|
-
...(options.signal !== undefined && {
|
|
163
|
-
signal: options.signal,
|
|
164
|
-
}),
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Re-list tools on a handle built from a snapshot older than the caller's
|
|
169
|
-
* `staleness.maxAgeMs`.
|
|
170
|
-
*
|
|
171
|
-
* Reached only when `reconnectOnExpiry` is false — otherwise a stale snapshot
|
|
172
|
-
* has already gone to `freshConnect`. Re-listing over the connection just opened
|
|
173
|
-
* honours `maxAgeMs` without the reconnect the caller declined: "stale" means the
|
|
174
|
-
* tool set needs re-reading, not that the transport needs rebuilding.
|
|
175
|
-
* `refresh()` also clears the carried `cachedAt`, so the write-back records the
|
|
176
|
-
* new age rather than carrying the snapshot's forward.
|
|
177
|
-
*/
|
|
178
|
-
async function refreshStaleReplay(handle) {
|
|
179
|
-
// `refresh()` swaps `handle.tools` to a fresh array exactly when the re-list
|
|
180
|
-
// succeeded, before it persists — so the reference tells re-list failure
|
|
181
|
-
// apart from persistence failure. Keying on that rather than on
|
|
182
|
-
// `MCPCacheWriteError` matters because persistence can fail OUTSIDE the
|
|
183
|
-
// store op too (the caller's OAuth provider rejecting inside `snapshot()`),
|
|
184
|
-
// and that failure must not masquerade as "re-listing tools failed".
|
|
185
|
-
const before = handle.tools;
|
|
186
|
-
try {
|
|
187
|
-
await handle.refresh();
|
|
188
|
-
}
|
|
189
|
-
catch (refreshErr) {
|
|
190
|
-
// Tools adopted: the re-list succeeded and only the persistence after it
|
|
191
|
-
// broke. Survivable, and must not fail the call — the tools ARE current;
|
|
192
|
-
// only the cache entry is stale, and the next rehydrate re-reads it.
|
|
193
|
-
// (A transient store outage here used to discard a connection whose tools
|
|
194
|
-
// had just been read successfully.)
|
|
195
|
-
if (handle.tools !== before || refreshErr instanceof MCPCacheWriteError) {
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
// A failed re-list is not. The connection is live and the snapshot's tools
|
|
199
|
-
// would work, but they are older than the caller's own `maxAgeMs` — serving
|
|
200
|
-
// them anyway is exactly the unbounded-age bug that check exists to prevent.
|
|
201
|
-
await closeQuietly(handle);
|
|
202
|
-
throw new MCPStaleSnapshotError('Snapshot is older than staleness.maxAgeMs and re-listing tools failed', {
|
|
203
|
-
cause: refreshErr,
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* The cases where a successful replay still writes to the cache store.
|
|
209
|
-
*
|
|
210
|
-
* The replay write-back is normally skipped as a no-op — the snapshot it would
|
|
211
|
-
* persist is the one just read. Three exceptions where the write genuinely does
|
|
212
|
-
* something, all best-effort:
|
|
213
|
-
*
|
|
214
|
-
* 1. **OAuth token rotation.** With `cacheCredentials: true` and an OAuth
|
|
215
|
-
* provider, the old per-hit write re-serialized the provider's *current*
|
|
216
|
-
* tokens; without it the stored entry keeps cold-connect-time tokens, and
|
|
217
|
-
* once those pass `expiresAt` every rehydrate takes the fresh-connect
|
|
218
|
-
* detour even though the provider holds a valid refreshed token.
|
|
219
|
-
* 2. **Static credential rotation.** Same story for `bearer`/`headers` auth:
|
|
220
|
-
* the old per-hit write kept the stored `auth.headers` in sync with the
|
|
221
|
-
* caller's live `auth`, so a rotated API key propagated on the next warm
|
|
222
|
-
* hit. When the caller passes static auth under `cacheCredentials: true`
|
|
223
|
-
* and the resolved headers differ from the stored ones, the stored entry's
|
|
224
|
-
* header block is updated — otherwise a later credential-bearing rehydrate
|
|
225
|
-
* (`authFromSnapshot`) would dial with the superseded secret.
|
|
226
|
-
* 3. **Legacy `sessionId` scrub.** Entries written by earlier versions can
|
|
227
|
-
* carry a bearer-equivalent `Mcp-Session-Id` under `cacheCredentials`; with
|
|
228
|
-
* the warm path never rewriting, that credential-grade value would sit in
|
|
229
|
-
* the external store indefinitely. One write — the entry copied without the
|
|
230
|
-
* field — removes it.
|
|
231
|
-
*
|
|
232
|
-
* All three share one invariant: they only ever REWRITE an entry the store
|
|
233
|
-
* already holds, read back first. The credential grafts move only their block
|
|
234
|
-
* onto the stored entry rather than re-serializing this call's live state — a
|
|
235
|
-
* direct `rehydrateMCPTools` may have loaded its snapshot from a file or
|
|
236
|
-
* another key, and writing that snapshot's (older) tool set and `cachedAt`
|
|
237
|
-
* over the store's entry would roll back a newer entry written by a concurrent
|
|
238
|
-
* `refresh()`. Copying the stored entry also cannot strip or introduce
|
|
239
|
-
* credentials the way a re-serialize under this call's options could (the
|
|
240
|
-
* DEV-766 hazard): each block is only updated where the stored entry already
|
|
241
|
-
* carries that block.
|
|
242
|
-
*/
|
|
243
|
-
/**
|
|
244
|
-
* Graft the provider's current tokens onto the STORED entry — never the other
|
|
245
|
-
* way round.
|
|
246
|
-
*
|
|
247
|
-
* Only the token block moves; the stored entry's tool set and `cachedAt` stay
|
|
248
|
-
* untouched, so a direct rehydrate whose input snapshot is older than the
|
|
249
|
-
* store's entry (a concurrent `refresh()` having written since) cannot roll the
|
|
250
|
-
* entry back. Returns undefined — no write — when the stored entry carries no
|
|
251
|
-
* tokens (grafting would introduce credentials into an entry that never held
|
|
252
|
-
* them) or the fresh serialize produced none.
|
|
253
|
-
*
|
|
254
|
-
* An UNROTATED token — same access token as stored — grafts nothing at all,
|
|
255
|
-
* for three reasons that all point the same way. No per-replay write (the
|
|
256
|
-
* documented warm-path economy, and no re-touching TTL-extending stores). No
|
|
257
|
-
* expiry ratchet: `serializeServer` stamps `expiresAt` as `Date.now() +
|
|
258
|
-
* expires_in * 1000`, but `expires_in` is relative to *issuance* (RFC 6749
|
|
259
|
-
* §5.1), so re-persisting the same token would push the recorded expiry
|
|
260
|
-
* forward each replay and `tokensExpired()` would never trip. And no field
|
|
261
|
-
* loss: a wholesale replace would drop stored fields the provider's `tokens()`
|
|
262
|
-
* no longer reports (a `refreshToken` held elsewhere, say) without any actual
|
|
263
|
-
* rotation. A rotated token replaces the block, fresh restamp included — the
|
|
264
|
-
* SDK just obtained it, so its relative `expires_in` genuinely is from ~now.
|
|
265
|
-
*/
|
|
266
|
-
function graftRotatedTokens(stored, serialized) {
|
|
267
|
-
const prev = stored.auth?.tokens;
|
|
268
|
-
const next = serialized.auth?.tokens;
|
|
269
|
-
if (prev === undefined || next === undefined) {
|
|
270
|
-
return undefined;
|
|
271
|
-
}
|
|
272
|
-
if (next.accessToken === prev.accessToken) {
|
|
273
|
-
return undefined;
|
|
274
|
-
}
|
|
275
|
-
return {
|
|
276
|
-
...stored,
|
|
277
|
-
auth: {
|
|
278
|
-
...stored.auth,
|
|
279
|
-
tokens: {
|
|
280
|
-
...next,
|
|
281
|
-
},
|
|
282
|
-
},
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
function headersEqual(a, b) {
|
|
286
|
-
const aKeys = Object.keys(a);
|
|
287
|
-
return aKeys.length === Object.keys(b).length && aKeys.every((k) => a[k] === b[k]);
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Graft the caller's current static headers onto the STORED entry — the
|
|
291
|
-
* `bearer`/`headers` counterpart of {@link graftRotatedTokens}, under the same
|
|
292
|
-
* invariants: only the header block moves, and only where the stored entry
|
|
293
|
-
* already carries headers (never introducing credentials into an entry that
|
|
294
|
-
* had none). Returns undefined — no write — when there is nothing to update.
|
|
295
|
-
*/
|
|
296
|
-
function graftStaticHeaders(stored, headers) {
|
|
297
|
-
const prev = stored.auth?.headers;
|
|
298
|
-
if (prev === undefined || Object.keys(prev).length === 0 || Object.keys(headers).length === 0) {
|
|
299
|
-
return undefined;
|
|
300
|
-
}
|
|
301
|
-
if (headersEqual(prev, headers)) {
|
|
302
|
-
return undefined;
|
|
303
|
-
}
|
|
304
|
-
return {
|
|
305
|
-
...stored,
|
|
306
|
-
auth: {
|
|
307
|
-
...stored.auth,
|
|
308
|
-
headers,
|
|
309
|
-
},
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Compute the maintenance rewrite for a stored entry, if any: an OAuth token
|
|
314
|
-
* graft, a static-header graft, or nothing. Split from
|
|
315
|
-
* {@link maintainReplayedEntry} to keep each piece readable.
|
|
316
|
-
*/
|
|
317
|
-
async function graftForReplay(args) {
|
|
318
|
-
const { options, handle, stored, effectiveAuth } = args;
|
|
319
|
-
if (options.cacheCredentials !== true) {
|
|
320
|
-
return undefined;
|
|
321
|
-
}
|
|
322
|
-
if (isOAuthAuth(effectiveAuth)) {
|
|
323
|
-
return graftRotatedTokens(stored, await handle.serialize());
|
|
324
|
-
}
|
|
325
|
-
// Static graft keys on the CALLER's auth, not `effectiveAuth`: auth derived
|
|
326
|
-
// from the input snapshot is by definition not a rotation.
|
|
327
|
-
if (options.auth !== undefined) {
|
|
328
|
-
return graftStaticHeaders(stored, resolveAuth(options.auth).headers);
|
|
329
|
-
}
|
|
330
|
-
return undefined;
|
|
331
|
-
}
|
|
332
|
-
async function maintainReplayedEntry(args) {
|
|
333
|
-
const { options, handle, cacheKey, effectiveAuth } = args;
|
|
334
|
-
const store = options.cache?.store;
|
|
335
|
-
if (store === undefined) {
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
try {
|
|
339
|
-
// Cheap gates first, so a warm hit with nothing to maintain performs ZERO
|
|
340
|
-
// store operations. Credential grafts can only apply under
|
|
341
|
-
// `cacheCredentials: true`; the scrub can only be needed when the *input*
|
|
342
|
-
// snapshot carries a legacy `sessionId` (on the warm `createMCPTools` path
|
|
343
|
-
// the input IS the store's entry, so a sessionId-free input — every entry
|
|
344
|
-
// this version writes — means a sessionId-free store).
|
|
345
|
-
const mayGraft = options.cacheCredentials === true &&
|
|
346
|
-
(isOAuthAuth(effectiveAuth) || options.auth !== undefined);
|
|
347
|
-
if (!mayGraft && args.snapshot.sessionId === undefined) {
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
350
|
-
// Read back before writing: every maintenance write is a rewrite of what
|
|
351
|
-
// THIS store currently holds, never a serialize of this call's state — a
|
|
352
|
-
// direct rehydrate's input snapshot may be older than the store's entry (a
|
|
353
|
-
// concurrent refresh() having written since), and its auth may belong to a
|
|
354
|
-
// store that never held credentials. One read per maintained replay is the
|
|
355
|
-
// price.
|
|
356
|
-
const stored = await store.get(cacheKey);
|
|
357
|
-
if (stored === null || stored === undefined || !isSerializedMCPServer(stored)) {
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
const grafted = mayGraft
|
|
361
|
-
? await graftForReplay({
|
|
362
|
-
options,
|
|
363
|
-
handle,
|
|
364
|
-
stored,
|
|
365
|
-
effectiveAuth,
|
|
366
|
-
})
|
|
367
|
-
: undefined;
|
|
368
|
-
// Nothing to graft and nothing to scrub — no write. A legacy sessionId in
|
|
369
|
-
// the stored entry composes with either graft into one write.
|
|
370
|
-
if (grafted === undefined && stored.sessionId === undefined) {
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
const next = {
|
|
374
|
-
...(grafted ?? stored),
|
|
375
|
-
};
|
|
376
|
-
delete next.sessionId;
|
|
377
|
-
await store.set(cacheKey, next);
|
|
378
|
-
}
|
|
379
|
-
catch {
|
|
380
|
-
// Best-effort, like every other store write: a cache outage never fails a
|
|
381
|
-
// working replay.
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
/**
|
|
385
|
-
* Rebuild an {@link MCPToolsHandle} from a cached snapshot. On the happy path we
|
|
386
|
-
* reconnect the transport and rebuild tools directly from the snapshot —
|
|
387
|
-
* skipping `listTools()`. If cached tokens are expired, credentials are missing,
|
|
388
|
-
* the snapshot is older than `staleness.maxAgeMs`, or the replay connection
|
|
389
|
-
* fails, we transparently fall back to a fresh connect (unless
|
|
390
|
-
* `reconnectOnExpiry` is false) — with one exception: a credential rejection is
|
|
391
|
-
* not retried, because the fallback reuses the same auth and re-attempting
|
|
392
|
-
* would re-drive an OAuth authorization flow. See {@link
|
|
393
|
-
* RehydrateMCPToolsOptions.reconnectOnExpiry}.
|
|
394
|
-
*/
|
|
395
|
-
export async function rehydrateMCPTools(options) {
|
|
396
|
-
const { snapshot } = options;
|
|
397
|
-
if (!isSerializedMCPServer(snapshot)) {
|
|
398
|
-
throw new MCPCacheError('Invalid MCP snapshot: failed structural validation');
|
|
399
|
-
}
|
|
400
|
-
const reconnectOnExpiry = options.reconnectOnExpiry ?? true;
|
|
401
|
-
const url = new URL(snapshot.url);
|
|
402
|
-
const cacheKey = options.cache?.key ?? defaultCacheKey(url.href);
|
|
403
|
-
// Fall back to credentials cached in the snapshot when the caller didn't pass
|
|
404
|
-
// any — otherwise a credential-bearing snapshot would reconnect unauthenticated.
|
|
405
|
-
const effectiveAuth = options.auth ?? authFromSnapshot(snapshot);
|
|
406
|
-
const hasCredentials = effectiveAuth !== undefined;
|
|
407
|
-
// Route the fallback through `freshConnect`, NOT `createMCPTools`: the latter
|
|
408
|
-
// would re-read this same snapshot and re-enter rehydrate, recursing without
|
|
409
|
-
// bound on any no-credential / expired-token snapshot. `freshConnect` still
|
|
410
|
-
// writes the refreshed result back to the cache via `makeHandle`.
|
|
411
|
-
const createOptions = toCreateOptions(options, snapshot, effectiveAuth);
|
|
412
|
-
// Staleness is checked here as well as in `createMCPTools`'s cache-hit path,
|
|
413
|
-
// so a direct `rehydrateMCPTools()` call honours `staleness.maxAgeMs` too.
|
|
414
|
-
// Previously only the `createMCPTools` route checked it, meaning callers who
|
|
415
|
-
// held their own snapshot silently got unbounded-age tools.
|
|
416
|
-
const staleSnapshot = snapshotIsStale(snapshot, options.staleness?.maxAgeMs);
|
|
417
|
-
if ((tokensExpired(snapshot) || !hasCredentials || staleSnapshot) && reconnectOnExpiry) {
|
|
418
|
-
return freshConnect(createOptions, url, cacheKey);
|
|
419
|
-
}
|
|
420
|
-
// Held outside the `try` so the `catch` can tear it down. `connect()` releases
|
|
421
|
-
// its own client when it fails, so this stays undefined on that path and only
|
|
422
|
-
// a post-connect failure has something to close.
|
|
423
|
-
let connection;
|
|
424
|
-
try {
|
|
425
|
-
connection = await connect(toReplayConnectOptions({
|
|
426
|
-
options,
|
|
427
|
-
snapshot,
|
|
428
|
-
url,
|
|
429
|
-
effectiveAuth,
|
|
430
|
-
}));
|
|
431
|
-
// Rebuild tools from the snapshot — no listTools() round-trip.
|
|
432
|
-
const handle = await makeHandle({
|
|
433
|
-
connection,
|
|
434
|
-
options: createOptions,
|
|
435
|
-
context: {
|
|
436
|
-
url,
|
|
437
|
-
transport: connection.transport,
|
|
438
|
-
cacheKey,
|
|
439
|
-
},
|
|
440
|
-
initialToolDefs: snapshotToToolDefs(snapshot),
|
|
441
|
-
// Replay, not a listTools() — keep the snapshot's original age so
|
|
442
|
-
// staleness.maxAgeMs stays measurable across repeated rehydrates.
|
|
443
|
-
replayedCachedAt: snapshot.cachedAt,
|
|
444
|
-
});
|
|
445
|
-
if (staleSnapshot) {
|
|
446
|
-
// `refresh()` re-listed and wrote the entry through `serialize` — which
|
|
447
|
-
// carries the provider's current tokens and omits `sessionId` — so every
|
|
448
|
-
// maintenance concern below is already satisfied. Running the scrub here
|
|
449
|
-
// would clobber the just-refreshed entry with the caller's older input
|
|
450
|
-
// snapshot.
|
|
451
|
-
await refreshStaleReplay(handle);
|
|
452
|
-
}
|
|
453
|
-
else {
|
|
454
|
-
await maintainReplayedEntry({
|
|
455
|
-
options,
|
|
456
|
-
snapshot,
|
|
457
|
-
handle,
|
|
458
|
-
cacheKey,
|
|
459
|
-
effectiveAuth,
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
return handle;
|
|
463
|
-
}
|
|
464
|
-
catch (err) {
|
|
465
|
-
// The stale re-list above already closed and reported; let its verdict stand
|
|
466
|
-
// rather than re-wrapping it as a generic rehydrate failure (and
|
|
467
|
-
// double-closing). It is a deliberate refusal, not a rehydrate that broke.
|
|
468
|
-
if (err instanceof MCPStaleSnapshotError) {
|
|
469
|
-
throw err;
|
|
470
|
-
}
|
|
471
|
-
// Tear down the replay connection before leaving this path, mirroring
|
|
472
|
-
// `freshConnect`'s guarantee in handle.ts. Whether we fall back (which opens
|
|
473
|
-
// its own connection) or rethrow, nothing else holds a reference to this
|
|
474
|
-
// one, so without the close its transport leaks. Reachable via `buildTools`
|
|
475
|
-
// rejecting on a duplicate tool name, or a caller's `cache.store.set`
|
|
476
|
-
// throwing during the initial write.
|
|
477
|
-
if (connection !== undefined) {
|
|
478
|
-
await closeQuietly(connection);
|
|
479
|
-
}
|
|
480
|
-
// The fallback is a third reconnect layer, and it reuses the same auth. If
|
|
481
|
-
// the replay's connect ended in a credential rejection, `freshConnect` would
|
|
482
|
-
// re-drive the OAuth flow — a third `redirectToAuthorization` behind the two
|
|
483
|
-
// layers below that already guard against exactly this. Rejected credentials
|
|
484
|
-
// are not something a fresh connection fixes.
|
|
485
|
-
// An aborted caller gets no fallback either — the third reconnect layer,
|
|
486
|
-
// matching the guards on the SSE fallback and the legacy retry. Dialling a
|
|
487
|
-
// fresh connection after the caller cancelled would both waste the dial and
|
|
488
|
-
// bury the cancellation under a "failed to connect" it didn't cause.
|
|
489
|
-
if (reconnectOnExpiry &&
|
|
490
|
-
options.signal?.aborted !== true &&
|
|
491
|
-
!isAuthFailure(err, effectiveAuth)) {
|
|
492
|
-
return freshConnect(createOptions, url, cacheKey);
|
|
493
|
-
}
|
|
494
|
-
throw new MCPCacheError('Failed to rehydrate MCP connection from snapshot', {
|
|
495
|
-
cause: err,
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
//# sourceMappingURL=rehydrate.js.map
|
package/esm/rehydrate.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rehydrate.js","sourceRoot":"","sources":["../src/rehydrate.ts"],"names":[],"mappings":"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"}
|
package/esm/resource-tools.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { Client } from '@modelcontextprotocol/client';
|
|
2
|
-
import type { McpBranded } from '@openrouter/agent/tool-types';
|
|
3
|
-
export interface ResourceToolsOptions {
|
|
4
|
-
client: Client;
|
|
5
|
-
namePrefix?: string;
|
|
6
|
-
signal?: AbortSignal;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Build synthetic tools that let the model browse and read MCP resources
|
|
10
|
-
* through the normal tool loop:
|
|
11
|
-
* - `list_resources`: concrete resources plus resource templates.
|
|
12
|
-
* - `read_resource`: fetch a resource's contents by URI.
|
|
13
|
-
*
|
|
14
|
-
* Only call this when the server advertises the `resources` capability.
|
|
15
|
-
*/
|
|
16
|
-
export declare function buildResourceTools(options: ResourceToolsOptions): McpBranded[];
|
|
17
|
-
//# sourceMappingURL=resource-tools.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resource-tools.d.ts","sourceRoot":"","sources":["../src/resource-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAG/D,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAgFD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,GAAG,UAAU,EAAE,CAwH9E"}
|