@cyanheads/congressgov-mcp-server 0.3.32 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +24 -3
- package/CLAUDE.md +24 -3
- package/Dockerfile +13 -0
- package/README.md +15 -4
- package/dist/config/server-config.d.ts +15 -0
- package/dist/config/server-config.d.ts.map +1 -1
- package/dist/config/server-config.js +65 -0
- package/dist/config/server-config.js.map +1 -1
- package/dist/index.js +30 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-bills.tool.d.ts +47 -0
- package/dist/mcp-server/tools/definitions/search-bills.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-bills.tool.js +99 -0
- package/dist/mcp-server/tools/definitions/search-bills.tool.js.map +1 -0
- package/dist/mcp-server/tools/format-helpers.d.ts +2 -0
- package/dist/mcp-server/tools/format-helpers.d.ts.map +1 -1
- package/dist/mcp-server/tools/format-helpers.js +31 -0
- package/dist/mcp-server/tools/format-helpers.js.map +1 -1
- package/dist/services/congress-mirror/congress-mirror-service.d.ts +45 -0
- package/dist/services/congress-mirror/congress-mirror-service.d.ts.map +1 -0
- package/dist/services/congress-mirror/congress-mirror-service.js +116 -0
- package/dist/services/congress-mirror/congress-mirror-service.js.map +1 -0
- package/dist/services/congress-mirror/ingest.d.ts +33 -0
- package/dist/services/congress-mirror/ingest.d.ts.map +1 -0
- package/dist/services/congress-mirror/ingest.js +179 -0
- package/dist/services/congress-mirror/ingest.js.map +1 -0
- package/dist/services/congress-mirror/normalize.d.ts +25 -0
- package/dist/services/congress-mirror/normalize.d.ts.map +1 -0
- package/dist/services/congress-mirror/normalize.js +47 -0
- package/dist/services/congress-mirror/normalize.js.map +1 -0
- package/dist/services/congress-mirror/schema.d.ts +19 -0
- package/dist/services/congress-mirror/schema.d.ts.map +1 -0
- package/dist/services/congress-mirror/schema.js +44 -0
- package/dist/services/congress-mirror/schema.js.map +1 -0
- package/dist/services/congress-mirror/types.d.ts +55 -0
- package/dist/services/congress-mirror/types.d.ts.map +1 -0
- package/dist/services/congress-mirror/types.js +9 -0
- package/dist/services/congress-mirror/types.js.map +1 -0
- package/package.json +30 -4
- package/scripts/_mirror-context.ts +30 -0
- package/scripts/congress-mirror-init.ts +23 -0
- package/scripts/congress-mirror-refresh.ts +24 -0
- package/scripts/congress-mirror-verify.ts +36 -0
- package/server.json +3 -3
package/AGENTS.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** congressgov-mcp-server
|
|
4
|
-
**Version:** 0.
|
|
4
|
+
**Version:** 0.4.0
|
|
5
5
|
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.10.10`
|
|
6
6
|
**Engines:** Bun ≥1.3.0, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/sdk` ^1.29.0
|
|
@@ -42,6 +42,10 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
42
42
|
|:--------|:---------|:------------|
|
|
43
43
|
| `CONGRESS_API_KEY` | No | Optional. Defaults to `DEMO_KEY` (30 req/hr). Own key from [api.data.gov](https://api.data.gov/signup/): 5,000 req/hr. |
|
|
44
44
|
| `CONGRESS_API_BASE_URL` | No | Defaults to `https://api.congress.gov/v3` |
|
|
45
|
+
| `CONGRESS_MIRROR_ENABLED` | No | Enable the local bill search mirror and `congressgov_search_bills`. Defaults to `false`. |
|
|
46
|
+
| `CONGRESS_MIRROR_PATH` | No | Filesystem path to the SQLite mirror index. Defaults to `.mirror/bills.sqlite3`. |
|
|
47
|
+
| `CONGRESS_MIRROR_REFRESH_CRON` | No | Cron schedule for the in-process mirror refresh (HTTP transport only). Unset runs `mirror:refresh` manually. |
|
|
48
|
+
| `CONGRESS_MIRROR_CONGRESSES` | No | Comma-separated congress numbers to mirror (e.g. `118,119`). Defaults to the current congress plus the prior one. |
|
|
45
49
|
|
|
46
50
|
---
|
|
47
51
|
|
|
@@ -60,7 +64,7 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
60
64
|
|
|
61
65
|
## MCP Surface
|
|
62
66
|
|
|
63
|
-
### Tools (
|
|
67
|
+
### Tools (11)
|
|
64
68
|
|
|
65
69
|
| Name | Description |
|
|
66
70
|
|:-----|:------------|
|
|
@@ -74,6 +78,7 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
74
78
|
| `congressgov_crs_reports` | Browse and retrieve nonpartisan CRS policy analysis reports |
|
|
75
79
|
| `congressgov_committee_reports` | Browse and retrieve committee reports accompanying legislation |
|
|
76
80
|
| `congressgov_daily_record` | Browse daily Congressional Record — floor speeches, debates, proceedings |
|
|
81
|
+
| `congressgov_search_bills` | Keyword-search bill titles/summaries via the opt-in local FTS mirror — off by default |
|
|
77
82
|
|
|
78
83
|
### Resources (5)
|
|
79
84
|
|
|
@@ -105,6 +110,12 @@ src/
|
|
|
105
110
|
congress-api/
|
|
106
111
|
congress-api-service.ts # API client — auth, pagination, rate limiting
|
|
107
112
|
types.ts # API response types
|
|
113
|
+
congress-mirror/
|
|
114
|
+
congress-mirror-service.ts # Mirror read path — FTS5 search, ready(), sync accessor
|
|
115
|
+
ingest.ts # Bill list + CRS summaries sync generator
|
|
116
|
+
normalize.ts # HTML→plain-text, FTS5 MATCH escaping
|
|
117
|
+
schema.ts # SQLite mirror store spec (bills table, FTS index)
|
|
118
|
+
types.ts # Mirror row, search filters, search page types
|
|
108
119
|
senate-lis/
|
|
109
120
|
senate-vote-service.ts # Senate LIS XML client — fetch, retry, not-found
|
|
110
121
|
parse.ts # pure XML → domain parsers (fast-xml-parser)
|
|
@@ -121,6 +132,7 @@ src/
|
|
|
121
132
|
crs-reports.tool.ts # congressgov_crs_reports
|
|
122
133
|
committee-reports.tool.ts # congressgov_committee_reports
|
|
123
134
|
daily-record.tool.ts # congressgov_daily_record
|
|
135
|
+
search-bills.tool.ts # congressgov_search_bills (opt-in — disabledTool() when the mirror is off)
|
|
124
136
|
resources/definitions/
|
|
125
137
|
current-congress.resource.ts # congress://current
|
|
126
138
|
bill-types.resource.ts # congress://bill-types
|
|
@@ -130,13 +142,18 @@ src/
|
|
|
130
142
|
prompts/definitions/
|
|
131
143
|
bill-analysis.prompt.ts # congressgov_bill_analysis
|
|
132
144
|
legislative-research.prompt.ts # congressgov_legislative_research
|
|
145
|
+
scripts/
|
|
146
|
+
_mirror-context.ts # Shared bootstrap for the mirror lifecycle CLI scripts
|
|
147
|
+
congress-mirror-init.ts # mirror:init — full out-of-band mirror build
|
|
148
|
+
congress-mirror-refresh.ts # mirror:refresh — incremental mirror refresh
|
|
149
|
+
congress-mirror-verify.ts # mirror:verify — readiness + integrity check
|
|
133
150
|
```
|
|
134
151
|
|
|
135
152
|
---
|
|
136
153
|
|
|
137
154
|
## Services
|
|
138
155
|
|
|
139
|
-
|
|
156
|
+
Three services. `CongressApiService` backs nine tools and the House branch of `congressgov_roll_votes`; `SenateVoteService` backs only the Senate branch of `congressgov_roll_votes` (the Congress.gov API exposes no Senate vote namespace); `CongressMirrorService` backs `congressgov_search_bills` only.
|
|
140
157
|
|
|
141
158
|
**`CongressApiService`** — wraps the Congress.gov REST API v3:
|
|
142
159
|
- API key via `X-Api-Key` header (never logged; kept out of the URL so it can't leak in upstream error messages)
|
|
@@ -151,6 +168,10 @@ Two services. `CongressApiService` backs nine tools and the House branch of `con
|
|
|
151
168
|
- The host returns HTTP 200 with an HTML page for unknown congress/session/vote, so "not found" is detected from the body, not the status code
|
|
152
169
|
- Party totals are derived from the roster (the feed publishes none)
|
|
153
170
|
|
|
171
|
+
**`CongressMirrorService`** — local SQLite FTS5 mirror of bill title + CRS summary text, backing `congressgov_search_bills` only:
|
|
172
|
+
- Opt-in via `CONGRESS_MIRROR_ENABLED` (off by default); built out-of-band via the `mirror:init`/`mirror:refresh` scripts, never on server startup
|
|
173
|
+
- No live-API fallback — ingests through the existing `CongressApiService`, and a mirror that hasn't finished its initial build returns an empty result with a notice, not an error
|
|
174
|
+
|
|
154
175
|
**Usage in tools:**
|
|
155
176
|
```ts
|
|
156
177
|
import { getCongressApi } from '@/services/congress-api/congress-api-service.js';
|
package/CLAUDE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** congressgov-mcp-server
|
|
4
|
-
**Version:** 0.
|
|
4
|
+
**Version:** 0.4.0
|
|
5
5
|
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.10.10`
|
|
6
6
|
**Engines:** Bun ≥1.3.0, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/sdk` ^1.29.0
|
|
@@ -42,6 +42,10 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
42
42
|
|:--------|:---------|:------------|
|
|
43
43
|
| `CONGRESS_API_KEY` | No | Optional. Defaults to `DEMO_KEY` (30 req/hr). Own key from [api.data.gov](https://api.data.gov/signup/): 5,000 req/hr. |
|
|
44
44
|
| `CONGRESS_API_BASE_URL` | No | Defaults to `https://api.congress.gov/v3` |
|
|
45
|
+
| `CONGRESS_MIRROR_ENABLED` | No | Enable the local bill search mirror and `congressgov_search_bills`. Defaults to `false`. |
|
|
46
|
+
| `CONGRESS_MIRROR_PATH` | No | Filesystem path to the SQLite mirror index. Defaults to `.mirror/bills.sqlite3`. |
|
|
47
|
+
| `CONGRESS_MIRROR_REFRESH_CRON` | No | Cron schedule for the in-process mirror refresh (HTTP transport only). Unset runs `mirror:refresh` manually. |
|
|
48
|
+
| `CONGRESS_MIRROR_CONGRESSES` | No | Comma-separated congress numbers to mirror (e.g. `118,119`). Defaults to the current congress plus the prior one. |
|
|
45
49
|
|
|
46
50
|
---
|
|
47
51
|
|
|
@@ -60,7 +64,7 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
60
64
|
|
|
61
65
|
## MCP Surface
|
|
62
66
|
|
|
63
|
-
### Tools (
|
|
67
|
+
### Tools (11)
|
|
64
68
|
|
|
65
69
|
| Name | Description |
|
|
66
70
|
|:-----|:------------|
|
|
@@ -74,6 +78,7 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
74
78
|
| `congressgov_crs_reports` | Browse and retrieve nonpartisan CRS policy analysis reports |
|
|
75
79
|
| `congressgov_committee_reports` | Browse and retrieve committee reports accompanying legislation |
|
|
76
80
|
| `congressgov_daily_record` | Browse daily Congressional Record — floor speeches, debates, proceedings |
|
|
81
|
+
| `congressgov_search_bills` | Keyword-search bill titles/summaries via the opt-in local FTS mirror — off by default |
|
|
77
82
|
|
|
78
83
|
### Resources (5)
|
|
79
84
|
|
|
@@ -105,6 +110,12 @@ src/
|
|
|
105
110
|
congress-api/
|
|
106
111
|
congress-api-service.ts # API client — auth, pagination, rate limiting
|
|
107
112
|
types.ts # API response types
|
|
113
|
+
congress-mirror/
|
|
114
|
+
congress-mirror-service.ts # Mirror read path — FTS5 search, ready(), sync accessor
|
|
115
|
+
ingest.ts # Bill list + CRS summaries sync generator
|
|
116
|
+
normalize.ts # HTML→plain-text, FTS5 MATCH escaping
|
|
117
|
+
schema.ts # SQLite mirror store spec (bills table, FTS index)
|
|
118
|
+
types.ts # Mirror row, search filters, search page types
|
|
108
119
|
senate-lis/
|
|
109
120
|
senate-vote-service.ts # Senate LIS XML client — fetch, retry, not-found
|
|
110
121
|
parse.ts # pure XML → domain parsers (fast-xml-parser)
|
|
@@ -121,6 +132,7 @@ src/
|
|
|
121
132
|
crs-reports.tool.ts # congressgov_crs_reports
|
|
122
133
|
committee-reports.tool.ts # congressgov_committee_reports
|
|
123
134
|
daily-record.tool.ts # congressgov_daily_record
|
|
135
|
+
search-bills.tool.ts # congressgov_search_bills (opt-in — disabledTool() when the mirror is off)
|
|
124
136
|
resources/definitions/
|
|
125
137
|
current-congress.resource.ts # congress://current
|
|
126
138
|
bill-types.resource.ts # congress://bill-types
|
|
@@ -130,13 +142,18 @@ src/
|
|
|
130
142
|
prompts/definitions/
|
|
131
143
|
bill-analysis.prompt.ts # congressgov_bill_analysis
|
|
132
144
|
legislative-research.prompt.ts # congressgov_legislative_research
|
|
145
|
+
scripts/
|
|
146
|
+
_mirror-context.ts # Shared bootstrap for the mirror lifecycle CLI scripts
|
|
147
|
+
congress-mirror-init.ts # mirror:init — full out-of-band mirror build
|
|
148
|
+
congress-mirror-refresh.ts # mirror:refresh — incremental mirror refresh
|
|
149
|
+
congress-mirror-verify.ts # mirror:verify — readiness + integrity check
|
|
133
150
|
```
|
|
134
151
|
|
|
135
152
|
---
|
|
136
153
|
|
|
137
154
|
## Services
|
|
138
155
|
|
|
139
|
-
|
|
156
|
+
Three services. `CongressApiService` backs nine tools and the House branch of `congressgov_roll_votes`; `SenateVoteService` backs only the Senate branch of `congressgov_roll_votes` (the Congress.gov API exposes no Senate vote namespace); `CongressMirrorService` backs `congressgov_search_bills` only.
|
|
140
157
|
|
|
141
158
|
**`CongressApiService`** — wraps the Congress.gov REST API v3:
|
|
142
159
|
- API key via `X-Api-Key` header (never logged; kept out of the URL so it can't leak in upstream error messages)
|
|
@@ -151,6 +168,10 @@ Two services. `CongressApiService` backs nine tools and the House branch of `con
|
|
|
151
168
|
- The host returns HTTP 200 with an HTML page for unknown congress/session/vote, so "not found" is detected from the body, not the status code
|
|
152
169
|
- Party totals are derived from the roster (the feed publishes none)
|
|
153
170
|
|
|
171
|
+
**`CongressMirrorService`** — local SQLite FTS5 mirror of bill title + CRS summary text, backing `congressgov_search_bills` only:
|
|
172
|
+
- Opt-in via `CONGRESS_MIRROR_ENABLED` (off by default); built out-of-band via the `mirror:init`/`mirror:refresh` scripts, never on server startup
|
|
173
|
+
- No live-API fallback — ingests through the existing `CongressApiService`, and a mirror that hasn't finished its initial build returns an empty result with a notice, not an error
|
|
174
|
+
|
|
154
175
|
**Usage in tools:**
|
|
155
176
|
```ts
|
|
156
177
|
import { getCongressApi } from '@/services/congress-api/congress-api-service.js';
|
package/Dockerfile
CHANGED
|
@@ -71,6 +71,19 @@ RUN if [ "$OTEL_ENABLED" = "true" ]; then \
|
|
|
71
71
|
# Copy the compiled application code from the build stage
|
|
72
72
|
COPY --from=build /usr/src/app/dist ./dist
|
|
73
73
|
|
|
74
|
+
# Copy the mirror lifecycle scripts (mirror:init / mirror:refresh / mirror:verify)
|
|
75
|
+
# and the shared context shim they import, then emit a runtime tsconfig so Bun
|
|
76
|
+
# resolves the @/ path alias against the compiled ./dist (the source ./src never
|
|
77
|
+
# reaches the runtime image). Same `bun run mirror:*` commands work in dev and the
|
|
78
|
+
# image; run `docker exec <container> bun run mirror:init` to build the index.
|
|
79
|
+
# See the api-mirror skill for the full recipe.
|
|
80
|
+
COPY --from=build /usr/src/app/scripts/congress-mirror-init.ts \
|
|
81
|
+
/usr/src/app/scripts/congress-mirror-refresh.ts \
|
|
82
|
+
/usr/src/app/scripts/congress-mirror-verify.ts \
|
|
83
|
+
/usr/src/app/scripts/_mirror-context.ts \
|
|
84
|
+
./scripts/
|
|
85
|
+
RUN echo '{"compilerOptions":{"baseUrl":".","paths":{"@/*":["./dist/*"]}}}' > tsconfig.json
|
|
86
|
+
|
|
74
87
|
# The 'oven/bun' image already provides a non-root user named 'bun'.
|
|
75
88
|
# We will use this existing user for enhanced security.
|
|
76
89
|
|
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<h1>@cyanheads/congressgov-mcp-server</h1>
|
|
3
3
|
<p><b>Access U.S. congressional data - bills, votes, members, committees - through MCP. STDIO & Streamable HTTP.</b>
|
|
4
|
-
<div>
|
|
4
|
+
<div>11 Tools • 5 Resources • 2 Prompts</div>
|
|
5
5
|
</p>
|
|
6
6
|
</div>
|
|
7
7
|
|
|
8
8
|
<div align="center">
|
|
9
9
|
|
|
10
|
-
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/congressgov-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/congressgov-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
13
|
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
## Tools
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
Eleven read-only tools for querying U.S. legislative data:
|
|
33
33
|
|
|
34
34
|
| Tool | Description |
|
|
35
35
|
|:---|:---|
|
|
@@ -43,6 +43,7 @@ Ten read-only tools for querying U.S. legislative data:
|
|
|
43
43
|
| `congressgov_crs_reports` | Browse and retrieve nonpartisan CRS policy analysis reports |
|
|
44
44
|
| `congressgov_committee_reports` | Browse and retrieve committee reports accompanying legislation |
|
|
45
45
|
| `congressgov_daily_record` | Browse the daily Congressional Record — floor speeches, debates, and proceedings |
|
|
46
|
+
| `congressgov_search_bills` | Keyword-search bill titles and CRS summaries via a local full-text mirror (opt-in, off by default) |
|
|
46
47
|
|
|
47
48
|
### `congressgov_bill_lookup`
|
|
48
49
|
|
|
@@ -112,6 +113,16 @@ Browse the daily Congressional Record — floor speeches, debates, and legislati
|
|
|
112
113
|
- Browse volumes by congress number
|
|
113
114
|
- Retrieve specific issue articles
|
|
114
115
|
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
### `congressgov_search_bills`
|
|
119
|
+
|
|
120
|
+
Keyword-search bill titles and CRS summaries against a local full-text mirror — the discovery path the Congress.gov API itself lacks.
|
|
121
|
+
|
|
122
|
+
- **Opt-in:** off by default. Requires `CONGRESS_MIRROR_ENABLED=true` and a locally built index (`bun run mirror:init`) — until then the tool is visible but not callable
|
|
123
|
+
- Narrow with `congress`, `billType`, and `originChamber` filters
|
|
124
|
+
- Returns BM25-ranked matches with each bill's derived id, ready for a follow-up `congressgov_bill_lookup` call
|
|
125
|
+
|
|
115
126
|
## Resources
|
|
116
127
|
|
|
117
128
|
| URI Pattern | Description |
|
|
@@ -271,7 +282,7 @@ docker run -e CONGRESS_API_KEY=your-api-key -p 3010:3010 congressgov-mcp-server
|
|
|
271
282
|
|
|
272
283
|
| Directory | Purpose |
|
|
273
284
|
|:---|:---|
|
|
274
|
-
| `src/mcp-server/tools/definitions/` | Tool definitions (`*.tool.ts`).
|
|
285
|
+
| `src/mcp-server/tools/definitions/` | Tool definitions (`*.tool.ts`). Eleven Congress.gov tools. |
|
|
275
286
|
| `src/mcp-server/resources/definitions/` | Resource definitions. Congress, bill, member, and committee resources. |
|
|
276
287
|
| `src/mcp-server/prompts/definitions/` | Prompt definitions. Bill analysis and legislative research prompts. |
|
|
277
288
|
| `src/services/congress-api/` | Congress.gov API client — auth, pagination, rate limiting. |
|
|
@@ -3,11 +3,26 @@
|
|
|
3
3
|
* @module config/server-config
|
|
4
4
|
*/
|
|
5
5
|
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
/** Default on-disk location of the SQLite bill FTS mirror. */
|
|
7
|
+
export declare const DEFAULT_MIRROR_PATH = ".mirror/bills.sqlite3";
|
|
8
|
+
/**
|
|
9
|
+
* Congress number covering a given date. The 1st U.S. Congress convened in 1789
|
|
10
|
+
* and each Congress spans two years, so `floor((year - 1789) / 2) + 1` yields the
|
|
11
|
+
* ordinal (2025–2026 → 119). Used to seed the default mirror window when
|
|
12
|
+
* `CONGRESS_MIRROR_CONGRESSES` is unset.
|
|
13
|
+
*/
|
|
14
|
+
export declare function currentCongressNumber(date?: Date): number;
|
|
6
15
|
declare const ServerConfigSchema: z.ZodObject<{
|
|
7
16
|
apiKey: z.ZodDefault<z.ZodString>;
|
|
8
17
|
baseUrl: z.ZodDefault<z.ZodString>;
|
|
18
|
+
mirrorEnabled: z.ZodPreprocess<z.ZodCodec<z.ZodString, z.ZodBoolean>>;
|
|
19
|
+
mirrorPath: z.ZodDefault<z.ZodString>;
|
|
20
|
+
mirrorRefreshCron: z.ZodPreprocess<z.ZodOptional<z.ZodString>>;
|
|
21
|
+
congresses: z.ZodPreprocess<z.ZodArray<z.ZodNumber>>;
|
|
9
22
|
}, z.core.$strip>;
|
|
10
23
|
export type ServerConfig = z.infer<typeof ServerConfigSchema>;
|
|
11
24
|
export declare function getServerConfig(): ServerConfig;
|
|
25
|
+
/** Reset the cached config — test-only. */
|
|
26
|
+
export declare function resetServerConfig(): void;
|
|
12
27
|
export {};
|
|
13
28
|
//# sourceMappingURL=server-config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAG3C,QAAA,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAG3C,8DAA8D;AAC9D,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAE3D;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,GAAE,IAAiB,GAAG,MAAM,CAErE;AAoBD,QAAA,MAAM,kBAAkB;;;;;;;iBA0CtB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D,wBAAgB,eAAe,IAAI,YAAY,CAU9C;AAED,2CAA2C;AAC3C,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
|
|
@@ -4,6 +4,34 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
6
|
import { parseEnvConfig } from '@cyanheads/mcp-ts-core/config';
|
|
7
|
+
/** Default on-disk location of the SQLite bill FTS mirror. */
|
|
8
|
+
export const DEFAULT_MIRROR_PATH = '.mirror/bills.sqlite3';
|
|
9
|
+
/**
|
|
10
|
+
* Congress number covering a given date. The 1st U.S. Congress convened in 1789
|
|
11
|
+
* and each Congress spans two years, so `floor((year - 1789) / 2) + 1` yields the
|
|
12
|
+
* ordinal (2025–2026 → 119). Used to seed the default mirror window when
|
|
13
|
+
* `CONGRESS_MIRROR_CONGRESSES` is unset.
|
|
14
|
+
*/
|
|
15
|
+
export function currentCongressNumber(date = new Date()) {
|
|
16
|
+
return Math.floor((date.getUTCFullYear() - 1789) / 2) + 1;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse `CONGRESS_MIRROR_CONGRESSES` — a comma-separated list of congress numbers
|
|
20
|
+
* ("118,119") — into a positive-integer array. Unset/empty falls back to the
|
|
21
|
+
* current congress plus the one prior (the realistic "what's this recent bill
|
|
22
|
+
* about" search window); a fully malformed value resolves to an empty array,
|
|
23
|
+
* which the `.min(1)` guard rejects loudly at startup.
|
|
24
|
+
*/
|
|
25
|
+
function parseCongresses(value) {
|
|
26
|
+
if (typeof value === 'string' && value.trim() !== '') {
|
|
27
|
+
return value
|
|
28
|
+
.split(',')
|
|
29
|
+
.map((s) => Number.parseInt(s.trim(), 10))
|
|
30
|
+
.filter((n) => Number.isInteger(n) && n > 0);
|
|
31
|
+
}
|
|
32
|
+
const current = currentCongressNumber();
|
|
33
|
+
return [current, current - 1];
|
|
34
|
+
}
|
|
7
35
|
const ServerConfigSchema = z.object({
|
|
8
36
|
apiKey: z
|
|
9
37
|
.string()
|
|
@@ -14,13 +42,50 @@ const ServerConfigSchema = z.object({
|
|
|
14
42
|
.url()
|
|
15
43
|
.default('https://api.congress.gov/v3')
|
|
16
44
|
.describe('Congress.gov API base URL'),
|
|
45
|
+
/**
|
|
46
|
+
* Master switch for the local bill FTS mirror + `congressgov_search_bills`.
|
|
47
|
+
* Off by default so the standard deploy stays config-free and the live-API
|
|
48
|
+
* tools are unaffected. Unset/empty/malformed resolves to `false`.
|
|
49
|
+
*/
|
|
50
|
+
mirrorEnabled: z
|
|
51
|
+
.preprocess((v) => (v === undefined || v === null || v === '' ? 'false' : v), z.stringbool())
|
|
52
|
+
.describe('Enable the local bill search mirror and the congressgov_search_bills tool.'),
|
|
53
|
+
/** Filesystem path to the SQLite mirror index file (matches the Dockerfile `.mirror` dir). */
|
|
54
|
+
mirrorPath: z
|
|
55
|
+
.string()
|
|
56
|
+
.min(1)
|
|
57
|
+
.default(DEFAULT_MIRROR_PATH)
|
|
58
|
+
.describe('Filesystem path to the SQLite bill mirror index.'),
|
|
59
|
+
/**
|
|
60
|
+
* Cron expression for the in-process incremental refresh (HTTP transport only).
|
|
61
|
+
* Unset means no in-process schedule — run `bun run mirror:refresh` out-of-band.
|
|
62
|
+
*/
|
|
63
|
+
mirrorRefreshCron: z
|
|
64
|
+
.preprocess((v) => (v === '' || v === null ? undefined : v), z.string().min(1).optional())
|
|
65
|
+
.describe('Cron schedule for the in-process mirror refresh (HTTP only; omit to run manually).'),
|
|
66
|
+
/**
|
|
67
|
+
* Congresses to mirror. Defaults to the current congress plus the one prior.
|
|
68
|
+
* Comma-separated env value (e.g. "118,119"); widening the window is a config
|
|
69
|
+
* change, not a redesign.
|
|
70
|
+
*/
|
|
71
|
+
congresses: z
|
|
72
|
+
.preprocess(parseCongresses, z.array(z.number().int().positive()).min(1))
|
|
73
|
+
.describe('Congress numbers included in the mirror (default: current + 1 prior).'),
|
|
17
74
|
});
|
|
18
75
|
let _config;
|
|
19
76
|
export function getServerConfig() {
|
|
20
77
|
_config ??= parseEnvConfig(ServerConfigSchema, {
|
|
21
78
|
apiKey: 'CONGRESS_API_KEY',
|
|
22
79
|
baseUrl: 'CONGRESS_API_BASE_URL',
|
|
80
|
+
mirrorEnabled: 'CONGRESS_MIRROR_ENABLED',
|
|
81
|
+
mirrorPath: 'CONGRESS_MIRROR_PATH',
|
|
82
|
+
mirrorRefreshCron: 'CONGRESS_MIRROR_REFRESH_CRON',
|
|
83
|
+
congresses: 'CONGRESS_MIRROR_CONGRESSES',
|
|
23
84
|
});
|
|
24
85
|
return _config;
|
|
25
86
|
}
|
|
87
|
+
/** Reset the cached config — test-only. */
|
|
88
|
+
export function resetServerConfig() {
|
|
89
|
+
_config = undefined;
|
|
90
|
+
}
|
|
26
91
|
//# sourceMappingURL=server-config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,OAAO,CAAC,UAAU,CAAC;SACnB,QAAQ,CACP,+FAA+F,CAChG;IACH,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,GAAG,EAAE;SACL,OAAO,CAAC,6BAA6B,CAAC;SACtC,QAAQ,CAAC,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"server-config.js","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* @module index
|
|
5
5
|
*/
|
|
6
6
|
import { createApp } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
import { logger, schedulerService } from '@cyanheads/mcp-ts-core/utils';
|
|
8
|
+
import { getServerConfig } from './config/server-config.js';
|
|
7
9
|
import { billAnalysisPrompt } from './mcp-server/prompts/definitions/bill-analysis.prompt.js';
|
|
8
10
|
import { legislativeResearchPrompt } from './mcp-server/prompts/definitions/legislative-research.prompt.js';
|
|
9
11
|
import { billResource } from './mcp-server/resources/definitions/bill.resource.js';
|
|
@@ -20,8 +22,10 @@ import { dailyRecordTool } from './mcp-server/tools/definitions/daily-record.too
|
|
|
20
22
|
import { enactedLawsTool } from './mcp-server/tools/definitions/enacted-laws.tool.js';
|
|
21
23
|
import { memberLookupTool } from './mcp-server/tools/definitions/member-lookup.tool.js';
|
|
22
24
|
import { rollVotesTool } from './mcp-server/tools/definitions/roll-votes.tool.js';
|
|
25
|
+
import { searchBillsTool } from './mcp-server/tools/definitions/search-bills.tool.js';
|
|
23
26
|
import { senateNominationsTool } from './mcp-server/tools/definitions/senate-nominations.tool.js';
|
|
24
27
|
import { initCongressApi } from './services/congress-api/congress-api-service.js';
|
|
28
|
+
import { getCongressMirror, initCongressMirror, } from './services/congress-mirror/congress-mirror-service.js';
|
|
25
29
|
import { initSenateVoteService } from './services/senate-lis/senate-vote-service.js';
|
|
26
30
|
const REPO_ROOT = 'https://github.com/cyanheads/congressgov-mcp-server';
|
|
27
31
|
/**
|
|
@@ -46,6 +50,7 @@ await createApp({
|
|
|
46
50
|
withSource(crsReportsTool, 'tools', 'crs-reports.tool.ts'),
|
|
47
51
|
withSource(committeeReportsTool, 'tools', 'committee-reports.tool.ts'),
|
|
48
52
|
withSource(dailyRecordTool, 'tools', 'daily-record.tool.ts'),
|
|
53
|
+
withSource(searchBillsTool, 'tools', 'search-bills.tool.ts'),
|
|
49
54
|
],
|
|
50
55
|
resources: [
|
|
51
56
|
withSource(currentCongressResource, 'resources', 'current-congress.resource.ts'),
|
|
@@ -58,15 +63,38 @@ await createApp({
|
|
|
58
63
|
withSource(billAnalysisPrompt, 'prompts', 'bill-analysis.prompt.ts'),
|
|
59
64
|
withSource(legislativeResearchPrompt, 'prompts', 'legislative-research.prompt.ts'),
|
|
60
65
|
],
|
|
61
|
-
instructions: `Use the congressgov_* tools to access U.S. legislative data via the Congress.gov API v3: bills, enacted laws, members, committees, roll call votes, presidential nominations, CRS reports, and the daily Congressional Record.
|
|
66
|
+
instructions: `Use the congressgov_* tools to access U.S. legislative data via the Congress.gov API v3: bills, enacted laws, members, committees, roll call votes, presidential nominations, CRS reports, and the daily Congressional Record. The Congress.gov API itself has no keyword search — browse by congress number, bill/report type, date range, chamber, state, and district. An optional local FTS mirror adds congressgov_search_bills (keyword search over bill titles and summaries) when CONGRESS_MIRROR_ENABLED is set; off by default, the tool is visible but not callable. Bills are addressed by congress + billType + billNumber (e.g. 118/hr/1234), members by bioguideId, committees by chamber-prefix codes. congressgov_roll_votes serves both chambers via its 'chamber' parameter — House votes come from the Congress.gov API, Senate votes from the Senate's official LIS feed.`,
|
|
62
67
|
landing: {
|
|
63
68
|
repoRoot: REPO_ROOT,
|
|
64
69
|
tagline: 'U.S. legislative data — bills, votes, members, committees — via MCP.',
|
|
65
70
|
requireAuth: false,
|
|
66
71
|
},
|
|
67
|
-
setup() {
|
|
72
|
+
setup(core) {
|
|
68
73
|
initCongressApi();
|
|
69
74
|
initSenateVoteService();
|
|
75
|
+
/**
|
|
76
|
+
* The bill FTS mirror is opt-in (off by default). When enabled, wire the
|
|
77
|
+
* service; a full init runs out-of-band via `mirror:init` (never on startup).
|
|
78
|
+
* The in-process incremental refresh is scheduled only under HTTP transport
|
|
79
|
+
* (a long-lived process owns the cron) and only when a cron is configured —
|
|
80
|
+
* stdio operators run `mirror:refresh` out-of-band.
|
|
81
|
+
*/
|
|
82
|
+
const config = getServerConfig();
|
|
83
|
+
if (config.mirrorEnabled) {
|
|
84
|
+
initCongressMirror({ mirrorPath: config.mirrorPath, congresses: config.congresses });
|
|
85
|
+
if (core.config.mcpTransportType === 'http' && config.mirrorRefreshCron) {
|
|
86
|
+
void scheduleMirrorRefresh(config.mirrorRefreshCron);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
70
89
|
},
|
|
71
90
|
});
|
|
91
|
+
/** Register and start the in-process incremental mirror refresh job. */
|
|
92
|
+
async function scheduleMirrorRefresh(cron) {
|
|
93
|
+
await schedulerService.schedule('congress-bills-refresh', cron, async (jobCtx) => {
|
|
94
|
+
logger.info('Starting scheduled Congress bill mirror refresh', jobCtx);
|
|
95
|
+
const result = await getCongressMirror().mirrorInstance.runSync({ mode: 'refresh' });
|
|
96
|
+
logger.info(`Scheduled Congress bill mirror refresh complete: ${result.recordsApplied} records applied (total ${result.total})`, jobCtx);
|
|
97
|
+
}, 'Incremental refresh of the local Congress bill FTS mirror from Congress.gov.');
|
|
98
|
+
schedulerService.start('congress-bills-refresh');
|
|
99
|
+
}
|
|
72
100
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview congressgov_search_bills — keyword search over the local bill FTS
|
|
3
|
+
* mirror, the discovery path the Congress.gov API structurally lacks. Queries the
|
|
4
|
+
* embedded SQLite + FTS5 index (title + summary), not the live API, so it has no
|
|
5
|
+
* live fallback: a mirror that has not finished its initial build returns an empty
|
|
6
|
+
* result with an enrichment notice rather than a thrown error. Gated behind
|
|
7
|
+
* CONGRESS_MIRROR_ENABLED via disabledTool() — visible-but-uncallable when the
|
|
8
|
+
* mirror is off (the default).
|
|
9
|
+
* @module mcp-server/tools/definitions/search-bills
|
|
10
|
+
*/
|
|
11
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
12
|
+
/**
|
|
13
|
+
* Gated behind the mirror master switch. When the mirror is off (the default) the
|
|
14
|
+
* tool renders on the landing page as present-but-uncallable with a hint, and is
|
|
15
|
+
* skipped during MCP registration so clients can't call a guaranteed-empty search.
|
|
16
|
+
*/
|
|
17
|
+
export declare const searchBillsTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
18
|
+
query: z.ZodString;
|
|
19
|
+
congress: z.ZodOptional<z.ZodNumber>;
|
|
20
|
+
billType: z.ZodOptional<z.ZodEnum<{
|
|
21
|
+
hr: "hr";
|
|
22
|
+
s: "s";
|
|
23
|
+
hjres: "hjres";
|
|
24
|
+
sjres: "sjres";
|
|
25
|
+
hconres: "hconres";
|
|
26
|
+
sconres: "sconres";
|
|
27
|
+
hres: "hres";
|
|
28
|
+
sres: "sres";
|
|
29
|
+
}>>;
|
|
30
|
+
originChamber: z.ZodOptional<z.ZodEnum<{
|
|
31
|
+
House: "House";
|
|
32
|
+
Senate: "Senate";
|
|
33
|
+
}>>;
|
|
34
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
35
|
+
offset: z.ZodDefault<z.ZodNumber>;
|
|
36
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
37
|
+
data: z.ZodArray<z.ZodObject<{}, z.core.$loose>>;
|
|
38
|
+
pagination: z.ZodObject<{
|
|
39
|
+
count: z.ZodNumber;
|
|
40
|
+
nextOffset: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
}, z.core.$loose>, undefined, {
|
|
43
|
+
effectiveQuery: z.ZodString;
|
|
44
|
+
totalCount: z.ZodNumber;
|
|
45
|
+
notice: z.ZodOptional<z.ZodString>;
|
|
46
|
+
}>;
|
|
47
|
+
//# sourceMappingURL=search-bills.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-bills.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-bills.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAsB,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAsG/D;;;;GAIG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKtB,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview congressgov_search_bills — keyword search over the local bill FTS
|
|
3
|
+
* mirror, the discovery path the Congress.gov API structurally lacks. Queries the
|
|
4
|
+
* embedded SQLite + FTS5 index (title + summary), not the live API, so it has no
|
|
5
|
+
* live fallback: a mirror that has not finished its initial build returns an empty
|
|
6
|
+
* result with an enrichment notice rather than a thrown error. Gated behind
|
|
7
|
+
* CONGRESS_MIRROR_ENABLED via disabledTool() — visible-but-uncallable when the
|
|
8
|
+
* mirror is off (the default).
|
|
9
|
+
* @module mcp-server/tools/definitions/search-bills
|
|
10
|
+
*/
|
|
11
|
+
import { disabledTool, tool, z } from '@cyanheads/mcp-ts-core';
|
|
12
|
+
import { getServerConfig } from '../../../config/server-config.js';
|
|
13
|
+
import { formatSearchBills } from '../../../mcp-server/tools/format-helpers.js';
|
|
14
|
+
import { buildEffectiveQuery, listEnrichment, listOutput, } from '../../../mcp-server/tools/tool-helpers.js';
|
|
15
|
+
import { BILL_TYPE_CODES } from '../../../services/congress-api/types.js';
|
|
16
|
+
import { getCongressMirror } from '../../../services/congress-mirror/congress-mirror-service.js';
|
|
17
|
+
const searchBillsDef = tool('congressgov_search_bills', {
|
|
18
|
+
description: `Keyword-search U.S. bills by title and CRS summary text — the discovery path the Congress.gov API itself lacks (it has no keyword search). Backed by a local full-text index over a bounded congress window; title and summary are indexed, but policy area and full bill text are not. Returns BM25-ranked matches, each with the bill's derived id (congress/billType/billNumber) for follow-up congressgov_bill_lookup calls and a truncated summary preview. Narrow with the optional congress, billType, and originChamber filters. Searches the local mirror, not the live API — if the mirror has not finished its initial build it returns an empty result with a notice, not an error.`,
|
|
19
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },
|
|
20
|
+
input: z.object({
|
|
21
|
+
query: z
|
|
22
|
+
.string()
|
|
23
|
+
.min(1)
|
|
24
|
+
.describe('Free-text keywords matched against bill titles and summaries (e.g. "semiconductor export controls"). Tokens are AND-combined.'),
|
|
25
|
+
congress: z
|
|
26
|
+
.number()
|
|
27
|
+
.int()
|
|
28
|
+
.positive()
|
|
29
|
+
.optional()
|
|
30
|
+
.describe('Restrict to a single congress (e.g. 119). Omit to search the whole mirrored window.'),
|
|
31
|
+
billType: z
|
|
32
|
+
.enum(BILL_TYPE_CODES)
|
|
33
|
+
.optional()
|
|
34
|
+
.describe('Restrict to a bill type (hr, s, hjres, sjres, hconres, sconres, hres, sres).'),
|
|
35
|
+
originChamber: z
|
|
36
|
+
.enum(['House', 'Senate'])
|
|
37
|
+
.optional()
|
|
38
|
+
.describe('Restrict to the originating chamber.'),
|
|
39
|
+
limit: z
|
|
40
|
+
.number()
|
|
41
|
+
.int()
|
|
42
|
+
.min(1)
|
|
43
|
+
.max(100)
|
|
44
|
+
.default(20)
|
|
45
|
+
.describe('Results per page (1–100, default 20).'),
|
|
46
|
+
offset: z.number().int().min(0).default(0).describe('Pagination offset.'),
|
|
47
|
+
}),
|
|
48
|
+
output: listOutput,
|
|
49
|
+
enrichment: listEnrichment,
|
|
50
|
+
format: formatSearchBills,
|
|
51
|
+
async handler(input, ctx) {
|
|
52
|
+
const service = getCongressMirror();
|
|
53
|
+
ctx.enrich.echo(buildEffectiveQuery('bill search', {
|
|
54
|
+
query: input.query,
|
|
55
|
+
congress: input.congress,
|
|
56
|
+
billType: input.billType,
|
|
57
|
+
originChamber: input.originChamber,
|
|
58
|
+
}));
|
|
59
|
+
/** No live-API fallback — a mirror that never completed an initial sync is an
|
|
60
|
+
* empty result plus a notice pointing at the refresh, never a throw. */
|
|
61
|
+
if (!(await service.ready())) {
|
|
62
|
+
ctx.enrich.total(0);
|
|
63
|
+
ctx.enrich.notice('The bill search mirror has not finished its initial build yet, so no results are available. Build it with the mirror:init script (or wait for the scheduled refresh) and retry.');
|
|
64
|
+
return { data: [], pagination: { count: 0, nextOffset: null } };
|
|
65
|
+
}
|
|
66
|
+
const page = await service.search({
|
|
67
|
+
query: input.query,
|
|
68
|
+
congress: input.congress,
|
|
69
|
+
billType: input.billType,
|
|
70
|
+
originChamber: input.originChamber,
|
|
71
|
+
limit: input.limit,
|
|
72
|
+
offset: input.offset,
|
|
73
|
+
}, ctx);
|
|
74
|
+
ctx.log.info('Bill search complete', { query: input.query, matches: page.total });
|
|
75
|
+
ctx.enrich.total(page.total);
|
|
76
|
+
if (page.items.length === 0) {
|
|
77
|
+
ctx.enrich.notice(`No bills matched "${input.query}". Try broader or fewer keywords, or remove the congress/billType/originChamber filters.`);
|
|
78
|
+
}
|
|
79
|
+
const nextOffset = page.offset + page.items.length < page.total ? page.offset + page.items.length : null;
|
|
80
|
+
/** The shared list envelope carries `data` as passthrough records; the typed
|
|
81
|
+
* search results widen cleanly to that shape. */
|
|
82
|
+
return {
|
|
83
|
+
data: page.items,
|
|
84
|
+
pagination: { count: page.total, nextOffset },
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
/**
|
|
89
|
+
* Gated behind the mirror master switch. When the mirror is off (the default) the
|
|
90
|
+
* tool renders on the landing page as present-but-uncallable with a hint, and is
|
|
91
|
+
* skipped during MCP registration so clients can't call a guaranteed-empty search.
|
|
92
|
+
*/
|
|
93
|
+
export const searchBillsTool = getServerConfig().mirrorEnabled
|
|
94
|
+
? searchBillsDef
|
|
95
|
+
: disabledTool(searchBillsDef, {
|
|
96
|
+
reason: 'The local bill search mirror is turned off in this deployment.',
|
|
97
|
+
hint: 'CONGRESS_MIRROR_ENABLED=true',
|
|
98
|
+
});
|
|
99
|
+
//# sourceMappingURL=search-bills.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-bills.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-bills.tool.ts"],"names":[],"mappings":"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"}
|