@cyanheads/federal-regulations-mcp-server 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/AGENTS.md +387 -0
  2. package/CLAUDE.md +387 -0
  3. package/Dockerfile +127 -0
  4. package/LICENSE +201 -0
  5. package/README.md +372 -0
  6. package/changelog/0.1.x/0.1.0.md +20 -0
  7. package/changelog/template.md +127 -0
  8. package/dist/config/server-config.d.ts +32 -0
  9. package/dist/config/server-config.d.ts.map +1 -0
  10. package/dist/config/server-config.js +64 -0
  11. package/dist/config/server-config.js.map +1 -0
  12. package/dist/index.d.ts +12 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +51 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/mcp-server/resources/definitions/cfr-section.resource.d.ts +14 -0
  17. package/dist/mcp-server/resources/definitions/cfr-section.resource.d.ts.map +1 -0
  18. package/dist/mcp-server/resources/definitions/cfr-section.resource.js +77 -0
  19. package/dist/mcp-server/resources/definitions/cfr-section.resource.js.map +1 -0
  20. package/dist/mcp-server/resources/definitions/document.resource.d.ts +12 -0
  21. package/dist/mcp-server/resources/definitions/document.resource.d.ts.map +1 -0
  22. package/dist/mcp-server/resources/definitions/document.resource.js +38 -0
  23. package/dist/mcp-server/resources/definitions/document.resource.js.map +1 -0
  24. package/dist/mcp-server/resources/definitions/index.d.ts +12 -0
  25. package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -0
  26. package/dist/mcp-server/resources/definitions/index.js +8 -0
  27. package/dist/mcp-server/resources/definitions/index.js.map +1 -0
  28. package/dist/mcp-server/tools/definitions/browse-cfr.tool.d.ts +73 -0
  29. package/dist/mcp-server/tools/definitions/browse-cfr.tool.d.ts.map +1 -0
  30. package/dist/mcp-server/tools/definitions/browse-cfr.tool.js +205 -0
  31. package/dist/mcp-server/tools/definitions/browse-cfr.tool.js.map +1 -0
  32. package/dist/mcp-server/tools/definitions/find-comments.tool.d.ts +85 -0
  33. package/dist/mcp-server/tools/definitions/find-comments.tool.d.ts.map +1 -0
  34. package/dist/mcp-server/tools/definitions/find-comments.tool.js +271 -0
  35. package/dist/mcp-server/tools/definitions/find-comments.tool.js.map +1 -0
  36. package/dist/mcp-server/tools/definitions/format-utils.d.ts +7 -0
  37. package/dist/mcp-server/tools/definitions/format-utils.d.ts.map +1 -0
  38. package/dist/mcp-server/tools/definitions/format-utils.js +9 -0
  39. package/dist/mcp-server/tools/definitions/format-utils.js.map +1 -0
  40. package/dist/mcp-server/tools/definitions/get-cfr-section.tool.d.ts +50 -0
  41. package/dist/mcp-server/tools/definitions/get-cfr-section.tool.d.ts.map +1 -0
  42. package/dist/mcp-server/tools/definitions/get-cfr-section.tool.js +152 -0
  43. package/dist/mcp-server/tools/definitions/get-cfr-section.tool.js.map +1 -0
  44. package/dist/mcp-server/tools/definitions/get-docket.tool.d.ts +67 -0
  45. package/dist/mcp-server/tools/definitions/get-docket.tool.d.ts.map +1 -0
  46. package/dist/mcp-server/tools/definitions/get-docket.tool.js +154 -0
  47. package/dist/mcp-server/tools/definitions/get-docket.tool.js.map +1 -0
  48. package/dist/mcp-server/tools/definitions/get-document.tool.d.ts +51 -0
  49. package/dist/mcp-server/tools/definitions/get-document.tool.d.ts.map +1 -0
  50. package/dist/mcp-server/tools/definitions/get-document.tool.js +138 -0
  51. package/dist/mcp-server/tools/definitions/get-document.tool.js.map +1 -0
  52. package/dist/mcp-server/tools/definitions/index.d.ts +356 -0
  53. package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
  54. package/dist/mcp-server/tools/definitions/index.js +21 -0
  55. package/dist/mcp-server/tools/definitions/index.js.map +1 -0
  56. package/dist/mcp-server/tools/definitions/list-open-comments.tool.d.ts +47 -0
  57. package/dist/mcp-server/tools/definitions/list-open-comments.tool.d.ts.map +1 -0
  58. package/dist/mcp-server/tools/definitions/list-open-comments.tool.js +179 -0
  59. package/dist/mcp-server/tools/definitions/list-open-comments.tool.js.map +1 -0
  60. package/dist/mcp-server/tools/definitions/search-rules.tool.d.ts +57 -0
  61. package/dist/mcp-server/tools/definitions/search-rules.tool.d.ts.map +1 -0
  62. package/dist/mcp-server/tools/definitions/search-rules.tool.js +185 -0
  63. package/dist/mcp-server/tools/definitions/search-rules.tool.js.map +1 -0
  64. package/dist/services/ecfr/ecfr-service.d.ts +54 -0
  65. package/dist/services/ecfr/ecfr-service.d.ts.map +1 -0
  66. package/dist/services/ecfr/ecfr-service.js +303 -0
  67. package/dist/services/ecfr/ecfr-service.js.map +1 -0
  68. package/dist/services/ecfr/types.d.ts +105 -0
  69. package/dist/services/ecfr/types.d.ts.map +1 -0
  70. package/dist/services/ecfr/types.js +7 -0
  71. package/dist/services/ecfr/types.js.map +1 -0
  72. package/dist/services/ecfr/xml.d.ts +15 -0
  73. package/dist/services/ecfr/xml.d.ts.map +1 -0
  74. package/dist/services/ecfr/xml.js +103 -0
  75. package/dist/services/ecfr/xml.js.map +1 -0
  76. package/dist/services/ecfr-mirror/ecfr-mirror.d.ts +43 -0
  77. package/dist/services/ecfr-mirror/ecfr-mirror.d.ts.map +1 -0
  78. package/dist/services/ecfr-mirror/ecfr-mirror.js +267 -0
  79. package/dist/services/ecfr-mirror/ecfr-mirror.js.map +1 -0
  80. package/dist/services/federal-register/federal-register-service.d.ts +30 -0
  81. package/dist/services/federal-register/federal-register-service.d.ts.map +1 -0
  82. package/dist/services/federal-register/federal-register-service.js +241 -0
  83. package/dist/services/federal-register/federal-register-service.js.map +1 -0
  84. package/dist/services/federal-register/types.d.ts +138 -0
  85. package/dist/services/federal-register/types.d.ts.map +1 -0
  86. package/dist/services/federal-register/types.js +8 -0
  87. package/dist/services/federal-register/types.js.map +1 -0
  88. package/dist/services/regulations-gov/regulations-gov-service.d.ts +55 -0
  89. package/dist/services/regulations-gov/regulations-gov-service.d.ts.map +1 -0
  90. package/dist/services/regulations-gov/regulations-gov-service.js +283 -0
  91. package/dist/services/regulations-gov/regulations-gov-service.js.map +1 -0
  92. package/dist/services/regulations-gov/types.d.ts +148 -0
  93. package/dist/services/regulations-gov/types.d.ts.map +1 -0
  94. package/dist/services/regulations-gov/types.js +7 -0
  95. package/dist/services/regulations-gov/types.js.map +1 -0
  96. package/dist/services/request-context.d.ts +13 -0
  97. package/dist/services/request-context.d.ts.map +1 -0
  98. package/dist/services/request-context.js +23 -0
  99. package/dist/services/request-context.js.map +1 -0
  100. package/package.json +94 -0
  101. package/scripts/_mirror-context.ts +101 -0
  102. package/scripts/ecfr-mirror-init.ts +36 -0
  103. package/scripts/ecfr-mirror-refresh.ts +29 -0
  104. package/scripts/ecfr-mirror-verify.ts +33 -0
  105. package/server.json +113 -0
