@chrischall/mcp-utils 0.14.2 → 0.16.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 CHANGED
@@ -32,7 +32,7 @@ import light:
32
32
  | Import | Contents |
33
33
  | --- | --- |
34
34
  | `@chrischall/mcp-utils` | core barrel: `server` + `response` + `errors` + `config` + `fs` + `http` + `concurrency` + `dates` + `zod` + `auth` + `scrape` |
35
- | `@chrischall/mcp-utils/session` | session registry, session store, token manager, cookie-session manager |
35
+ | `@chrischall/mcp-utils/session` | session registry, session store, state persistence, token manager, cookie-session manager |
36
36
  | `@chrischall/mcp-utils/fetchproxy` | fetchproxy transport adapter, bot-wall / retry / concurrency helpers |
37
37
  | `@chrischall/mcp-utils/html` | opt-in HTML scraping helpers (needs `node-html-parser`) |
38
38
  | `@chrischall/mcp-utils/scrape` | convenience alias for the zero-dep `scrape` module (also in the core barrel) |
@@ -48,7 +48,7 @@ import { createFetchproxyTransport } from '@chrischall/mcp-utils/fetchproxy';
48
48
 
49
49
  ### `server` — bootstrap & lifecycle
50
50
 
51
- `createMcpServer`, `runMcp`, `withGracefulShutdown`.
51
+ `createMcpServer`, `runMcp`, `withGracefulShutdown`, `surfaceToolHints`.
52
52
 
53
53
  ```ts
54
54
  import { runMcp, textResult } from '@chrischall/mcp-utils';
@@ -67,6 +67,21 @@ await runMcp({
67
67
  handlers via `withGracefulShutdown`. Use `createMcpServer` directly if you need
68
68
  the server instance without connecting a transport.
69
69
 
70
+ Both render a thrown `McpToolError`'s `hint` into the failing tool's text:
71
+
72
+ ```
73
+ no such option 999
74
+
75
+ Hint: Available: 1 (Bus), 2 (Walker)
76
+ ```
77
+
78
+ The MCP tool boundary itself surfaces only `message`, so a `hint` — the
79
+ actionable half — used to be dropped even though `wrapToolError` preserved it.
80
+ Anything that is not an `McpToolError`, or has no `hint`, propagates untouched,
81
+ so a genuine bug still reads as one. Opt out with `surfaceHints: false`.
82
+ `createTestHarness` applies the same wrapper, so a tool's failure text under
83
+ test is the text production returns.
84
+
70
85
  ### `response` — tool-result formatting
71
86
 
72
87
  `textResult` / `jsonResult` (alias), `rawTextResult`, `imageResult`,
@@ -470,6 +485,72 @@ Replaces the hand-rolled re-login / single-flight / 401-replay code in
470
485
  `artsonia-mcp`, `canvas-parent-mcp`, `evite-mcp`, `signupgenius-mcp`, and
471
486
  `skylight-mcp`.
472
487
 
488
+ #### Surviving a restart — `StatePersistence` *(opt-in)*
489
+
490
+ Both managers own a credential only for the life of the process. On a
491
+ scale-to-zero host that means a full login on every cold start — children idle
492
+ out after ten minutes, several services rate-limit the login endpoint, and one
493
+ escalates repeated attempts to a captcha that breaks server-side auth outright.
494
+ Pass `persistence` and the credential survives instead:
495
+
496
+ ```ts
497
+ import {
498
+ TokenManager,
499
+ createFileStatePersistence,
500
+ resolveStateDir,
501
+ type BearerTokens,
502
+ } from '@chrischall/mcp-utils/session';
503
+ import { join } from 'node:path';
504
+
505
+ const tokens = new TokenManager({
506
+ // Function form: run the login ONLY when nothing usable was restored.
507
+ initial: () => loginWithPassword(),
508
+ refresh: (rt) => exchangeRefreshToken(rt),
509
+ persistence: createFileStatePersistence<BearerTokens>({
510
+ filePath: join(resolveStateDir({ subdir: '.acme-mcp' }), 'tokens.json'),
511
+ }),
512
+ });
513
+ ```
514
+
515
+ What that buys, in order of how often it applies: a stored token that is still
516
+ valid costs **nothing**; a stored token that has expired but carries a refresh
517
+ token costs **one refresh** instead of a login; only an empty or unusable store
518
+ runs `initial`. A refresh token revoked between runs is not terminal — the
519
+ stored copy is discarded and the login re-runs, so a stale file cannot brick the
520
+ server. A *transient* refresh failure is treated differently: a `RateLimitedError`,
521
+ a `RequestTimeoutError` or a 5xx `ApiError` surfaces to the caller with the
522
+ refresh token left intact, because destroying a valid credential and burning a
523
+ login on a passing outage is the cost this feature exists to avoid. Override
524
+ `isRefreshRevoked` for a service that signals revocation some other way.
525
+
526
+ `createFileStatePersistence` writes atomically (temp file + rename), leaves the
527
+ file `0600`, and creates any missing directory `0700` — but does **not**
528
+ re-permission a directory that already exists, since a bare `resolveStateDir()`
529
+ is `$HOME` and `mcp-host` creates the data dir before the child starts. It never
530
+ throws: a read-only or full disk degrades to in-memory operation, costing a
531
+ login rather than a failed request. `resolveStateDir` prefers `MCP_DATA_DIR` — the variable `mcp-host`
532
+ injects for a registration with `state.dataDir: true` — then `HOME`, then the OS
533
+ home directory. It reads both through `readEnvVar`, so blank values, the
534
+ `'null'` / `'undefined'` sentinels and unexpanded `${...}` placeholders are all
535
+ treated as unset (`MCP_DATA_DIR=null` would otherwise be a *relative* `./null`
536
+ directory, quietly parking the credential under the process cwd).
537
+
538
+ > On `mcp-host`, set `state.dataDir: true` in the repo's `mint.yaml` when you
539
+ > adopt this. Without it the child's `$HOME` is on the container rootfs, which
540
+ > an idle-stop discards — the runner's unpersisted-state detector will report
541
+ > the omission, but the writes still vanish.
542
+
543
+ `CookieSessionManager` takes the same option, storing `{ session, sessionAt }`
544
+ so `maxAgeMs` keeps counting from the original login. Its `invalidate()` clears
545
+ the stored copy — without that, a session detected as expired would be read back
546
+ off disk and the expiry would loop.
547
+
548
+ Persistence is **opt-in throughout**: a manager constructed without it behaves
549
+ exactly as before, and no credential reaches a disk because a dependency was
550
+ upgraded. The interface is two methods (`load` / `save`, plus an optional
551
+ `clear`), each allowed to be async, so a backend other than the local filesystem
552
+ can be dropped in.
553
+
473
554
  ### `fetchproxy` — transport adapter *(subpath, optional peer)*
474
555
 
475
556
  ```ts
