us-gov-open-data-mcp 1.0.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 (310) hide show
  1. package/README.md +211 -0
  2. package/dist/client.d.ts +54 -0
  3. package/dist/client.d.ts.map +1 -0
  4. package/dist/client.js +388 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/instructions.d.ts +8 -0
  7. package/dist/instructions.d.ts.map +1 -0
  8. package/dist/instructions.js +549 -0
  9. package/dist/instructions.js.map +1 -0
  10. package/dist/modules/bea.d.ts +28 -0
  11. package/dist/modules/bea.d.ts.map +1 -0
  12. package/dist/modules/bea.js +158 -0
  13. package/dist/modules/bea.js.map +1 -0
  14. package/dist/modules/bls.d.ts +29 -0
  15. package/dist/modules/bls.d.ts.map +1 -0
  16. package/dist/modules/bls.js +244 -0
  17. package/dist/modules/bls.js.map +1 -0
  18. package/dist/modules/bts.d.ts +26 -0
  19. package/dist/modules/bts.d.ts.map +1 -0
  20. package/dist/modules/bts.js +112 -0
  21. package/dist/modules/bts.js.map +1 -0
  22. package/dist/modules/cdc.d.ts +26 -0
  23. package/dist/modules/cdc.d.ts.map +1 -0
  24. package/dist/modules/cdc.js +310 -0
  25. package/dist/modules/cdc.js.map +1 -0
  26. package/dist/modules/census.d.ts +23 -0
  27. package/dist/modules/census.d.ts.map +1 -0
  28. package/dist/modules/census.js +141 -0
  29. package/dist/modules/census.js.map +1 -0
  30. package/dist/modules/cfpb.d.ts +20 -0
  31. package/dist/modules/cfpb.d.ts.map +1 -0
  32. package/dist/modules/cfpb.js +135 -0
  33. package/dist/modules/cfpb.js.map +1 -0
  34. package/dist/modules/clinical-trials.d.ts +22 -0
  35. package/dist/modules/clinical-trials.d.ts.map +1 -0
  36. package/dist/modules/clinical-trials.js +171 -0
  37. package/dist/modules/clinical-trials.js.map +1 -0
  38. package/dist/modules/cms.d.ts +21 -0
  39. package/dist/modules/cms.d.ts.map +1 -0
  40. package/dist/modules/cms.js +135 -0
  41. package/dist/modules/cms.js.map +1 -0
  42. package/dist/modules/college-scorecard.d.ts +39 -0
  43. package/dist/modules/college-scorecard.d.ts.map +1 -0
  44. package/dist/modules/college-scorecard.js +192 -0
  45. package/dist/modules/college-scorecard.js.map +1 -0
  46. package/dist/modules/congress.d.ts +28 -0
  47. package/dist/modules/congress.d.ts.map +1 -0
  48. package/dist/modules/congress.js +883 -0
  49. package/dist/modules/congress.js.map +1 -0
  50. package/dist/modules/dol.d.ts +27 -0
  51. package/dist/modules/dol.d.ts.map +1 -0
  52. package/dist/modules/dol.js +209 -0
  53. package/dist/modules/dol.js.map +1 -0
  54. package/dist/modules/eia.d.ts +33 -0
  55. package/dist/modules/eia.d.ts.map +1 -0
  56. package/dist/modules/eia.js +227 -0
  57. package/dist/modules/eia.js.map +1 -0
  58. package/dist/modules/epa.d.ts +21 -0
  59. package/dist/modules/epa.d.ts.map +1 -0
  60. package/dist/modules/epa.js +91 -0
  61. package/dist/modules/epa.js.map +1 -0
  62. package/dist/modules/fbi.d.ts +28 -0
  63. package/dist/modules/fbi.d.ts.map +1 -0
  64. package/dist/modules/fbi.js +143 -0
  65. package/dist/modules/fbi.js.map +1 -0
  66. package/dist/modules/fda.d.ts +35 -0
  67. package/dist/modules/fda.d.ts.map +1 -0
  68. package/dist/modules/fda.js +262 -0
  69. package/dist/modules/fda.js.map +1 -0
  70. package/dist/modules/fdic.d.ts +21 -0
  71. package/dist/modules/fdic.d.ts.map +1 -0
  72. package/dist/modules/fdic.js +186 -0
  73. package/dist/modules/fdic.js.map +1 -0
  74. package/dist/modules/fec.d.ts +29 -0
  75. package/dist/modules/fec.d.ts.map +1 -0
  76. package/dist/modules/fec.js +282 -0
  77. package/dist/modules/fec.js.map +1 -0
  78. package/dist/modules/federal-register.d.ts +24 -0
  79. package/dist/modules/federal-register.d.ts.map +1 -0
  80. package/dist/modules/federal-register.js +184 -0
  81. package/dist/modules/federal-register.js.map +1 -0
  82. package/dist/modules/fema.d.ts +20 -0
  83. package/dist/modules/fema.d.ts.map +1 -0
  84. package/dist/modules/fema.js +156 -0
  85. package/dist/modules/fema.js.map +1 -0
  86. package/dist/modules/fred.d.ts +40 -0
  87. package/dist/modules/fred.d.ts.map +1 -0
  88. package/dist/modules/fred.js +143 -0
  89. package/dist/modules/fred.js.map +1 -0
  90. package/dist/modules/govinfo.d.ts +24 -0
  91. package/dist/modules/govinfo.d.ts.map +1 -0
  92. package/dist/modules/govinfo.js +147 -0
  93. package/dist/modules/govinfo.js.map +1 -0
  94. package/dist/modules/hud.d.ts +17 -0
  95. package/dist/modules/hud.d.ts.map +1 -0
  96. package/dist/modules/hud.js +170 -0
  97. package/dist/modules/hud.js.map +1 -0
  98. package/dist/modules/naep.d.ts +27 -0
  99. package/dist/modules/naep.d.ts.map +1 -0
  100. package/dist/modules/naep.js +210 -0
  101. package/dist/modules/naep.js.map +1 -0
  102. package/dist/modules/nhtsa.d.ts +13 -0
  103. package/dist/modules/nhtsa.d.ts.map +1 -0
  104. package/dist/modules/nhtsa.js +196 -0
  105. package/dist/modules/nhtsa.js.map +1 -0
  106. package/dist/modules/noaa.d.ts +41 -0
  107. package/dist/modules/noaa.d.ts.map +1 -0
  108. package/dist/modules/noaa.js +135 -0
  109. package/dist/modules/noaa.js.map +1 -0
  110. package/dist/modules/nrel.d.ts +25 -0
  111. package/dist/modules/nrel.d.ts.map +1 -0
  112. package/dist/modules/nrel.js +87 -0
  113. package/dist/modules/nrel.js.map +1 -0
  114. package/dist/modules/regulations.d.ts +24 -0
  115. package/dist/modules/regulations.d.ts.map +1 -0
  116. package/dist/modules/regulations.js +173 -0
  117. package/dist/modules/regulations.js.map +1 -0
  118. package/dist/modules/sec.d.ts +25 -0
  119. package/dist/modules/sec.d.ts.map +1 -0
  120. package/dist/modules/sec.js +192 -0
  121. package/dist/modules/sec.js.map +1 -0
  122. package/dist/modules/senate-lobbying.d.ts +21 -0
  123. package/dist/modules/senate-lobbying.d.ts.map +1 -0
  124. package/dist/modules/senate-lobbying.js +189 -0
  125. package/dist/modules/senate-lobbying.js.map +1 -0
  126. package/dist/modules/treasury.d.ts +23 -0
  127. package/dist/modules/treasury.d.ts.map +1 -0
  128. package/dist/modules/treasury.js +234 -0
  129. package/dist/modules/treasury.js.map +1 -0
  130. package/dist/modules/usaspending.d.ts +19 -0
  131. package/dist/modules/usaspending.d.ts.map +1 -0
  132. package/dist/modules/usaspending.js +204 -0
  133. package/dist/modules/usaspending.js.map +1 -0
  134. package/dist/modules/usda-fooddata.d.ts +24 -0
  135. package/dist/modules/usda-fooddata.d.ts.map +1 -0
  136. package/dist/modules/usda-fooddata.js +118 -0
  137. package/dist/modules/usda-fooddata.js.map +1 -0
  138. package/dist/modules/usda-nass.d.ts +46 -0
  139. package/dist/modules/usda-nass.d.ts.map +1 -0
  140. package/dist/modules/usda-nass.js +151 -0
  141. package/dist/modules/usda-nass.js.map +1 -0
  142. package/dist/modules/usgs.d.ts +21 -0
  143. package/dist/modules/usgs.d.ts.map +1 -0
  144. package/dist/modules/usgs.js +203 -0
  145. package/dist/modules/usgs.js.map +1 -0
  146. package/dist/modules/uspto.d.ts +13 -0
  147. package/dist/modules/uspto.d.ts.map +1 -0
  148. package/dist/modules/uspto.js +157 -0
  149. package/dist/modules/uspto.js.map +1 -0
  150. package/dist/modules/world-bank.d.ts +21 -0
  151. package/dist/modules/world-bank.d.ts.map +1 -0
  152. package/dist/modules/world-bank.js +130 -0
  153. package/dist/modules/world-bank.js.map +1 -0
  154. package/dist/prompts.d.ts +12 -0
  155. package/dist/prompts.d.ts.map +1 -0
  156. package/dist/prompts.js +858 -0
  157. package/dist/prompts.js.map +1 -0
  158. package/dist/sdk/bea.d.ts +111 -0
  159. package/dist/sdk/bea.d.ts.map +1 -0
  160. package/dist/sdk/bea.js +242 -0
  161. package/dist/sdk/bea.js.map +1 -0
  162. package/dist/sdk/bls.d.ts +65 -0
  163. package/dist/sdk/bls.d.ts.map +1 -0
  164. package/dist/sdk/bls.js +203 -0
  165. package/dist/sdk/bls.js.map +1 -0
  166. package/dist/sdk/bts.d.ts +108 -0
  167. package/dist/sdk/bts.d.ts.map +1 -0
  168. package/dist/sdk/bts.js +121 -0
  169. package/dist/sdk/bts.js.map +1 -0
  170. package/dist/sdk/cdc.d.ts +105 -0
  171. package/dist/sdk/cdc.d.ts.map +1 -0
  172. package/dist/sdk/cdc.js +222 -0
  173. package/dist/sdk/cdc.js.map +1 -0
  174. package/dist/sdk/census.d.ts +47 -0
  175. package/dist/sdk/census.d.ts.map +1 -0
  176. package/dist/sdk/census.js +99 -0
  177. package/dist/sdk/census.js.map +1 -0
  178. package/dist/sdk/cfpb.d.ts +148 -0
  179. package/dist/sdk/cfpb.d.ts.map +1 -0
  180. package/dist/sdk/cfpb.js +153 -0
  181. package/dist/sdk/cfpb.js.map +1 -0
  182. package/dist/sdk/clinical-trials.d.ts +214 -0
  183. package/dist/sdk/clinical-trials.d.ts.map +1 -0
  184. package/dist/sdk/clinical-trials.js +134 -0
  185. package/dist/sdk/clinical-trials.js.map +1 -0
  186. package/dist/sdk/cms.d.ts +81 -0
  187. package/dist/sdk/cms.d.ts.map +1 -0
  188. package/dist/sdk/cms.js +227 -0
  189. package/dist/sdk/cms.js.map +1 -0
  190. package/dist/sdk/college-scorecard.d.ts +63 -0
  191. package/dist/sdk/college-scorecard.d.ts.map +1 -0
  192. package/dist/sdk/college-scorecard.js +131 -0
  193. package/dist/sdk/college-scorecard.js.map +1 -0
  194. package/dist/sdk/congress.d.ts +575 -0
  195. package/dist/sdk/congress.d.ts.map +1 -0
  196. package/dist/sdk/congress.js +659 -0
  197. package/dist/sdk/congress.js.map +1 -0
  198. package/dist/sdk/dol.d.ts +299 -0
  199. package/dist/sdk/dol.d.ts.map +1 -0
  200. package/dist/sdk/dol.js +252 -0
  201. package/dist/sdk/dol.js.map +1 -0
  202. package/dist/sdk/eia.d.ts +91 -0
  203. package/dist/sdk/eia.d.ts.map +1 -0
  204. package/dist/sdk/eia.js +156 -0
  205. package/dist/sdk/eia.js.map +1 -0
  206. package/dist/sdk/epa.d.ts +128 -0
  207. package/dist/sdk/epa.d.ts.map +1 -0
  208. package/dist/sdk/epa.js +120 -0
  209. package/dist/sdk/epa.js.map +1 -0
  210. package/dist/sdk/fbi.d.ts +48 -0
  211. package/dist/sdk/fbi.d.ts.map +1 -0
  212. package/dist/sdk/fbi.js +69 -0
  213. package/dist/sdk/fbi.js.map +1 -0
  214. package/dist/sdk/fda.d.ts +356 -0
  215. package/dist/sdk/fda.d.ts.map +1 -0
  216. package/dist/sdk/fda.js +162 -0
  217. package/dist/sdk/fda.js.map +1 -0
  218. package/dist/sdk/fdic.d.ts +227 -0
  219. package/dist/sdk/fdic.d.ts.map +1 -0
  220. package/dist/sdk/fdic.js +172 -0
  221. package/dist/sdk/fdic.js.map +1 -0
  222. package/dist/sdk/fec.d.ts +142 -0
  223. package/dist/sdk/fec.d.ts.map +1 -0
  224. package/dist/sdk/fec.js +92 -0
  225. package/dist/sdk/fec.js.map +1 -0
  226. package/dist/sdk/federal-register.d.ts +88 -0
  227. package/dist/sdk/federal-register.d.ts.map +1 -0
  228. package/dist/sdk/federal-register.js +100 -0
  229. package/dist/sdk/federal-register.js.map +1 -0
  230. package/dist/sdk/fema.d.ts +137 -0
  231. package/dist/sdk/fema.d.ts.map +1 -0
  232. package/dist/sdk/fema.js +197 -0
  233. package/dist/sdk/fema.js.map +1 -0
  234. package/dist/sdk/fred.d.ts +72 -0
  235. package/dist/sdk/fred.d.ts.map +1 -0
  236. package/dist/sdk/fred.js +59 -0
  237. package/dist/sdk/fred.js.map +1 -0
  238. package/dist/sdk/govinfo.d.ts +64 -0
  239. package/dist/sdk/govinfo.d.ts.map +1 -0
  240. package/dist/sdk/govinfo.js +187 -0
  241. package/dist/sdk/govinfo.js.map +1 -0
  242. package/dist/sdk/hud.d.ts +87 -0
  243. package/dist/sdk/hud.d.ts.map +1 -0
  244. package/dist/sdk/hud.js +91 -0
  245. package/dist/sdk/hud.js.map +1 -0
  246. package/dist/sdk/index.d.ts +51 -0
  247. package/dist/sdk/index.d.ts.map +1 -0
  248. package/dist/sdk/index.js +51 -0
  249. package/dist/sdk/index.js.map +1 -0
  250. package/dist/sdk/naep.d.ts +93 -0
  251. package/dist/sdk/naep.d.ts.map +1 -0
  252. package/dist/sdk/naep.js +163 -0
  253. package/dist/sdk/naep.js.map +1 -0
  254. package/dist/sdk/nhtsa.d.ts +169 -0
  255. package/dist/sdk/nhtsa.d.ts.map +1 -0
  256. package/dist/sdk/nhtsa.js +102 -0
  257. package/dist/sdk/nhtsa.js.map +1 -0
  258. package/dist/sdk/noaa.d.ts +72 -0
  259. package/dist/sdk/noaa.d.ts.map +1 -0
  260. package/dist/sdk/noaa.js +64 -0
  261. package/dist/sdk/noaa.js.map +1 -0
  262. package/dist/sdk/nrel.d.ts +145 -0
  263. package/dist/sdk/nrel.d.ts.map +1 -0
  264. package/dist/sdk/nrel.js +93 -0
  265. package/dist/sdk/nrel.js.map +1 -0
  266. package/dist/sdk/regulations.d.ts +146 -0
  267. package/dist/sdk/regulations.d.ts.map +1 -0
  268. package/dist/sdk/regulations.js +103 -0
  269. package/dist/sdk/regulations.js.map +1 -0
  270. package/dist/sdk/sec.d.ts +114 -0
  271. package/dist/sdk/sec.d.ts.map +1 -0
  272. package/dist/sdk/sec.js +151 -0
  273. package/dist/sdk/sec.js.map +1 -0
  274. package/dist/sdk/senate-lobbying.d.ts +147 -0
  275. package/dist/sdk/senate-lobbying.d.ts.map +1 -0
  276. package/dist/sdk/senate-lobbying.js +125 -0
  277. package/dist/sdk/senate-lobbying.js.map +1 -0
  278. package/dist/sdk/treasury.d.ts +59 -0
  279. package/dist/sdk/treasury.d.ts.map +1 -0
  280. package/dist/sdk/treasury.js +1397 -0
  281. package/dist/sdk/treasury.js.map +1 -0
  282. package/dist/sdk/usaspending.d.ts +126 -0
  283. package/dist/sdk/usaspending.d.ts.map +1 -0
  284. package/dist/sdk/usaspending.js +270 -0
  285. package/dist/sdk/usaspending.js.map +1 -0
  286. package/dist/sdk/usda-fooddata.d.ts +112 -0
  287. package/dist/sdk/usda-fooddata.d.ts.map +1 -0
  288. package/dist/sdk/usda-fooddata.js +80 -0
  289. package/dist/sdk/usda-fooddata.js.map +1 -0
  290. package/dist/sdk/usda-nass.d.ts +75 -0
  291. package/dist/sdk/usda-nass.d.ts.map +1 -0
  292. package/dist/sdk/usda-nass.js +83 -0
  293. package/dist/sdk/usda-nass.js.map +1 -0
  294. package/dist/sdk/usgs.d.ts +221 -0
  295. package/dist/sdk/usgs.d.ts.map +1 -0
  296. package/dist/sdk/usgs.js +182 -0
  297. package/dist/sdk/usgs.js.map +1 -0
  298. package/dist/sdk/uspto.d.ts +109 -0
  299. package/dist/sdk/uspto.d.ts.map +1 -0
  300. package/dist/sdk/uspto.js +286 -0
  301. package/dist/sdk/uspto.js.map +1 -0
  302. package/dist/sdk/world-bank.d.ts +78 -0
  303. package/dist/sdk/world-bank.d.ts.map +1 -0
  304. package/dist/sdk/world-bank.js +72 -0
  305. package/dist/sdk/world-bank.js.map +1 -0
  306. package/dist/server.d.ts +22 -0
  307. package/dist/server.d.ts.map +1 -0
  308. package/dist/server.js +196 -0
  309. package/dist/server.js.map +1 -0
  310. package/package.json +113 -0
