@cyanheads/federal-regulations-mcp-server 0.2.0 → 0.2.2

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 (63) hide show
  1. package/AGENTS.md +3 -1
  2. package/CLAUDE.md +3 -1
  3. package/README.md +5 -1
  4. package/changelog/0.2.x/0.2.1.md +18 -0
  5. package/changelog/0.2.x/0.2.2.md +15 -0
  6. package/dist/mcp-server/resources/definitions/cfr-section.resource.d.ts +12 -1
  7. package/dist/mcp-server/resources/definitions/cfr-section.resource.d.ts.map +1 -1
  8. package/dist/mcp-server/resources/definitions/cfr-section.resource.js +19 -3
  9. package/dist/mcp-server/resources/definitions/cfr-section.resource.js.map +1 -1
  10. package/dist/mcp-server/resources/definitions/document.resource.d.ts +12 -1
  11. package/dist/mcp-server/resources/definitions/document.resource.d.ts.map +1 -1
  12. package/dist/mcp-server/resources/definitions/document.resource.js +15 -0
  13. package/dist/mcp-server/resources/definitions/document.resource.js.map +1 -1
  14. package/dist/mcp-server/resources/definitions/index.d.ts +22 -2
  15. package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -1
  16. package/dist/mcp-server/tools/definitions/browse-cfr.tool.d.ts +2 -2
  17. package/dist/mcp-server/tools/definitions/browse-cfr.tool.d.ts.map +1 -1
  18. package/dist/mcp-server/tools/definitions/browse-cfr.tool.js +2 -2
  19. package/dist/mcp-server/tools/definitions/browse-cfr.tool.js.map +1 -1
  20. package/dist/mcp-server/tools/definitions/find-comments.tool.d.ts +3 -3
  21. package/dist/mcp-server/tools/definitions/find-comments.tool.d.ts.map +1 -1
  22. package/dist/mcp-server/tools/definitions/find-comments.tool.js +8 -4
  23. package/dist/mcp-server/tools/definitions/find-comments.tool.js.map +1 -1
  24. package/dist/mcp-server/tools/definitions/get-cfr-section.tool.d.ts.map +1 -1
  25. package/dist/mcp-server/tools/definitions/get-cfr-section.tool.js +11 -1
  26. package/dist/mcp-server/tools/definitions/get-cfr-section.tool.js.map +1 -1
  27. package/dist/mcp-server/tools/definitions/get-docket.tool.d.ts +5 -4
  28. package/dist/mcp-server/tools/definitions/get-docket.tool.d.ts.map +1 -1
  29. package/dist/mcp-server/tools/definitions/get-docket.tool.js +10 -5
  30. package/dist/mcp-server/tools/definitions/get-docket.tool.js.map +1 -1
  31. package/dist/mcp-server/tools/definitions/get-document.tool.d.ts +1 -1
  32. package/dist/mcp-server/tools/definitions/get-document.tool.js +1 -1
  33. package/dist/mcp-server/tools/definitions/get-document.tool.js.map +1 -1
  34. package/dist/mcp-server/tools/definitions/index.d.ts +9 -9
  35. package/dist/services/ecfr/ecfr-service.d.ts +20 -2
  36. package/dist/services/ecfr/ecfr-service.d.ts.map +1 -1
  37. package/dist/services/ecfr/ecfr-service.js +50 -28
  38. package/dist/services/ecfr/ecfr-service.js.map +1 -1
  39. package/dist/services/ecfr/xml.d.ts +20 -2
  40. package/dist/services/ecfr/xml.d.ts.map +1 -1
  41. package/dist/services/ecfr/xml.js +77 -10
  42. package/dist/services/ecfr/xml.js.map +1 -1
  43. package/dist/services/ecfr-mirror/ecfr-mirror.d.ts.map +1 -1
  44. package/dist/services/ecfr-mirror/ecfr-mirror.js +31 -5
  45. package/dist/services/ecfr-mirror/ecfr-mirror.js.map +1 -1
  46. package/dist/services/federal-register/federal-register-service.d.ts +15 -3
  47. package/dist/services/federal-register/federal-register-service.d.ts.map +1 -1
  48. package/dist/services/federal-register/federal-register-service.js +38 -10
  49. package/dist/services/federal-register/federal-register-service.js.map +1 -1
  50. package/dist/services/regulations-gov/regulations-gov-service.d.ts +27 -7
  51. package/dist/services/regulations-gov/regulations-gov-service.d.ts.map +1 -1
  52. package/dist/services/regulations-gov/regulations-gov-service.js +77 -18
  53. package/dist/services/regulations-gov/regulations-gov-service.js.map +1 -1
  54. package/dist/services/upstream-failure.d.ts +110 -0
  55. package/dist/services/upstream-failure.d.ts.map +1 -0
  56. package/dist/services/upstream-failure.js +143 -0
  57. package/dist/services/upstream-failure.js.map +1 -0
  58. package/package.json +1 -1
  59. package/scripts/_mirror-context.ts +16 -3
  60. package/scripts/ecfr-mirror-init.ts +20 -11
  61. package/scripts/ecfr-mirror-refresh.ts +9 -6
  62. package/scripts/ecfr-mirror-verify.ts +31 -19
  63. package/server.json +3 -3