@@ -54,7 +54,34 @@ export interface CreateMcpServerOptions<TDeps = unknown> {
54
54
  * `'stdio'`.
55
55
  */
56
56
  transport?: TransportSpec;
57
+ /**
58
+ * Append an {@link McpToolError}'s `hint` to the text a failing tool returns.
59
+ * Default `true`. Set `false` only for a server that deliberately wants the
60
+ * bare message.
61
+ */
62
+ surfaceHints?: boolean;
57
63
  }
64
+ /**
65
+ * Wrap `server.registerTool` so every tool handler surfaces its error `hint`.
66
+ *
67
+ * Why this lives here rather than in each repo: the MCP tool boundary renders
68
+ * only a thrown error's `message`. `McpToolError` has carried a `hint` — the
69
+ * actionable half ("the available options are …", "set FOO_API_KEY") — since
70
+ * the beginning, and {@link wrapToolError} is careful to preserve it, but
71
+ * nothing ever rendered it, so every hint thrown from a tool handler was
72
+ * invisible to the caller. Two repos had independently grown the same
73
+ * hand-rolled wrapper before this landed.
74
+ *
75
+ * Handlers are invoked variadically because the SDK passes `(args, extra)` for
76
+ * a tool with an `inputSchema` and `(extra)` for one without; forwarding
77
+ * whatever arrived keeps both shapes intact. Both a synchronous throw and a
78
+ * rejected promise are handled, since a handler may fail either way.
79
+ *
80
+ * Exported so `createTestHarness` can apply the same wrapper: a harness that
81
+ * built a bare `McpServer` would show tests a different error surface than
82
+ * production, which is the one thing a harness must never do.
83
+ */
84
+ export declare function surfaceToolHints(server: McpServer): void;
58
85
  /**
59
86
  * Build an {@link McpServer}, print the optional stderr banner, and apply every
60
87
  * tool registrar (awaiting async ones) — but do **not** connect a transport.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAE/E;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,CAAC,KAAK,GAAG,OAAO,IAAI,CAC3C,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,KAAK,KACR,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,+EAA+E;AAC/E,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,CAAC;AAEhD,2CAA2C;AAC3C,MAAM,WAAW,sBAAsB,CAAC,KAAK,GAAG,OAAO;IACrD,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;IAC9B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,mGAAmG;IACnG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,KAAK,GAAG,OAAO,EACnD,IAAI,EAAE,sBAAsB,CAAC,KAAK,CAAC,GAClC,OAAO,CAAC,SAAS,CAAC,CAgBpB;AAED,wDAAwD;AACxD,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,CAAC;AAElD,gDAAgD;AAChD,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,EAChC,IAAI,GAAE,uBAA4B,GACjC,IAAI,CAyBN;AAED,oFAAoF;AACpF,MAAM,WAAW,aAAa,CAAC,KAAK,GAAG,OAAO,CAAE,SAAQ,sBAAsB,CAAC,KAAK,CAAC;IACnF;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,uBAAuB,CAAC;CAC9C;AAED;;;;;;;;GAQG;AACH,wBAAsB,MAAM,CAAC,KAAK,GAAG,OAAO,EAC1C,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,GACzB,OAAO,CAAC,SAAS,CAAC,CAapB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAK/E;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,CAAC,KAAK,GAAG,OAAO,IAAI,CAC3C,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,KAAK,KACR,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,+EAA+E;AAC/E,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,CAAC;AAEhD,2CAA2C;AAC3C,MAAM,WAAW,sBAAsB,CAAC,KAAK,GAAG,OAAO;IACrD,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;IAC9B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,mGAAmG;IACnG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAiBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsBxD;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,KAAK,GAAG,OAAO,EACnD,IAAI,EAAE,sBAAsB,CAAC,KAAK,CAAC,GAClC,OAAO,CAAC,SAAS,CAAC,CAmBpB;AAED,wDAAwD;AACxD,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,CAAC;AAElD,gDAAgD;AAChD,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,EAChC,IAAI,GAAE,uBAA4B,GACjC,IAAI,CAyBN;AAED,oFAAoF;AACpF,MAAM,WAAW,aAAa,CAAC,KAAK,GAAG,OAAO,CAAE,SAAQ,sBAAsB,CAAC,KAAK,CAAC;IACnF;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,uBAAuB,CAAC;CAC9C;AAED;;;;;;;;GAQG;AACH,wBAAsB,MAAM,CAAC,KAAK,GAAG,OAAO,EAC1C,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,GACzB,OAAO,CAAC,SAAS,CAAC,CAapB"}
@@ -20,6 +20,58 @@
20
20
  */