@@ -0,0 +1,883 @@
1
+ /**
2
+ * Congress.gov MCP module — tools + metadata. Delegates all API calls to sdk/congress.
3
+ *
4
+ * Tools return raw JSON data — no markdown formatting. The client decides how to present it.
5
+ */
6
+ import { z } from "zod";
7
+ import { searchBills, getBillDetails, searchMembers, getHouseVotes, getSenateVotes, getRecentLaws, getMemberBills, getBillActions, getBillAmendments, getBillCommittees, getBillRelatedBills, getBillSubjects, getBillSummaries, getBillTextVersions, getMemberDetails, searchAmendments, getAmendmentDetails, listCommittees, getCommitteeBills, listNominations, getNominationDetails, listTreaties, getTreatyDetails, searchCrsReports, getCongressionalRecord, currentCongress, billTypeToUrlSegment, } from "../sdk/congress.js";
8
+ // ─── Metadata (server.ts reads these) ────────────────────────────────
9
+ export const name = "congress";
10
+ export const displayName = "Congress.gov";
11
+ export const description = "Bills, votes, members, laws, amendments, and committee data from Congress.gov. House votes use Congress.gov API (118th+) with clerk.house.gov fallback (1990+). Senate votes from senate.gov (101st/1989+).";
12
+ export const auth = { envVar: "DATA_GOV_API_KEY", signup: "https://api.data.gov/signup/" };
13
+ export const workflow = "congress_search_bills → congress_bill_details for sponsors/cosponsors/status → congress_house_votes or congress_senate_votes for party-line breakdown → cross-reference with FEC (donors), lobbying_search (who lobbied), and FRED (economic impact)";
14
+ export const tips = "Congress numbers: 119th (2025-2026), 118th (2023-2024), 117th (2021-2022). Bill types: hr, s, hjres, sjres, hconres, sconres, hres, sres. House votes: use year param for historical (1990+). Senate votes: 101st Congress (1989) to present. Always compare House and Senate votes on the same bill to reveal bicameral differences. For accountability investigations: use congress_member_details to get committee assignments (e.g. Banking Committee chair), then congress_senate_votes/congress_house_votes for party-line breakdown, then cross-reference with FEC disbursements and lobbying spend.";
15
+ export const reference = {
16
+ billTypes: {
17
+ hr: "House Bill", s: "Senate Bill",
18
+ hjres: "House Joint Resolution", sjres: "Senate Joint Resolution",
19
+ hconres: "House Concurrent Resolution", sconres: "Senate Concurrent Resolution",
20
+ hres: "House Simple Resolution", sres: "Senate Simple Resolution",
21
+ },
22
+ congressNumbers: {
23
+ 119: "2025-2026", 118: "2023-2024", 117: "2021-2022",
24
+ 116: "2019-2020", 115: "2017-2018", 114: "2015-2016",
25
+ },
26
+ docs: {
27
+ "API Docs": "https://api.congress.gov/",
28
+ "Interactive Docs": "https://api.congress.gov/#/",
29
+ "Sign Up": "https://api.congress.gov/sign-up/",
30
+ },
31
+ };
32
+ // ─── Helpers ─────────────────────────────────────────────────────────
33
+ function summarizeBill(b) {
34
+ return {
35
+ type: b.type ?? null,
36
+ number: b.number ?? null,
37
+ title: b.title ?? null,
38
+ congress: b.congress ?? null,
39
+ introducedDate: b.introducedDate ?? null,
40
+ sponsor: b.sponsor ? { name: b.sponsor.name, party: b.sponsor.party, state: b.sponsor.state } : null,
41
+ latestAction: b.latestAction ? { text: b.latestAction.text, date: b.latestAction.actionDate } : null,
42
+ url: b.url ?? null,
43
+ };
44
+ }
45
+ function summarizeMember(m) {
46
+ return {
47
+ name: m.name ?? (m.firstName && m.lastName ? `${m.firstName} ${m.lastName}` : null),
48
+ party: m.partyName ?? m.party ?? null,
49
+ state: m.state ?? null,
50
+ chamber: m.chamber ?? null,
51
+ district: m.district ?? null,
52
+ bioguideId: m.bioguideId ?? null,
53
+ startYear: m.startYear ?? null,
54
+ endYear: m.endYear ?? null,
55
+ };
56
+ }
57
+ function summarizeVote(v) {
58
+ return {
59
+ voteNumber: v.rollCallNumber ?? v.voteNumber ?? null,
60
+ date: v.startDate ?? v.date ?? null,
61
+ question: v.voteQuestion ?? v.question ?? null,
62
+ result: v.result ?? null,
63
+ voteType: v.voteType ?? null,
64
+ legislation: v.legislationType && v.legislationNumber
65
+ ? { type: v.legislationType, number: v.legislationNumber, url: v.legislationUrl }
66
+ : v.bill ? { type: v.bill.type, number: v.bill.number, title: v.bill.title } : null,
67
+ };
68
+ }
69
+ function summarizeLaw(l) {
70
+ return {
71
+ type: l.type ?? null,
72
+ number: l.number ?? null,
73
+ title: l.title ?? null,
74
+ signedDate: l.latestAction?.actionDate ?? null,
75
+ url: l.url ?? null,
76
+ };
77
+ }
78
+ function summarizeSponsoredBill(b) {
79
+ return {
80
+ type: b.type ?? null,
81
+ number: b.number ?? null,
82
+ title: b.title ?? null,
83
+ congress: b.congress ?? null,
84
+ introducedDate: b.introducedDate ?? null,
85
+ latestAction: b.latestAction ? { text: b.latestAction.text, date: b.latestAction.actionDate } : null,
86
+ };
87
+ }
88
+ // ─── Tools ───────────────────────────────────────────────────────────
89
+ export const tools = [
90
+ {
91
+ name: "congress_search_bills",
92
+ description: "Search for bills in Congress by keyword, congress number, or bill type. " +
93
+ "Returns bill number, title, sponsor, latest action, and status.\n\n" +
94
+ "Congress numbers: 118th (2023-2024), 119th (2025-2026), 117th (2021-2022).\n" +
95
+ "Bill types: hr (House), s (Senate), hjres, sjres, hconres, sconres, hres, sres",
96
+ annotations: { title: "Congress: Search Bills", readOnlyHint: true },
97
+ parameters: z.object({
98
+ query: z.string().optional().describe("Keyword/text search across bill titles and summaries (e.g., 'infrastructure', 'tax reform', 'climate')"),
99
+ congress: z.number().int().optional().describe("Congress number (e.g., 119 for 2025-2026, 118 for 2023-2024). Default: current"),
100
+ bill_type: z.string().optional().describe("Bill type: 'hr', 's', 'hjres', 'sjres', 'hconres', 'sconres', 'hres', 'sres'"),
101
+ limit: z.number().int().positive().max(250).optional().describe("Max results (default: 20)"),
102
+ offset: z.number().int().optional().describe("Results offset for pagination (default: 0)"),
103
+ }),
104
+ execute: async ({ query, congress, bill_type, limit, offset }) => {
105
+ const data = await searchBills({ query, congress, bill_type, limit, offset });
106
+ const bills = data.bills;
107
+ if (!bills.length) {
108
+ return JSON.stringify({ summary: query ? `No bills found matching "${query}".` : "No bills found.", bills: [] });
109
+ }
110
+ return JSON.stringify({
111
+ summary: `Bill search${query ? ` "${query}"` : ""}${congress ? ` (${congress}th Congress)` : ""}: ${bills.length} results`,
112
+ bills: bills.map(summarizeBill),
113
+ });
114
+ },
115
+ },
116
+ {
117
+ name: "congress_bill_details",
118
+ description: "Get detailed information about a specific bill including sponsors, cosponsors with party breakdown, " +
119
+ "actions, committees, and current status.",
120
+ annotations: { title: "Congress: Bill Details", readOnlyHint: true },
121
+ parameters: z.object({
122
+ congress: z.number().int().describe("Congress number (e.g., 119, 118, 117)"),
123
+ bill_type: z.string().describe("Bill type: 'hr', 's', 'hjres', 'sjres'"),
124
+ bill_number: z.number().int().describe("Bill number (e.g., 1, 25, 3076)"),
125
+ }),
126
+ execute: async ({ congress, bill_type, bill_number }) => {
127
+ const { bill, cosponsors, cosponsorPartyBreakdown } = await getBillDetails(congress, bill_type, bill_number);
128
+ const sponsors = bill.sponsors;
129
+ const sponsor = sponsors?.[0];
130
+ return JSON.stringify({
131
+ summary: `${bill.type ?? ""}${bill.number ?? ""}: ${bill.title ?? "No title"} (${congress}th Congress)`,
132
+ congress,
133
+ type: bill.type ?? null,
134
+ number: bill.number ?? null,
135
+ title: bill.title ?? null,
136
+ introducedDate: bill.introducedDate ?? null,
137
+ sponsor: sponsor ? {
138
+ name: `${sponsor.firstName ?? ""} ${sponsor.lastName ?? ""}`.trim(),
139
+ party: sponsor.party ?? null,
140
+ state: sponsor.state ?? null,
141
+ } : null,
142
+ cosponsors: {
143
+ total: cosponsors.length,
144
+ partyBreakdown: cosponsorPartyBreakdown,
145
+ },
146
+ policyArea: bill.policyArea?.name ?? null,
147
+ latestAction: bill.latestAction ? { text: bill.latestAction.text, date: bill.latestAction.actionDate } : null,
148
+ laws: bill.laws?.map(l => ({ type: l.type, number: l.number })) ?? [],
149
+ congressGovUrl: `https://www.congress.gov/bill/${congress}th-congress/${billTypeToUrlSegment(bill_type)}/${bill_number}`,
150
+ });
151
+ },
152
+ },
153
+ {
154
+ name: "congress_search_members",
155
+ description: "Search for members of Congress by state, congress number, or get all current members.",
156
+ annotations: { title: "Congress: Search Members", readOnlyHint: true },
157
+ parameters: z.object({
158
+ congress: z.number().int().optional().describe("Congress number (default: current)"),
159
+ state: z.string().optional().describe("Two-letter state code to filter by, e.g. 'CA', 'TX'"),
160
+ district: z.number().int().optional().describe("House district number (use with state)"),
161
+ limit: z.number().int().positive().max(250).optional().describe("Max results (default: 50)"),
162
+ }),
163
+ execute: async ({ congress, state, district, limit }) => {
164
+ const data = await searchMembers({ congress, state, district, limit });
165
+ const members = data.members;
166
+ if (!members.length) {
167
+ return JSON.stringify({ summary: "No members found.", members: [] });
168
+ }
169
+ return JSON.stringify({
170
+ summary: `Members of Congress: ${members.length} results${state ? ` (${state.toUpperCase()})` : ""}`,
171
+ members: members.map(summarizeMember),
172
+ });
173
+ },
174
+ },
175
+ {
176
+ name: "congress_house_votes",
177
+ description: "Get House of Representatives roll call vote results with member-level party breakdown. " +
178
+ "Primary source: Congress.gov API (118th-119th Congress); falls back to clerk.house.gov XML for older congresses. " +
179
+ "Coverage: 1990 to present. Use year param for historical votes. " +
180
+ "Cross-reference with: congress_senate_votes (same bill's Senate vote), FEC (congress_member donors via fec_candidate_financials), " +
181
+ "lobbying_search (who lobbied on the bill), FRED (economic impact 1-3 years after passage). " +
182
+ "For Senate votes, use congress_senate_votes.",
183
+ annotations: { title: "Congress: House Roll Call Votes", readOnlyHint: true },
184
+ parameters: z.object({
185
+ congress: z.number().int().optional().describe("Congress number (default: current). Used with session to determine year."),
186
+ session: z.number().int().optional().describe("Session (1 or 2). Default: current session"),
187
+ year: z.number().int().optional().describe("Calendar year (e.g. 2024). Overrides congress+session if provided."),
188
+ vote_number: z.number().int().optional().describe("Specific roll call vote number. Omit to list recent votes."),
189
+ limit: z.number().int().positive().max(250).optional().describe("Max results when listing votes (default: 20)"),
190
+ }),
191
+ execute: async ({ congress, session, year, vote_number, limit }) => {
192
+ const data = await getHouseVotes({ congress, session, year, vote_number, limit });
193
+ const congressNum = congress ?? currentCongress();
194
+ // Specific vote with member breakdown
195
+ if (data.members && data.partyTally) {
196
+ return JSON.stringify({
197
+ summary: `House Vote #${vote_number} (${congressNum}th Congress, Session ${session}): ${data.members.length} members voting`,
198
+ congress: congressNum,
199
+ session,
200
+ voteNumber: vote_number,
201
+ totalVoting: data.members.length,
202
+ partyBreakdown: data.partyTally,
203
+ });
204
+ }
205
+ // Specific vote without member breakdown (fallback)
206
+ if (data.vote) {
207
+ const v = data.vote;
208
+ return JSON.stringify({
209
+ summary: `House Vote #${vote_number} (${congressNum}th Congress): ${v.result ?? "Unknown result"}`,
210
+ congress: congressNum,
211
+ session,
212
+ voteNumber: vote_number,
213
+ question: v.question ?? null,
214
+ description: v.description ?? null,
215
+ result: v.result ?? null,
216
+ date: v.date ?? null,
217
+ bill: v.bill ? { type: v.bill.type, number: v.bill.number } : null,
218
+ });
219
+ }
220
+ // List of recent votes
221
+ const votes = data.votes ?? [];
222
+ if (!votes.length) {
223
+ return JSON.stringify({ summary: "No House votes found.", votes: [] });
224
+ }
225
+ return JSON.stringify({
226
+ summary: `House votes (${congressNum}th Congress${session ? `, Session ${session}` : ""}): ${votes.length} results`,
227
+ congress: congressNum,
228
+ votes: votes.map(summarizeVote),
229
+ });
230
+ },
231
+ },
232
+ {
233
+ name: "congress_senate_votes",
234
+ description: "Get Senate roll call vote results from senate.gov XML. " +
235
+ "Shows how senators voted by party on specific legislation, nominations, and procedural motions. " +
236
+ "Coverage: 101st Congress (1989) to present. " +
237
+ "Cross-reference with: congress_house_votes (same bill's House vote), FEC (senator donors via fec_candidate_financials), " +
238
+ "lobbying_search (who lobbied on the bill), congress_member_bills (senator's voting vs sponsoring patterns). " +
239
+ "For House votes, use congress_house_votes.",
240
+ annotations: { title: "Congress: Senate Roll Call Votes", readOnlyHint: true },
241
+ parameters: z.object({
242
+ congress: z.number().int().optional().describe("Congress number (default: current). Coverage: 101st (1989) to present"),
243
+ session: z.number().int().optional().describe("Session (1 or 2). Default: current session (1 for odd years, 2 for even)"),
244
+ vote_number: z.number().int().optional().describe("Specific roll call vote number. Omit to list recent votes."),
245
+ limit: z.number().int().positive().max(250).optional().describe("Max results when listing votes (default: 20)"),
246
+ }),
247
+ execute: async ({ congress, session, vote_number, limit }) => {
248
+ const data = await getSenateVotes({ congress, session, vote_number, limit });
249
+ const congressNum = congress ?? currentCongress();
250
+ const sessionNum = session ?? (new Date().getFullYear() % 2 === 1 ? 1 : 2);
251
+ // Specific vote with member breakdown
252
+ if (data.members && data.partyTally && data.vote) {
253
+ return JSON.stringify({
254
+ summary: `Senate Vote #${vote_number} (${congressNum}th Congress, Session ${sessionNum}): ${data.vote.result} — ${data.members.length} senators voting`,
255
+ congress: congressNum,
256
+ session: sessionNum,
257
+ voteNumber: vote_number,
258
+ question: data.vote.question,
259
+ result: data.vote.result,
260
+ title: data.vote.title,
261
+ date: data.vote.date,
262
+ majorityRequired: data.vote.majorityRequired,
263
+ count: data.vote.count,
264
+ document: data.vote.document ?? null,
265
+ tieBreaker: data.vote.tieBreaker ?? null,
266
+ totalVoting: data.members.length,
267
+ partyBreakdown: data.partyTally,
268
+ });
269
+ }
270
+ // List of recent votes
271
+ const votes = data.votes ?? [];
272
+ if (!votes.length) {
273
+ return JSON.stringify({ summary: "No Senate votes found.", votes: [] });
274
+ }
275
+ return JSON.stringify({
276
+ summary: `Senate votes (${congressNum}th Congress, Session ${sessionNum}): ${votes.length} results`,
277
+ congress: congressNum,
278
+ session: sessionNum,
279
+ votes: votes.map((v) => ({
280
+ voteNumber: v.voteNumber,
281
+ date: v.date,
282
+ question: v.question,
283
+ result: v.result,
284
+ title: v.title,
285
+ issue: v.description,
286
+ count: v.count,
287
+ })),
288
+ });
289
+ },
290
+ },
291
+ {
292
+ name: "congress_recent_laws",
293
+ description: "Get recently enacted laws (bills signed by the President). " +
294
+ "Shows what legislation has become law.",
295
+ annotations: { title: "Congress: Recent Laws", readOnlyHint: true },
296
+ parameters: z.object({
297
+ congress: z.number().int().optional().describe("Congress number (default: current)"),
298
+ limit: z.number().int().positive().max(250).optional().describe("Max results (default: 20)"),
299
+ }),
300
+ execute: async ({ congress, limit }) => {
301
+ const congressNum = congress ?? currentCongress();
302
+ const data = await getRecentLaws({ congress, limit });
303
+ const laws = data.laws;
304
+ if (!laws.length) {
305
+ return JSON.stringify({ summary: `No laws found for the ${congressNum}th Congress.`, laws: [] });
306
+ }
307
+ return JSON.stringify({
308
+ summary: `Laws enacted (${congressNum}th Congress): ${laws.length} results`,
309
+ congress: congressNum,
310
+ laws: laws.map(summarizeLaw),
311
+ });
312
+ },
313
+ },
314
+ {
315
+ name: "congress_member_bills",
316
+ description: "Get bills sponsored or cosponsored by a specific member of Congress. " +
317
+ "Requires the member's BioGuide ID (use congress_search_members to find it).",
318
+ annotations: { title: "Congress: Member's Sponsored Bills", readOnlyHint: true },
319
+ parameters: z.object({
320
+ bioguide_id: z.string().describe("Member's BioGuide ID (e.g., 'S000033' for Bernie Sanders, 'C001098' for Ted Cruz)"),
321
+ type: z.string().optional().describe("'sponsored' (default) or 'cosponsored'"),
322
+ limit: z.number().int().positive().max(250).optional().describe("Max results (default: 20)"),
323
+ }),
324
+ execute: async ({ bioguide_id, type, limit }) => {
325
+ const legType = (type === "cosponsored" ? "cosponsored" : "sponsored");
326
+ const data = await getMemberBills(bioguide_id, legType, limit ?? 20);
327
+ const bills = data.bills;
328
+ if (!bills.length) {
329
+ return JSON.stringify({ summary: `No ${legType} legislation found for member ${bioguide_id}.`, bioguideId: bioguide_id, bills: [] });
330
+ }
331
+ return JSON.stringify({
332
+ summary: `${legType === "cosponsored" ? "Cosponsored" : "Sponsored"} legislation for ${bioguide_id}: ${bills.length} results`,
333
+ bioguideId: bioguide_id,
334
+ type: legType,
335
+ bills: bills.map(summarizeSponsoredBill),
336
+ });
337
+ },
338
+ },
339
+ // ─── Bill Sub-resource Tools ─────────────────────────────────────
340
+ {
341
+ name: "congress_bill_actions",
342
+ description: "Get the full action history / timeline for a bill — every step from introduction through committee, " +
343
+ "floor votes, amendments, and signing. Shows recorded roll-call vote numbers when available.\n\n" +
344
+ "Use congress_search_bills first to find the congress number, bill type, and bill number.",
345
+ annotations: { title: "Congress: Bill Actions/Timeline", readOnlyHint: true },
346
+ parameters: z.object({
347
+ congress: z.number().int().describe("Congress number (e.g., 118)"),
348
+ bill_type: z.string().describe("Bill type: 'hr', 's', 'hjres', 'sjres', etc."),
349
+ bill_number: z.number().int().describe("Bill number"),
350
+ limit: z.number().int().positive().max(250).optional().describe("Max actions to return (default: 100)"),
351
+ }),
352
+ execute: async ({ congress, bill_type, bill_number, limit }) => {
353
+ const data = await getBillActions(congress, billTypeToUrlSegment(bill_type), bill_number, limit ?? 100);
354
+ if (!data.actions.length) {
355
+ return JSON.stringify({ summary: `No actions found for ${bill_type.toUpperCase()} ${bill_number} (${congress}th Congress).`, actions: [] });
356
+ }
357
+ return JSON.stringify({
358
+ summary: `${bill_type.toUpperCase()} ${bill_number} (${congress}th Congress): ${data.actions.length} actions`,
359
+ actions: data.actions.map(a => ({
360
+ date: a.actionDate ?? null,
361
+ text: a.text ?? null,
362
+ type: a.type ?? null,
363
+ actionCode: a.actionCode ?? null,
364
+ sourceSystem: a.sourceSystem?.name ?? null,
365
+ committees: a.committees?.map(c => c.name) ?? null,
366
+ recordedVotes: a.recordedVotes?.map(rv => ({ rollNumber: rv.rollNumber, chamber: rv.chamber, date: rv.date })) ?? null,
367
+ })),
368
+ });
369
+ },
370
+ },
371
+ {
372
+ name: "congress_bill_amendments",
373
+ description: "Get amendments filed on a specific bill. Shows amendment sponsors, " +
374
+ "purposes, and status. Critical for tracking how bills are modified (e.g., 'gutted and replaced').",
375
+ annotations: { title: "Congress: Bill Amendments", readOnlyHint: true },
376
+ parameters: z.object({
377
+ congress: z.number().int().describe("Congress number"),
378
+ bill_type: z.string().describe("Bill type: 'hr', 's', 'hjres', 'sjres', etc."),
379
+ bill_number: z.number().int().describe("Bill number"),
380
+ limit: z.number().int().positive().max(250).optional().describe("Max results (default: 50)"),
381
+ }),
382
+ execute: async ({ congress, bill_type, bill_number, limit }) => {
383
+ const data = await getBillAmendments(congress, billTypeToUrlSegment(bill_type), bill_number, limit ?? 50);
384
+ if (!data.amendments.length) {
385
+ return JSON.stringify({ summary: `No amendments found for ${bill_type.toUpperCase()} ${bill_number} (${congress}th Congress).`, amendments: [] });
386
+ }
387
+ return JSON.stringify({
388
+ summary: `${bill_type.toUpperCase()} ${bill_number} (${congress}th Congress): ${data.amendments.length} amendments`,
389
+ amendments: data.amendments.map(a => ({
390
+ number: a.number ?? null,
391
+ type: a.type ?? null,
392
+ congress: a.congress ?? null,
393
+ description: a.description ?? null,
394
+ purpose: a.purpose ?? null,
395
+ sponsor: a.sponsor ? { name: `${a.sponsor.firstName ?? ""} ${a.sponsor.lastName ?? ""}`.trim(), party: a.sponsor.party, state: a.sponsor.state, bioguideId: a.sponsor.bioguideId } : null,
396
+ latestAction: a.latestAction ? { text: a.latestAction.text, date: a.latestAction.actionDate } : null,
397
+ })),
398
+ });
399
+ },
400
+ },
401
+ {
402
+ name: "congress_bill_summaries",
403
+ description: "Get CRS (Congressional Research Service) summaries of a bill. " +
404
+ "These are plain-English, non-partisan summaries written by CRS analysts. " +
405
+ "Multiple versions may exist (as introduced, as reported, as passed).",
406
+ annotations: { title: "Congress: Bill Summaries", readOnlyHint: true },
407
+ parameters: z.object({
408
+ congress: z.number().int().describe("Congress number"),
409
+ bill_type: z.string().describe("Bill type: 'hr', 's', etc."),
410
+ bill_number: z.number().int().describe("Bill number"),
411
+ }),
412
+ execute: async ({ congress, bill_type, bill_number }) => {
413
+ const data = await getBillSummaries(congress, billTypeToUrlSegment(bill_type), bill_number);
414
+ if (!data.summaries.length) {
415
+ return JSON.stringify({ summary: `No CRS summaries available for ${bill_type.toUpperCase()} ${bill_number} (${congress}th Congress).`, summaries: [] });
416
+ }
417
+ return JSON.stringify({
418
+ summary: `${bill_type.toUpperCase()} ${bill_number} (${congress}th Congress): ${data.summaries.length} CRS summaries`,
419
+ summaries: data.summaries.map(s => ({
420
+ versionCode: s.versionCode ?? null,
421
+ actionDate: s.actionDate ?? null,
422
+ actionDesc: s.actionDesc ?? null,
423
+ text: s.text ?? null,
424
+ updateDate: s.updateDate ?? null,
425
+ })),
426
+ });
427
+ },
428
+ },
429
+ {
430
+ name: "congress_bill_text",
431
+ description: "Get available text versions for a bill (e.g., introduced, reported, engrossed, enrolled). " +
432
+ "Returns version types and format URLs. For full bill text content, use govinfo_bill_text.",
433
+ annotations: { title: "Congress: Bill Text Versions", readOnlyHint: true },
434
+ parameters: z.object({
435
+ congress: z.number().int().describe("Congress number"),
436
+ bill_type: z.string().describe("Bill type: 'hr', 's', etc."),
437
+ bill_number: z.number().int().describe("Bill number"),
438
+ }),
439
+ execute: async ({ congress, bill_type, bill_number }) => {
440
+ const data = await getBillTextVersions(congress, billTypeToUrlSegment(bill_type), bill_number);
441
+ if (!data.textVersions.length) {
442
+ return JSON.stringify({ summary: `No text versions found for ${bill_type.toUpperCase()} ${bill_number} (${congress}th Congress).`, textVersions: [] });
443
+ }
444
+ return JSON.stringify({
445
+ summary: `${bill_type.toUpperCase()} ${bill_number} (${congress}th Congress): ${data.textVersions.length} text versions`,
446
+ textVersions: data.textVersions.map(t => ({
447
+ type: t.type ?? null,
448
+ date: t.date ?? null,
449
+ formats: t.formats?.map(f => ({ type: f.type, url: f.url })) ?? null,
450
+ })),
451
+ });
452
+ },
453
+ },
454
+ {
455
+ name: "congress_bill_related",
456
+ description: "Find related/companion bills. Identifies House-Senate companion bills, " +
457
+ "identical bills, and bills with related provisions. Useful for tracking legislation across chambers.",
458
+ annotations: { title: "Congress: Related Bills", readOnlyHint: true },
459
+ parameters: z.object({
460
+ congress: z.number().int().describe("Congress number"),
461
+ bill_type: z.string().describe("Bill type: 'hr', 's', etc."),
462
+ bill_number: z.number().int().describe("Bill number"),
463
+ limit: z.number().int().positive().max(250).optional().describe("Max results (default: 50)"),
464
+ }),
465
+ execute: async ({ congress, bill_type, bill_number, limit }) => {
466
+ const data = await getBillRelatedBills(congress, billTypeToUrlSegment(bill_type), bill_number, limit ?? 50);
467
+ if (!data.relatedBills.length) {
468
+ return JSON.stringify({ summary: `No related bills found for ${bill_type.toUpperCase()} ${bill_number} (${congress}th Congress).`, relatedBills: [] });
469
+ }
470
+ return JSON.stringify({
471
+ summary: `${bill_type.toUpperCase()} ${bill_number} (${congress}th Congress): ${data.relatedBills.length} related bills`,
472
+ relatedBills: data.relatedBills.map(r => ({
473
+ type: r.type ?? null,
474
+ number: r.number ?? null,
475
+ congress: r.congress ?? null,
476
+ title: r.title ?? null,
477
+ relationship: r.relationshipDetails?.map(rd => rd.type) ?? null,
478
+ latestAction: r.latestAction ? { text: r.latestAction.text, date: r.latestAction.actionDate } : null,
479
+ })),
480
+ });
481
+ },
482
+ },
483
+ {
484
+ name: "congress_bill_subjects",
485
+ description: "Get legislative subjects tagged on a bill, plus the primary policy area. " +
486
+ "Useful for finding all bills on a topic and for cross-referencing with lobbying data.",
487
+ annotations: { title: "Congress: Bill Subjects", readOnlyHint: true },
488
+ parameters: z.object({
489
+ congress: z.number().int().describe("Congress number"),
490
+ bill_type: z.string().describe("Bill type: 'hr', 's', etc."),
491
+ bill_number: z.number().int().describe("Bill number"),
492
+ limit: z.number().int().positive().max(250).optional().describe("Max results (default: 100)"),
493
+ }),
494
+ execute: async ({ congress, bill_type, bill_number, limit }) => {
495
+ const data = await getBillSubjects(congress, billTypeToUrlSegment(bill_type), bill_number, limit ?? 100);
496
+ return JSON.stringify({
497
+ summary: `${bill_type.toUpperCase()} ${bill_number} (${congress}th Congress): ${data.subjects.length} subjects${data.policyArea ? `, policy area: ${data.policyArea}` : ""}`,
498
+ policyArea: data.policyArea ?? null,
499
+ subjects: data.subjects.map(s => s.name),
500
+ });
501
+ },
502
+ },
503
+ {
504
+ name: "congress_bill_committees",
505
+ description: "Get committees a bill was referred to, with activity dates. " +
506
+ "Shows which committees had jurisdiction and what actions they took (referral, hearings, markup, reporting).",
507
+ annotations: { title: "Congress: Bill Committees", readOnlyHint: true },
508
+ parameters: z.object({
509
+ congress: z.number().int().describe("Congress number"),
510
+ bill_type: z.string().describe("Bill type: 'hr', 's', etc."),
511
+ bill_number: z.number().int().describe("Bill number"),
512
+ }),
513
+ execute: async ({ congress, bill_type, bill_number }) => {
514
+ const data = await getBillCommittees(congress, billTypeToUrlSegment(bill_type), bill_number);
515
+ if (!data.committees.length) {
516
+ return JSON.stringify({ summary: `No committee data for ${bill_type.toUpperCase()} ${bill_number} (${congress}th Congress).`, committees: [] });
517
+ }
518
+ return JSON.stringify({
519
+ summary: `${bill_type.toUpperCase()} ${bill_number} (${congress}th Congress): referred to ${data.committees.length} committees`,
520
+ committees: data.committees.map(c => ({
521
+ name: c.name ?? null,
522
+ systemCode: c.systemCode ?? null,
523
+ chamber: c.chamber ?? null,
524
+ type: c.type ?? null,
525
+ activities: c.activities?.map(a => ({ name: a.name, date: a.date })) ?? null,
526
+ })),
527
+ });
528
+ },
529
+ },
530
+ // ─── Member Details ──────────────────────────────────────────────
531
+ {
532
+ name: "congress_member_details",
533
+ description: "Get detailed information about a specific member of Congress by BioGuide ID. " +
534
+ "Returns full bio, party history, all terms served, committee assignments, photo URL, and official website.\n\n" +
535
+ "Use congress_search_members first to find the BioGuide ID.",
536
+ annotations: { title: "Congress: Member Details", readOnlyHint: true },
537
+ parameters: z.object({
538
+ bioguide_id: z.string().describe("BioGuide ID (e.g., 'P000197' for Pelosi, 'M000355' for McConnell)"),
539
+ }),
540
+ execute: async ({ bioguide_id }) => {
541
+ const data = await getMemberDetails(bioguide_id);
542
+ const m = data.member;
543
+ return JSON.stringify({
544
+ summary: `${m.directOrderName ?? m.invertedOrderName ?? `${m.firstName} ${m.lastName}`} (${m.party ?? "Unknown"}-${m.state ?? "?"})`,
545
+ bioguideId: m.bioguideId ?? bioguide_id,
546
+ name: m.directOrderName ?? `${m.firstName ?? ""} ${m.lastName ?? ""}`.trim(),
547
+ party: m.party ?? null,
548
+ state: m.state ?? null,
549
+ birthYear: m.birthYear ?? null,
550
+ deathYear: m.deathYear ?? null,
551
+ currentMember: m.currentMember ?? null,
552
+ officialWebsiteUrl: m.officialWebsiteUrl ?? null,
553
+ depiction: m.depiction ?? null,
554
+ partyHistory: m.partyHistory ?? null,
555
+ terms: m.terms ?? null,
556
+ });
557
+ },
558
+ },
559
+ // ─── Committees ──────────────────────────────────────────────────
560
+ {
561
+ name: "congress_committees",
562
+ description: "List congressional committees. Filter by congress number and/or chamber (house, senate, joint). " +
563
+ "Returns committee name, system code, and chamber.",
564
+ annotations: { title: "Congress: List Committees", readOnlyHint: true },
565
+ parameters: z.object({
566
+ congress: z.number().int().optional().describe("Congress number (e.g., 119). Default: current"),
567
+ chamber: z.string().optional().describe("Chamber: 'house', 'senate', or 'joint'"),
568
+ limit: z.number().int().positive().max(250).optional().describe("Max results (default: 50)"),
569
+ }),
570
+ execute: async ({ congress, chamber, limit }) => {
571
+ const data = await listCommittees({ congress, chamber, limit });
572
+ if (!data.committees.length) {
573
+ return JSON.stringify({ summary: "No committees found matching criteria.", committees: [] });
574
+ }
575
+ return JSON.stringify({
576
+ summary: `${data.committees.length} committees${congress ? ` (${congress}th Congress)` : ""}${chamber ? ` — ${chamber}` : ""}`,
577
+ committees: data.committees.map(c => ({
578
+ name: c.name ?? null,
579
+ systemCode: c.systemCode ?? null,
580
+ chamber: c.chamber ?? null,
581
+ type: c.type ?? null,
582
+ isCurrent: c.isCurrent ?? null,
583
+ subcommittees: c.subcommittees?.map(sc => sc.name) ?? null,
584
+ })),
585
+ });
586
+ },
587
+ },
588
+ {
589
+ name: "congress_committee_bills",
590
+ description: "Get bills referred to a specific committee. Use congress_committees to find the committee system code. " +
591
+ "Useful for tracking which bills die in committee vs. get reported out.",
592
+ annotations: { title: "Congress: Committee Bills", readOnlyHint: true },
593
+ parameters: z.object({
594
+ chamber: z.string().describe("Chamber: 'house', 'senate', or 'joint'"),
595
+ committee_code: z.string().describe("Committee system code (e.g., 'hsba00' for House Financial Services, 'ssfi00' for Senate Finance)"),
596
+ limit: z.number().int().positive().max(250).optional().describe("Max results (default: 20)"),
597
+ }),
598
+ execute: async ({ chamber, committee_code, limit }) => {
599
+ const data = await getCommitteeBills(chamber, committee_code, limit ?? 20);
600
+ if (!data.bills.length) {
601
+ return JSON.stringify({ summary: `No bills found for committee ${committee_code}.`, bills: [] });
602
+ }
603
+ return JSON.stringify({
604
+ summary: `${data.bills.length} bills referred to committee ${committee_code}`,
605
+ committee: committee_code,
606
+ bills: data.bills.map(summarizeBill),
607
+ });
608
+ },
609
+ },
610
+ // ─── Amendments ──────────────────────────────────────────────────
611
+ {
612
+ name: "congress_amendments",
613
+ description: "Search/list amendments by congress and optional type (hamdt = House, samdt = Senate, suamdt = Senate Unnumbered). " +
614
+ "Returns amendment number, type, sponsor, purpose, and status.",
615
+ annotations: { title: "Congress: Search Amendments", readOnlyHint: true },
616
+ parameters: z.object({
617
+ congress: z.number().int().optional().describe("Congress number (default: current)"),
618
+ amendment_type: z.string().optional().describe("Amendment type: 'hamdt' (House), 'samdt' (Senate), 'suamdt' (Senate Unnumbered)"),
619
+ limit: z.number().int().positive().max(250).optional().describe("Max results (default: 20)"),
620
+ }),
621
+ execute: async ({ congress, amendment_type, limit }) => {
622
+ const data = await searchAmendments({ congress, amendmentType: amendment_type, limit });
623
+ if (!data.amendments.length) {
624
+ return JSON.stringify({ summary: "No amendments found.", amendments: [] });
625
+ }
626
+ return JSON.stringify({
627
+ summary: `${data.amendments.length} amendments${congress ? ` (${congress}th Congress)` : ""}`,
628
+ amendments: data.amendments.map(a => ({
629
+ number: a.number ?? null,
630
+ type: a.type ?? null,
631
+ congress: a.congress ?? null,
632
+ description: a.description ?? null,
633
+ purpose: a.purpose ?? null,
634
+ latestAction: a.latestAction ? { text: a.latestAction.text, date: a.latestAction.actionDate } : null,
635
+ })),
636
+ });
637
+ },
638
+ },
639
+ {
640
+ name: "congress_amendment_details",
641
+ description: "Get detailed information about a specific amendment, including its actions/timeline. " +
642
+ "Requires congress number, amendment type (hamdt/samdt), and amendment number.",
643
+ annotations: { title: "Congress: Amendment Details", readOnlyHint: true },
644
+ parameters: z.object({
645
+ congress: z.number().int().describe("Congress number"),
646
+ amendment_type: z.string().describe("'hamdt' (House) or 'samdt' (Senate)"),
647
+ amendment_number: z.union([z.string(), z.number()]).describe("Amendment number"),
648
+ }),
649
+ execute: async ({ congress, amendment_type, amendment_number }) => {
650
+ const data = await getAmendmentDetails(congress, amendment_type, amendment_number);
651
+ const a = data.amendment;
652
+ return JSON.stringify({
653
+ summary: `${amendment_type.toUpperCase()} ${amendment_number} (${congress}th Congress)`,
654
+ amendment: {
655
+ number: a.number ?? null,
656
+ type: a.type ?? null,
657
+ congress: a.congress ?? null,
658
+ description: a.description ?? null,
659
+ purpose: a.purpose ?? null,
660
+ sponsor: a.sponsor ? { name: `${a.sponsor.firstName ?? ""} ${a.sponsor.lastName ?? ""}`.trim(), party: a.sponsor.party, state: a.sponsor.state, bioguideId: a.sponsor.bioguideId } : null,
661
+ latestAction: a.latestAction ? { text: a.latestAction.text, date: a.latestAction.actionDate } : null,
662
+ },
663
+ actions: data.actions.map(act => ({
664
+ date: act.actionDate ?? null,
665
+ text: act.text ?? null,
666
+ type: act.type ?? null,
667
+ })),
668
+ });
669
+ },
670
+ },
671
+ // ─── Nominations ─────────────────────────────────────────────────
672
+ {
673
+ name: "congress_nominations",
674
+ description: "List presidential nominations to federal offices (judges, cabinet, ambassadors, agency heads). " +
675
+ "Shows nominee name, position, organization, and confirmation status.",
676
+ annotations: { title: "Congress: Nominations", readOnlyHint: true },
677
+ parameters: z.object({
678
+ congress: z.number().int().optional().describe("Congress number (default: current)"),
679
+ limit: z.number().int().positive().max(250).optional().describe("Max results (default: 20)"),
680
+ }),
681
+ execute: async ({ congress, limit }) => {
682
+ const congressNum = congress ?? currentCongress();
683
+ const data = await listNominations({ congress, limit });
684
+ if (!data.nominations.length) {
685
+ return JSON.stringify({ summary: `No nominations found for ${congressNum}th Congress.`, nominations: [] });
686
+ }
687
+ return JSON.stringify({
688
+ summary: `${data.nominations.length} nominations (${congressNum}th Congress)`,
689
+ nominations: data.nominations.map(n => ({
690
+ number: n.number ?? null,
691
+ congress: n.congress ?? null,
692
+ description: n.description ?? null,
693
+ organization: n.organization ?? null,
694
+ receivedDate: n.receivedDate ?? null,
695
+ nominees: n.nominees ?? null,
696
+ latestAction: n.latestAction ? { text: n.latestAction.text, date: n.latestAction.actionDate } : null,
697
+ })),
698
+ });
699
+ },
700
+ },
701
+ {
702
+ name: "congress_nomination_details",
703
+ description: "Get detailed information about a specific presidential nomination, including all actions (committee referral, hearing, vote, confirmation/rejection).",
704
+ annotations: { title: "Congress: Nomination Details", readOnlyHint: true },
705
+ parameters: z.object({
706
+ congress: z.number().int().describe("Congress number"),
707
+ nomination_number: z.union([z.string(), z.number()]).describe("Nomination number (PN number)"),
708
+ }),
709
+ execute: async ({ congress, nomination_number }) => {
710
+ const data = await getNominationDetails(congress, nomination_number);
711
+ const n = data.nomination;
712
+ return JSON.stringify({
713
+ summary: `Nomination PN${nomination_number} (${congress}th Congress)`,
714
+ nomination: {
715
+ number: n.number ?? null,
716
+ congress: n.congress ?? null,
717
+ description: n.description ?? null,
718
+ organization: n.organization ?? null,
719
+ receivedDate: n.receivedDate ?? null,
720
+ nominees: n.nominees ?? null,
721
+ latestAction: n.latestAction ? { text: n.latestAction.text, date: n.latestAction.actionDate } : null,
722
+ },
723
+ actions: data.actions.map(a => ({
724
+ date: a.actionDate ?? null,
725
+ text: a.text ?? null,
726
+ type: a.type ?? null,
727
+ })),
728
+ });
729
+ },
730
+ },
731
+ // ─── Treaties ────────────────────────────────────────────────────
732
+ {
733
+ name: "congress_treaties",
734
+ description: "List treaties submitted to the Senate. Shows treaty topic, " +
735
+ "date transmitted, and ratification status.",
736
+ annotations: { title: "Congress: Treaties", readOnlyHint: true },
737
+ parameters: z.object({
738
+ congress: z.number().int().optional().describe("Congress number (default: all)"),
739
+ limit: z.number().int().positive().max(250).optional().describe("Max results (default: 20)"),
740
+ }),
741
+ execute: async ({ congress, limit }) => {
742
+ const data = await listTreaties({ congress, limit });
743
+ if (!data.treaties.length) {
744
+ return JSON.stringify({ summary: "No treaties found.", treaties: [] });
745
+ }
746
+ return JSON.stringify({
747
+ summary: `${data.treaties.length} treaties${congress ? ` (${congress}th Congress)` : ""}`,
748
+ treaties: data.treaties.map(t => ({
749
+ number: t.number ?? null,
750
+ suffix: t.suffix ?? null,
751
+ congress: t.congress ?? null,
752
+ topic: t.topic ?? null,
753
+ transmittedDate: t.transmittedDate ?? null,
754
+ inForceDate: t.inForceDate ?? null,
755
+ latestAction: t.latestAction ? { text: t.latestAction.text, date: t.latestAction.actionDate } : null,
756
+ })),
757
+ });
758
+ },
759
+ },
760
+ {
761
+ name: "congress_treaty_details",
762
+ description: "Get detailed information about a specific treaty, including all Senate actions (committee referral, hearings, ratification vote).",
763
+ annotations: { title: "Congress: Treaty Details", readOnlyHint: true },
764
+ parameters: z.object({
765
+ congress: z.number().int().describe("Congress in which the treaty was received"),
766
+ treaty_number: z.union([z.string(), z.number()]).describe("Treaty document number"),
767
+ }),
768
+ execute: async ({ congress, treaty_number }) => {
769
+ const data = await getTreatyDetails(congress, treaty_number);
770
+ const t = data.treaty;
771
+ return JSON.stringify({
772
+ summary: `Treaty Doc. ${treaty_number} (${congress}th Congress): ${t.topic ?? "No topic"}`,
773
+ treaty: {
774
+ number: t.number ?? null,
775
+ suffix: t.suffix ?? null,
776
+ congress: t.congress ?? null,
777
+ congressReceived: t.congressReceived ?? null,
778
+ topic: t.topic ?? null,
779
+ transmittedDate: t.transmittedDate ?? null,
780
+ inForceDate: t.inForceDate ?? null,
781
+ resolutionText: t.resolutionText ?? null,
782
+ latestAction: t.latestAction ? { text: t.latestAction.text, date: t.latestAction.actionDate } : null,
783
+ },
784
+ actions: data.actions.map(a => ({
785
+ date: a.actionDate ?? null,
786
+ text: a.text ?? null,
787
+ type: a.type ?? null,
788
+ })),
789
+ });
790
+ },
791
+ },
792
+ // ─── CRS Reports ─────────────────────────────────────────────────
793
+ {
794
+ name: "congress_crs_reports",
795
+ description: "Get Congressional Research Service reports — authoritative, nonpartisan analysis on legislative topics. " +
796
+ "CRS reports are considered the gold standard for policy research.",
797
+ annotations: { title: "Congress: CRS Reports", readOnlyHint: true },
798
+ parameters: z.object({
799
+ limit: z.number().int().positive().max(250).optional().describe("Max results (default: 20)"),
800
+ }),
801
+ execute: async ({ limit }) => {
802
+ const data = await searchCrsReports({ limit });
803
+ if (!data.reports.length) {
804
+ return JSON.stringify({ summary: "No CRS reports found.", reports: [] });
805
+ }
806
+ return JSON.stringify({
807
+ summary: `${data.reports.length} CRS reports`,
808
+ reports: data.reports.map(r => ({
809
+ reportNumber: r.reportNumber ?? null,
810
+ title: r.title ?? null,
811
+ type: r.type ?? null,
812
+ activeRecord: r.activeRecord ?? null,
813
+ })),
814
+ });
815
+ },
816
+ },
817
+ // ─── Congressional Record ────────────────────────────────────────
818
+ {
819
+ name: "congress_congressional_record",
820
+ description: "Get Congressional Record issues — the official daily record of debate, speeches, and proceedings in Congress. " +
821
+ "Filter by year, month, and day.",
822
+ annotations: { title: "Congress: Congressional Record", readOnlyHint: true },
823
+ parameters: z.object({
824
+ year: z.number().int().optional().describe("Year (e.g., 2024)"),
825
+ month: z.number().int().min(1).max(12).optional().describe("Month (1-12)"),
826
+ day: z.number().int().min(1).max(31).optional().describe("Day of month"),
827
+ limit: z.number().int().positive().max(250).optional().describe("Max results (default: 20)"),
828
+ }),
829
+ execute: async ({ year, month, day, limit }) => {
830
+ const data = await getCongressionalRecord({ year, month, day, limit });
831
+ if (!data.issues.length) {
832
+ return JSON.stringify({ summary: "No Congressional Record issues found.", issues: [] });
833
+ }
834
+ return JSON.stringify({
835
+ summary: `${data.issues.length} Congressional Record issues`,
836
+ issues: data.issues.map(i => ({
837
+ issueNumber: i.issueNumber ?? null,
838
+ volumeNumber: i.volumeNumber ?? null,
839
+ issueDate: i.issueDate ?? null,
840
+ congress: i.congress ?? null,
841
+ sessionNumber: i.sessionNumber ?? null,
842
+ url: i.url ?? null,
843
+ })),
844
+ });
845
+ },
846
+ },
847
+ ];
848
+ // ─── Re-export cache control from SDK ────────────────────────────────
849
+ export { clearCache } from "../sdk/congress.js";
850
+ // ─── Prompts (FastMCP InputPrompt type) ──────────────────────────────
851
+ export const prompts = [
852
+ {
853
+ name: "legislation_tracker",
854
+ description: "Track the status and details of a specific bill or recent legislation on a topic, with full cross-source analysis.",
855
+ arguments: [
856
+ { name: "topic", description: "Topic or bill name, e.g. 'CHIPS Act', 'border security', 'student loans'", required: true },
857
+ ],
858
+ load: async ({ topic }) => `Find and analyze legislation related to "${topic}".\n\n` +
859
+ `== LEGISLATION DETAILS ==\n` +
860
+ `1. Use congress_search_bills to find relevant bills (try current and recent congresses)\n` +
861
+ `2. For the most relevant bill(s), use congress_bill_details to get sponsors, cosponsors (with party breakdown), and status\n` +
862
+ `3. Use congress_bill_actions to see the full legislative timeline\n` +
863
+ `4. Use congress_bill_summaries for the CRS summary\n` +
864
+ `5. Use congress_bill_committees to see which committees handled the bill\n` +
865
+ `6. Check congress_bill_amendments to see if the bill was modified\n` +
866
+ `7. Use congress_bill_subjects to understand the policy areas\n` +
867
+ `8. Use congress_bill_related to find companion bills in the other chamber\n\n` +
868
+ `== VOTE ANALYSIS ==\n` +
869
+ `9. If the bill had a House vote, use congress_house_votes for party-line breakdown\n` +
870
+ `10. If the bill had a Senate vote, use congress_senate_votes for party-line breakdown\n` +
871
+ `11. Compare House and Senate votes to show bicameral alignment or divergence\n\n` +
872
+ `== CROSS-SOURCE CONNECTIONS ==\n` +
873
+ `12. If it became law, use congress_recent_laws to confirm\n` +
874
+ `13. Use lobbying_search to find who lobbied for/against this bill\n` +
875
+ `14. Use fec_search_candidates for top sponsors — check their top donors for potential connections\n` +
876
+ `15. If it affected spending, use usa_spending_over_time to see spending trends before/after\n` +
877
+ `16. Check Federal Register (fr_search_rules) for implementing regulations\n` +
878
+ `17. Use FRED series to check relevant economic indicators before and after passage\n\n` +
879
+ `Present a clear timeline: introduced → committee → floor vote → signed/vetoed.\n` +
880
+ `Always show party-line vote breakdown alongside donor/lobbying data for transparency.`,
881
+ },
882
+ ];
883
+ //# sourceMappingURL=congress.js.map