@@ -3,16 +3,21 @@
3
3
  * API (api.regulations.gov/v4, `X-Api-Key`). Backs `get_docket` and
4
4
  * `find_comments`, and enriches `list_open_comments`. JSON:API responses are
5
5
  * unwrapped to flat domain objects. The key is optional at the service level
6
- * (`hasKey()` lets keyless tools degrade or throw `auth_required`); 429s carry a
7
- * distinct `rate_limited` signal via `Retry-After`, and a 400 that names an
8
- * unusable resource ID joins the 404s on the `not_found` path. Comment bodies are
9
- * HTML-stripped and attachment-primary submissions flagged.
6
+ * (`hasKey()` lets keyless tools degrade or throw `auth_required`, which a key
7
+ * the API rejects raises too); 429s carry a distinct `rate_limited` signal via
8
+ * `Retry-After`, and a 400 that names an unusable resource ID joins the 404s on
9
+ * the `not_found` path. Those branches read the live `Response`, so requests go
10
+ * through `fetchUpstream` rather than the framework's `fetchWithTimeout`, which
11
+ * throws every non-2xx before a caller can inspect it; the wrapper keeps the
12
+ * branching and still classifies a connect-level failure as a transport failure.
13
+ * Comment bodies are HTML-stripped and attachment-primary submissions flagged.
10
14
  * @module services/regulations-gov/regulations-gov-service
11
15
  */
12
- import { internalError, notFound, rateLimited } from '@cyanheads/mcp-ts-core/errors';
16
+ import { internalError, notFound, rateLimited, unauthorized } from '@cyanheads/mcp-ts-core/errors';
13
17
  import { httpErrorFromResponse, withRetry } from '@cyanheads/mcp-ts-core/utils';
14
18
  import { getServerConfig } from '../../config/server-config.js';
15
19
  import { toRequestContext } from '../../services/request-context.js';
20
+ import { fetchUpstream, rethrowTransportFailure, retryTransportOnly, withUpstreamReason, } from '../../services/upstream-failure.js';
16
21
  const BASE_DELAY_MS = 1500;