@@ -0,0 +1,283 @@
1
+ /**
2
+ * @fileoverview RegulationsGovService — keyed client for the Regulations.gov v4
3
+ * API (api.regulations.gov/v4, `X-Api-Key`). Backs `get_docket` and
4
+ * `find_comments`, and enriches `list_open_comments`. JSON:API responses are
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`. Comment bodies are
8
+ * HTML-stripped and attachment-primary submissions flagged.
9
+ * @module services/regulations-gov/regulations-gov-service
10
+ */
11
+ import { internalError, notFound, rateLimited } from '@cyanheads/mcp-ts-core/errors';
12
+ import { httpErrorFromResponse, withRetry } from '@cyanheads/mcp-ts-core/utils';
13
+ import { getServerConfig } from '../../config/server-config.js';
14
+ import { toRequestContext } from '../../services/request-context.js';
15
+ const BASE_DELAY_MS = 1500;
16
+ export class RegulationsGovService {
17
+ baseUrl;
18
+ apiKey;
19
+ constructor(_config, _storage) {
20
+ const cfg = getServerConfig();
21
+ this.baseUrl = cfg.regulationsGovBaseUrl.replace(/\/$/, '');
22
+ this.apiKey = cfg.regulationsGovApiKey;
23
+ }
24
+ /** Whether a Regulations.gov API key is configured. */
25
+ hasKey() {
26
+ return typeof this.apiKey === 'string' && this.apiKey.length > 0;
27
+ }
28
+ /** Fetch a docket's metadata plus the documents filed in it. */
29
+ async getDocket(params, ctx) {
30
+ const docketUrl = `${this.baseUrl}/dockets/${encodeURIComponent(params.docketId)}`;
31
+ const docketRaw = await this.fetchJson(docketUrl, ctx, 'RegulationsGovService.getDocket');
32
+ const attrs = docketRaw.data?.attributes ?? {};
33
+ const docSearch = new URLSearchParams({
34
+ 'filter[docketId]': params.docketId,
35
+ 'page[size]': String(params.perPage),
36
+ 'page[number]': String(params.page),
37
+ sort: '-postedDate',
38
+ });
39
+ for (const type of params.documentTypes ?? []) {
40
+ docSearch.append('filter[documentType]', type);
41
+ }
42
+ const docsUrl = `${this.baseUrl}/documents?${docSearch.toString()}`;
43
+ const docsRaw = await this.fetchJson(docsUrl, ctx, 'RegulationsGovService.getDocketDocuments');
44
+ const documents = (docsRaw.data ?? [])
45
+ .map((d) => normalizeDocument(d))
46
+ .filter((d) => d !== null);
47
+ return {
48
+ docketId: params.docketId,
49
+ title: attrs.title ?? '(untitled docket)',
50
+ docketType: attrs.docketType ?? null,
51
+ agencyId: attrs.agencyId ?? null,
52
+ rin: attrs.rin ?? null,
53
+ abstract: attrs.dkAbstract ?? null,
54
+ modifyDate: attrs.modifyDate ?? null,
55
+ objectId: attrs.objectId ?? null,
56
+ documentCount: docsRaw.meta?.totalElements ?? documents.length,
57
+ documents,
58
+ };
59
+ }
60
+ /** List comments on a document (by object ID) or a docket (by docket ID). */
61
+ async listComments(params, ctx) {
62
+ const search = new URLSearchParams({
63
+ 'page[size]': String(params.perPage),
64
+ 'page[number]': String(params.page),
65
+ sort: '-postedDate',
66
+ });
67
+ if ('commentOnId' in params.filter) {
68
+ search.set('filter[commentOnId]', params.filter.commentOnId);
69
+ }
70
+ else {
71
+ search.set('filter[docketId]', params.filter.docketId);
72
+ }
73
+ const url = `${this.baseUrl}/comments?${search.toString()}`;
74
+ const raw = await this.fetchJson(url, ctx, 'RegulationsGovService.listComments');
75
+ const comments = (raw.data ?? [])
76
+ .map((c) => normalizeCommentSummary(c))
77
+ .filter((c) => c !== null);
78
+ return { totalCount: raw.meta?.totalElements ?? comments.length, comments };
79
+ }
80
+ /** Fetch one comment's full detail and attachments by comment ID. */
81
+ async getComment(commentId, ctx) {
82
+ const url = `${this.baseUrl}/comments/${encodeURIComponent(commentId)}?include=attachments`;
83
+ const raw = await this.fetchJson(url, ctx, 'RegulationsGovService.getComment');
84
+ return normalizeCommentDetail(commentId, raw);
85
+ }
86
+ /**
87
+ * Resolve a Federal Register document number to its Regulations.gov primary
88
+ * document object ID, via `filter[searchTerm]` on the FR number. Returns null
89
+ * when no matching document is found.
90
+ */
91
+ async resolveFrDocumentObjectId(frDocumentNumber, ctx) {
92
+ const search = new URLSearchParams({
93
+ 'filter[searchTerm]': frDocumentNumber,
94
+ 'page[size]': '5',
95
+ 'page[number]': '1',
96
+ });
97
+ const url = `${this.baseUrl}/documents?${search.toString()}`;
98
+ const raw = await this.fetchJson(url, ctx, 'RegulationsGovService.resolveFrDocument');
99
+ for (const d of raw.data ?? []) {
100
+ if (d.attributes?.frDocNum === frDocumentNumber && d.attributes?.objectId) {
101
+ return d.attributes.objectId;
102
+ }
103
+ }
104
+ // Fall back to the first result's objectId if present.
105
+ const first = (raw.data ?? [])[0];
106
+ return first?.attributes?.objectId ?? null;
107
+ }
108
+ /** Fetch + parse JSON with key header and retry; maps 429 → rate_limited. */
109
+ fetchJson(url, ctx, operation) {
110
+ const key = this.apiKey;
111
+ if (!key) {
112
+ // Unreachable in normal operation: both keyed tools gate on hasKey() and
113
+ // throw auth_required before any service call. An invariant violation here
114
+ // is a programmer error (a caller bypassed the gate), not an operational one.
115
+ throw internalError('RegulationsGovService called without an API key.', { operation });
116
+ }
117
+ const reqCtx = toRequestContext(ctx, operation);
118
+ return withRetry(async () => {
119
+ const response = await fetch(url, {
120
+ headers: { 'X-Api-Key': key, Accept: 'application/vnd.api+json' },
121
+ signal: ctx.signal,
122
+ });
123
+ if (!response.ok) {
124
+ if (response.status === 429) {
125
+ const retryAfter = response.headers.get('retry-after');
126
+ // Fail fast on the shared key's hourly limit: surface rate_limited so
127
+ // the agent backs off, rather than retry-storming the same key.
128
+ // `retryable: false` opts this throw out of withRetry's retry loop.
129
+ throw rateLimited('Regulations.gov rate limit hit (1,000 requests/hour per key).', {
130
+ reason: 'rate_limited',
131
+ retryable: false,
132
+ ...(retryAfter ? { retryAfter } : {}),
133
+ });
134
+ }
135
+ if (response.status === 404) {
136
+ // Translate the bare 404 into an actionable not_found so the tool's
137
+ // contract recovery surfaces, rather than "returned HTTP 404".
138
+ throw notFound('No matching docket, document, or comment found on Regulations.gov. Verify the ID (e.g. "EPA-HQ-OAR-2025-0194" for a docket).', { operation });
139
+ }
140
+ throw await httpErrorFromResponse(response, {
141
+ service: 'Regulations.gov',
142
+ data: { operation },
143
+ });
144
+ }
145
+ return (await response.json());
146
+ }, { operation, context: reqCtx, baseDelayMs: BASE_DELAY_MS, signal: ctx.signal });
147
+ }
148
+ }
149
+ function normalizeDocument(d) {
150
+ const a = d.attributes;
151
+ if (!d.id || !a?.objectId)
152
+ return null;
153
+ return {
154
+ documentId: d.id,
155
+ objectId: a.objectId,
156
+ title: a.title ?? '(untitled)',
157
+ documentType: a.documentType ?? 'Unknown',
158
+ postedDate: a.postedDate ?? '',
159
+ frDocNum: a.frDocNum ?? null,
160
+ commentEndDate: a.commentEndDate ?? null,
161
+ withdrawn: a.withdrawn ?? false,
162
+ };
163
+ }
164
+ function normalizeCommentSummary(c) {
165
+ const a = c.attributes;
166
+ if (!c.id)
167
+ return null;
168
+ return {
169
+ commentId: c.id,
170
+ title: a?.title ?? '(untitled comment)',
171
+ documentType: a?.documentType ?? 'Public Submission',
172
+ postedDate: a?.postedDate ?? '',
173
+ agencyId: a?.agencyId ?? null,
174
+ objectId: a?.objectId ?? '',
175
+ withdrawn: a?.withdrawn ?? false,
176
+ };
177
+ }
178
+ /** Collect attachments from a JSON:API `included[]` block. */
179
+ function collectAttachments(included) {
180
+ return (included ?? [])
181
+ .filter((r) => r.type === 'attachments')
182
+ .map((r) => {
183
+ const formats = (r.attributes?.fileFormats ?? [])
184
+ .filter((f) => typeof f?.fileUrl === 'string' && f.fileUrl.length > 0)
185
+ .map((f) => ({
186
+ format: f.format ?? 'unknown',
187
+ fileUrl: f.fileUrl,
188
+ size: typeof f.size === 'number' ? f.size : null,
189
+ }));
190
+ return { title: r.attributes?.title ?? '(untitled attachment)', formats };
191
+ })
192
+ .filter((a) => a.formats.length > 0);
193
+ }
194
+ const HTML_NAMED_ENTITIES = {
195
+ amp: '&',
196
+ lt: '<',
197
+ gt: '>',
198
+ quot: '"',
199
+ apos: "'",
200
+ nbsp: ' ',
201
+ mdash: '—',
202
+ ndash: '–',
203
+ rsquo: '’',
204
+ lsquo: '‘',
205
+ ldquo: '“',
206
+ rdquo: '”',
207
+ hellip: '…',
208
+ };
209
+ /** Strip HTML tags + decode entities from a comment body. */
210
+ function stripHtml(html) {
211
+ const text = html
212
+ .replace(/<\s*br\s*\/?>/gi, '\n')
213
+ .replace(/<\/(p|div|li)\s*>/gi, '\n')
214
+ .replace(/<[^>]+>/g, '');
215
+ return text
216
+ .replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z]+);/g, (match, body) => {
217
+ if (body.startsWith('#x') || body.startsWith('#X')) {
218
+ const code = Number.parseInt(body.slice(2), 16);
219
+ return Number.isNaN(code) ? match : String.fromCodePoint(code);
220
+ }
221
+ if (body.startsWith('#')) {
222
+ const code = Number.parseInt(body.slice(1), 10);
223
+ return Number.isNaN(code) ? match : String.fromCodePoint(code);
224
+ }
225
+ return HTML_NAMED_ENTITIES[body] ?? match;
226
+ })
227
+ .replace(/[ \t]+/g, ' ')
228
+ .replace(/\n{3,}/g, '\n\n')
229
+ .trim();
230
+ }
231
+ /**
232
+ * A body that is empty or a "see attached" stub signals attachment-primary
233
+ * content. Regulations.gov emits several stub phrasings for attachment-only
234
+ * submissions — "See attached", "See attached file", "See attached file(s)",
235
+ * "See attachment(s)", "See attached document(s)", "Please see attached", etc.
236
+ * Match the whole family: an optional lead-in, "see attach(ed|ment)", an optional
237
+ * noun (file/document/comment, singular or plural with optional "(s)"), and
238
+ * trailing punctuation — nothing substantive beyond that.
239
+ */
240
+ function isStubBody(text) {
241
+ if (!text)
242
+ return true;
243
+ const trimmed = text.trim();
244
+ if (trimmed.length === 0)
245
+ return true;
246
+ // (please) see (the) attach{ed|ment(s)|ments} (file|document|comment){s|(s)}? .
247
+ return /^(please\s+)?see\s+(the\s+)?attach(ed|ment\(s\)|ments?)(\s+(file|document|comment)s?(\(s\))?)?\.?$/i.test(trimmed);
248
+ }
249
+ function normalizeCommentDetail(commentId, raw) {
250
+ const a = raw.data?.attributes ?? {};
251
+ const attachments = collectAttachments(raw.included);
252
+ const bodyText = typeof a.comment === 'string' && a.comment.length > 0 ? stripHtml(a.comment) : null;
253
+ const submitterName = [a.firstName, a.lastName]
254
+ .filter((s) => typeof s === 'string' && s.length > 0)
255
+ .join(' ');
256
+ return {
257
+ commentId,
258
+ title: a.title ?? '(untitled comment)',
259
+ docketId: a.docketId ?? null,
260
+ commentOnDocumentId: a.commentOnDocumentId ?? null,
261
+ postedDate: a.postedDate ?? '',
262
+ receivedDate: a.receivedDate ?? null,
263
+ submitterName: submitterName.length > 0 ? submitterName : null,
264
+ organization: a.organization ?? null,
265
+ bodyText,
266
+ attachmentOnly: attachments.length > 0 && isStubBody(bodyText),
267
+ attachments,
268
+ withdrawn: a.withdrawn ?? false,
269
+ restrictReason: a.restrictReason ?? null,
270
+ };
271
+ }
272
+ // --- Init/accessor pattern ---
273
+ let _service;
274
+ export function initRegulationsGovService(config, storage) {
275
+ _service = new RegulationsGovService(config, storage);
276
+ }
277
+ export function getRegulationsGovService() {
278
+ if (!_service) {
279
+ throw new Error('RegulationsGovService not initialized — call initRegulationsGovService() in setup()');
280
+ }
281
+ return _service;
282
+ }
283
+ //# sourceMappingURL=regulations-gov-service.js.map
@@ -0,0 +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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"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * @fileoverview Domain and raw JSON:API types for the Regulations.gov v4 service
3
+ * (dockets, documents, comments). Raw types mirror the real (sparse) payloads.
4
+ * @module services/regulations-gov/types
5
+ */
6
+ /** Generic JSON:API resource object. */
7
+ export interface JsonApiResource<A> {
8
+ attributes?: A;
9
+ id?: string;
10
+ relationships?: Record<string, {
11
+ data?: Array<{
12
+ id?: string;
13
+ type?: string;
14
+ }> | null;
15
+ }>;
16
+ type?: string;
17
+ }
18
+ /** JSON:API list envelope. */
19
+ export interface JsonApiList<A> {
20
+ data?: Array<JsonApiResource<A>>;
21
+ included?: Array<JsonApiResource<RawAttachmentAttributes>>;
22
+ meta?: {
23
+ totalElements?: number;
24
+ totalPages?: number;
25
+ hasNextPage?: boolean;
26
+ pageNumber?: number;
27
+ pageSize?: number;
28
+ } | null;
29
+ }
30
+ /** JSON:API single-resource envelope. */
31
+ export interface JsonApiSingle<A> {
32
+ data?: JsonApiResource<A>;
33
+ included?: Array<JsonApiResource<RawAttachmentAttributes>>;
34
+ }
35
+ /** Raw docket attributes. */
36
+ export interface RawDocketAttributes {
37
+ agencyId?: string | null;
38
+ dkAbstract?: string | null;
39
+ docketType?: string | null;
40
+ modifyDate?: string | null;
41
+ objectId?: string | null;
42
+ program?: string | null;
43
+ rin?: string | null;
44
+ title?: string | null;
45
+ }
46
+ /** Raw document attributes. */
47
+ export interface RawDocumentAttributes {
48
+ commentEndDate?: string | null;
49
+ docketId?: string | null;
50
+ documentType?: string | null;
51
+ frDocNum?: string | null;
52
+ objectId?: string | null;
53
+ openForComment?: boolean | null;
54
+ postedDate?: string | null;
55
+ title?: string | null;
56
+ withdrawn?: boolean | null;
57
+ }
58
+ /** Raw comment attributes (list + detail). */
59
+ export interface RawCommentAttributes {
60
+ agencyId?: string | null;
61
+ comment?: string | null;
62
+ commentOnDocumentId?: string | null;
63
+ docketId?: string | null;
64
+ documentType?: string | null;
65
+ firstName?: string | null;
66
+ lastName?: string | null;
67
+ objectId?: string | null;
68
+ organization?: string | null;
69
+ postedDate?: string | null;
70
+ receivedDate?: string | null;
71
+ restrictReason?: string | null;
72
+ title?: string | null;
73
+ withdrawn?: boolean | null;
74
+ }
75
+ /** Raw attachment record (from `included[]` when `?include=attachments`). */
76
+ export interface RawAttachmentAttributes {
77
+ fileFormats?: Array<{
78
+ format?: string | null;
79
+ fileUrl?: string | null;
80
+ size?: number | null;
81
+ }> | null;
82
+ title?: string | null;
83
+ }
84
+ /** Normalized docket document. */
85
+ export interface RegDocument {
86
+ commentEndDate: string | null;
87
+ documentId: string;
88
+ documentType: string;
89
+ frDocNum: string | null;
90
+ objectId: string;
91
+ postedDate: string;
92
+ title: string;
93
+ withdrawn: boolean;
94
+ }
95
+ /** Normalized docket result. */
96
+ export interface DocketResult {
97
+ abstract: string | null;
98
+ agencyId: string | null;
99
+ docketId: string;
100
+ docketType: string | null;
101
+ documentCount: number;
102
+ documents: RegDocument[];
103
+ modifyDate: string | null;
104
+ objectId: string | null;
105
+ rin: string | null;
106
+ title: string;
107
+ }
108
+ /** Normalized comment summary (list mode). */
109
+ export interface CommentSummary {
110
+ agencyId: string | null;
111
+ commentId: string;
112
+ documentType: string;
113
+ objectId: string;
114
+ postedDate: string;
115
+ title: string;
116
+ withdrawn: boolean;
117
+ }
118
+ /** Normalized comment list. */
119
+ export interface CommentListResult {
120
+ comments: CommentSummary[];
121
+ totalCount: number;
122
+ }
123
+ /** Normalized attachment. */
124
+ export interface CommentAttachment {
125
+ formats: Array<{
126
+ format: string;
127
+ fileUrl: string;
128
+ size: number | null;
129
+ }>;
130
+ title: string;
131
+ }
132
+ /** Normalized comment detail. */
133
+ export interface CommentDetailResult {
134
+ attachmentOnly: boolean;
135
+ attachments: CommentAttachment[];
136
+ bodyText: string | null;
137
+ commentId: string;
138
+ commentOnDocumentId: string | null;
139
+ docketId: string | null;
140
+ organization: string | null;
141
+ postedDate: string;
142
+ receivedDate: string | null;
143
+ restrictReason: string | null;
144
+ submitterName: string | null;
145
+ title: string;
146
+ withdrawn: boolean;
147
+ }
148
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/regulations-gov/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fileoverview Domain and raw JSON:API types for the Regulations.gov v4 service
3
+ * (dockets, documents, comments). Raw types mirror the real (sparse) payloads.
4
+ * @module services/regulations-gov/types
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/services/regulations-gov/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @fileoverview Shared helper to derive a framework `RequestContext` from the
3
+ * handler `Context` for the HTTP utilities (`fetchWithTimeout`, `withRetry`),
4
+ * which are typed against the open `RequestContext` bag rather than the closed
5
+ * handler `Context`. Centralizes the canonical-field projection so the three
6
+ * data-source services don't each repeat it.
7
+ * @module services/request-context
8
+ */
9
+ import type { Context } from '@cyanheads/mcp-ts-core';
10
+ import type { RequestContext } from '@cyanheads/mcp-ts-core/utils';
11
+ /** Build a correlated `RequestContext` from a handler `Context` for an operation. */
12
+ export declare function toRequestContext(ctx: Context, operation: string): RequestContext;
13
+ //# sourceMappingURL=request-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/services/request-context.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGnE,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,cAAc,CAWhF"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @fileoverview Shared helper to derive a framework `RequestContext` from the
3
+ * handler `Context` for the HTTP utilities (`fetchWithTimeout`, `withRetry`),
4
+ * which are typed against the open `RequestContext` bag rather than the closed
5
+ * handler `Context`. Centralizes the canonical-field projection so the three
6
+ * data-source services don't each repeat it.
7
+ * @module services/request-context
8
+ */
9
+ import { requestContextService } from '@cyanheads/mcp-ts-core/utils';
10
+ /** Build a correlated `RequestContext` from a handler `Context` for an operation. */
11
+ export function toRequestContext(ctx, operation) {
12
+ return requestContextService.createRequestContext({
13
+ operation,
14
+ parentContext: {
15
+ requestId: ctx.requestId,
16
+ timestamp: ctx.timestamp,
17
+ ...(ctx.traceId ? { traceId: ctx.traceId } : {}),
18
+ ...(ctx.spanId ? { spanId: ctx.spanId } : {}),
19
+ ...(ctx.tenantId ? { tenantId: ctx.tenantId } : {}),
20
+ },
21
+ });
22
+ }
23
+ //# sourceMappingURL=request-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../src/services/request-context.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAErE,qFAAqF;AACrF,MAAM,UAAU,gBAAgB,CAAC,GAAY,EAAE,SAAiB;IAC9D,OAAO,qBAAqB,CAAC,oBAAoB,CAAC;QAChD,SAAS;QACT,aAAa,EAAE;YACb,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChD,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpD;KACF,CAAC,CAAC;AACL,CAAC"}
package/package.json ADDED
@@ -0,0 +1,94 @@
1
+ {
2
+ "name": "@cyanheads/federal-regulations-mcp-server",
3
+ "version": "0.1.0",
4
+ "mcpName": "io.github.cyanheads/federal-regulations-mcp-server",
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
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "bin": {
10
+ "federal-regulations-mcp-server": "dist/index.js"
11
+ },
12
+ "files": [
13
+ "changelog/",
14
+ "dist/",
15
+ "scripts/_mirror-context.ts",
16
+ "scripts/ecfr-mirror-init.ts",
17
+ "scripts/ecfr-mirror-refresh.ts",
18
+ "scripts/ecfr-mirror-verify.ts",
19
+ "README.md",
20
+ "LICENSE",
21
+ "CLAUDE.md",
22
+ "AGENTS.md",
23
+ "Dockerfile",
24
+ "server.json"
25
+ ],
26
+ "scripts": {
27
+ "build": "bun run scripts/build.ts",
28
+ "rebuild": "bun run scripts/clean.ts && bun run scripts/build.ts",
29
+ "clean": "bun run scripts/clean.ts",
30
+ "devcheck": "bun run scripts/devcheck.ts",
31
+ "audit:refresh": "rm -f bun.lock && bun install && bun audit",
32
+ "tree": "bun run scripts/tree.ts",
33
+ "list-skills": "bun run scripts/list-skills.ts",
34
+ "format": "biome check --write .",
35
+ "format:unsafe": "biome check --write --unsafe .",
36
+ "lint:mcp": "bun run scripts/lint-mcp.ts",
37
+ "lint:packaging": "bun run scripts/lint-packaging.ts",
38
+ "bundle": "bun run build && npx -y @anthropic-ai/mcpb pack . dist/federal-regulations-mcp-server.mcpb && bun run scripts/clean-mcpb.ts dist/federal-regulations-mcp-server.mcpb",
39
+ "changelog:build": "bun run scripts/build-changelog.ts",
40
+ "changelog:check": "bun run scripts/build-changelog.ts --check",
41
+ "release:github": "bun run scripts/release-github.ts",
42
+ "publish-mcp": "mcp-publisher login github -token \"$(security find-generic-password -a \"$USER\" -s mcp-publisher-github-pat -w)\" && mcp-publisher publish",
43
+ "mirror:init": "bun run scripts/ecfr-mirror-init.ts",
44
+ "mirror:refresh": "bun run scripts/ecfr-mirror-refresh.ts",
45
+ "mirror:verify": "bun run scripts/ecfr-mirror-verify.ts",
46
+ "test": "vitest run",
47
+ "start": "node dist/index.js",
48
+ "start:stdio": "MCP_TRANSPORT_TYPE=stdio node dist/index.js",
49
+ "start:http": "MCP_TRANSPORT_TYPE=http node dist/index.js"
50
+ },
51
+ "keywords": [
52
+ "mcp",
53
+ "mcp-server",
54
+ "model-context-protocol",
55
+ "federal-register",
56
+ "ecfr",
57
+ "cfr",
58
+ "regulations",
59
+ "regulations-gov",
60
+ "rulemaking",
61
+ "administrative-law"
62
+ ],
63
+ "repository": {
64
+ "type": "git",
65
+ "url": "git+https://github.com/cyanheads/federal-regulations-mcp-server.git"
66
+ },
67
+ "bugs": {
68
+ "url": "https://github.com/cyanheads/federal-regulations-mcp-server/issues"
69
+ },
70
+ "homepage": "https://github.com/cyanheads/federal-regulations-mcp-server#readme",
71
+ "license": "Apache-2.0",
72
+ "engines": {
73
+ "bun": ">=1.3.0",
74
+ "node": ">=24.0.0"
75
+ },
76
+ "publishConfig": {
77
+ "access": "public"
78
+ },
79
+ "dependencies": {
80
+ "@cyanheads/mcp-ts-core": "^0.10.6",
81
+ "pino-pretty": "^13.1.3",
82
+ "zod": "^4.4.3"
83
+ },
84
+ "devDependencies": {
85
+ "@biomejs/biome": "2.5.0",
86
+ "@types/node": "25.9.3",
87
+ "better-sqlite3": "^12.0.0",
88
+ "depcheck": "^1.4.7",
89
+ "ignore": "^7.0.5",
90
+ "tsc-alias": "^1.8.17",
91
+ "typescript": "^6.0.3",
92
+ "vitest": "^4.1.8"
93
+ }
94
+ }