@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.
- package/AGENTS.md +387 -0
- package/CLAUDE.md +387 -0
- package/Dockerfile +127 -0
- package/LICENSE +201 -0
- package/README.md +372 -0
- package/changelog/0.1.x/0.1.0.md +20 -0
- package/changelog/template.md +127 -0
- package/dist/config/server-config.d.ts +32 -0
- package/dist/config/server-config.d.ts.map +1 -0
- package/dist/config/server-config.js +64 -0
- package/dist/config/server-config.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/resources/definitions/cfr-section.resource.d.ts +14 -0
- package/dist/mcp-server/resources/definitions/cfr-section.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/cfr-section.resource.js +77 -0
- package/dist/mcp-server/resources/definitions/cfr-section.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/document.resource.d.ts +12 -0
- package/dist/mcp-server/resources/definitions/document.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/document.resource.js +38 -0
- package/dist/mcp-server/resources/definitions/document.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/index.d.ts +12 -0
- package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/index.js +8 -0
- package/dist/mcp-server/resources/definitions/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/browse-cfr.tool.d.ts +73 -0
- package/dist/mcp-server/tools/definitions/browse-cfr.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/browse-cfr.tool.js +205 -0
- package/dist/mcp-server/tools/definitions/browse-cfr.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/find-comments.tool.d.ts +85 -0
- package/dist/mcp-server/tools/definitions/find-comments.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/find-comments.tool.js +271 -0
- package/dist/mcp-server/tools/definitions/find-comments.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/format-utils.d.ts +7 -0
- package/dist/mcp-server/tools/definitions/format-utils.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/format-utils.js +9 -0
- package/dist/mcp-server/tools/definitions/format-utils.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-cfr-section.tool.d.ts +50 -0
- package/dist/mcp-server/tools/definitions/get-cfr-section.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-cfr-section.tool.js +152 -0
- package/dist/mcp-server/tools/definitions/get-cfr-section.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-docket.tool.d.ts +67 -0
- package/dist/mcp-server/tools/definitions/get-docket.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-docket.tool.js +154 -0
- package/dist/mcp-server/tools/definitions/get-docket.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-document.tool.d.ts +51 -0
- package/dist/mcp-server/tools/definitions/get-document.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-document.tool.js +138 -0
- package/dist/mcp-server/tools/definitions/get-document.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/index.d.ts +356 -0
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/index.js +21 -0
- package/dist/mcp-server/tools/definitions/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/list-open-comments.tool.d.ts +47 -0
- package/dist/mcp-server/tools/definitions/list-open-comments.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/list-open-comments.tool.js +179 -0
- package/dist/mcp-server/tools/definitions/list-open-comments.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-rules.tool.d.ts +57 -0
- package/dist/mcp-server/tools/definitions/search-rules.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-rules.tool.js +185 -0
- package/dist/mcp-server/tools/definitions/search-rules.tool.js.map +1 -0
- package/dist/services/ecfr/ecfr-service.d.ts +54 -0
- package/dist/services/ecfr/ecfr-service.d.ts.map +1 -0
- package/dist/services/ecfr/ecfr-service.js +303 -0
- package/dist/services/ecfr/ecfr-service.js.map +1 -0
- package/dist/services/ecfr/types.d.ts +105 -0
- package/dist/services/ecfr/types.d.ts.map +1 -0
- package/dist/services/ecfr/types.js +7 -0
- package/dist/services/ecfr/types.js.map +1 -0
- package/dist/services/ecfr/xml.d.ts +15 -0
- package/dist/services/ecfr/xml.d.ts.map +1 -0
- package/dist/services/ecfr/xml.js +103 -0
- package/dist/services/ecfr/xml.js.map +1 -0
- package/dist/services/ecfr-mirror/ecfr-mirror.d.ts +43 -0
- package/dist/services/ecfr-mirror/ecfr-mirror.d.ts.map +1 -0
- package/dist/services/ecfr-mirror/ecfr-mirror.js +267 -0
- package/dist/services/ecfr-mirror/ecfr-mirror.js.map +1 -0
- package/dist/services/federal-register/federal-register-service.d.ts +30 -0
- package/dist/services/federal-register/federal-register-service.d.ts.map +1 -0
- package/dist/services/federal-register/federal-register-service.js +241 -0
- package/dist/services/federal-register/federal-register-service.js.map +1 -0
- package/dist/services/federal-register/types.d.ts +138 -0
- package/dist/services/federal-register/types.d.ts.map +1 -0
- package/dist/services/federal-register/types.js +8 -0
- package/dist/services/federal-register/types.js.map +1 -0
- package/dist/services/regulations-gov/regulations-gov-service.d.ts +55 -0
- package/dist/services/regulations-gov/regulations-gov-service.d.ts.map +1 -0
- package/dist/services/regulations-gov/regulations-gov-service.js +283 -0
- package/dist/services/regulations-gov/regulations-gov-service.js.map +1 -0
- package/dist/services/regulations-gov/types.d.ts +148 -0
- package/dist/services/regulations-gov/types.d.ts.map +1 -0
- package/dist/services/regulations-gov/types.js +7 -0
- package/dist/services/regulations-gov/types.js.map +1 -0
- package/dist/services/request-context.d.ts +13 -0
- package/dist/services/request-context.d.ts.map +1 -0
- package/dist/services/request-context.js +23 -0
- package/dist/services/request-context.js.map +1 -0
- package/package.json +94 -0
- package/scripts/_mirror-context.ts +101 -0
- package/scripts/ecfr-mirror-init.ts +36 -0
- package/scripts/ecfr-mirror-refresh.ts +29 -0
- package/scripts/ecfr-mirror-verify.ts +33 -0
- package/server.json +113 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview regulations_get_cfr_section — read the codified text of a CFR
|
|
3
|
+
* section (or whole part) via eCFR, current or as of a past date. Mirror row
|
|
4
|
+
* lookup is the primary path for a current single section; historical dates,
|
|
5
|
+
* whole-part fetches, and a cold mirror fall back to the live eCFR versioner.
|
|
6
|
+
* Keyless.
|
|
7
|
+
* @module mcp-server/tools/definitions/get-cfr-section.tool
|
|
8
|
+
*/
|
|
9
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
10
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
11
|
+
export declare const getCfrSectionTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
12
|
+
title: z.ZodNumber;
|
|
13
|
+
part: z.ZodString;
|
|
14
|
+
section: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>;
|
|
15
|
+
date: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>;
|
|
16
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
17
|
+
cfrCite: z.ZodString;
|
|
18
|
+
title: z.ZodNumber;
|
|
19
|
+
part: z.ZodString;
|
|
20
|
+
section: z.ZodNullable<z.ZodString>;
|
|
21
|
+
heading: z.ZodString;
|
|
22
|
+
hierarchyPath: z.ZodString;
|
|
23
|
+
date: z.ZodString;
|
|
24
|
+
source: z.ZodEnum<{
|
|
25
|
+
mirror: "mirror";
|
|
26
|
+
live: "live";
|
|
27
|
+
}>;
|
|
28
|
+
bodyText: z.ZodString;
|
|
29
|
+
sections: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
30
|
+
section: z.ZodString;
|
|
31
|
+
heading: z.ZodString;
|
|
32
|
+
bodyText: z.ZodString;
|
|
33
|
+
}, z.core.$strip>>>;
|
|
34
|
+
}, z.core.$strip>, readonly [{
|
|
35
|
+
readonly reason: "not_found";
|
|
36
|
+
readonly code: JsonRpcErrorCode.NotFound;
|
|
37
|
+
readonly when: "No such title/part/section at that date.";
|
|
38
|
+
readonly recovery: "Verify the cite with regulations_browse_cfr (structure mode); the part or section may not exist or may be reserved.";
|
|
39
|
+
}, {
|
|
40
|
+
readonly reason: "date_out_of_range";
|
|
41
|
+
readonly code: JsonRpcErrorCode.InvalidParams;
|
|
42
|
+
readonly when: "The requested date precedes eCFR historical coverage.";
|
|
43
|
+
readonly recovery: "Use a date from ~2017 onward, or omit date for the current text.";
|
|
44
|
+
}, {
|
|
45
|
+
readonly reason: "upstream_unavailable";
|
|
46
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
47
|
+
readonly when: "eCFR returned a 5xx, timed out, or served an HTML error page (live path).";
|
|
48
|
+
readonly recovery: "Retry after a brief wait; the eCFR API may be momentarily unavailable.";
|
|
49
|
+
}], undefined>;
|
|
50
|
+
//# sourceMappingURL=get-cfr-section.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-cfr-section.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-cfr-section.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAIjE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA4K5B,CAAC"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview regulations_get_cfr_section — read the codified text of a CFR
|
|
3
|
+
* section (or whole part) via eCFR, current or as of a past date. Mirror row
|
|
4
|
+
* lookup is the primary path for a current single section; historical dates,
|
|
5
|
+
* whole-part fetches, and a cold mirror fall back to the live eCFR versioner.
|
|
6
|
+
* Keyless.
|
|
7
|
+
* @module mcp-server/tools/definitions/get-cfr-section.tool
|
|
8
|
+
*/
|
|
9
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
10
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
11
|
+
import { ECFR_EARLIEST_DATE, getEcfrService } from '../../../services/ecfr/ecfr-service.js';
|
|
12
|
+
import { mirrorGetSection, mirrorReady } from '../../../services/ecfr-mirror/ecfr-mirror.js';
|
|
13
|
+
export const getCfrSectionTool = tool('regulations_get_cfr_section', {
|
|
14
|
+
title: 'regulations_get_cfr_section',
|
|
15
|
+
description: 'Read the codified text of a specific CFR section (or a whole part) via eCFR — current or as of a past date. Answers "what does 40 CFR 50.1 say today?" and "...as of 2019-01-01?". Provide title + part + section for one section, or omit section to fetch the whole part (large parts can be very long; prefer a specific section when you know it). eCFR retains historical versions back to roughly 2017; a date before coverage is rejected with guidance. Current single-section reads are served from a synced local mirror when available; the source is reported.',
|
|
16
|
+
annotations: { readOnlyHint: true, idempotentHint: true },
|
|
17
|
+
input: z.object({
|
|
18
|
+
title: z
|
|
19
|
+
.number()
|
|
20
|
+
.int()
|
|
21
|
+
.min(1)
|
|
22
|
+
.max(50)
|
|
23
|
+
.describe('CFR title number (1–50). E.g. 40 for "Protection of Environment".'),
|
|
24
|
+
part: z
|
|
25
|
+
.string()
|
|
26
|
+
.describe('CFR part within the title (e.g. "50"). Parts can be alphanumeric. Obtain from regulations_browse_cfr or a Federal Register document\'s cfrReferences.'),
|
|
27
|
+
section: z
|
|
28
|
+
.union([z.literal(''), z.string().describe('Section identifier (e.g. "50.1").')])
|
|
29
|
+
.optional()
|
|
30
|
+
.describe('Section identifier within the part (e.g. "50.1"). Omit to fetch the entire part — large parts can be very long; prefer a specific section when you know it.'),
|
|
31
|
+
date: z
|
|
32
|
+
.union([
|
|
33
|
+
z.literal(''),
|
|
34
|
+
z
|
|
35
|
+
.string()
|
|
36
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
37
|
+
.describe('ISO 8601 date (YYYY-MM-DD).'),
|
|
38
|
+
])
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('Point-in-time date, ISO 8601 (YYYY-MM-DD). Default current. eCFR retains historical versions back to ~2017; a date before coverage is rejected.'),
|
|
41
|
+
}),
|
|
42
|
+
output: z.object({
|
|
43
|
+
cfrCite: z.string().describe('Assembled cite, e.g. "40 CFR 50.1".'),
|
|
44
|
+
title: z.number().describe('CFR title number.'),
|
|
45
|
+
part: z.string().describe('CFR part.'),
|
|
46
|
+
section: z
|
|
47
|
+
.string()
|
|
48
|
+
.nullable()
|
|
49
|
+
.describe('Section identifier; null when a whole part was fetched.'),
|
|
50
|
+
heading: z.string().describe('Section/part heading.'),
|
|
51
|
+
hierarchyPath: z.string().describe('Human-readable hierarchy path.'),
|
|
52
|
+
date: z.string().describe('The issue/point-in-time date the text reflects (ISO 8601).'),
|
|
53
|
+
source: z
|
|
54
|
+
.enum(['mirror', 'live'])
|
|
55
|
+
.describe('Provenance: the synced mirror, or the live eCFR API.'),
|
|
56
|
+
bodyText: z
|
|
57
|
+
.string()
|
|
58
|
+
.describe('Section text, XML stripped to plain text (paragraph structure preserved).'),
|
|
59
|
+
sections: z
|
|
60
|
+
.array(z
|
|
61
|
+
.object({
|
|
62
|
+
section: z.string().describe('Section identifier.'),
|
|
63
|
+
heading: z.string().describe('Section heading.'),
|
|
64
|
+
bodyText: z.string().describe('Section text.'),
|
|
65
|
+
})
|
|
66
|
+
.describe('One section within the part.'))
|
|
67
|
+
.optional()
|
|
68
|
+
.describe('Present only when a whole part was fetched — each section in the part.'),
|
|
69
|
+
}),
|
|
70
|
+
errors: [
|
|
71
|
+
{
|
|
72
|
+
reason: 'not_found',
|
|
73
|
+
code: JsonRpcErrorCode.NotFound,
|
|
74
|
+
when: 'No such title/part/section at that date.',
|
|
75
|
+
recovery: 'Verify the cite with regulations_browse_cfr (structure mode); the part or section may not exist or may be reserved.',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
reason: 'date_out_of_range',
|
|
79
|
+
code: JsonRpcErrorCode.InvalidParams,
|
|
80
|
+
when: 'The requested date precedes eCFR historical coverage.',
|
|
81
|
+
recovery: 'Use a date from ~2017 onward, or omit date for the current text.',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
reason: 'upstream_unavailable',
|
|
85
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
86
|
+
when: 'eCFR returned a 5xx, timed out, or served an HTML error page (live path).',
|
|
87
|
+
recovery: 'Retry after a brief wait; the eCFR API may be momentarily unavailable.',
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
async handler(input, ctx) {
|
|
91
|
+
const service = getEcfrService();
|
|
92
|
+
const section = input.section?.trim() || undefined;
|
|
93
|
+
const requestedDate = input.date?.trim() || undefined;
|
|
94
|
+
if (requestedDate && requestedDate < ECFR_EARLIEST_DATE) {
|
|
95
|
+
throw ctx.fail('date_out_of_range', `Date ${requestedDate} precedes eCFR coverage (~${ECFR_EARLIEST_DATE}).`, {
|
|
96
|
+
...ctx.recoveryFor('date_out_of_range'),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
// Fast path: current single section served from the mirror when ready.
|
|
100
|
+
if (section && !requestedDate && (await mirrorReady())) {
|
|
101
|
+
const hit = await mirrorGetSection(input.title, input.part, section);
|
|
102
|
+
if (hit) {
|
|
103
|
+
const hierarchyPath = await service.hierarchyPath(input.title, input.part, section, hit.date, ctx);
|
|
104
|
+
return {
|
|
105
|
+
cfrCite: `${input.title} CFR ${section}`,
|
|
106
|
+
title: input.title,
|
|
107
|
+
part: input.part,
|
|
108
|
+
section,
|
|
109
|
+
heading: hit.heading,
|
|
110
|
+
hierarchyPath,
|
|
111
|
+
date: hit.date,
|
|
112
|
+
source: 'mirror',
|
|
113
|
+
bodyText: hit.bodyText,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// Mirror miss → fall through to the live versioner.
|
|
117
|
+
}
|
|
118
|
+
const date = requestedDate ?? (await service.latestIssueDate(input.title, ctx));
|
|
119
|
+
const result = await service.getSectionText(input.title, input.part, section, date, ctx);
|
|
120
|
+
const hierarchyPath = await service.hierarchyPath(input.title, input.part, section, result.date, ctx);
|
|
121
|
+
return {
|
|
122
|
+
cfrCite: section ? `${input.title} CFR ${section}` : `${input.title} CFR ${input.part}`,
|
|
123
|
+
title: input.title,
|
|
124
|
+
part: input.part,
|
|
125
|
+
section: result.section,
|
|
126
|
+
heading: result.heading,
|
|
127
|
+
hierarchyPath,
|
|
128
|
+
date: result.date,
|
|
129
|
+
source: 'live',
|
|
130
|
+
bodyText: result.bodyText,
|
|
131
|
+
...(result.sections ? { sections: result.sections } : {}),
|
|
132
|
+
};
|
|
133
|
+
},
|
|
134
|
+
format: (result) => {
|
|
135
|
+
const lines = [];
|
|
136
|
+
lines.push(`# ${result.cfrCite} — ${result.heading}`);
|
|
137
|
+
lines.push(`Title ${result.title} · Part ${result.part}${result.section ? ` · § ${result.section}` : ' (whole part)'}`);
|
|
138
|
+
lines.push(`_${result.hierarchyPath}_ · as of ${result.date} · source: ${result.source}`);
|
|
139
|
+
lines.push('');
|
|
140
|
+
lines.push(result.bodyText);
|
|
141
|
+
if (result.sections) {
|
|
142
|
+
lines.push('');
|
|
143
|
+
for (const s of result.sections) {
|
|
144
|
+
lines.push(`## § ${s.section} — ${s.heading}`);
|
|
145
|
+
lines.push(s.bodyText);
|
|
146
|
+
lines.push('');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return [{ type: 'text', text: lines.join('\n').trim() }];
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
//# sourceMappingURL=get-cfr-section.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-cfr-section.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-cfr-section.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview regulations_get_docket — pull a rulemaking docket from
|
|
3
|
+
* Regulations.gov by docket ID: docket metadata plus the documents filed in it.
|
|
4
|
+
* Key-gated: returns an actionable auth_required error when REGULATIONS_GOV_API_KEY
|
|
5
|
+
* is absent. Each document's objectId feeds regulations_find_comments.
|
|
6
|
+
* @module mcp-server/tools/definitions/get-docket.tool
|
|
7
|
+
*/
|
|
8
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
9
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
10
|
+
export declare const getDocketTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
11
|
+
docket_id: z.ZodString;
|
|
12
|
+
document_types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
13
|
+
"Proposed Rule": "Proposed Rule";
|
|
14
|
+
Rule: "Rule";
|
|
15
|
+
Notice: "Notice";
|
|
16
|
+
"Supporting & Related Material": "Supporting & Related Material";
|
|
17
|
+
Other: "Other";
|
|
18
|
+
}>>>;
|
|
19
|
+
per_page: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
20
|
+
page: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
21
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
22
|
+
docketId: z.ZodString;
|
|
23
|
+
title: z.ZodString;
|
|
24
|
+
docketType: z.ZodNullable<z.ZodString>;
|
|
25
|
+
agencyId: z.ZodNullable<z.ZodString>;
|
|
26
|
+
rin: z.ZodNullable<z.ZodString>;
|
|
27
|
+
abstract: z.ZodNullable<z.ZodString>;
|
|
28
|
+
modifyDate: z.ZodNullable<z.ZodString>;
|
|
29
|
+
objectId: z.ZodNullable<z.ZodString>;
|
|
30
|
+
documentCount: z.ZodNumber;
|
|
31
|
+
documents: z.ZodArray<z.ZodObject<{
|
|
32
|
+
documentId: z.ZodString;
|
|
33
|
+
objectId: z.ZodString;
|
|
34
|
+
title: z.ZodString;
|
|
35
|
+
documentType: z.ZodString;
|
|
36
|
+
postedDate: z.ZodString;
|
|
37
|
+
frDocNum: z.ZodNullable<z.ZodString>;
|
|
38
|
+
commentEndDate: z.ZodNullable<z.ZodString>;
|
|
39
|
+
withdrawn: z.ZodBoolean;
|
|
40
|
+
}, z.core.$strip>>;
|
|
41
|
+
}, z.core.$strip>, readonly [{
|
|
42
|
+
readonly reason: "auth_required";
|
|
43
|
+
readonly code: JsonRpcErrorCode.Unauthorized;
|
|
44
|
+
readonly when: "REGULATIONS_GOV_API_KEY is not configured.";
|
|
45
|
+
readonly recovery: "Set the REGULATIONS_GOV_API_KEY env var (free key at https://api.data.gov/signup/). The Federal Register and eCFR tools work without it.";
|
|
46
|
+
}, {
|
|
47
|
+
readonly reason: "not_found";
|
|
48
|
+
readonly code: JsonRpcErrorCode.NotFound;
|
|
49
|
+
readonly when: "No docket exists with that ID.";
|
|
50
|
+
readonly recovery: "Verify the docket ID from a Federal Register document's docketId; format is like \"EPA-HQ-OAR-2025-0194\".";
|
|
51
|
+
}, {
|
|
52
|
+
readonly reason: "rate_limited";
|
|
53
|
+
readonly code: JsonRpcErrorCode.RateLimited;
|
|
54
|
+
readonly when: "Regulations.gov returned 429 (1,000 requests/hour per key).";
|
|
55
|
+
readonly retryable: true;
|
|
56
|
+
readonly recovery: "Wait and retry — the per-key hourly limit was hit.";
|
|
57
|
+
}, {
|
|
58
|
+
readonly reason: "upstream_unavailable";
|
|
59
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
60
|
+
readonly when: "Regulations.gov returned a 5xx or timed out.";
|
|
61
|
+
readonly recovery: "Retry after a brief wait.";
|
|
62
|
+
}], {
|
|
63
|
+
readonly truncated: z.ZodOptional<z.ZodBoolean>;
|
|
64
|
+
readonly shown: z.ZodOptional<z.ZodNumber>;
|
|
65
|
+
readonly notice: z.ZodOptional<z.ZodString>;
|
|
66
|
+
}>;
|
|
67
|
+
//# sourceMappingURL=get-docket.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-docket.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-docket.tool.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAIjE,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4KxB,CAAC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview regulations_get_docket — pull a rulemaking docket from
|
|
3
|
+
* Regulations.gov by docket ID: docket metadata plus the documents filed in it.
|
|
4
|
+
* Key-gated: returns an actionable auth_required error when REGULATIONS_GOV_API_KEY
|
|
5
|
+
* is absent. Each document's objectId feeds regulations_find_comments.
|
|
6
|
+
* @module mcp-server/tools/definitions/get-docket.tool
|
|
7
|
+
*/
|
|
8
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
9
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
10
|
+
import { getRegulationsGovService } from '../../../services/regulations-gov/regulations-gov-service.js';
|
|
11
|
+
import { escapePipes } from './format-utils.js';
|
|
12
|
+
export const getDocketTool = tool('regulations_get_docket', {
|
|
13
|
+
title: 'regulations_get_docket',
|
|
14
|
+
description: 'Pull a rulemaking docket from Regulations.gov by docket ID (e.g. "EPA-HQ-OAR-2025-0194") — the docket\'s metadata (title, agency, RIN, abstract) and the documents filed in it (NPRM, final rule, supporting materials). The docket is the folder holding a rule\'s whole paper trail; each returned document\'s objectId feeds regulations_find_comments. A docket often contains hundreds of supporting materials — filter document_types to "Proposed Rule"/"Rule" to find the rule documents themselves. Requires REGULATIONS_GOV_API_KEY (free at https://api.data.gov/signup/); the Federal Register and eCFR tools work without it.',
|
|
15
|
+
annotations: { readOnlyHint: true, idempotentHint: true },
|
|
16
|
+
input: z.object({
|
|
17
|
+
docket_id: z
|
|
18
|
+
.string()
|
|
19
|
+
.regex(/^[A-Za-z0-9_-]+$/)
|
|
20
|
+
.describe('Regulations.gov docket ID (e.g. "EPA-HQ-OAR-2025-0194"). Obtain from a Federal Register document\'s docketId (regulations_get_document) or an agency rulemaking reference.'),
|
|
21
|
+
document_types: z
|
|
22
|
+
.array(z.enum(['Proposed Rule', 'Rule', 'Notice', 'Supporting & Related Material', 'Other']))
|
|
23
|
+
.optional()
|
|
24
|
+
.describe('Filter the docket\'s documents to these types. Omit for all. A docket often contains hundreds of "Supporting & Related Material" items — filter to "Proposed Rule"/"Rule" to find the rule documents.'),
|
|
25
|
+
per_page: z
|
|
26
|
+
.number()
|
|
27
|
+
.int()
|
|
28
|
+
.min(5)
|
|
29
|
+
.max(250)
|
|
30
|
+
.optional()
|
|
31
|
+
.default(25)
|
|
32
|
+
.describe('Documents per page (5–250, default 25). Regulations.gov requires a minimum page size of 5.'),
|
|
33
|
+
page: z
|
|
34
|
+
.number()
|
|
35
|
+
.int()
|
|
36
|
+
.min(1)
|
|
37
|
+
.max(20)
|
|
38
|
+
.optional()
|
|
39
|
+
.default(1)
|
|
40
|
+
.describe('Page number (1-based). Regulations.gov caps a query at 20 pages (5,000 records); beyond that, narrow with document_types.'),
|
|
41
|
+
}),
|
|
42
|
+
output: z.object({
|
|
43
|
+
docketId: z.string().describe('Regulations.gov docket ID.'),
|
|
44
|
+
title: z.string().describe('Docket title.'),
|
|
45
|
+
docketType: z.string().nullable().describe('Docket type (e.g. "Rulemaking"), or null.'),
|
|
46
|
+
agencyId: z.string().nullable().describe('Agency ID (e.g. "EPA"), or null.'),
|
|
47
|
+
rin: z
|
|
48
|
+
.string()
|
|
49
|
+
.nullable()
|
|
50
|
+
.describe('Regulation Identifier Number ("Not Assigned" when none), or null.'),
|
|
51
|
+
abstract: z.string().nullable().describe('Docket abstract, or null.'),
|
|
52
|
+
modifyDate: z.string().nullable().describe('Last-modified date, or null.'),
|
|
53
|
+
objectId: z.string().nullable().describe('Docket object ID, or null.'),
|
|
54
|
+
documentCount: z.number().describe('Total documents in the docket (before pagination).'),
|
|
55
|
+
documents: z
|
|
56
|
+
.array(z
|
|
57
|
+
.object({
|
|
58
|
+
documentId: z.string().describe('Regulations.gov document ID.'),
|
|
59
|
+
objectId: z
|
|
60
|
+
.string()
|
|
61
|
+
.describe('Document object ID — chains into regulations_find_comments(document_object_id).'),
|
|
62
|
+
title: z.string().describe('Document title.'),
|
|
63
|
+
documentType: z.string().describe('Document type.'),
|
|
64
|
+
postedDate: z.string().describe('Posted date.'),
|
|
65
|
+
frDocNum: z
|
|
66
|
+
.string()
|
|
67
|
+
.nullable()
|
|
68
|
+
.describe('Federal Register document number — chains back into regulations_get_document. Null when absent.'),
|
|
69
|
+
commentEndDate: z
|
|
70
|
+
.string()
|
|
71
|
+
.nullable()
|
|
72
|
+
.describe('Comment-period end date; when set, open for comment.'),
|
|
73
|
+
withdrawn: z.boolean().describe('True when the document was withdrawn.'),
|
|
74
|
+
})
|
|
75
|
+
.describe('One document filed in the docket.'))
|
|
76
|
+
.describe('Documents filed in the docket (this page).'),
|
|
77
|
+
}),
|
|
78
|
+
enrichment: {
|
|
79
|
+
truncated: z
|
|
80
|
+
.boolean()
|
|
81
|
+
.optional()
|
|
82
|
+
.describe('True when documentCount exceeds the returned set / 5,000 ceiling.'),
|
|
83
|
+
shown: z.number().optional().describe('Documents returned on this page.'),
|
|
84
|
+
notice: z.string().optional().describe('Guidance when the docket has no documents.'),
|
|
85
|
+
},
|
|
86
|
+
errors: [
|
|
87
|
+
{
|
|
88
|
+
reason: 'auth_required',
|
|
89
|
+
code: JsonRpcErrorCode.Unauthorized,
|
|
90
|
+
when: 'REGULATIONS_GOV_API_KEY is not configured.',
|
|
91
|
+
recovery: 'Set the REGULATIONS_GOV_API_KEY env var (free key at https://api.data.gov/signup/). The Federal Register and eCFR tools work without it.',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
reason: 'not_found',
|
|
95
|
+
code: JsonRpcErrorCode.NotFound,
|
|
96
|
+
when: 'No docket exists with that ID.',
|
|
97
|
+
recovery: 'Verify the docket ID from a Federal Register document\'s docketId; format is like "EPA-HQ-OAR-2025-0194".',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
reason: 'rate_limited',
|
|
101
|
+
code: JsonRpcErrorCode.RateLimited,
|
|
102
|
+
when: 'Regulations.gov returned 429 (1,000 requests/hour per key).',
|
|
103
|
+
retryable: true,
|
|
104
|
+
recovery: 'Wait and retry — the per-key hourly limit was hit.',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
reason: 'upstream_unavailable',
|
|
108
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
109
|
+
when: 'Regulations.gov returned a 5xx or timed out.',
|
|
110
|
+
recovery: 'Retry after a brief wait.',
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
async handler(input, ctx) {
|
|
114
|
+
const service = getRegulationsGovService();
|
|
115
|
+
if (!service.hasKey()) {
|
|
116
|
+
throw ctx.fail('auth_required', undefined, { ...ctx.recoveryFor('auth_required') });
|
|
117
|
+
}
|
|
118
|
+
const result = await service.getDocket({
|
|
119
|
+
docketId: input.docket_id,
|
|
120
|
+
documentTypes: input.document_types,
|
|
121
|
+
perPage: input.per_page,
|
|
122
|
+
page: input.page,
|
|
123
|
+
}, ctx);
|
|
124
|
+
if (result.documents.length === 0) {
|
|
125
|
+
ctx.enrich.notice(`Docket ${input.docket_id} returned no documents${input.document_types?.length ? ' for the requested document_types' : ''}. Drop the document_types filter to see all.`);
|
|
126
|
+
}
|
|
127
|
+
else if (result.documentCount > result.documents.length) {
|
|
128
|
+
ctx.enrich.truncated({
|
|
129
|
+
shown: result.documents.length,
|
|
130
|
+
cap: input.per_page,
|
|
131
|
+
guidance: `${result.documentCount} documents total. Raise per_page (max 250), page forward (max 20 pages), or filter document_types.`,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
135
|
+
},
|
|
136
|
+
format: (result) => {
|
|
137
|
+
const lines = [];
|
|
138
|
+
lines.push(`# Docket ${result.docketId} — ${result.title}`);
|
|
139
|
+
lines.push(`${result.agencyId ?? '—'} · ${result.docketType ?? '—'} · RIN ${result.rin ?? '—'}${result.modifyDate ? ` · modified ${result.modifyDate}` : ''}`);
|
|
140
|
+
lines.push(`Docket object ID: ${result.objectId ?? '—'}`);
|
|
141
|
+
if (result.abstract)
|
|
142
|
+
lines.push(`\n${result.abstract}`);
|
|
143
|
+
lines.push(`\n**${result.documentCount} documents** (showing ${result.documents.length}):\n`);
|
|
144
|
+
lines.push('| Type | Title | Posted | Comments Close | Document ID | Object ID (→ find_comments) |');
|
|
145
|
+
lines.push('|---|---|---|---|---|---|');
|
|
146
|
+
for (const d of result.documents) {
|
|
147
|
+
const fr = d.frDocNum ? ` [FR ${d.frDocNum}]` : '';
|
|
148
|
+
const wd = d.withdrawn ? ' (withdrawn)' : '';
|
|
149
|
+
lines.push(`| ${d.documentType} | ${escapePipes(d.title)}${fr}${wd} | ${d.postedDate} | ${d.commentEndDate ?? '—'} | ${d.documentId} | \`${d.objectId}\` |`);
|
|
150
|
+
}
|
|
151
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
//# sourceMappingURL=get-docket.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-docket.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-docket.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview regulations_get_document — fetch one Federal Register document by
|
|
3
|
+
* FR number: full metadata plus the cross-source handles (docket ID, affected CFR
|
|
4
|
+
* parts, Regulations.gov document ID, comment count) that chain into the comment
|
|
5
|
+
* and codified-text tools. The stitching tool of this server. Keyless.
|
|
6
|
+
* @module mcp-server/tools/definitions/get-document.tool
|
|
7
|
+
*/
|
|
8
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
9
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
10
|
+
export declare const getDocumentTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
11
|
+
document_number: z.ZodString;
|
|
12
|
+
include_full_text: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
13
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
14
|
+
documentNumber: z.ZodString;
|
|
15
|
+
title: z.ZodString;
|
|
16
|
+
type: z.ZodString;
|
|
17
|
+
abstract: z.ZodNullable<z.ZodString>;
|
|
18
|
+
action: z.ZodNullable<z.ZodString>;
|
|
19
|
+
dates: z.ZodNullable<z.ZodString>;
|
|
20
|
+
publicationDate: z.ZodString;
|
|
21
|
+
effectiveOn: z.ZodNullable<z.ZodString>;
|
|
22
|
+
commentsCloseOn: z.ZodNullable<z.ZodString>;
|
|
23
|
+
agencies: z.ZodArray<z.ZodString>;
|
|
24
|
+
regulationIdNumbers: z.ZodArray<z.ZodString>;
|
|
25
|
+
cfrReferences: z.ZodArray<z.ZodObject<{
|
|
26
|
+
title: z.ZodNumber;
|
|
27
|
+
part: z.ZodString;
|
|
28
|
+
}, z.core.$strip>>;
|
|
29
|
+
docketId: z.ZodNullable<z.ZodString>;
|
|
30
|
+
regulationsGovDocumentId: z.ZodNullable<z.ZodString>;
|
|
31
|
+
commentCount: z.ZodNullable<z.ZodNumber>;
|
|
32
|
+
supportingDocuments: z.ZodArray<z.ZodObject<{
|
|
33
|
+
title: z.ZodString;
|
|
34
|
+
documentId: z.ZodString;
|
|
35
|
+
}, z.core.$strip>>;
|
|
36
|
+
bodyHtmlUrl: z.ZodString;
|
|
37
|
+
rawTextUrl: z.ZodString;
|
|
38
|
+
htmlUrl: z.ZodString;
|
|
39
|
+
fullText: z.ZodOptional<z.ZodString>;
|
|
40
|
+
}, z.core.$strip>, readonly [{
|
|
41
|
+
readonly reason: "not_found";
|
|
42
|
+
readonly code: JsonRpcErrorCode.NotFound;
|
|
43
|
+
readonly when: "No Federal Register document exists with that number.";
|
|
44
|
+
readonly recovery: "Verify the number via regulations_search_rules; FR numbers look like \"2025-14555\".";
|
|
45
|
+
}, {
|
|
46
|
+
readonly reason: "upstream_unavailable";
|
|
47
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
48
|
+
readonly when: "Federal Register returned a 5xx, timed out, or served an HTML error page.";
|
|
49
|
+
readonly recovery: "Retry after a brief wait; the Federal Register API may be momentarily down.";
|
|
50
|
+
}], undefined>;
|
|
51
|
+
//# sourceMappingURL=get-document.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-document.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/get-document.tool.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAsJ1B,CAAC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview regulations_get_document — fetch one Federal Register document by
|
|
3
|
+
* FR number: full metadata plus the cross-source handles (docket ID, affected CFR
|
|
4
|
+
* parts, Regulations.gov document ID, comment count) that chain into the comment
|
|
5
|
+
* and codified-text tools. The stitching tool of this server. Keyless.
|
|
6
|
+
* @module mcp-server/tools/definitions/get-document.tool
|
|
7
|
+
*/
|
|
8
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
9
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
10
|
+
import { getFederalRegisterService } from '../../../services/federal-register/federal-register-service.js';
|
|
11
|
+
export const getDocumentTool = tool('regulations_get_document', {
|
|
12
|
+
title: 'regulations_get_document',
|
|
13
|
+
description: 'Fetch one Federal Register document by its FR document number — full metadata (title, type, agencies, abstract, action, effective/comment dates, RINs) plus the cross-source handles that make this a workflow server. The output carries the docket ID (chain into regulations_get_docket or regulations_find_comments) and the affected CFR parts (chain into regulations_get_cfr_section). Set include_full_text only when the rule body itself is needed — final rules can run tens of thousands of words.',
|
|
14
|
+
annotations: { readOnlyHint: true, idempotentHint: true },
|
|
15
|
+
input: z.object({
|
|
16
|
+
document_number: z
|
|
17
|
+
.string()
|
|
18
|
+
.regex(/^[0-9]{4}-[0-9]+$/)
|
|
19
|
+
.describe('Federal Register document number (e.g. "2025-14555"). Obtain from regulations_search_rules results (the documentNumber field).'),
|
|
20
|
+
include_full_text: z
|
|
21
|
+
.boolean()
|
|
22
|
+
.optional()
|
|
23
|
+
.default(false)
|
|
24
|
+
.describe('When true, fetch and inline the document body as plain text (can be large). Default false returns the body URLs only; fetch full text only when you need to read the rule itself, not just its metadata and cross-links.'),
|
|
25
|
+
}),
|
|
26
|
+
output: z.object({
|
|
27
|
+
documentNumber: z.string().describe('Federal Register document number.'),
|
|
28
|
+
title: z.string().describe('Document title.'),
|
|
29
|
+
type: z.string().describe('Document type.'),
|
|
30
|
+
abstract: z.string().nullable().describe('Abstract summary, or null.'),
|
|
31
|
+
action: z.string().nullable().describe('Action line (e.g. "Final rule."), or null.'),
|
|
32
|
+
dates: z.string().nullable().describe('Free-text dates summary from the rule, or null.'),
|
|
33
|
+
publicationDate: z.string().describe('Publication date (ISO 8601).'),
|
|
34
|
+
effectiveOn: z.string().nullable().describe('Effective date (ISO 8601), or null.'),
|
|
35
|
+
commentsCloseOn: z
|
|
36
|
+
.string()
|
|
37
|
+
.nullable()
|
|
38
|
+
.describe('Comment-period close date (ISO 8601); when set, still open for comment.'),
|
|
39
|
+
agencies: z.array(z.string()).describe('Issuing agency names.'),
|
|
40
|
+
regulationIdNumbers: z.array(z.string()).describe('Regulation Identifier Number(s) (RIN).'),
|
|
41
|
+
cfrReferences: z
|
|
42
|
+
.array(z
|
|
43
|
+
.object({
|
|
44
|
+
title: z.number().describe('CFR title number.'),
|
|
45
|
+
part: z.string().describe('CFR part.'),
|
|
46
|
+
})
|
|
47
|
+
.describe('A single affected CFR title + part.'))
|
|
48
|
+
.describe('Affected CFR parts — chain into regulations_get_cfr_section.'),
|
|
49
|
+
docketId: z
|
|
50
|
+
.string()
|
|
51
|
+
.nullable()
|
|
52
|
+
.describe('Regulations.gov docket ID — chain into regulations_get_docket / find_comments. Null when not on Regulations.gov.'),
|
|
53
|
+
regulationsGovDocumentId: z
|
|
54
|
+
.string()
|
|
55
|
+
.nullable()
|
|
56
|
+
.describe('Regulations.gov document ID — chain into regulations_find_comments (document-scoped). Null when absent.'),
|
|
57
|
+
commentCount: z
|
|
58
|
+
.number()
|
|
59
|
+
.nullable()
|
|
60
|
+
.describe('FR-reported comment count from Regulations.gov; null when not on Regulations.gov.'),
|
|
61
|
+
supportingDocuments: z
|
|
62
|
+
.array(z
|
|
63
|
+
.object({
|
|
64
|
+
title: z.string().describe('Supporting document title.'),
|
|
65
|
+
documentId: z.string().describe('Regulations.gov document ID.'),
|
|
66
|
+
})
|
|
67
|
+
.describe('One related Regulations.gov supporting document.'))
|
|
68
|
+
.describe('Related Regulations.gov supporting documents.'),
|
|
69
|
+
bodyHtmlUrl: z.string().describe('URL of the rendered HTML body.'),
|
|
70
|
+
rawTextUrl: z.string().describe('URL of the plain-text body.'),
|
|
71
|
+
htmlUrl: z.string().describe('Federal Register web URL for the document.'),
|
|
72
|
+
fullText: z
|
|
73
|
+
.string()
|
|
74
|
+
.optional()
|
|
75
|
+
.describe('Inlined plain-text body — present only when include_full_text=true.'),
|
|
76
|
+
}),
|
|
77
|
+
errors: [
|
|
78
|
+
{
|
|
79
|
+
reason: 'not_found',
|
|
80
|
+
code: JsonRpcErrorCode.NotFound,
|
|
81
|
+
when: 'No Federal Register document exists with that number.',
|
|
82
|
+
recovery: 'Verify the number via regulations_search_rules; FR numbers look like "2025-14555".',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
reason: 'upstream_unavailable',
|
|
86
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
87
|
+
when: 'Federal Register returned a 5xx, timed out, or served an HTML error page.',
|
|
88
|
+
recovery: 'Retry after a brief wait; the Federal Register API may be momentarily down.',
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
async handler(input, ctx) {
|
|
92
|
+
const service = getFederalRegisterService();
|
|
93
|
+
return await service.getDocument(input.document_number, input.include_full_text, ctx);
|
|
94
|
+
},
|
|
95
|
+
format: (result) => {
|
|
96
|
+
const lines = [];
|
|
97
|
+
lines.push(`# ${result.title}`);
|
|
98
|
+
lines.push(`**FR ${result.documentNumber}** · ${result.type} · ${result.agencies.join(', ') || '—'} · published ${result.publicationDate}`);
|
|
99
|
+
if (result.action)
|
|
100
|
+
lines.push(`**Action:** ${result.action}`);
|
|
101
|
+
if (result.dates)
|
|
102
|
+
lines.push(`**Dates:** ${result.dates}`);
|
|
103
|
+
if (result.effectiveOn)
|
|
104
|
+
lines.push(`**Effective:** ${result.effectiveOn}`);
|
|
105
|
+
if (result.commentsCloseOn)
|
|
106
|
+
lines.push(`**Comments close:** ${result.commentsCloseOn}`);
|
|
107
|
+
if (result.regulationIdNumbers.length)
|
|
108
|
+
lines.push(`**RIN:** ${result.regulationIdNumbers.join(', ')}`);
|
|
109
|
+
if (result.abstract)
|
|
110
|
+
lines.push(`\n${result.abstract}`);
|
|
111
|
+
lines.push('\n## Cross-source handles');
|
|
112
|
+
lines.push(result.docketId
|
|
113
|
+
? `- **Docket ID:** \`${result.docketId}\` → regulations_get_docket / regulations_find_comments(docket_id)`
|
|
114
|
+
: '- **Docket ID:** not on Regulations.gov');
|
|
115
|
+
if (result.regulationsGovDocumentId) {
|
|
116
|
+
lines.push(`- **Regulations.gov document ID:** \`${result.regulationsGovDocumentId}\` → regulations_find_comments(document_object_id)`);
|
|
117
|
+
}
|
|
118
|
+
lines.push(`- **Comment count:** ${result.commentCount ?? 'unknown'} → regulations_find_comments(fr_document_number="${result.documentNumber}")`);
|
|
119
|
+
if (result.cfrReferences.length) {
|
|
120
|
+
const cites = result.cfrReferences.map((c) => `${c.title} CFR ${c.part}`).join(', ');
|
|
121
|
+
lines.push(`- **Affected CFR parts:** ${cites} → regulations_get_cfr_section`);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
lines.push('- **Affected CFR parts:** none listed');
|
|
125
|
+
}
|
|
126
|
+
if (result.supportingDocuments.length) {
|
|
127
|
+
lines.push(`- **Supporting documents:** ${result.supportingDocuments.map((d) => `${d.title} (${d.documentId})`).join('; ')}`);
|
|
128
|
+
}
|
|
129
|
+
lines.push('\n## Body');
|
|
130
|
+
lines.push(`- HTML: ${result.bodyHtmlUrl}`);
|
|
131
|
+
lines.push(`- Raw text: ${result.rawTextUrl}`);
|
|
132
|
+
lines.push(`- Federal Register page: ${result.htmlUrl}`);
|
|
133
|
+
if (result.fullText)
|
|
134
|
+
lines.push(`\n---\n\n${result.fullText}`);
|
|
135
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=get-document.tool.js.map
|