17
22
  export class RegulationsGovService {
18
23
  baseUrl;
@@ -107,9 +112,25 @@ export class RegulationsGovService {
107
112
  return first?.attributes?.objectId ?? null;
108
113
  }
109
114
  /**
110
- * Fetch + parse JSON with key header and retry; maps 429 → rate_limited and
111
- * both flavours of "no such record" (404, and the 400 Regulations.gov issues
112
- * for an ID it cannot parse) → not_found.
115
+ * Fetch + parse JSON with key header and retry; maps 401/403 → auth_required,
116
+ * 429 → rate_limited, and both flavours of "no such record" (404, and the 400
117
+ * Regulations.gov issues for an ID it cannot parse) → not_found. Whatever
118
+ * survives retry as a transport failure leaves as upstream_unavailable.
119
+ *
120
+ * The request goes through `fetchUpstream` rather than bare `fetch` so a
121
+ * connect-level failure — one that never produces a `Response`, so none of the
122
+ * status branches below can see it — is classified as a transport failure
123
+ * instead of reaching the caller as an unclassified `InternalError`. The
124
+ * branches themselves need the live `Response` (the 400 discrimination reads
125
+ * the body, the 429 reads `Retry-After`), which is why this is not
126
+ * `fetchWithTimeout`: that helper turns every non-2xx into a thrown `McpError`
127
+ * before the caller sees it, and its `expectedStatuses` option only lowers the
128
+ * log severity of that throw.
129
+ *
130
+ * Retry is scoped to `retryTransportOnly`: a 429 on the shared hourly key is
131
+ * deterministic for the rest of the window, and expressing that here rather
132
+ * than through `data.retryable` keeps the flag — which is also the caller's own
133
+ * backoff hint — from contradicting the contract both tools declare.
113
134
  */
114
135
  fetchJson(url, ctx, operation) {
115
136
  const key = this.apiKey;
@@ -120,23 +141,37 @@ export class RegulationsGovService {
120
141
  throw internalError('RegulationsGovService called without an API key.', { operation });
121
142
  }
122
143
  const reqCtx = toRequestContext(ctx, operation);
123
- return withRetry(async () => {
124
- const response = await fetch(url, {
144
+ return withUpstreamReason(withRetry(async () => {
145
+ const response = await fetchUpstream(url, {
125
146
  headers: { 'X-Api-Key': key, Accept: 'application/vnd.api+json' },
126
147
  signal: ctx.signal,
127
- });
148
+ }, { service: 'Regulations.gov', operation });
128
149
  if (!response.ok) {
129
150
  if (response.status === 429) {
130
151
  const retryAfter = response.headers.get('retry-after');
131
- // Fail fast on the shared key's hourly limit: surface rate_limited so
132
- // the agent backs off, rather than retry-storming the same key.
133
- // `retryable: false` opts this throw out of withRetry's retry loop.
152
+ // Surface rate_limited so the agent backs off, rather than
153
+ // retry-storming the shared key's hourly limit. The fail-fast lives
154
+ // in this call's `isTransient`, not in `data.retryable` — that key
155
+ // is also the caller's own backoff hint, and both tools declare this
156
+ // failure retryable.
134
157
  throw rateLimited('Regulations.gov rate limit hit (1,000 requests/hour per key).', {
135
158
  reason: 'rate_limited',
136
- retryable: false,
137
159
  ...(retryAfter ? { retryAfter } : {}),
160
+ ...rateLimitRecovery(ctx, retryAfter),
138
161
  });
139
162
  }
163
+ if (response.status === 401 || response.status === 403) {
164
+ // The same failure the hasKey() gate names, one step further on: a
165
+ // key that is configured but rejected. api.data.gov answers both
166
+ // with 403 (API_KEY_INVALID / API_KEY_MISSING) and reserves 401 for
167
+ // the same class, and the caller's move is identical either way —
168
+ // supply a working key. Raised as Unauthorized because that is the
169
+ // code both tools declare auth_required against; a Forbidden here
170
+ // would answer with a code its own contract contradicts. The
171
+ // upstream body is deliberately not captured: a rejected-credential
172
+ // response is the one place an upstream echoes what it was sent.
173
+ throw unauthorized(`Regulations.gov rejected the configured API key (HTTP ${response.status}).`, { operation, reason: 'auth_required', ...ctx.recoveryFor('auth_required') });
174
+ }
140
175
  if (response.status === 404) {
141
176
  // Translate the bare 404 into an actionable not_found so the tool's
142
177
  // contract recovery surfaces, rather than "returned HTTP 404".
@@ -154,15 +189,39 @@ export class RegulationsGovService {
154
189
  throw notFound(`No matching docket, document, or comment found on Regulations.gov for "${invalidId}". Verify the ID (e.g. "EPA-HQ-OAR-2025-0194" for a docket, "EPA-HQ-OAR-2025-0194-0001" for a document, "EPA-HQ-OAR-2025-0194-31102" for a comment).`, { operation, reason: 'not_found', ...ctx.recoveryFor('not_found') });
155
190
  }
156
191
  }
157
- throw await httpErrorFromResponse(response, {
192
+ rethrowTransportFailure(await httpErrorFromResponse(response, {
158
193
  service: 'Regulations.gov',
159
194
  data: { operation },
160
- });
195
+ }));
161
196
  }
162
197
  return (await response.json());
163
- }, { operation, context: reqCtx, baseDelayMs: BASE_DELAY_MS, signal: ctx.signal });
198
+ }, {
199
+ operation,
200
+ context: reqCtx,
201
+ baseDelayMs: BASE_DELAY_MS,
202
+ signal: ctx.signal,
203
+ isTransient: retryTransportOnly,
204
+ }), ctx);
164
205
  }
165
206
  }
