@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
package/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2025 Casey Hand @cyanheads
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,372 @@
1
+ <div align="center">
2
+ <h1>@cyanheads/federal-regulations-mcp-server</h1>
3
+ <p><b>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.</b>
4
+ <div>7 Tools • 2 Resources</div>
5
+ </p>
6
+ </div>
7
+
8
+ <div align="center">
9
+
10
+ [![Version](https://img.shields.io/badge/Version-0.1.0-blue.svg?style=flat-square)](./CHANGELOG.md) [![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg?style=flat-square)](./LICENSE) [![Docker](https://img.shields.io/badge/Docker-ghcr.io-2496ED?style=flat-square&logo=docker&logoColor=white)](https://github.com/users/cyanheads/packages/container/package/federal-regulations-mcp-server) [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-^1.29.0-green.svg?style=flat-square)](https://modelcontextprotocol.io/) [![npm](https://img.shields.io/npm/v/@cyanheads/federal-regulations-mcp-server?style=flat-square&logo=npm&logoColor=white)](https://www.npmjs.com/package/@cyanheads/federal-regulations-mcp-server) [![TypeScript](https://img.shields.io/badge/TypeScript-^6.0.3-3178C6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Bun](https://img.shields.io/badge/Bun-v1.3-blueviolet.svg?style=flat-square)](https://bun.sh/)
11
+
12
+ </div>
13
+
14
+ <div align="center">
15
+
16
+ [![Install in Claude Desktop](https://img.shields.io/badge/Install_in-Claude_Desktop-D97757?style=for-the-badge&logo=anthropic&logoColor=white)](https://github.com/cyanheads/federal-regulations-mcp-server/releases/latest/download/federal-regulations-mcp-server.mcpb) [![Install in Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=federal-regulations-mcp-server&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBjeWFuaGVhZHMvZmVkZXJhbC1yZWd1bGF0aW9ucy1tY3Atc2VydmVyIl19) [![Install in VS Code](https://img.shields.io/badge/VS_Code-Install_Server-0098FF?style=for-the-badge&logo=visualstudiocode&logoColor=white)](https://vscode.dev/redirect?url=vscode:mcp/install?%7B%22name%22%3A%22federal-regulations-mcp-server%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40cyanheads%2Ffederal-regulations-mcp-server%22%5D%7D)
17
+
18
+ [![Framework](https://img.shields.io/badge/Built%20on-@cyanheads/mcp--ts--core-67E8F9?style=flat-square)](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
19
+
20
+ </div>
21
+
22
+ ---
23
+
24
+ US administrative law is where agencies turn statutes into binding rules — and it spans three official sources that don't talk to each other. This server stitches them into one workflow: the **Federal Register** (the daily journal of proposed/final rules and notices), the **eCFR** (the codified Code of Federal Regulations, full text, point-in-time), and **Regulations.gov** (rulemaking dockets and the public comments filed on them). Every Federal Register document carries the docket ID and CFR-part handles that chain across sources, so a rule can be traced **proposal → comments → final → codified text** in one sequence.
25
+
26
+ The agent sees regulatory verbs — `search_rules`, `get_cfr_section`, `find_comments` — not three API clients. The Federal Register and eCFR tools are **keyless**; the two Regulations.gov tools need a free `api.data.gov` key and return an actionable error without it.
27
+
28
+ ## Tools
29
+
30
+ Seven tools across the regulatory workflow. The **Federal Register** and **eCFR** tools (1–4, 7) are keyless. The two **Regulations.gov** tools (5–6) need `REGULATIONS_GOV_API_KEY`; `regulations_list_open_comments` runs keyless and only adds comment counts when the key is present.
31
+
32
+ | Tool | Source | Key | Description |
33
+ |:---|:---|:---|:---|
34
+ | `regulations_search_rules` | Federal Register | — | Search proposed rules, final rules, notices, and presidential documents by query, type, agency, date range, and open-for-comment status. The primary discovery entry point. |
35
+ | `regulations_get_document` | Federal Register | — | Fetch one FR document by number — full metadata plus the cross-source handles (docket ID, CFR parts, comment count) that chain into the comment and codified-text tools. |
36
+ | `regulations_browse_cfr` | eCFR | — | Walk the CFR hierarchy (structure mode) or full-text-search the codified CFR (search mode). Both feed `regulations_get_cfr_section`. |
37
+ | `regulations_get_cfr_section` | eCFR | — | Read the codified text of a CFR section or whole part — current or as of a past date. |
38
+ | `regulations_get_docket` | Regulations.gov | ✔ | Pull a rulemaking docket and the documents filed in it (NPRM, final rule, supporting materials). |
39
+ | `regulations_find_comments` | Regulations.gov | ✔ | Fetch public comments on a document or docket, or one comment's full body and attachments. Flags attachment-only submissions. |
40
+ | `regulations_list_open_comments` | Federal Register (+ Reg.gov enrich) | optional | Rules currently open for public comment, closing soonest first. Fully functional keyless; enriches comment counts when keyed. |
41
+
42
+ ---
43
+
44
+ ### `regulations_search_rules`
45
+
46
+ Search the Federal Register — the daily journal of US proposed rules, final rules, notices, and presidential documents (1994–present). Keyless.
47
+
48
+ - Full-text `query` across title and body, or browse by filters alone
49
+ - Filter by document `type` (`PRORULE`, `RULE`, `NOTICE`, `PRESDOCU`), `agencies` (Federal Register agency slug), and publication date window (`published_after` / `published_before`)
50
+ - Each result carries the `documentNumber`, `docketIds`, `regulationIdNumbers` (RIN), and `cfrReferences` that chain into the document, comment, and codified-text tools
51
+ - Pagination up to 100 per page, 50 pages; the Federal Register caps navigation at 5,000 records and the match count at 10,000 — when a result set is larger, the tool flags it and steers you to date-windowing
52
+
53
+ ---
54
+
55
+ ### `regulations_get_document`
56
+
57
+ Fetch one Federal Register document by its FR number — the stitching tool of this server. Keyless.
58
+
59
+ - Full metadata: title, type, agencies, abstract, action, effective/comment dates, RINs
60
+ - The output renders a **cross-source handles** block — the docket ID (→ `regulations_get_docket` / `regulations_find_comments`), affected CFR parts (→ `regulations_get_cfr_section`), and Regulations.gov document ID and comment count — each next to the tool name that consumes it
61
+ - `include_full_text` inlines the document body as plain text; default false returns the body URLs only (final rules can run tens of thousands of words)
62
+
63
+ ---
64
+
65
+ ### `regulations_browse_cfr`
66
+
67
+ Explore the codified Code of Federal Regulations via eCFR in two modes. Keyless.
68
+
69
+ - `structure` mode walks the CFR tree (all 50 titles, or one title's chapters → parts → sections) to discover a cite when the exact citation is unknown
70
+ - `search` mode runs a full-text query across the codified CFR and returns matching sections with their hierarchy path and a snippet
71
+ - Search is served from a synced local mirror (FTS5) when available and falls back to the live eCFR search API on a cold deploy; the `source` (`mirror` or `live`) is reported on each result
72
+ - Both modes assemble a `cfrCite` that feeds `regulations_get_cfr_section`
73
+
74
+ ---
75
+
76
+ ### `regulations_get_cfr_section`
77
+
78
+ Read the codified text of a specific CFR section, or a whole part, via eCFR. Keyless.
79
+
80
+ - Answers "what does 40 CFR 50.1 say today?" and "...as of 2019-01-01?" — pass `date` for point-in-time text
81
+ - Provide `title` + `part` + `section` for one section, or omit `section` to fetch the whole part
82
+ - Current single-section reads are served from the local mirror when ready (the `source` is reported); historical dates, whole-part fetches, and a cold mirror fall back to the live eCFR versioner
83
+ - eCFR retains historical versions back to roughly 2017; a date before coverage is rejected with guidance
84
+
85
+ ---
86
+
87
+ ### `regulations_get_docket` · key required
88
+
89
+ Pull a rulemaking docket from Regulations.gov by docket ID (e.g. `EPA-HQ-OAR-2025-0194`). Requires `REGULATIONS_GOV_API_KEY`.
90
+
91
+ - Docket metadata (title, agency, RIN, abstract) plus the documents filed in it (NPRM, final rule, supporting materials)
92
+ - Each returned document's `objectId` feeds `regulations_find_comments(document_object_id)`; `frDocNum` chains back to `regulations_get_document`
93
+ - A docket often holds hundreds of supporting materials — filter `document_types` to `Proposed Rule` / `Rule` to find the rule documents themselves
94
+ - Regulations.gov requires a page size of 5–250 and caps a query at 20 pages (5,000 records)
95
+
96
+ ---
97
+
98
+ ### `regulations_find_comments` · key required
99
+
100
+ Fetch public comments — the unique corpus of what citizens and organizations actually submitted. Requires `REGULATIONS_GOV_API_KEY`.
101
+
102
+ - Target with exactly one of: `docket_id` (all comments in a docket), `document_object_id` (comments on one document), `fr_document_number` (convenience — resolves the FR number to its Regulations.gov document internally), or `comment_id` (one comment's full detail)
103
+ - The list endpoint returns no body text or attachment info — call with `comment_id` to read a comment's body
104
+ - When a comment's real content is a PDF/DOCX attachment, the body is a stub and `attachmentOnly` is `true`; the attachment download URLs are returned so the agent knows where the substance lives. The flag reaches both the structured output and the rendered text
105
+ - Regulations.gov caps a query at 20 pages (5,000 records); a high-volume docket surfaces a sample, flagged as truncated
106
+
107
+ ---
108
+
109
+ ### `regulations_list_open_comments`
110
+
111
+ Rules currently open for public comment, sorted by closing date (soonest first) — "what can I still weigh in on?" Keyless, degrades gracefully.
112
+
113
+ - Filter by `agencies` (Federal Register slug) and `query`; `closing_before` finds deadlines you need to act on soon
114
+ - Each row carries `daysRemaining`, the `documentNumber` (→ `regulations_get_document`), and `docketIds` (→ `regulations_find_comments`)
115
+ - Fully functional without a key; when `REGULATIONS_GOV_API_KEY` is configured, each row is enriched with the comment count read from the Federal Register document's own embedded Regulations.gov info (no extra rate-limited call)
116
+
117
+ ## Resources
118
+
119
+ | Type | Name | Description |
120
+ |:---|:---|:---|
121
+ | Resource | `regulations://document/{documentNumber}` | A single Federal Register document — metadata plus cross-source handles (mirrors `regulations_get_document`, full text omitted). |
122
+ | Resource | `regulations://cfr/{title}/{part}/{section}` | Codified text of a current CFR section (mirrors `regulations_get_cfr_section` at the current date, mirror-backed with a live eCFR fallback). |
123
+
124
+ All resource data is also reachable via the tool surface — tool-only MCP clients lose nothing. Collections (rule search, comment lists) are not exposed as resources; use `regulations_search_rules` and `regulations_find_comments` instead.
125
+
126
+ ## Features
127
+
128
+ Built on [`@cyanheads/mcp-ts-core`](https://www.npmjs.com/package/@cyanheads/mcp-ts-core):
129
+
130
+ - Declarative tool and resource definitions — single file per primitive, framework handles registration and validation
131
+ - Unified error handling — handlers throw, framework catches, classifies, and formats; typed error contracts with recovery hints
132
+ - Pluggable auth: `none`, `jwt`, `oauth`
133
+ - Swappable storage backends: `in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2/D1`
134
+ - Structured logging with optional OpenTelemetry tracing
135
+ - STDIO and Streamable HTTP transports
136
+
137
+ Federal-regulations-specific:
138
+
139
+ - One workflow over three official sources — the agent sees regulatory verbs, not three API clients; which source is hit is a service-layer detail
140
+ - Cross-source stitching — every Federal Register document surfaces its docket ID and CFR-part handles next to the tools that consume them, priming the proposal → comments → final → codified-text trace
141
+ - Keyless core — Federal Register + eCFR (5 of 7 tools) is a complete deployment with no API key; the Regulations.gov leg layers on top
142
+ - Locally mirrored codified CFR — the eCFR is synced once into embedded SQLite + FTS5 and queried by exact cite or full text, with a live-API fallback before the mirror is ready
143
+ - Three independent service clients, each with its own base URL, retry/backoff, and rate-limit handling (Regulations.gov honors `Retry-After` on 429)
144
+
145
+ Agent-friendly output:
146
+
147
+ - Provenance on every CFR read — `source: "mirror" | "live"` so agents know whether text came from the synced index or the live API
148
+ - Honest truncation — Federal Register (50-page / 5,000-record) and Regulations.gov (20-page / 5,000-record) ceilings are surfaced with guidance to narrow, never silently dropped
149
+ - Attachment-aware comments — `attachmentOnly` flags when a comment's substance is a file rather than inline text, with the download URLs, on both the structured and text surfaces
150
+ - Actionable `auth_required` errors — the two keyed tools name the env var and the free signup URL rather than passing through a raw 401/403
151
+
152
+ ## Getting started
153
+
154
+ Add the following to your MCP client configuration file. The Federal Register and eCFR tools work with no key; set `REGULATIONS_GOV_API_KEY` (free at [api.data.gov/signup](https://api.data.gov/signup/)) to enable the Regulations.gov docket and comment tools.
155
+
156
+ ```json
157
+ {
158
+ "mcpServers": {
159
+ "federal-regulations-mcp-server": {
160
+ "type": "stdio",
161
+ "command": "bunx",
162
+ "args": ["@cyanheads/federal-regulations-mcp-server@latest"],
163
+ "env": {
164
+ "MCP_TRANSPORT_TYPE": "stdio",
165
+ "MCP_LOG_LEVEL": "info",
166
+ "REGULATIONS_GOV_API_KEY": "your-key-here"
167
+ }
168
+ }
169
+ }
170
+ }
171
+ ```
172
+
173
+ Or with npx (no Bun required):
174
+
175
+ ```json
176
+ {
177
+ "mcpServers": {
178
+ "federal-regulations-mcp-server": {
179
+ "type": "stdio",
180
+ "command": "npx",
181
+ "args": ["-y", "@cyanheads/federal-regulations-mcp-server@latest"],
182
+ "env": {
183
+ "MCP_TRANSPORT_TYPE": "stdio",
184
+ "MCP_LOG_LEVEL": "info",
185
+ "REGULATIONS_GOV_API_KEY": "your-key-here"
186
+ }
187
+ }
188
+ }
189
+ }
190
+ ```
191
+
192
+ Or with Docker:
193
+
194
+ ```json
195
+ {
196
+ "mcpServers": {
197
+ "federal-regulations-mcp-server": {
198
+ "type": "stdio",
199
+ "command": "docker",
200
+ "args": [
201
+ "run", "-i", "--rm",
202
+ "-e", "MCP_TRANSPORT_TYPE=stdio",
203
+ "-e", "REGULATIONS_GOV_API_KEY=your-key-here",
204
+ "ghcr.io/cyanheads/federal-regulations-mcp-server:latest"
205
+ ]
206
+ }
207
+ }
208
+ }
209
+ ```
210
+
211
+ > Omit the `REGULATIONS_GOV_API_KEY` line entirely to run the keyless core (Federal Register + eCFR). The two Regulations.gov tools then return an actionable `auth_required` error, and `regulations_list_open_comments` runs without comment counts.
212
+
213
+ For Streamable HTTP, set the transport and start the server:
214
+
215
+ ```sh
216
+ MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
217
+ # Server listens at http://localhost:3010/mcp
218
+ ```
219
+
220
+ ### Prerequisites
221
+
222
+ - [Bun v1.3](https://bun.sh/) or higher (or Node.js v24+).
223
+ - Optional: a free [api.data.gov key](https://api.data.gov/signup/) for the Regulations.gov tools (`regulations_get_docket`, `regulations_find_comments`, and comment counts in `regulations_list_open_comments`). The Federal Register and eCFR tools need no key. The shared key allows 1,000 requests/hour.
224
+
225
+ ### Installation
226
+
227
+ 1. **Clone the repository:**
228
+
229
+ ```sh
230
+ git clone https://github.com/cyanheads/federal-regulations-mcp-server.git
231
+ ```
232
+
233
+ 2. **Navigate into the directory:**
234
+
235
+ ```sh
236
+ cd federal-regulations-mcp-server
237
+ ```
238
+
239
+ 3. **Install dependencies:**
240
+
241
+ ```sh
242
+ bun install
243
+ ```
244
+
245
+ 4. **Configure environment:**
246
+
247
+ ```sh
248
+ cp .env.example .env
249
+ # optionally set REGULATIONS_GOV_API_KEY
250
+ ```
251
+
252
+ ## Configuration
253
+
254
+ All configuration is validated at startup via Zod schemas in `src/config/server-config.ts`. Key environment variables:
255
+
256
+ | Variable | Description | Default |
257
+ |:---|:---|:---|
258
+ | `REGULATIONS_GOV_API_KEY` | `api.data.gov` key for the Regulations.gov tools (`get_docket`, `find_comments`, and comment-count enrichment in `list_open_comments`). Optional — the Federal Register and eCFR tools work without it. | — |
259
+ | `FEDERAL_REGISTER_BASE_URL` | Federal Register API v1 base URL. | `https://www.federalregister.gov/api/v1` |
260
+ | `ECFR_BASE_URL` | eCFR API base URL. | `https://www.ecfr.gov/api` |
261
+ | `REGULATIONS_GOV_BASE_URL` | Regulations.gov API v4 base URL. | `https://api.regulations.gov/v4` |
262
+ | `ECFR_MIRROR_PATH` | Filesystem path for the eCFR SQLite mirror database. | `./data/ecfr-mirror.sqlite` |
263
+ | `ECFR_MIRROR_REFRESH_CRON` | Cron expression for the weekly mirror refresh (HTTP transport only). | `0 4 * * 0` |
264
+ | `ECFR_MIRROR_TITLES` | Comma-separated CFR title numbers to scope the mirror to (e.g. `21,40`). Omit to mirror all 50 titles. Cites outside the set fall through to the live eCFR API. | — (all titles) |
265
+ | `MCP_TRANSPORT_TYPE` | Transport: `stdio` or `http`. | `stdio` |
266
+ | `MCP_HTTP_PORT` | Port for the HTTP server. | `3010` |
267
+ | `MCP_AUTH_MODE` | Auth mode: `none`, `jwt`, or `oauth`. | `none` |
268
+ | `MCP_LOG_LEVEL` | Log level (RFC 5424). | `info` |
269
+ | `STORAGE_PROVIDER_TYPE` | Storage backend. | `in-memory` |
270
+ | `OTEL_ENABLED` | Enable [OpenTelemetry instrumentation](https://github.com/cyanheads/mcp-ts-core/tree/main/docs/telemetry). | `false` |
271
+
272
+ See [`.env.example`](./.env.example) for the full list of optional overrides.
273
+
274
+ ## The eCFR mirror
275
+
276
+ The codified CFR is large (~50 titles, hundreds of MB of XML — Title 40 alone is ~150 MB) but changes far less often than it is queried. This server mirrors it once into an embedded SQLite + FTS5 index and serves `regulations_get_cfr_section` (current single sections) and `regulations_browse_cfr` (full-text search) from it, falling back to the live eCFR API when the mirror has not yet completed an init or a historical/whole-part read is requested.
277
+
278
+ **The mirror is populated out-of-band, never on startup** — a full title sweep takes a while and must not block the server. Build it with:
279
+
280
+ ```sh
281
+ # Mirror all 50 CFR titles (idempotent, resumable from the persisted cursor)
282
+ bun run mirror:init
283
+
284
+ # Or scope to specific titles to build a smaller, faster mirror
285
+ ECFR_MIRROR_TITLES=21,40 bun run mirror:init
286
+
287
+ # Incremental refresh against the latest eCFR issues
288
+ bun run mirror:refresh
289
+
290
+ # Report row counts and the last-synced issue date
291
+ bun run mirror:verify
292
+ ```
293
+
294
+ Until the mirror has completed an init, the codified-text tools run against the live eCFR API — so the server is useful immediately on a fresh deploy; the mirror is a latency/throughput optimization, not a hard dependency. On the HTTP transport a weekly refresh is scheduled automatically (`ECFR_MIRROR_REFRESH_CRON`); stdio operators run the lifecycle scripts above.
295
+
296
+ The mirror database (`./data/ecfr-mirror.sqlite`) is a local artifact — it is git-ignored and excluded from the `.mcpb` bundle, never shipped in the package.
297
+
298
+ ## Running the server
299
+
300
+ ### Local development
301
+
302
+ - **Build and run:**
303
+
304
+ ```sh
305
+ # One-time build
306
+ bun run rebuild
307
+
308
+ # Run the built server
309
+ bun run start:stdio
310
+ # or
311
+ bun run start:http
312
+ ```
313
+
314
+ - **Run checks and tests:**
315
+
316
+ ```sh
317
+ bun run devcheck # Lint, format, typecheck, security, changelog sync
318
+ bun run test # Vitest test suite
319
+ bun run lint:mcp # Validate MCP definitions against the linter rules
320
+ ```
321
+
322
+ ### Docker
323
+
324
+ ```sh
325
+ docker build -t federal-regulations-mcp-server .
326
+ docker run --rm -e REGULATIONS_GOV_API_KEY=your-key -p 3010:3010 federal-regulations-mcp-server
327
+ ```
328
+
329
+ The Dockerfile defaults to HTTP transport, stateless session mode, and logs to `/var/log/federal-regulations-mcp-server`. The build stage installs dependencies with `--ignore-scripts` — `better-sqlite3` is a build/ingest-only dependency whose native compile is skipped, and the runtime reads the mirror through Bun's built-in `bun:sqlite`. Populate the mirror in a running container with `docker exec <container> bun run mirror:init`; mount a volume over `/usr/src/app/data` so the synced index survives container recreation. OpenTelemetry peer dependencies are installed by default — build with `--build-arg OTEL_ENABLED=false` to omit them.
330
+
331
+ ## Project structure
332
+
333
+ | Directory | Purpose |
334
+ |:---|:---|
335
+ | `src/index.ts` | `createApp()` entry point — registers tools/resources, inits the three services, and schedules the mirror refresh on HTTP. |
336
+ | `src/config` | Server-specific environment variable parsing and validation with Zod. |
337
+ | `src/mcp-server/tools` | Tool definitions (`*.tool.ts`) — the seven `regulations_*` tools. |
338
+ | `src/mcp-server/resources` | Resource definitions (`*.resource.ts`) — the document and CFR-section resources. |
339
+ | `src/services/federal-register` | Federal Register API v1 client (keyless). |
340
+ | `src/services/ecfr` | eCFR API client (keyless) — versioner, structure, search, and section XML parsing. |
341
+ | `src/services/ecfr-mirror` | eCFR codified-text mirror (MirrorService — SQLite + FTS5) and its read path. |
342
+ | `src/services/regulations-gov` | Regulations.gov v4 client (`X-Api-Key`) — dockets and comments. |
343
+ | `scripts/ecfr-mirror-*.ts` | Out-of-band mirror lifecycle: `init`, `refresh`, `verify`. |
344
+ | `tests/` | Unit and integration tests mirroring `src/`. |
345
+
346
+ ## Development guide
347
+
348
+ See [`CLAUDE.md`](./CLAUDE.md) for development guidelines and architectural rules. The short version:
349
+
350
+ - Handlers throw, framework catches — no `try/catch` in tool logic
351
+ - Use `ctx.log` for request-scoped logging, `ctx.state` for tenant-scoped storage
352
+ - Register new tools and resources via the barrels in `src/mcp-server/*/definitions/index.ts`
353
+ - Wrap external API calls: validate raw → normalize to the domain type → return the output schema; never fabricate missing upstream fields
354
+
355
+ ## Contributing
356
+
357
+ Issues and pull requests are welcome. Run checks and tests before submitting:
358
+
359
+ ```sh
360
+ bun run devcheck
361
+ bun run test
362
+ ```
363
+
364
+ ## Data disclaimer
365
+
366
+ eCFR content is "authoritative but unofficial" per the Office of the Federal Register — it is not the official legal edition of the Code of Federal Regulations. The official CFR is published annually in print and digitally at [govinfo.gov](https://www.govinfo.gov/app/collection/cfr). For legal research requiring the official text, verify against govinfo.gov or the annual printed CFR.
367
+
368
+ This server is not affiliated with or endorsed by the Office of the Federal Register (OFR), the Government Publishing Office (GPO), or the General Services Administration (GSA).
369
+
370
+ ## License
371
+
372
+ Apache-2.0 — see [LICENSE](LICENSE) for details.
@@ -0,0 +1,20 @@
1
+ ---
2
+ summary: "Initial release — 7 tools and 2 resources over the Federal Register, eCFR (locally mirrored), and Regulations.gov, with cross-source rule tracing."
3
+ ---
4
+
5
+ # 0.1.0 — 2026-06-13
6
+
7
+ Initial release. A multi-source workflow server over three official US federal regulatory sources: the **Federal Register** (proposed/final rules and notices, keyless), the **eCFR** (codified, point-in-time CFR full text, mirrored locally), and **Regulations.gov** v4 (rulemaking dockets and public comments, key-gated). Every Federal Register document carries the docket ID and CFR-part handles that chain across sources, so a rule can be traced proposal → comments → final → codified text.
8
+
9
+ ## Added
10
+
11
+ - **`regulations_search_rules`** — search the Federal Register by query, type, agency, date window, and open-for-comment status. Keyless.
12
+ - **`regulations_get_document`** — fetch one FR document with the cross-source handles (docket ID, CFR parts, Regulations.gov document ID, comment count) that chain into the comment and codified-text tools. Keyless.
13
+ - **`regulations_browse_cfr`** — navigate the CFR hierarchy (structure mode) or full-text-search the codified CFR (search mode, mirror-backed with a live eCFR fallback). Keyless.
14
+ - **`regulations_get_cfr_section`** — read the codified text of a CFR section or part, current or point-in-time, served from the local mirror when ready with a live versioner fallback. Keyless.
15
+ - **`regulations_get_docket`** — pull a Regulations.gov rulemaking docket and its filed documents. Requires `REGULATIONS_GOV_API_KEY`.
16
+ - **`regulations_find_comments`** — fetch public comments on a document or docket (list mode) or one comment's full body and attachments (detail mode), flagging attachment-primary submissions. Requires `REGULATIONS_GOV_API_KEY`.
17
+ - **`regulations_list_open_comments`** — rules currently open for comment, closing soonest first. Keyless; enriches comment counts when `REGULATIONS_GOV_API_KEY` is present.
18
+ - Resources **`regulations://document/{documentNumber}`** and **`regulations://cfr/{title}/{part}/{section}`** mirroring the document and CFR-section tool outputs for injectable-context clients.
19
+ - **eCFR mirror** (MirrorService — embedded SQLite + FTS5) with `mirror:init`, `mirror:refresh`, and `mirror:verify` lifecycle scripts and a weekly refresh cron (HTTP transport). The codified CFR is mirrored once and queried locally for section lookup and full-text search; tools fall back to the live eCFR API before the mirror has completed an init.
20
+ - Config: `REGULATIONS_GOV_API_KEY` (optional — the Federal Register and eCFR tools are a complete keyless deployment without it), plus `FEDERAL_REGISTER_BASE_URL`, `ECFR_BASE_URL`, `REGULATIONS_GOV_BASE_URL`, `ECFR_MIRROR_PATH`, `ECFR_MIRROR_REFRESH_CRON`, and `ECFR_MIRROR_TITLES` (scope the mirror to specific CFR titles) overrides.