@cyanheads/congressgov-mcp-server 0.7.1 → 0.7.3
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 +20 -15
- package/CLAUDE.md +20 -15
- package/Dockerfile +23 -10
- package/README.md +90 -93
- package/changelog/0.7.x/0.7.2.md +20 -0
- package/changelog/0.7.x/0.7.3.md +36 -0
- package/dist/mcp-server/tools/definitions/bill-lookup.tool.d.ts +5 -4
- package/dist/mcp-server/tools/definitions/bill-lookup.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/bill-lookup.tool.js +93 -2
- package/dist/mcp-server/tools/definitions/bill-lookup.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/bill-summaries.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/bill-summaries.tool.js +32 -4
- package/dist/mcp-server/tools/definitions/bill-summaries.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/committee-reports.tool.d.ts +2 -2
- package/dist/mcp-server/tools/definitions/daily-record.tool.d.ts +2 -2
- package/dist/mcp-server/tools/format-helpers.d.ts.map +1 -1
- package/dist/mcp-server/tools/format-helpers.js +85 -30
- package/dist/mcp-server/tools/format-helpers.js.map +1 -1
- package/dist/mcp-server/tools/summary-window.d.ts +112 -0
- package/dist/mcp-server/tools/summary-window.d.ts.map +1 -0
- package/dist/mcp-server/tools/summary-window.js +182 -0
- package/dist/mcp-server/tools/summary-window.js.map +1 -0
- package/dist/mcp-server/tools/tool-helpers.d.ts +21 -4
- package/dist/mcp-server/tools/tool-helpers.d.ts.map +1 -1
- package/dist/mcp-server/tools/tool-helpers.js +21 -4
- package/dist/mcp-server/tools/tool-helpers.js.map +1 -1
- package/dist/services/congress-documents/extract-text-stream.js +1 -1
- package/dist/services/congress-documents/extract-text-stream.js.map +1 -1
- package/dist/services/congress-documents/extract-text.d.ts +0 -6
- package/dist/services/congress-documents/extract-text.d.ts.map +1 -1
- package/dist/services/congress-documents/extract-text.js +4 -37
- package/dist/services/congress-documents/extract-text.js.map +1 -1
- package/dist/services/congress-mirror/normalize.d.ts +4 -1
- package/dist/services/congress-mirror/normalize.d.ts.map +1 -1
- package/dist/services/congress-mirror/normalize.js +8 -12
- package/dist/services/congress-mirror/normalize.js.map +1 -1
- package/dist/services/senate-lis/parse.d.ts.map +1 -1
- package/dist/services/senate-lis/parse.js +74 -2
- package/dist/services/senate-lis/parse.js.map +1 -1
- package/dist/services/senate-lis/types.d.ts +8 -1
- package/dist/services/senate-lis/types.d.ts.map +1 -1
- package/dist/utils/character-references.d.ts +27 -0
- package/dist/utils/character-references.d.ts.map +1 -0
- package/dist/utils/character-references.js +60 -0
- package/dist/utils/character-references.js.map +1 -0
- package/package.json +7 -6
- package/server.json +3 -3
package/AGENTS.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** congressgov-mcp-server
|
|
4
|
-
**Version:** 0.7.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.
|
|
4
|
+
**Version:** 0.7.3
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.9`
|
|
6
6
|
**Engines:** Bun ≥1.4.0, Node ≥24.0.0
|
|
7
|
-
**MCP SDK:** `@modelcontextprotocol/server`
|
|
7
|
+
**MCP SDK:** `@modelcontextprotocol/server` ^2.1.0
|
|
8
8
|
**Zod:** ^4.6.5
|
|
9
9
|
|
|
10
10
|
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
|
@@ -53,7 +53,7 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
53
53
|
|
|
54
54
|
- **Logic throws, framework catches.** Tool/resource handlers are pure — throw on failure, no `try/catch`. Plain `Error` is fine; the framework catches, classifies, and formats. Use error factories (`notFound()`, `validationError()`, etc.) when the error code matters.
|
|
55
55
|
- **Use `ctx.log`** for request-scoped logging. No `console` calls.
|
|
56
|
-
- **Use `ctx.state`** for tenant-scoped storage. Never access persistence directly.
|
|
56
|
+
- **Use `ctx.state`** for tenant-scoped storage. Never access persistence directly. Values round-trip as JSON; a `Date` reads back as an ISO string.
|
|
57
57
|
- **Need input the caller didn't supply?** `return ctx.requestInput(...)` and read `ctx.inputs` when the handler is re-entered. Never `await` for user input mid-handler.
|
|
58
58
|
- **Secrets in env vars only** — never hardcoded.
|
|
59
59
|
- **All tools are read-only.** Every tool gets `annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true }`.
|
|
@@ -68,18 +68,20 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
68
68
|
|
|
69
69
|
| Name | Description |
|
|
70
70
|
|:-----|:------------|
|
|
71
|
-
| `congressgov_bill_lookup` | Browse, filter, and retrieve bill data (actions, sponsors, summaries, text, related bills) + bounded document text via `content` |
|
|
71
|
+
| `congressgov_bill_lookup` | Browse, filter, and retrieve bill data (actions, sponsors, summaries, text, related bills) + bounded document text via `content`; `summaries` takes `versionCode` and the shared `characterOffset`/`characterLimit` window |
|
|
72
72
|
| `congressgov_enacted_laws` | Browse enacted public and private laws by congress |
|
|
73
73
|
| `congressgov_member_lookup` | Discover members by state/district/congress, retrieve legislative portfolios |
|
|
74
74
|
| `congressgov_committee_lookup` | Browse committees and retrieve legislation, reports, nominations |
|
|
75
75
|
| `congressgov_roll_votes` | Retrieve House and Senate roll call votes and member voting positions |
|
|
76
76
|
| `congressgov_senate_nominations` | Browse presidential nominations, track Senate confirmation pipeline |
|
|
77
|
-
| `congressgov_bill_summaries` | Browse recent CRS bill summaries — the "what's happening" feed |
|
|
77
|
+
| `congressgov_bill_summaries` | Browse recent CRS bill summaries — the "what's happening" feed, bounded by the shared summary page budget and per-row text window |
|
|
78
78
|
| `congressgov_crs_reports` | Browse and retrieve nonpartisan CRS policy analysis reports |
|
|
79
79
|
| `congressgov_committee_reports` | Browse and retrieve committee reports accompanying legislation + bounded report text via `content` |
|
|
80
80
|
| `congressgov_daily_record` | Browse daily Congressional Record — floor speeches, debates, proceedings + bounded article text via `content` |
|
|
81
81
|
| `congressgov_search_bills` | Keyword-search bill titles/summaries via the opt-in local FTS mirror — off by default |
|
|
82
82
|
|
|
83
|
+
**Summary bounding** (`src/mcp-server/tools/summary-window.ts`, constants in `tool-helpers.ts`). Both summary surfaces enforce two limits. `SUMMARY_PAGE_CHARACTERS` stops a page once its serialized rows reach the budget — the first row always returns, `pagination.nextOffset` counts the rows actually returned, and an enrichment notice discloses the stop. `DEFAULT_SUMMARY_TEXT_CHARACTERS` bounds one row's upstream `text`; a windowed row gains `textTotalCharacters` / `textTruncated` / `textNextOffset`, and its window end is retracted off any HTML tag or character reference it would otherwise split (unless the construct is wider than the whole window, where the requested limit wins). A row inside both limits is returned untouched, so an unbounded page stays byte-identical. `congressgov_bill_lookup` `summaries` overrides the row window with `characterOffset`/`characterLimit` and selects one version with `versionCode` — Congress.gov publishes no version filter, so selection reads the bill's whole summary list and matches client-side.
|
|
84
|
+
|
|
83
85
|
### Resources (5)
|
|
84
86
|
|
|
85
87
|
| URI Template | Description |
|
|
@@ -114,6 +116,7 @@ src/
|
|
|
114
116
|
congress-documents-service.ts # www.congress.gov document fetch — host allowlist, byte ceiling, character window
|
|
115
117
|
document-formats.ts # Format label → URL resolution over upstream format lists
|
|
116
118
|
extract-text.ts # GPO `<pre>` / XML body → deterministic plain text
|
|
119
|
+
extract-text-stream.ts # Incremental twin of extract-text.ts — one character window, constant memory
|
|
117
120
|
types.ts # Document format + content window types
|
|
118
121
|
congress-mirror/
|
|
119
122
|
congress-mirror-service.ts # Mirror read path — FTS5 search, ready(), sync accessor
|
|
@@ -147,6 +150,8 @@ src/
|
|
|
147
150
|
prompts/definitions/
|
|
148
151
|
bill-analysis.prompt.ts # congressgov_bill_analysis
|
|
149
152
|
legislative-research.prompt.ts # congressgov_legislative_research
|
|
153
|
+
utils/
|
|
154
|
+
character-references.ts # Single-pass HTML/XML character-reference decoding
|
|
150
155
|
scripts/
|
|
151
156
|
_mirror-context.ts # Shared bootstrap for the mirror lifecycle CLI scripts
|
|
152
157
|
congress-mirror-init.ts # mirror:init — full out-of-band mirror build
|
|
@@ -179,7 +184,7 @@ Four services. `CongressApiService` backs nine tools and the House branch of `co
|
|
|
179
184
|
- The fetch is bounded: a 25 MB ceiling (refused on `Content-Length`, else mid-stream), a 30s deadline, and a content-type allowlist
|
|
180
185
|
- The body is extracted as it streams and only the requested window is retained, so a read's live set is flat in the size of the document (transient allocation is not — peak RSS runs above a buffered read); the ceiling bounds how long a response may run, not how much of one fits in a buffer
|
|
181
186
|
- The structured response is bounded by an exact character window — `structuredContent.content.text` and its offsets index the extracted plain text and are never snapped to section breaks, so feeding `nextOffset` back walks a document with no overlap and no gap; `content[]` wraps that unchanged window in a dynamically safe Markdown fence for presentation
|
|
182
|
-
- `extract-text.ts` unwraps GPO's `<pre>` print output verbatim (whitespace is the document's structure), while no-`<pre>` XML gains one space only at an otherwise-unseparated sibling close→open element boundary; both readings decode
|
|
187
|
+
- `extract-text.ts` unwraps GPO's `<pre>` print output verbatim (whitespace is the document's structure), while no-`<pre>` XML gains one space only at an otherwise-unseparated sibling close→open element boundary; both readings decode character references through `src/utils/character-references.ts` — the one decoder every HTML/XML → text path in the server shares, single-pass so an escaped reference stays escaped — and `extract-text-stream.ts` is their incremental twin, pinned byte-for-byte against the whole-string extractor
|
|
183
188
|
|
|
184
189
|
**`CongressMirrorService`** — local SQLite FTS5 mirror of bill title + CRS summary text, backing `congressgov_search_bills` only:
|
|
185
190
|
- Opt-in via `CONGRESS_MIRROR_ENABLED` (off by default); built out-of-band via the `mirror:init`/`mirror:refresh` scripts, never on server startup
|
|
@@ -212,7 +217,7 @@ All tools share these patterns. The service layer handles them uniformly:
|
|
|
212
217
|
| Invalid params | `validationError('...', { field })` |
|
|
213
218
|
| Network error | `serviceUnavailable('Unable to reach the Congress.gov API.')` |
|
|
214
219
|
|
|
215
|
-
The `content` operation adds `documentErrorContracts` (tool-helpers) on top: `document_unavailable`, `format_unavailable`, `document_fetch_failed`, `document_too_large`, and `offset_past_end
|
|
220
|
+
The `content` operation adds `documentErrorContracts` (tool-helpers) on top: `document_unavailable`, `format_unavailable`, `document_fetch_failed`, `document_too_large`, and `offset_past_end` — the last of which `congressgov_bill_lookup` also raises from its `summaries` branch when `characterOffset` is past the end of every returned row's text. `CongressDocumentsService` raises each with a matching `data.reason` and resolves the hint via `ctx.recoveryFor` — note that `ctx.fail` does **not** auto-populate `recovery`, so handler-side `ctx.fail` calls must spread `ctx.recoveryFor(reason)` into their data or the hint never reaches the wire.
|
|
216
221
|
|
|
217
222
|
Service-only contract reasons carry `thrownBy: 'service'`; handler-local reasons remain checked by `error-contract-unthrown`. `RequestCancelled` is a baseline code and needs no contract entry. Retry predicates compose `defaultIsTransient` with the existing exclusion of `RateLimited` codes and preserve upstream `retryable: false`.
|
|
218
223
|
|
|
@@ -267,7 +272,7 @@ Available skills:
|
|
|
267
272
|
| `code-simplifier` | Post-session cleanup against `git diff` — modernize syntax, consolidate duplication, align with the codebase |
|
|
268
273
|
| `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
|
|
269
274
|
| `git-wrapup` | Land the commit stack, version bump, and changelog on a release branch; open the release PR |
|
|
270
|
-
| `release-pr-review` | Review
|
|
275
|
+
| `release-pr-review` | Review pass on an open release PR — simplifier + correctness review, fixes as ordinary commits on top of the stack, PR body kept in sync. Release PR mode only |
|
|
271
276
|
| `release-and-publish` | Fast-forward main, tag, push, and publish to npm, MCP Registry, GitHub Releases, and Docker |
|
|
272
277
|
| `maintenance` | Investigate changelogs, adopt upstream changes, sync skills to agent dirs |
|
|
273
278
|
| `report-issue-framework` | File bugs/features against `@cyanheads/mcp-ts-core` |
|
|
@@ -276,9 +281,9 @@ Available skills:
|
|
|
276
281
|
| `api-config` | AppConfig, parseConfig, env vars |
|
|
277
282
|
| `api-context` | Context interface, RequestContext, logger, state, multi-round-trip input |
|
|
278
283
|
| `api-errors` | McpError, JsonRpcErrorCode, error patterns |
|
|
279
|
-
| `api-linter` |
|
|
284
|
+
| `api-linter` | Definition linter rule catalog — invoked by `bun run lint:mcp` and `devcheck` |
|
|
280
285
|
| `api-canvas` | DataCanvas: register tabular data, run SQL, export, plus the `spillover()` helper — Tier 3 opt-in |
|
|
281
|
-
| `api-mirror` | MirrorService: persistent local SQLite
|
|
286
|
+
| `api-mirror` | MirrorService: persistent self-refreshing local mirror (embedded SQLite + FTS5) of a bulk upstream dataset — Tier 3 opt-in |
|
|
282
287
|
| `api-services` | LLM, Speech, Graph services |
|
|
283
288
|
| `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
|
|
284
289
|
| `api-testing` | createMockContext, test patterns |
|
|
@@ -310,8 +315,8 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
310
315
|
| `bun run bundle` | Build and pack as `.mcpb` for one-click Claude Desktop install |
|
|
311
316
|
| `bun run changelog:build` | Regenerate `CHANGELOG.md` from `changelog/*.md` |
|
|
312
317
|
| `bun run changelog:check` | Verify `CHANGELOG.md` is in sync (used by devcheck) |
|
|
313
|
-
| `bun run release:github` |
|
|
314
|
-
| `bun run test` | Run tests |
|
|
318
|
+
| `bun run release:github` | Validate the current annotated tag and create its GitHub Release; `-- --check` validates only |
|
|
319
|
+
| `bun run test` | Run tests (Vitest — use `bun run test`, not `bun test`) |
|
|
315
320
|
| `bun run dev:stdio` | Dev mode (stdio) |
|
|
316
321
|
| `bun run dev:http` | Dev mode (HTTP) |
|
|
317
322
|
| `bun run start:stdio` | Production mode (stdio) |
|
|
@@ -387,6 +392,6 @@ Remind the user to run these after completing a release flow.
|
|
|
387
392
|
- [ ] Registered in `createApp()` arrays (directly or via barrel exports)
|
|
388
393
|
- [ ] Tests use `createMockContext()` from `@cyanheads/mcp-ts-core/testing`
|
|
389
394
|
- [ ] `.codex-plugin/plugin.json` populated — `name` and `interface.displayName` = unscoped repo name; `version`, `description`, `repository`, `license` and `interface.shortDescription` from `package.json`
|
|
390
|
-
- [ ] `.codex-plugin/mcp.json` updated — server name key
|
|
391
|
-
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license
|
|
395
|
+
- [ ] `.codex-plugin/mcp.json` updated — server name key is the unscoped repo name; every user-supplied variable is listed in `env_vars`. Never write `"KEY": ""` into `env` — it overrides the user's exported key
|
|
396
|
+
- [ ] `.claude-plugin/plugin.json` populated — unscoped `name`, `version`, `description`, `author`, `repository`, `license`, `keywords`; inline `mcpServers` entry keyed by the unscoped repo name. User-supplied variables use `userConfig` and `"KEY": "${user_config.<option>}"` env references, matching `manifest.json`
|
|
392
397
|
- [ ] `bun run devcheck` passes
|
package/CLAUDE.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** congressgov-mcp-server
|
|
4
|
-
**Version:** 0.7.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.
|
|
4
|
+
**Version:** 0.7.3
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.9`
|
|
6
6
|
**Engines:** Bun ≥1.4.0, Node ≥24.0.0
|
|
7
|
-
**MCP SDK:** `@modelcontextprotocol/server`
|
|
7
|
+
**MCP SDK:** `@modelcontextprotocol/server` ^2.1.0
|
|
8
8
|
**Zod:** ^4.6.5
|
|
9
9
|
|
|
10
10
|
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
|
@@ -53,7 +53,7 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
53
53
|
|
|
54
54
|
- **Logic throws, framework catches.** Tool/resource handlers are pure — throw on failure, no `try/catch`. Plain `Error` is fine; the framework catches, classifies, and formats. Use error factories (`notFound()`, `validationError()`, etc.) when the error code matters.
|
|
55
55
|
- **Use `ctx.log`** for request-scoped logging. No `console` calls.
|
|
56
|
-
- **Use `ctx.state`** for tenant-scoped storage. Never access persistence directly.
|
|
56
|
+
- **Use `ctx.state`** for tenant-scoped storage. Never access persistence directly. Values round-trip as JSON; a `Date` reads back as an ISO string.
|
|
57
57
|
- **Need input the caller didn't supply?** `return ctx.requestInput(...)` and read `ctx.inputs` when the handler is re-entered. Never `await` for user input mid-handler.
|
|
58
58
|
- **Secrets in env vars only** — never hardcoded.
|
|
59
59
|
- **All tools are read-only.** Every tool gets `annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true }`.
|
|
@@ -68,18 +68,20 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
68
68
|
|
|
69
69
|
| Name | Description |
|
|
70
70
|
|:-----|:------------|
|
|
71
|
-
| `congressgov_bill_lookup` | Browse, filter, and retrieve bill data (actions, sponsors, summaries, text, related bills) + bounded document text via `content` |
|
|
71
|
+
| `congressgov_bill_lookup` | Browse, filter, and retrieve bill data (actions, sponsors, summaries, text, related bills) + bounded document text via `content`; `summaries` takes `versionCode` and the shared `characterOffset`/`characterLimit` window |
|
|
72
72
|
| `congressgov_enacted_laws` | Browse enacted public and private laws by congress |
|
|
73
73
|
| `congressgov_member_lookup` | Discover members by state/district/congress, retrieve legislative portfolios |
|
|
74
74
|
| `congressgov_committee_lookup` | Browse committees and retrieve legislation, reports, nominations |
|
|
75
75
|
| `congressgov_roll_votes` | Retrieve House and Senate roll call votes and member voting positions |
|
|
76
76
|
| `congressgov_senate_nominations` | Browse presidential nominations, track Senate confirmation pipeline |
|
|
77
|
-
| `congressgov_bill_summaries` | Browse recent CRS bill summaries — the "what's happening" feed |
|
|
77
|
+
| `congressgov_bill_summaries` | Browse recent CRS bill summaries — the "what's happening" feed, bounded by the shared summary page budget and per-row text window |
|
|
78
78
|
| `congressgov_crs_reports` | Browse and retrieve nonpartisan CRS policy analysis reports |
|
|
79
79
|
| `congressgov_committee_reports` | Browse and retrieve committee reports accompanying legislation + bounded report text via `content` |
|
|
80
80
|
| `congressgov_daily_record` | Browse daily Congressional Record — floor speeches, debates, proceedings + bounded article text via `content` |
|
|
81
81
|
| `congressgov_search_bills` | Keyword-search bill titles/summaries via the opt-in local FTS mirror — off by default |
|
|
82
82
|
|
|
83
|
+
**Summary bounding** (`src/mcp-server/tools/summary-window.ts`, constants in `tool-helpers.ts`). Both summary surfaces enforce two limits. `SUMMARY_PAGE_CHARACTERS` stops a page once its serialized rows reach the budget — the first row always returns, `pagination.nextOffset` counts the rows actually returned, and an enrichment notice discloses the stop. `DEFAULT_SUMMARY_TEXT_CHARACTERS` bounds one row's upstream `text`; a windowed row gains `textTotalCharacters` / `textTruncated` / `textNextOffset`, and its window end is retracted off any HTML tag or character reference it would otherwise split (unless the construct is wider than the whole window, where the requested limit wins). A row inside both limits is returned untouched, so an unbounded page stays byte-identical. `congressgov_bill_lookup` `summaries` overrides the row window with `characterOffset`/`characterLimit` and selects one version with `versionCode` — Congress.gov publishes no version filter, so selection reads the bill's whole summary list and matches client-side.
|
|
84
|
+
|
|
83
85
|
### Resources (5)
|
|
84
86
|
|
|
85
87
|
| URI Template | Description |
|
|
@@ -114,6 +116,7 @@ src/
|
|
|
114
116
|
congress-documents-service.ts # www.congress.gov document fetch — host allowlist, byte ceiling, character window
|
|
115
117
|
document-formats.ts # Format label → URL resolution over upstream format lists
|
|
116
118
|
extract-text.ts # GPO `<pre>` / XML body → deterministic plain text
|
|
119
|
+
extract-text-stream.ts # Incremental twin of extract-text.ts — one character window, constant memory
|
|
117
120
|
types.ts # Document format + content window types
|
|
118
121
|
congress-mirror/
|
|
119
122
|
congress-mirror-service.ts # Mirror read path — FTS5 search, ready(), sync accessor
|
|
@@ -147,6 +150,8 @@ src/
|
|
|
147
150
|
prompts/definitions/
|
|
148
151
|
bill-analysis.prompt.ts # congressgov_bill_analysis
|
|
149
152
|
legislative-research.prompt.ts # congressgov_legislative_research
|
|
153
|
+
utils/
|
|
154
|
+
character-references.ts # Single-pass HTML/XML character-reference decoding
|
|
150
155
|
scripts/
|
|
151
156
|
_mirror-context.ts # Shared bootstrap for the mirror lifecycle CLI scripts
|
|
152
157
|
congress-mirror-init.ts # mirror:init — full out-of-band mirror build
|
|
@@ -179,7 +184,7 @@ Four services. `CongressApiService` backs nine tools and the House branch of `co
|
|
|
179
184
|
- The fetch is bounded: a 25 MB ceiling (refused on `Content-Length`, else mid-stream), a 30s deadline, and a content-type allowlist
|
|
180
185
|
- The body is extracted as it streams and only the requested window is retained, so a read's live set is flat in the size of the document (transient allocation is not — peak RSS runs above a buffered read); the ceiling bounds how long a response may run, not how much of one fits in a buffer
|
|
181
186
|
- The structured response is bounded by an exact character window — `structuredContent.content.text` and its offsets index the extracted plain text and are never snapped to section breaks, so feeding `nextOffset` back walks a document with no overlap and no gap; `content[]` wraps that unchanged window in a dynamically safe Markdown fence for presentation
|
|
182
|
-
- `extract-text.ts` unwraps GPO's `<pre>` print output verbatim (whitespace is the document's structure), while no-`<pre>` XML gains one space only at an otherwise-unseparated sibling close→open element boundary; both readings decode
|
|
187
|
+
- `extract-text.ts` unwraps GPO's `<pre>` print output verbatim (whitespace is the document's structure), while no-`<pre>` XML gains one space only at an otherwise-unseparated sibling close→open element boundary; both readings decode character references through `src/utils/character-references.ts` — the one decoder every HTML/XML → text path in the server shares, single-pass so an escaped reference stays escaped — and `extract-text-stream.ts` is their incremental twin, pinned byte-for-byte against the whole-string extractor
|
|
183
188
|
|
|
184
189
|
**`CongressMirrorService`** — local SQLite FTS5 mirror of bill title + CRS summary text, backing `congressgov_search_bills` only:
|
|
185
190
|
- Opt-in via `CONGRESS_MIRROR_ENABLED` (off by default); built out-of-band via the `mirror:init`/`mirror:refresh` scripts, never on server startup
|
|
@@ -212,7 +217,7 @@ All tools share these patterns. The service layer handles them uniformly:
|
|
|
212
217
|
| Invalid params | `validationError('...', { field })` |
|
|
213
218
|
| Network error | `serviceUnavailable('Unable to reach the Congress.gov API.')` |
|
|
214
219
|
|
|
215
|
-
The `content` operation adds `documentErrorContracts` (tool-helpers) on top: `document_unavailable`, `format_unavailable`, `document_fetch_failed`, `document_too_large`, and `offset_past_end
|
|
220
|
+
The `content` operation adds `documentErrorContracts` (tool-helpers) on top: `document_unavailable`, `format_unavailable`, `document_fetch_failed`, `document_too_large`, and `offset_past_end` — the last of which `congressgov_bill_lookup` also raises from its `summaries` branch when `characterOffset` is past the end of every returned row's text. `CongressDocumentsService` raises each with a matching `data.reason` and resolves the hint via `ctx.recoveryFor` — note that `ctx.fail` does **not** auto-populate `recovery`, so handler-side `ctx.fail` calls must spread `ctx.recoveryFor(reason)` into their data or the hint never reaches the wire.
|
|
216
221
|
|
|
217
222
|
Service-only contract reasons carry `thrownBy: 'service'`; handler-local reasons remain checked by `error-contract-unthrown`. `RequestCancelled` is a baseline code and needs no contract entry. Retry predicates compose `defaultIsTransient` with the existing exclusion of `RateLimited` codes and preserve upstream `retryable: false`.
|
|
218
223
|
|
|
@@ -267,7 +272,7 @@ Available skills:
|
|
|
267
272
|
| `code-simplifier` | Post-session cleanup against `git diff` — modernize syntax, consolidate duplication, align with the codebase |
|
|
268
273
|
| `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
|
|
269
274
|
| `git-wrapup` | Land the commit stack, version bump, and changelog on a release branch; open the release PR |
|
|
270
|
-
| `release-pr-review` | Review
|
|
275
|
+
| `release-pr-review` | Review pass on an open release PR — simplifier + correctness review, fixes as ordinary commits on top of the stack, PR body kept in sync. Release PR mode only |
|
|
271
276
|
| `release-and-publish` | Fast-forward main, tag, push, and publish to npm, MCP Registry, GitHub Releases, and Docker |
|
|
272
277
|
| `maintenance` | Investigate changelogs, adopt upstream changes, sync skills to agent dirs |
|
|
273
278
|
| `report-issue-framework` | File bugs/features against `@cyanheads/mcp-ts-core` |
|
|
@@ -276,9 +281,9 @@ Available skills:
|
|
|
276
281
|
| `api-config` | AppConfig, parseConfig, env vars |
|
|
277
282
|
| `api-context` | Context interface, RequestContext, logger, state, multi-round-trip input |
|
|
278
283
|
| `api-errors` | McpError, JsonRpcErrorCode, error patterns |
|
|
279
|
-
| `api-linter` |
|
|
284
|
+
| `api-linter` | Definition linter rule catalog — invoked by `bun run lint:mcp` and `devcheck` |
|
|
280
285
|
| `api-canvas` | DataCanvas: register tabular data, run SQL, export, plus the `spillover()` helper — Tier 3 opt-in |
|
|
281
|
-
| `api-mirror` | MirrorService: persistent local SQLite
|
|
286
|
+
| `api-mirror` | MirrorService: persistent self-refreshing local mirror (embedded SQLite + FTS5) of a bulk upstream dataset — Tier 3 opt-in |
|
|
282
287
|
| `api-services` | LLM, Speech, Graph services |
|
|
283
288
|
| `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
|
|
284
289
|
| `api-testing` | createMockContext, test patterns |
|
|
@@ -310,8 +315,8 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
310
315
|
| `bun run bundle` | Build and pack as `.mcpb` for one-click Claude Desktop install |
|
|
311
316
|
| `bun run changelog:build` | Regenerate `CHANGELOG.md` from `changelog/*.md` |
|
|
312
317
|
| `bun run changelog:check` | Verify `CHANGELOG.md` is in sync (used by devcheck) |
|
|
313
|
-
| `bun run release:github` |
|
|
314
|
-
| `bun run test` | Run tests |
|
|
318
|
+
| `bun run release:github` | Validate the current annotated tag and create its GitHub Release; `-- --check` validates only |
|
|
319
|
+
| `bun run test` | Run tests (Vitest — use `bun run test`, not `bun test`) |
|
|
315
320
|
| `bun run dev:stdio` | Dev mode (stdio) |
|
|
316
321
|
| `bun run dev:http` | Dev mode (HTTP) |
|
|
317
322
|
| `bun run start:stdio` | Production mode (stdio) |
|
|
@@ -387,6 +392,6 @@ Remind the user to run these after completing a release flow.
|
|
|
387
392
|
- [ ] Registered in `createApp()` arrays (directly or via barrel exports)
|
|
388
393
|
- [ ] Tests use `createMockContext()` from `@cyanheads/mcp-ts-core/testing`
|
|
389
394
|
- [ ] `.codex-plugin/plugin.json` populated — `name` and `interface.displayName` = unscoped repo name; `version`, `description`, `repository`, `license` and `interface.shortDescription` from `package.json`
|
|
390
|
-
- [ ] `.codex-plugin/mcp.json` updated — server name key
|
|
391
|
-
- [ ] `.claude-plugin/plugin.json` populated — `name`, `version`, `description`, `repository`, `license
|
|
395
|
+
- [ ] `.codex-plugin/mcp.json` updated — server name key is the unscoped repo name; every user-supplied variable is listed in `env_vars`. Never write `"KEY": ""` into `env` — it overrides the user's exported key
|
|
396
|
+
- [ ] `.claude-plugin/plugin.json` populated — unscoped `name`, `version`, `description`, `author`, `repository`, `license`, `keywords`; inline `mcpServers` entry keyed by the unscoped repo name. User-supplied variables use `userConfig` and `"KEY": "${user_config.<option>}"` env references, matching `manifest.json`
|
|
392
397
|
- [ ] `bun run devcheck` passes
|
package/Dockerfile
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
# multi-arch buildx run on an arm64 host. This stage only runs tsc and emits
|
|
10
10
|
# architecture-independent JavaScript, and the production stage installs its own
|
|
11
11
|
# dependencies natively, so building it on the host architecture is safe.
|
|
12
|
-
FROM --platform=$BUILDPLATFORM oven/bun:1.4.
|
|
12
|
+
FROM --platform=$BUILDPLATFORM oven/bun:1.4.2 AS build
|
|
13
13
|
|
|
14
14
|
WORKDIR /usr/src/app
|
|
15
15
|
|
|
@@ -39,7 +39,7 @@ RUN bun run build
|
|
|
39
39
|
# application. It uses a slim base image and only includes production
|
|
40
40
|
# dependencies and build artifacts.
|
|
41
41
|
# ==============================================================================
|
|
42
|
-
FROM oven/bun:1.4.
|
|
42
|
+
FROM oven/bun:1.4.2-slim AS production
|
|
43
43
|
|
|
44
44
|
WORKDIR /usr/src/app
|
|
45
45
|
|
|
@@ -55,8 +55,11 @@ LABEL org.opencontainers.image.source="https://github.com/cyanheads/congressgov-
|
|
|
55
55
|
LABEL org.opencontainers.image.licenses="Apache-2.0"
|
|
56
56
|
LABEL org.opencontainers.image.version="${APP_VERSION}"
|
|
57
57
|
|
|
58
|
-
# Copy dependency manifests
|
|
59
|
-
COPY package.json bun.lock ./
|
|
58
|
+
# Copy dependency manifests and preserve the release-age gate and scanner.
|
|
59
|
+
COPY package.json bun.lock bunfig.toml ./
|
|
60
|
+
|
|
61
|
+
# Seed the scanner because the production install omits this devDependency.
|
|
62
|
+
COPY --from=build /usr/src/app/node_modules/@socketsecurity/bun-security-scanner ./node_modules/@socketsecurity/bun-security-scanner
|
|
60
63
|
|
|
61
64
|
# Install only production dependencies, ignoring any lifecycle scripts (like 'prepare')
|
|
62
65
|
# that are not needed in the final production image.
|
|
@@ -69,21 +72,32 @@ RUN --mount=type=cache,target=/root/.bun/install/cache \
|
|
|
69
72
|
bun install --production --omit=peer --frozen-lockfile --ignore-scripts
|
|
70
73
|
|
|
71
74
|
# Conditionally install OpenTelemetry optional peer dependencies (Tier 3).
|
|
72
|
-
#
|
|
73
|
-
#
|
|
75
|
+
# Installed by default; omit with --build-arg OTEL_ENABLED=false.
|
|
76
|
+
# Resolve each package inside the installed framework's tested peer range.
|
|
74
77
|
ARG OTEL_ENABLED=true
|
|
75
78
|
RUN --mount=type=cache,target=/root/.bun/install/cache \
|
|
76
79
|
if [ "$OTEL_ENABLED" = "true" ]; then \
|
|
77
|
-
bun
|
|
78
|
-
|
|
80
|
+
specs=$(bun -e ' \
|
|
81
|
+
const { peerDependencies: peers } = await Bun.file("node_modules/@cyanheads/mcp-ts-core/package.json").json(); \
|
|
82
|
+
const names = process.argv.slice(1); \
|
|
83
|
+
const missing = names.filter((name) => !peers?.[name]); \
|
|
84
|
+
if (missing.length > 0) throw new Error(`no peerDependencies range for ${missing.join(", ")}`); \
|
|
85
|
+
console.log(names.map((name) => `${name}@${peers[name]}`).join(" ")); \
|
|
86
|
+
' \
|
|
87
|
+
@hono/otel \
|
|
88
|
+
@opentelemetry/api-logs \
|
|
89
|
+
@opentelemetry/exporter-logs-otlp-http \
|
|
79
90
|
@opentelemetry/exporter-metrics-otlp-http \
|
|
80
91
|
@opentelemetry/exporter-trace-otlp-http \
|
|
92
|
+
@opentelemetry/instrumentation-http \
|
|
81
93
|
@opentelemetry/instrumentation-pino \
|
|
82
94
|
@opentelemetry/resources \
|
|
95
|
+
@opentelemetry/sdk-logs \
|
|
83
96
|
@opentelemetry/sdk-metrics \
|
|
84
97
|
@opentelemetry/sdk-node \
|
|
85
98
|
@opentelemetry/sdk-trace-node \
|
|
86
|
-
@opentelemetry/semantic-conventions
|
|
99
|
+
@opentelemetry/semantic-conventions) \
|
|
100
|
+
&& bun add --omit=dev --omit=peer --ignore-scripts $specs; \
|
|
87
101
|
fi
|
|
88
102
|
|
|
89
103
|
# Copy the compiled application code from the build stage
|
|
@@ -128,7 +142,6 @@ ENV MCP_TRANSPORT_TYPE="http"
|
|
|
128
142
|
ENV MCP_SESSION_MODE="stateless"
|
|
129
143
|
ENV MCP_LOG_LEVEL="info"
|
|
130
144
|
ENV LOGS_DIR="/var/log/congressgov-mcp-server"
|
|
131
|
-
ENV MCP_FORCE_CONSOLE_LOGGING="true"
|
|
132
145
|
|
|
133
146
|
# Expose the port the server listens on
|
|
134
147
|
EXPOSE ${MCP_HTTP_PORT}
|