207
+ /**
208
+ * The declared `rate_limited` hint, carrying the wait Regulations.gov asked for
209
+ * when it sent one.
210
+ *
211
+ * `Retry-After` already reaches the JSON surface as `data.retryAfter`, but never
212
+ * reaches a client reading `content[]`, which sees the `Recovery:` line and
213
+ * nothing else — so the number is folded into the hint each tool declares rather
214
+ * than replacing it. Falls back to the declared hint alone when the header is
215
+ * absent, or when the calling definition declares no `rate_limited` recovery.
216
+ */
217
+ function rateLimitRecovery(ctx, retryAfter) {
218
+ const declared = ctx.recoveryFor('rate_limited');
219
+ if (!retryAfter || !('recovery' in declared))
220
+ return declared;
221
+ return {
222
+ recovery: { hint: `${declared.recovery.hint} Regulations.gov asked for ${retryAfter}s.` },
223
+ };
224
+ }
166
225
  /**
167
226
  * The offending ID from a Regulations.gov 400 whose body reports an unusable
168
227
  * resource ID, or null for every other 400. The API answers a single-resource
@@ -1 +1 @@
1
- {"version":3,"file":"regulations-gov-service.js","sourceRoot":"","sources":["../../../src/services/regulations-gov/regulations-gov-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"regulations-gov-service.js","sourceRoot":"","sources":["../../../src/services/regulations-gov/regulations-gov-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * @fileoverview The shared pieces of how a transport failure becomes
3
+ * `upstream_unavailable` on this surface: `fetchUpstream` raises one from a
4
+ * request that never produced a response, `rethrowTransportFailure` re-codes the
5
+ * 5xx statuses the status→code map does not call one, `retryTransportOnly` says
6
+ * which of them a retry can fix, and `withUpstreamReason` stamps the contract
7
+ * reason onto whichever transport failure reaches it.
8
+ *
9
+ * Every tool on this surface declares `upstream_unavailable`, but the failure it
10
+ * describes is raised below any handler: the framework's fetch pipeline
11
+ * classifies a 5xx, a network error, or a deadline, and `withRetry` exhausts its
12
+ * attempts before the error surfaces. Nothing on that path knows the calling
13
+ * tool's contract, so the answer used to reach the caller with the right code and
14
+ * a null `data.reason` — the one failure an agent most needs to switch on to
15
+ * decide whether to retry.
16
+ *
17
+ * Services carry the reason the way the framework prescribes for code that has
18
+ * no `ctx.fail`: put `reason` in the thrown error's `data`, and spread
19
+ * `ctx.recoveryFor` so each tool's own declared hint rides along (the resolver
20
+ * returns `{}` when the caller declares nothing, so this is safe from any call
21
+ * site).
22
+ * @module services/upstream-failure
23
+ */
24
+ import type { Context } from '@cyanheads/mcp-ts-core';
25
+ /** Identifies the request in the raised error's message and `data`. */
26
+ interface UpstreamRequestContext {
27
+ /** Service method raising the request, e.g. `RegulationsGovService.getDocket`. */
28
+ operation: string;
29
+ /** Upstream named in the error message, e.g. `Regulations.gov`. */
30
+ service: string;
31
+ }
32
+ /**
33
+ * Perform an upstream request, raising a classified `ServiceUnavailable` when it
34
+ * never produced a response.
35
+ *
36
+ * `fetchWithTimeout` already does this for the services that route through it,
37
+ * but a service that has to branch on `response.status` calls `fetch` directly
38
+ * and gets no such classification — `fetch` rejects with whatever the runtime
39
+ * throws, which is not an `McpError`, so it reaches the caller as an
40
+ * unclassified `InternalError` with no reason. That is the gap this closes.
41
+ *
42
+ * **Classified by position, not by message.** A rejection here means no
43
+ * `Response` was ever produced — DNS failure, refused connection, TLS failure, a
44
+ * socket dropped before headers — which is exactly the condition
45
+ * `upstream_unavailable` names. Matching the message text instead would be a rule
46
+ * per runtime: Bun answers both a refused connection and an unresolvable host
47
+ * with the one message "Unable to connect. Is the computer able to access the
48
+ * url?" and no `cause` at all, while Node says "fetch failed" and keeps the
49
+ * syscall detail one level below that. Neither puts `ECONNREFUSED`/`ENOTFOUND`
50
+ * where the framework's patterns for them look, so those never match. Reaching
51
+ * this catch is itself the evidence.
52
+ *
53
+ * An abort is the exception and re-throws untouched: the caller ending its own
54
+ * request is not an upstream failure, and the framework already classifies it.
55
+ *
56
+ * This wrapper adds no deadline of its own — the request is bounded only by
57
+ * `init.signal`, unlike the `fetchWithTimeout` legs.
58
+ */
59
+ export declare function fetchUpstream(url: string, init: RequestInit, { service, operation }: UpstreamRequestContext): Promise<Response>;
60
+ /**
61
+ * Re-raise an upstream failure, re-coding a 5xx the status→code map does not
62
+ * already call a transport failure.
63
+ *
64
+ * Both HTTP helpers map 500 and 501 to `InternalError` and everything else in
65
+ * the range to `ServiceUnavailable`. That split is right for a status→code map —
66
+ * "the server has a bug" is not "the server is down" — but every definition here
67
+ * declares `upstream_unavailable` for a 5xx, and a 500 is the commonest one an
68
+ * upstream serves. Left alone it reached the caller as `InternalError` with no
69
+ * reason and no hint, and `withRetry` did not retry it, while the 502 beside it
70
+ * was retried and answered `upstream_unavailable`.
71
+ *
72
+ * **Keyed on the status, not the code or the message.** `data.status` is set only
73
+ * by the two helpers that read a real `Response`, so a caller abort (an
74
+ * `InternalError` carrying `errorSource: 'FetchAborted'` and no status) and a
75
+ * programmer error (no `data` at all) cannot reach this branch — which is the
76
+ * point, since both are `InternalError` too and neither is an unreachable
77
+ * upstream. An error already carrying a transport code is left alone rather than
78
+ * re-wrapped to the same code: a 504's `Timeout` then reaches
79
+ * {@link withUpstreamReason} as itself, and the 502/503 that need nothing done
80
+ * to them keep their own object and a `cause` chain one link shorter.
81
+ */
82
+ export declare function rethrowTransportFailure(error: unknown): never;
83
+ /**
84
+ * Retry predicate for a service that raises a non-retryable failure with a
85
+ * retryable code.
86
+ *
87
+ * `withRetry`'s default treats every `RateLimited` as transient unless the throw
88
+ * carries `data.retryable: false`. That flag is also the client's own backoff
89
+ * hint, so opting out through it tells the caller not to retry a failure the
90
+ * tools declare as retryable. Deciding it here keeps the wire honest: a transport
91
+ * failure is retried, an answer with a status is not, and an unclassified throw
92
+ * (a parse failure mid-pipeline) stays transient the way the default has it.
93
+ */
94
+ export declare function retryTransportOnly(error: unknown): boolean;
95
+ /**
96
+ * Run upstream work, stamping `upstream_unavailable` on a transport failure.
97
+ *
98
+ * A `Timeout` is re-coded to `ServiceUnavailable` rather than kept as-is: the
99
+ * reason is declared against one code on every tool that carries it, and a
100
+ * contract that names a code the wire contradicts is worse than one that loses
101
+ * the distinction between "did not answer in time" and "answered 503". The
102
+ * distinction survives in the message, which the framework built from the
103
+ * deadline it missed, and in the `cause` chain.
104
+ *
105
+ * Anything else passes through untouched — an already-classified domain failure,
106
+ * a parse error, a caller abort, a programmer error.
107
+ */
108
+ export declare function withUpstreamReason<T>(work: Promise<T>, ctx: Context): Promise<T>;
109
+ export {};
110
+ //# sourceMappingURL=upstream-failure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upstream-failure.d.ts","sourceRoot":"","sources":["../../src/services/upstream-failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGtD,uEAAuE;AACvE,UAAU,sBAAsB;IAC9B,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,EACjB,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,sBAAsB,GAC7C,OAAO,CAAC,QAAQ,CAAC,CAgBnB;AAaD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAQ7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAG1D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAShF"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * @fileoverview The shared pieces of how a transport failure becomes
3
+ * `upstream_unavailable` on this surface: `fetchUpstream` raises one from a
4
+ * request that never produced a response, `rethrowTransportFailure` re-codes the
5
+ * 5xx statuses the status→code map does not call one, `retryTransportOnly` says
6
+ * which of them a retry can fix, and `withUpstreamReason` stamps the contract
7
+ * reason onto whichever transport failure reaches it.
8
+ *
9
+ * Every tool on this surface declares `upstream_unavailable`, but the failure it
10
+ * describes is raised below any handler: the framework's fetch pipeline
11
+ * classifies a 5xx, a network error, or a deadline, and `withRetry` exhausts its
12
+ * attempts before the error surfaces. Nothing on that path knows the calling
13
+ * tool's contract, so the answer used to reach the caller with the right code and
14
+ * a null `data.reason` — the one failure an agent most needs to switch on to
15
+ * decide whether to retry.
16
+ *
17
+ * Services carry the reason the way the framework prescribes for code that has
18
+ * no `ctx.fail`: put `reason` in the thrown error's `data`, and spread
19
+ * `ctx.recoveryFor` so each tool's own declared hint rides along (the resolver
20
+ * returns `{}` when the caller declares nothing, so this is safe from any call
21
+ * site).
22
+ * @module services/upstream-failure
23
+ */
24
+ import { JsonRpcErrorCode, McpError, serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
25
+ /**
26
+ * Perform an upstream request, raising a classified `ServiceUnavailable` when it
27
+ * never produced a response.
28
+ *
29
+ * `fetchWithTimeout` already does this for the services that route through it,
30
+ * but a service that has to branch on `response.status` calls `fetch` directly
31
+ * and gets no such classification — `fetch` rejects with whatever the runtime
32
+ * throws, which is not an `McpError`, so it reaches the caller as an
33
+ * unclassified `InternalError` with no reason. That is the gap this closes.
34
+ *
35
+ * **Classified by position, not by message.** A rejection here means no
36
+ * `Response` was ever produced — DNS failure, refused connection, TLS failure, a
37
+ * socket dropped before headers — which is exactly the condition
38
+ * `upstream_unavailable` names. Matching the message text instead would be a rule
39
+ * per runtime: Bun answers both a refused connection and an unresolvable host
40
+ * with the one message "Unable to connect. Is the computer able to access the
41
+ * url?" and no `cause` at all, while Node says "fetch failed" and keeps the
42
+ * syscall detail one level below that. Neither puts `ECONNREFUSED`/`ENOTFOUND`
43
+ * where the framework's patterns for them look, so those never match. Reaching
44
+ * this catch is itself the evidence.
45
+ *
46
+ * An abort is the exception and re-throws untouched: the caller ending its own
47
+ * request is not an upstream failure, and the framework already classifies it.
48
+ *
49
+ * This wrapper adds no deadline of its own — the request is bounded only by
50
+ * `init.signal`, unlike the `fetchWithTimeout` legs.
51
+ */
52
+ export async function fetchUpstream(url, init, { service, operation }) {
53
+ try {
54
+ return await fetch(url, init);
55
+ }
56
+ catch (error) {
57
+ if (init.signal?.aborted || (error instanceof Error && error.name === 'AbortError')) {
58
+ throw error;
59
+ }
60
+ const detail = error instanceof Error ? error.message : String(error);
61
+ throw serviceUnavailable(`${service} could not be reached: ${detail}`, { operation }, {
62
+ cause: error,
63
+ });
64
+ }
65
+ }
66
+ /**
67
+ * Codes that mean the upstream never produced a usable response. Kept to these
68
+ * two on purpose: a 404, a 400, a 401, or a 429 is an answer, and each already
69
+ * has a reason of its own (`not_found`, `date_out_of_range`, `auth_required`,
70
+ * `rate_limited`) that this must not overwrite.
71
+ */
72
+ const TRANSPORT_CODES = new Set([
73
+ JsonRpcErrorCode.ServiceUnavailable,
74
+ JsonRpcErrorCode.Timeout,
75
+ ]);
76
+ /**
77
+ * Re-raise an upstream failure, re-coding a 5xx the status→code map does not
78
+ * already call a transport failure.
79
+ *
80
+ * Both HTTP helpers map 500 and 501 to `InternalError` and everything else in
81
+ * the range to `ServiceUnavailable`. That split is right for a status→code map —
82
+ * "the server has a bug" is not "the server is down" — but every definition here
83
+ * declares `upstream_unavailable` for a 5xx, and a 500 is the commonest one an
84
+ * upstream serves. Left alone it reached the caller as `InternalError` with no
85
+ * reason and no hint, and `withRetry` did not retry it, while the 502 beside it
86
+ * was retried and answered `upstream_unavailable`.
87
+ *
88
+ * **Keyed on the status, not the code or the message.** `data.status` is set only
89
+ * by the two helpers that read a real `Response`, so a caller abort (an
90
+ * `InternalError` carrying `errorSource: 'FetchAborted'` and no status) and a
91
+ * programmer error (no `data` at all) cannot reach this branch — which is the
92
+ * point, since both are `InternalError` too and neither is an unreachable
93
+ * upstream. An error already carrying a transport code is left alone rather than
94
+ * re-wrapped to the same code: a 504's `Timeout` then reaches
95
+ * {@link withUpstreamReason} as itself, and the 502/503 that need nothing done
96
+ * to them keep their own object and a `cause` chain one link shorter.
97
+ */
98
+ export function rethrowTransportFailure(error) {
99
+ if (error instanceof McpError && !TRANSPORT_CODES.has(error.code)) {
100
+ const status = error.data?.status;
101
+ if (typeof status === 'number' && status >= 500) {
102
+ throw serviceUnavailable(error.message, { ...error.data }, { cause: error });
103
+ }
104
+ }
105
+ throw error;
106
+ }
107
+ /**
108
+ * Retry predicate for a service that raises a non-retryable failure with a
109
+ * retryable code.
110
+ *
111
+ * `withRetry`'s default treats every `RateLimited` as transient unless the throw
112
+ * carries `data.retryable: false`. That flag is also the client's own backoff
113
+ * hint, so opting out through it tells the caller not to retry a failure the
114
+ * tools declare as retryable. Deciding it here keeps the wire honest: a transport
115
+ * failure is retried, an answer with a status is not, and an unclassified throw
116
+ * (a parse failure mid-pipeline) stays transient the way the default has it.
117
+ */
118
+ export function retryTransportOnly(error) {
119
+ if (!(error instanceof McpError))
120
+ return true;
121
+ return TRANSPORT_CODES.has(error.code);
122
+ }
123
+ /**
124
+ * Run upstream work, stamping `upstream_unavailable` on a transport failure.
125
+ *
126
+ * A `Timeout` is re-coded to `ServiceUnavailable` rather than kept as-is: the
127
+ * reason is declared against one code on every tool that carries it, and a
128
+ * contract that names a code the wire contradicts is worse than one that loses
129
+ * the distinction between "did not answer in time" and "answered 503". The
130
+ * distinction survives in the message, which the framework built from the
131
+ * deadline it missed, and in the `cause` chain.
132
+ *
133
+ * Anything else passes through untouched — an already-classified domain failure,
134
+ * a parse error, a caller abort, a programmer error.
135
+ */
136
+ export function withUpstreamReason(work, ctx) {
137
+ return work.catch((err) => {
138
+ if (!(err instanceof McpError) || !TRANSPORT_CODES.has(err.code))
139
+ throw err;
140
+ throw serviceUnavailable(err.message, { ...err.data, reason: 'upstream_unavailable', ...ctx.recoveryFor('upstream_unavailable') }, { cause: err });
141
+ });
142
+ }
143
+ //# sourceMappingURL=upstream-failure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upstream-failure.js","sourceRoot":"","sources":["../../src/services/upstream-failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAU/F;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAW,EACX,IAAiB,EACjB,EAAE,OAAO,EAAE,SAAS,EAA0B;IAE9C,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,EAAE,CAAC;YACpF,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtE,MAAM,kBAAkB,CACtB,GAAG,OAAO,0BAA0B,MAAM,EAAE,EAC5C,EAAE,SAAS,EAAE,EACb;YACE,KAAK,EAAE,KAAK;SACb,CACF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,eAAe,GAAG,IAAI,GAAG,CAAmB;IAChD,gBAAgB,CAAC,kBAAkB;IACnC,gBAAgB,CAAC,OAAO;CACzB,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAc;IACpD,IAAI,KAAK,YAAY,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAClE,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;QAClC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YAChD,MAAM,kBAAkB,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IACD,MAAM,KAAK,CAAC;AACd,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,IAAI,CAAC,CAAC,KAAK,YAAY,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,OAAO,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAI,IAAgB,EAAE,GAAY;IAClE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QACjC,IAAI,CAAC,CAAC,GAAG,YAAY,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,GAAG,CAAC;QAC5E,MAAM,kBAAkB,CACtB,GAAG,CAAC,OAAO,EACX,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,sBAAsB,EAAE,GAAG,GAAG,CAAC,WAAW,CAAC,sBAAsB,CAAC,EAAE,EAC3F,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyanheads/federal-regulations-mcp-server",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "mcpName": "io.github.cyanheads/federal-regulations-mcp-server",
5
5
  "description": "Search and trace US federal rules across the Federal Register (proposed/final rules and notices), the eCFR (codified, point-in-time CFR full text, locally mirrored), and Regulations.gov (rulemaking dockets and public comments) via MCP. STDIO or Streamable HTTP.",
6
6
  "type": "module",
@@ -2,8 +2,9 @@
2
2
  * @fileoverview Shared bootstrap for the eCFR mirror lifecycle scripts
3
3
  * (mirror:init / mirror:refresh / mirror:verify). These run out-of-band (CLI /
4
4
  * cron), not inside the MCP request pipeline, so they wire up the minimum the
5
- * mirror's `sync` ingester needs: the eCFR service (which the ingester calls)
6
- * and an abort signal. The framework logger is already a global singleton.
5
+ * mirror's `sync` ingester needs: the eCFR service (which the ingester calls),
6
+ * an abort signal, and the request context their log lines carry. The framework
7
+ * logger is already a global singleton.
7
8
  *
8
9
  * Imported by the three named lifecycle scripts; travels with them into the npm
9
10
  * tarball and the Docker runtime stage (see Dockerfile + package.json files[]).
@@ -14,9 +15,21 @@
14
15
  import { config } from '@cyanheads/mcp-ts-core/config';
15
16
  import { StorageService } from '@cyanheads/mcp-ts-core/storage';
16
17
  import type { IStorageProvider, ListResult } from '@cyanheads/mcp-ts-core/storage/types';
17
- import { logger } from '@cyanheads/mcp-ts-core/utils';
18
+ import { logger, type RequestContext, requestContextService } from '@cyanheads/mcp-ts-core/utils';
18
19
  import { initEcfrService } from '@/services/ecfr/ecfr-service.js';
19
20
 
21
+ /**
22
+ * A `RequestContext` carrying `fields`, for the second argument of a `logger`
23
+ * call. That argument is a RequestContext rather than a bare data bag, so fields
24
+ * handed over outside one are never correlated to the run that produced them.
25
+ */
26
+ export function mirrorLogContext(
27
+ operation: string,
28
+ fields: Record<string, unknown>,
29
+ ): RequestContext {
30
+ return requestContextService.createRequestContext({ operation, ...fields });
31
+ }
32
+
20
33
  /**
21
34
  * A minimal Map-backed in-memory storage provider. The mirror owns its own
22
35
  * SQLite store and the eCFR service does not use `ctx.state`, so this exists only
@@ -10,7 +10,10 @@
10
10
 
11
11
  import { logger } from '@cyanheads/mcp-ts-core/utils';
12
12
  import { ecfrMirror } from '@/services/ecfr-mirror/ecfr-mirror.js';
13
- import { bootstrapMirrorServices, signalFromProcess } from './_mirror-context.js';
13
+ import { bootstrapMirrorServices, mirrorLogContext, signalFromProcess } from './_mirror-context.js';
14
+
15
+ const logContext = (fields: Record<string, unknown>) =>
16
+ mirrorLogContext('ecfr-mirror:init', fields);
14
17
 
15
18
  await bootstrapMirrorServices();
16
19
 
@@ -19,18 +22,24 @@ const result = await ecfrMirror.runSync({
19
22
  mode: 'init',
20
23
  signal: signalFromProcess(),
21
24
  onProgress: (info) => {
22
- logger.info('eCFR mirror init progress', {
23
- pages: info.pages,
24
- records: info.records,
25
- checkpoint: info.checkpoint,
26
- });
25
+ logger.info(
26
+ 'eCFR mirror init progress',
27
+ logContext({
28
+ pages: info.pages,
29
+ records: info.records,
30
+ checkpoint: info.checkpoint,
31
+ }),
32
+ );
27
33
  },
28
34
  });
29
35
 
30
- logger.info('eCFR mirror init: complete', {
31
- pagesFetched: result.pagesFetched,
32
- recordsApplied: result.recordsApplied,
33
- total: result.total,
34
- });
36
+ logger.info(
37
+ 'eCFR mirror init: complete',
38
+ logContext({
39
+ pagesFetched: result.pagesFetched,
40
+ recordsApplied: result.recordsApplied,
41
+ total: result.total,
42
+ }),
43
+ );
35
44
 
36
45
  await ecfrMirror.close();
@@ -10,7 +10,7 @@
10
10
 
11
11
  import { logger } from '@cyanheads/mcp-ts-core/utils';
12
12
  import { ecfrMirror } from '@/services/ecfr-mirror/ecfr-mirror.js';
13
- import { bootstrapMirrorServices, signalFromProcess } from './_mirror-context.js';
13
+ import { bootstrapMirrorServices, mirrorLogContext, signalFromProcess } from './_mirror-context.js';
14
14
 
15
15
  await bootstrapMirrorServices();
16
16
 
@@ -20,10 +20,13 @@ const result = await ecfrMirror.runSync({
20
20
  signal: signalFromProcess(),
21
21
  });
22
22
 
23
- logger.info('eCFR mirror refresh: complete', {
24
- pagesFetched: result.pagesFetched,
25
- recordsApplied: result.recordsApplied,
26
- total: result.total,
27
- });
23
+ logger.info(
24
+ 'eCFR mirror refresh: complete',
25
+ mirrorLogContext('ecfr-mirror:refresh', {
26
+ pagesFetched: result.pagesFetched,
27
+ recordsApplied: result.recordsApplied,
28
+ total: result.total,
29
+ }),
30
+ );
28
31
 
29
32
  await ecfrMirror.close();