21
21
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
22
22
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
23
+ import { McpToolError } from '../errors/index.js';
24
+ import { errorResult } from '../response/index.js';
25
+ /**
26
+ * Turn a thrown value into a tool result carrying its remediation `hint`, or
27
+ * rethrow it untouched.
28
+ *
29
+ * Only {@link McpToolError} with a `hint` is converted. Anything else keeps
30
+ * propagating so a genuine bug still reads as one instead of being flattened
31
+ * into advice.
32
+ */
33
+ function hintResultOrRethrow(err) {
34
+ if (err instanceof McpToolError && err.hint) {
35
+ return errorResult(`${err.message}\n\nHint: ${err.hint}`);
36
+ }
37
+ throw err;
38
+ }
39
+ /**
40
+ * Wrap `server.registerTool` so every tool handler surfaces its error `hint`.
41
+ *
42
+ * Why this lives here rather than in each repo: the MCP tool boundary renders
43
+ * only a thrown error's `message`. `McpToolError` has carried a `hint` — the
44
+ * actionable half ("the available options are …", "set FOO_API_KEY") — since
45
+ * the beginning, and {@link wrapToolError} is careful to preserve it, but
46
+ * nothing ever rendered it, so every hint thrown from a tool handler was
47
+ * invisible to the caller. Two repos had independently grown the same
48
+ * hand-rolled wrapper before this landed.
49
+ *
50
+ * Handlers are invoked variadically because the SDK passes `(args, extra)` for
51
+ * a tool with an `inputSchema` and `(extra)` for one without; forwarding
52
+ * whatever arrived keeps both shapes intact. Both a synchronous throw and a
53
+ * rejected promise are handled, since a handler may fail either way.
54
+ *
55
+ * Exported so `createTestHarness` can apply the same wrapper: a harness that
56
+ * built a bare `McpServer` would show tests a different error surface than
57
+ * production, which is the one thing a harness must never do.
58
+ */
59
+ export function surfaceToolHints(server) {
60
+ const register = server.registerTool.bind(server);
61
+ // The SDK's `registerTool` is heavily generic over the input/output schemas.
62
+ // Re-expressing those generics here would buy nothing — the wrapper is
63
+ // transparent — so the seam is cast once, here, and nowhere else.
64
+ server.registerTool = (name, config, cb) => register(name, config, (...args) => {
65
+ let result;
66
+ try {
67
+ result = cb(...args);
68
+ }
69
+ catch (err) {
70
+ return hintResultOrRethrow(err);
71
+ }
72
+ return result instanceof Promise ? result.catch(hintResultOrRethrow) : result;
73
+ });
74
+ }
23
75
  /**
24
76
  * Build an {@link McpServer}, print the optional stderr banner, and apply every
25
77
  * tool registrar (awaiting async ones) — but do **not** connect a transport.
@@ -28,6 +80,9 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
28
80
  */
