@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.
- package/AGENTS.md +3 -1
- package/CLAUDE.md +3 -1
- package/README.md +5 -1
- package/changelog/0.2.x/0.2.1.md +18 -0
- package/changelog/0.2.x/0.2.2.md +15 -0
- package/dist/mcp-server/resources/definitions/cfr-section.resource.d.ts +12 -1
- package/dist/mcp-server/resources/definitions/cfr-section.resource.d.ts.map +1 -1
- package/dist/mcp-server/resources/definitions/cfr-section.resource.js +19 -3
- package/dist/mcp-server/resources/definitions/cfr-section.resource.js.map +1 -1
- package/dist/mcp-server/resources/definitions/document.resource.d.ts +12 -1
- package/dist/mcp-server/resources/definitions/document.resource.d.ts.map +1 -1
- package/dist/mcp-server/resources/definitions/document.resource.js +15 -0
- package/dist/mcp-server/resources/definitions/document.resource.js.map +1 -1
- package/dist/mcp-server/resources/definitions/index.d.ts +22 -2
- package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/browse-cfr.tool.d.ts +2 -2
- package/dist/mcp-server/tools/definitions/browse-cfr.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/browse-cfr.tool.js +2 -2
- package/dist/mcp-server/tools/definitions/browse-cfr.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/find-comments.tool.d.ts +3 -3
- package/dist/mcp-server/tools/definitions/find-comments.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/find-comments.tool.js +8 -4
- package/dist/mcp-server/tools/definitions/find-comments.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-cfr-section.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-cfr-section.tool.js +11 -1
- package/dist/mcp-server/tools/definitions/get-cfr-section.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-docket.tool.d.ts +5 -4
- package/dist/mcp-server/tools/definitions/get-docket.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/get-docket.tool.js +10 -5
- package/dist/mcp-server/tools/definitions/get-docket.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/get-document.tool.d.ts +1 -1
- package/dist/mcp-server/tools/definitions/get-document.tool.js +1 -1
- package/dist/mcp-server/tools/definitions/get-document.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/index.d.ts +9 -9
- package/dist/services/ecfr/ecfr-service.d.ts +20 -2
- package/dist/services/ecfr/ecfr-service.d.ts.map +1 -1
- package/dist/services/ecfr/ecfr-service.js +50 -28
- package/dist/services/ecfr/ecfr-service.js.map +1 -1
- package/dist/services/ecfr/xml.d.ts +20 -2
- package/dist/services/ecfr/xml.d.ts.map +1 -1
- package/dist/services/ecfr/xml.js +77 -10
- package/dist/services/ecfr/xml.js.map +1 -1
- package/dist/services/ecfr-mirror/ecfr-mirror.d.ts.map +1 -1
- package/dist/services/ecfr-mirror/ecfr-mirror.js +31 -5
- package/dist/services/ecfr-mirror/ecfr-mirror.js.map +1 -1
- package/dist/services/federal-register/federal-register-service.d.ts +15 -3
- package/dist/services/federal-register/federal-register-service.d.ts.map +1 -1
- package/dist/services/federal-register/federal-register-service.js +38 -10
- package/dist/services/federal-register/federal-register-service.js.map +1 -1
- package/dist/services/regulations-gov/regulations-gov-service.d.ts +27 -7
- package/dist/services/regulations-gov/regulations-gov-service.d.ts.map +1 -1
- package/dist/services/regulations-gov/regulations-gov-service.js +77 -18
- package/dist/services/regulations-gov/regulations-gov-service.js.map +1 -1
- package/dist/services/upstream-failure.d.ts +110 -0
- package/dist/services/upstream-failure.d.ts.map +1 -0
- package/dist/services/upstream-failure.js +143 -0
- package/dist/services/upstream-failure.js.map +1 -0
- package/package.json +1 -1
- package/scripts/_mirror-context.ts +16 -3
- package/scripts/ecfr-mirror-init.ts +20 -11
- package/scripts/ecfr-mirror-refresh.ts +9 -6
- package/scripts/ecfr-mirror-verify.ts +31 -19
- 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
|
|
7
|
-
*
|
|
8
|
-
* unusable resource ID joins the 404s on
|
|
9
|
-
*
|
|
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
|
|
111
|
-
* both flavours of "no such record" (404, and the 400
|
|
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
|
|
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
|
-
//
|
|
132
|
-
// the
|
|
133
|
-
//
|
|
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
|
-
|
|
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
|
-
}, {
|
|
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.
|
|
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
|
-
*
|
|
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(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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();
|