29
81
  export async function createMcpServer(opts) {
30
82
  const server = new McpServer({ name: opts.name, version: opts.version });
83
+ // Before the registrars run, so every tool they register is wrapped.
84
+ if (opts.surfaceHints !== false)
85
+ surfaceToolHints(server);
31
86
  if (opts.banner !== undefined) {
32
87
  // stderr only: stdout carries the JSON-RPC frames over stdio transport.
33
88
  console.error(opts.banner);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Session scaffolding for the MCP fleet — four related-but-distinct surfaces
2
+ * Session scaffolding for the MCP fleet — five related-but-distinct surfaces
3
3
  * consolidated behind one subpath (`@chrischall/mcp-utils/session`):
4
4
  *
5
5
  * 1. {@link SessionRegistry} — an *ephemeral, in-memory* registry of signed-in
@@ -12,12 +12,18 @@
12
12
  * (0600 file / 0700 dir), normalized keys, and a most-recently-used "active"
13
13
  * pointer. Used by ofw/creditkarma/honeybook.
14
14
  *
15
- * 3. {@link TokenManager} — a bearer-token lifecycle manager: proactive refresh
16
- * inside a 5-minute skew window, reactive 401-replay, and a single-flight
17
- * semaphore so concurrent callers coalesce into ONE refresh. Used by
18
- * skylight/canvas/creditkarma/honeybook/zola.
15
+ * 3. {@link StatePersistence} — the opt-in seam that lets the two managers
16
+ * below survive a process restart, with {@link createFileStatePersistence}
17
+ * (atomic, 0600) and {@link resolveStateDir} (`MCP_DATA_DIR` `HOME`) as
18
+ * the disk-backed default. Without it a scale-to-zero host re-runs a full
19
+ * login on every cold start, against endpoints that often rate-limit it.
19
20
  *
20
- * 4. {@link CookieSessionManager} — the cookie-session analog of TokenManager:
21
+ * 4. {@link TokenManager} — a bearer-token lifecycle manager: a lazily
22
+ * bootstrapped login, proactive refresh inside a 5-minute skew window,
23
+ * reactive 401-replay, and a single-flight semaphore so concurrent callers
24
+ * coalesce into ONE exchange. Used by skylight/canvas/creditkarma/honeybook/zola.
25
+ *
26
+ * 5. {@link CookieSessionManager} — the cookie-session analog of TokenManager:
21
27
  * a single-flight login + reactive expiry-replay (with heuristic, not just
22
28
  * status-code, expiry detection) + clear-on-settle so a rejected login never
23
29
  * sticks. Used by artsonia/canvas/evite/signupgenius/skylight.
@@ -179,6 +185,98 @@ export declare class SessionStore<T extends Record<string, unknown>> {
179
185
  /** Clear in-memory state without touching disk. Test helper. */
180
186
  resetForTest(): void;
181
187
  }
188
+ /**
189
+ * A place to keep a credential between processes.
190
+ *
191
+ * Why this exists: {@link TokenManager} and {@link CookieSessionManager} own a
192
+ * credential's lifecycle *within* a process, and every fleet server used to
193
+ * throw that credential away on exit — so a cold start re-ran the full login
194
+ * even when a valid refresh token had been minted seconds earlier. On
195
+ * `mcp-host` that is the normal case, not the exception: children idle out
196
+ * after ten minutes and the machine scales to zero behind them. Several
197
+ * services rate-limit the login endpoint, and at least one (per the kiaaccess
198
+ * notes) escalates repeated attempts to a captcha that breaks server-side auth
199
+ * for the account permanently. Re-login is not always a free retry.
200
+ *
201
+ * Deliberately opt-in: a manager given no `persistence` behaves exactly as it
202
+ * did before, and no credential reaches a disk because a package was upgraded.
203
+ *
204
+ * Both methods may be sync or async. The fleet's own implementation
205
+ * ({@link createFileStatePersistence}) is sync — it writes one small file — but
206
+ * the async signature leaves room for a backend that has to go over a wire.
207
+ *
208
+ * **Implementations must not throw.** The managers guard every call anyway, but
209
+ * the contract is that a persistence failure degrades to in-memory operation:
210
+ * a read-only or full disk must cost a re-login, never a failed request.
211
+ */
212
+ export interface StatePersistence<T> {
213
+ /** Read the stored state; `null` when absent, unparseable, or unusable. */
214
+ load(): T | null | Promise<T | null>;
215
+ /** Write state, replacing whatever was there. */
216
+ save(state: T): void | Promise<void>;
217
+ /**
218
+ * Discard the stored state. Optional, but a manager that detects its stored
219
+ * credential is no good calls this — without it, an expired session is read
220
+ * straight back off disk and the expiry loops.
221
+ */
222
+ clear?(): void | Promise<void>;
223
+ }
224
+ /** Options for {@link createFileStatePersistence}. */
225
+ export interface FileStatePersistenceOptions<T> {
226
+ /** Absolute path to the JSON file. Parent directories are created as needed. */
227
+ filePath: string;
228
+ /**
229
+ * Narrow the parsed JSON to `T`, returning `null` to reject it. Without this
230
+ * any well-formed JSON is handed back and the caller must check the shape —
231
+ * the managers do, but a custom consumer should pass a guard.
232
+ */
233
+ validate?: (raw: unknown) => T | null;
234
+ }
235
+ /**
236
+ * File-backed {@link StatePersistence}. The file is `0600`, re-asserted after
237
+ * the write because `mode` only applies on creation. A directory is created
238
+ * `0700` and re-asserted the same way — but ONLY one this call creates: a bare
239
+ * {@link resolveStateDir} is `$HOME`, and on `mcp-host` the data dir exists
240
+ * before the child starts, so re-permissioning a pre-existing directory would
241
+ * be an invasive side effect of writing one token file rather than hardening.
242
+ *
243
+ * Two differences from {@link SessionStore}, which is why this is its own
244
+ * implementation rather than a wrapper over it. It holds ONE record rather than
245
+ * a keyed collection; and it replaces the file **atomically** — written to a
246
+ * temp file beside it, then renamed over the target — because two children of
247
+ * the same registration can share a data directory, and a half-written token
248
+ * file that parses as valid JSON is worse than none.
249
+ *
250
+ * Nothing here throws. A load failure (absent, corrupt, rejected by `validate`)
251
+ * returns `null`; a save failure is swallowed and leaves the previous file
252
+ * intact. On `mcp-host` this belongs under {@link resolveStateDir}, which needs
253
+ * the registration to declare `state.dataDir: true` — the runner's
254
+ * unpersisted-state detector will report the omission rather than let the
255
+ * writes silently vanish on the next idle-stop.
256
+ */
257
+ export declare function createFileStatePersistence<T>(opts: FileStatePersistenceOptions<T>): Required<StatePersistence<T>>;
258
+ /** Options for {@link resolveStateDir}. */
259
+ export interface ResolveStateDirOptions {
260
+ /** Environment to read (defaults to `process.env`) — injectable for tests. */
261
+ env?: Record<string, string | undefined>;
262
+ /** Optional service-scoped subdirectory to join onto the base. */
263
+ subdir?: string;
264
+ }
265
+ /**
266
+ * Where a server should keep state that must survive a restart.
267
+ *
268
+ * `MCP_DATA_DIR` first — that is the variable `mcp-host` injects for a
269
+ * registration with `state.dataDir: true`, pointing at a path on the Fly volume
270
+ * keyed by the registration itself (a slot `$HOME` is handed out by arrival
271
+ * order and moves between boots, which is why the data dir is the fix and a
272
+ * bigger rootfs is not). Then `HOME`, then the OS home directory.
273
+ *
274
+ * Blank and unexpanded-placeholder values (`${MCP_DATA_DIR}`, the shape a host
275
+ * config leaves behind when a variable was never substituted) are ignored
276
+ * rather than used as a literal directory name — the same hardening
277
+ * {@link readEnvVar} applies.
278
+ */
279
+ export declare function resolveStateDir(opts?: ResolveStateDirOptions): string;
182
280
  /** Refresh proactively this many ms before the access token expires. */
183
281
  export declare const TOKEN_REFRESH_SKEW_MS: number;
184
282
  /** A bearer access token + (optional) refresh token + absolute expiry. */
@@ -198,8 +296,21 @@ export interface RefreshedTokens {
198
296
  }
199
297
  /** Options for {@link TokenManager}. */
200
298
  export interface TokenManagerOptions {
201
- /** Initial tokens (typically from env or a one-shot bootstrap). */
202
- initial: BearerTokens;
299
+ /**
300
+ * The starting tokens — either the tokens themselves, or a **bootstrap
301
+ * function** that mints them (typically a full login).
302
+ *
303
+ * Pass the function form to get the persistence benefit: it is invoked only
304
+ * when {@link TokenManagerOptions.persistence} has nothing usable, so a
305
+ * restart that finds a stored token never logs in at all, and one that finds
306
+ * an expired token with a refresh token spends a refresh instead of a login.
307
+ * It is single-flighted like every other credential operation here, so a
308
+ * burst of first calls hits a rate-limited login endpoint exactly once.
309
+ *
310
+ * The eager object form is unchanged: the caller already paid for the login,
311
+ * so persistence is not consulted and the tokens are used as given.
312
+ */
313
+ initial: BearerTokens | (() => Promise<BearerTokens>);
203
314
  /**
204
315
  * Exchange the current refresh token for fresh tokens. Called at most once
205
316
  * per concurrent burst (the in-flight promise is shared).
@@ -210,36 +321,109 @@ export interface TokenManagerOptions {
210
321
  * refresh). Defaults to {@link TOKEN_REFRESH_SKEW_MS} (5 minutes).
211
322
  */
212
323
  skewMs?: number;
324
+ /**
325
+ * Keep tokens across process restarts. Read once on the bootstrap path
326
+ * (function-form `initial` only), written after every successful bootstrap
327
+ * and refresh, including rotation. Omit for the previous in-memory-only
328
+ * behaviour. See {@link StatePersistence}.
329
+ */
330
+ persistence?: StatePersistence<BearerTokens>;
331
+ /**
332
+ * Decide whether a {@link TokenManagerOptions.refresh} rejection means the
333
+ * credential itself is dead (re-mint via the bootstrap) or the endpoint was
334
+ * merely unreachable (surface it, keep the token).
335
+ *
336
+ * The distinction matters in both directions. Treating a transient failure as
337
+ * revocation deletes a still-VALID refresh token and burns a login against an
338
+ * endpoint that may rate-limit or escalate to a captcha — the exact cost this
339
+ * whole feature exists to avoid. Treating a real revocation as transient
340
+ * leaves the server broken until someone deletes the stored file by hand.
341
+ *
342
+ * The default resolves that by only excusing failures that are transient *by
343
+ * construction* — a {@link RateLimitedError}, a {@link RequestTimeoutError},
344
+ * or an {@link ApiError} with a 5xx status. Anything else is assumed to be a
345
+ * dead credential, which keeps the recover-from-revocation guarantee. Override
346
+ * it for a service that signals revocation some other way (or, conversely, one
347
+ * that answers a live token with a 5xx). Mirrors the permanent-vs-transient
348
+ * split {@link CookieSessionManagerOptions.isPermanentError} already makes.
349
+ */
350
+ isRefreshRevoked?: (err: unknown) => boolean;
351
+ /** Injectable clock (defaults to `Date.now`) — for tests. */
352
+ now?: () => number;
213
353
  }
214
354
  /**
215
355
  * Manages a bearer access token's lifecycle:
216
356
  *
357
+ * - **Lazy bootstrap:** with a function-form {@link TokenManagerOptions.initial}
358
+ * the login runs on first use, and only if {@link TokenManagerOptions.persistence}
359
+ * has no usable token — the difference between a cold start costing a login
360
+ * and costing nothing.
217
361
  * - **Proactive:** {@link TokenManager.getAccessToken} refreshes when the token
218
362
  * is within `skewMs` (default 5 min) of expiry, returning a still-valid token.
219
363
  * - **Reactive:** {@link TokenManager.withAuth} runs a request, and on a `401`
220
364
  * refreshes once and replays exactly once (no infinite loop).
221
- * - **Race-safe:** concurrent refreshes coalesce onto a single in-flight promise
222
- * (semaphore), so a burst of callers triggers exactly ONE token exchange. The
223
- * in-flight promise is cleared on settle so a later refresh can run again.
365
+ * - **Race-safe:** concurrent refreshes (and concurrent bootstraps) coalesce
366
+ * onto a single in-flight promise, so a burst of callers triggers exactly ONE
367
+ * exchange. The in-flight promise is cleared on settle so a later attempt can
368
+ * run again — a rejected bootstrap never sticks.
369
+ * - **Recoverable:** when a refresh fails and a bootstrap function is available,
370
+ * the stored credential is discarded and the login re-runs. A refresh token
371
+ * revoked between two runs of the process must not brick the server.
224
372
  */
225
373
  export declare class TokenManager {
226
- private accessToken;
227
- private refreshToken;
228
- private expiresAt;
374
+ private tokens;
375
+ private readonly bootstrapFn;
229
376
  private readonly refreshFn;
230
377
  private readonly skewMs;
378
+ private readonly persistence;
379
+ private readonly now;
380
+ private readonly isRefreshRevokedFn;
231
381
  private inFlight;
382
+ private bootstrapInFlight;
383
+ /**
384
+ * Persistence is consulted at most once per process. Without this the
385
+ * revoked-token recovery below re-reads the SAME rejected record — `clear()`
386
+ * is optional on {@link StatePersistence} and its failures are swallowed, so
387
+ * recovery must not depend on it. After the first read the in-memory tokens
388
+ * (or their deliberate absence) are the truth.
389
+ */
390
+ private persistenceRead;
232
391
  constructor(opts: TokenManagerOptions);
233
392
  /** Whether the token is within the skew window of (or past) expiry. */
234
393
  private needsRefresh;
394
+ /**
395
+ * A stored token is worth using when it is still valid, OR when it carries a
396
+ * refresh token — an expired-but-refreshable token still saves the login,
397
+ * which is the expensive half.
398
+ */
399
+ private isUsable;
400
+ /** Read persisted tokens, guarding shape and usability. Never throws. */
401
+ private loadPersisted;
402
+ /** Write tokens. Never throws — a failed write costs a login, not a request. */
403
+ private persist;
404
+ /** Discard persisted tokens (a refresh they could not satisfy). Never throws. */
405
+ private clearPersisted;
406
+ /** The current tokens, single-flighting the bootstrap if there are none. */
407
+ private ensureTokens;
408
+ /** One bootstrap attempt: persisted tokens if usable, else the login. */
409
+ private runBootstrap;
235
410
  /**
236
411
  * Single-flight refresh. Concurrent callers share one in-flight promise; it is
237
412
  * cleared on settle (success or failure) so a subsequent refresh can proceed.
238
413
  */
239
414
  refreshNow(): Promise<void>;
415
+ /** One refresh attempt against the current refresh token. */
416
+ private runRefresh;
417
+ /**
418
+ * Recover from a refresh the current credential could not satisfy — commonly
419
+ * a refresh token restored from a previous process and revoked since. Without
420
+ * a bootstrap to fall back on this is terminal; with one, re-minting beats
421
+ * staying broken forever. Shared so the two entry points cannot diverge.
422
+ */
423
+ private reBootstrap;
240
424
  /** Get a valid access token, refreshing proactively inside the skew window. */
241
425
  getAccessToken(): Promise<string>;
242
- /** Current absolute expiry (epoch ms). */
426
+ /** Current absolute expiry (epoch ms), or `0` before the first bootstrap. */
243
427
  getExpiresAt(): number;
244
428
  /**
245
429
  * Run an authenticated request with reactive 401-replay. `call` receives a
@@ -329,6 +513,25 @@ export interface CookieSessionManagerOptions<S, R = Response> {
329
513
  * login failure to the caller instead of the stale response.
330
514
  */
331
515
  onReplayLoginError?: (err: unknown) => void;
516
+ /**
517
+ * Keep the session across process restarts. Read ONCE, on the first login
518
+ * path, and written after every successful login and {@link
519
+ * CookieSessionManager.seed}. {@link CookieSessionManager.invalidate} clears
520
+ * it — without that, a session detected as expired would be read straight
521
+ * back off disk and the expiry would loop.
522
+ *
523
+ * The stored envelope carries the login time alongside the session so
524
+ * {@link CookieSessionManagerOptions.maxAgeMs} keeps counting from the
525
+ * original login rather than restarting at the restore. Omit for the previous
526
+ * in-memory-only behaviour. See {@link StatePersistence}.
527
+ */
528
+ persistence?: StatePersistence<PersistedCookieSession<S>>;
529
+ }
530
+ /** What {@link CookieSessionManagerOptions.persistence} stores: a session plus its login time. */
531
+ export interface PersistedCookieSession<S> {
532
+ session: S;
533
+ /** Epoch ms the session was minted or seeded — the `maxAgeMs` clock. */
534
+ sessionAt: number;
332
535
  }
333
536
  /**
334
537
  * Cookie-session analog of {@link TokenManager}: owns a site's cookie-session
@@ -382,6 +585,16 @@ export declare class CookieSessionManager<S = CookieSession, R = Response> {
382
585
  private readonly maxAgeMs;
383
586
  private readonly now;
384
587
  private readonly onReplayLoginErrorFn;
588
+ private readonly persistence;
589
+ /** Persistence is consulted once per process; a miss must not be re-read. */
590
+ private persistenceRead;
591
+ /**
592
+ * Serializes persistence writes. `seed()` and `invalidate()` are synchronous
593
+ * by contract and so fire-and-forget their save/clear; with an async backend a
594
+ * slow save could otherwise land AFTER the clear that followed it and leave an
595
+ * invalidated session on disk.
596
+ */
597
+ private persistChain;
385
598
  constructor(opts: CookieSessionManagerOptions<S, R>);
386
599
  /** The current session, or `undefined` before the first successful login. */
387
600
  get current(): S | undefined;
@@ -425,6 +638,18 @@ export declare class CookieSessionManager<S = CookieSession, R = Response> {
425
638
  * (new config). Used to recover from a detected session expiry.
426
639
  */
427
640
  invalidate(): void;
641
+ /**
642
+ * The persisted session, if there is one worth using. Read at most once per
643
+ * process — after that the in-memory session (or its absence) is the truth,
644
+ * so an invalidate() cannot be undone by a stale file.
645
+ */
646
+ private restoreFromPersistence;
647
+ /** Append a persistence op to the chain, preserving call order. Never throws. */
648
+ private enqueuePersist;
649
+ /** Write the session. Never throws — a failed write costs a login, not a request. */
650
+ private persist;
651
+ /** Discard the persisted session. Never throws. */
652
+ private clearPersisted;
428
653
  /**
429
654
  * Run an authenticated `call` with the current session and reactive
430
655
  * expiry-replay. `call` receives the session and returns a `Response`. If
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"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"}