@cyanheads/openfec-mcp-server 0.4.0 → 0.4.2
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/CLAUDE.md +73 -34
- package/README.md +2 -2
- package/dist/mcp-server/resources/definitions/candidate.resource.d.ts +7 -1
- package/dist/mcp-server/resources/definitions/candidate.resource.d.ts.map +1 -1
- package/dist/mcp-server/resources/definitions/candidate.resource.js +15 -2
- package/dist/mcp-server/resources/definitions/candidate.resource.js.map +1 -1
- package/dist/mcp-server/resources/definitions/committee.resource.d.ts +7 -1
- package/dist/mcp-server/resources/definitions/committee.resource.d.ts.map +1 -1
- package/dist/mcp-server/resources/definitions/committee.resource.js +17 -2
- package/dist/mcp-server/resources/definitions/committee.resource.js.map +1 -1
- package/dist/mcp-server/resources/definitions/election.resource.d.ts +3 -3
- package/dist/mcp-server/resources/definitions/election.resource.d.ts.map +1 -1
- package/dist/mcp-server/resources/definitions/index.d.ts +13 -3
- package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/index.d.ts +59 -9
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/lookup-calendar.tool.d.ts +1 -1
- package/dist/mcp-server/tools/definitions/lookup-calendar.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/lookup-calendar.tool.js +3 -1
- package/dist/mcp-server/tools/definitions/lookup-calendar.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/lookup-elections.tool.d.ts +22 -1
- package/dist/mcp-server/tools/definitions/lookup-elections.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/lookup-elections.tool.js +46 -6
- package/dist/mcp-server/tools/definitions/lookup-elections.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-candidates.tool.d.ts +7 -1
- package/dist/mcp-server/tools/definitions/search-candidates.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-candidates.tool.js +15 -4
- package/dist/mcp-server/tools/definitions/search-candidates.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-committees.tool.d.ts +7 -1
- package/dist/mcp-server/tools/definitions/search-committees.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-committees.tool.js +14 -3
- package/dist/mcp-server/tools/definitions/search-committees.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-contributions.tool.d.ts +12 -1
- package/dist/mcp-server/tools/definitions/search-contributions.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-contributions.tool.js +20 -4
- package/dist/mcp-server/tools/definitions/search-contributions.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-disbursements.tool.d.ts +1 -1
- package/dist/mcp-server/tools/definitions/search-disbursements.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-disbursements.tool.js +1 -1
- package/dist/mcp-server/tools/definitions/search-disbursements.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-expenditures.tool.d.ts +7 -1
- package/dist/mcp-server/tools/definitions/search-expenditures.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-expenditures.tool.js +16 -3
- package/dist/mcp-server/tools/definitions/search-expenditures.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-filings.tool.d.ts +1 -1
- package/dist/mcp-server/tools/definitions/search-filings.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-filings.tool.js +3 -1
- package/dist/mcp-server/tools/definitions/search-filings.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/search-legal.tool.d.ts +7 -1
- package/dist/mcp-server/tools/definitions/search-legal.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/search-legal.tool.js +13 -3
- package/dist/mcp-server/tools/definitions/search-legal.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/utils/id-validators.d.ts +2 -2
- package/dist/mcp-server/tools/definitions/utils/id-validators.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/utils/id-validators.js +5 -5
- package/dist/mcp-server/tools/definitions/utils/id-validators.js.map +1 -1
- package/package.json +9 -10
- package/server.json +3 -3
package/CLAUDE.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** openfec-mcp-server
|
|
4
|
-
**Version:** 0.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
|
|
4
|
+
**Version:** 0.4.2
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.8.19`
|
|
6
|
+
**Engines:** Bun ≥1.3.0, Node ≥24.0.0
|
|
6
7
|
|
|
7
8
|
> **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.
|
|
8
9
|
|
|
@@ -14,13 +15,14 @@ When the user asks what to do next, what's left, or needs direction, suggest rel
|
|
|
14
15
|
|
|
15
16
|
1. **Re-run the `setup` skill** — ensures CLAUDE.md, skills, structure, and metadata are populated and up to date with the current codebase
|
|
16
17
|
2. **Run the `design-mcp-server` skill** — if the tool/resource surface hasn't been mapped yet, work through domain design
|
|
17
|
-
3. **Add tools/resources/prompts** — scaffold new definitions using the `add-tool`, `add-resource`, `add-prompt` skills
|
|
18
|
+
3. **Add tools/resources/prompts** — scaffold new definitions using the `add-tool`, `add-app-tool`, `add-resource`, `add-prompt` skills
|
|
18
19
|
4. **Add services** — scaffold domain service integrations using the `add-service` skill
|
|
19
20
|
5. **Add tests** — scaffold tests for existing definitions using the `add-test` skill
|
|
20
21
|
6. **Field-test definitions** — exercise tools/resources/prompts with real inputs using the `field-test` skill, get a report of issues and pain points
|
|
21
22
|
7. **Run `devcheck`** — lint, format, typecheck, and security audit
|
|
22
|
-
8. **Run the `
|
|
23
|
-
9. **Run the `
|
|
23
|
+
8. **Run the `security-pass` skill** — audit handlers for MCP-specific security gaps: output injection, scope blast radius, input sinks, tenant isolation
|
|
24
|
+
9. **Run the `polish-docs-meta` skill** — finalize README, CHANGELOG, metadata, and agent protocol for shipping
|
|
25
|
+
10. **Run the `maintenance` skill** — investigate changelogs, adopt upstream changes, and sync skills after `bun update --latest`
|
|
24
26
|
|
|
25
27
|
Tailor suggestions to what's actually missing or stale — don't recite the full list every time.
|
|
26
28
|
|
|
@@ -34,9 +36,10 @@ The OpenFEC OpenAPI spec (Swagger 2.0) is at `docs/openapi-spec.json` — 100 pa
|
|
|
34
36
|
|
|
35
37
|
## Core Rules
|
|
36
38
|
|
|
37
|
-
- **Logic throws, framework catches.** Tool/resource handlers are pure — throw on failure, no `try/catch`.
|
|
39
|
+
- **Logic throws, framework catches.** Tool/resource handlers are pure — throw on failure, no `try/catch`. Prefer typed contracts (`errors[]` + `ctx.fail(reason)`) when the failure is part of the public surface; fall back to error factories (`notFound()`, `validationError()`) or plain `Error` otherwise. The framework catches, classifies, and formats.
|
|
38
40
|
- **Use `ctx.log`** for request-scoped logging. No `console` calls.
|
|
39
41
|
- **Use `ctx.state`** for tenant-scoped storage. Never access persistence directly.
|
|
42
|
+
- **Check `ctx.elicit` / `ctx.sample`** for presence before calling.
|
|
40
43
|
- **Secrets in env vars only** — never hardcoded.
|
|
41
44
|
|
|
42
45
|
---
|
|
@@ -47,12 +50,24 @@ The OpenFEC OpenAPI spec (Swagger 2.0) is at `docs/openapi-spec.json` — 100 pa
|
|
|
47
50
|
|
|
48
51
|
```ts
|
|
49
52
|
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
50
|
-
import {
|
|
53
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
51
54
|
import { getOpenFecService } from '@/services/openfec/openfec-service.js';
|
|
55
|
+
import { validateCandidateId } from './utils/id-validators.js';
|
|
52
56
|
|
|
53
57
|
export const searchCandidates = tool('openfec_search_candidates', {
|
|
54
58
|
description: 'Find federal candidates by name, state, office, party, or cycle.',
|
|
55
59
|
annotations: { readOnlyHint: true, idempotentHint: true },
|
|
60
|
+
|
|
61
|
+
errors: [
|
|
62
|
+
{
|
|
63
|
+
reason: 'candidate_not_found',
|
|
64
|
+
code: JsonRpcErrorCode.NotFound,
|
|
65
|
+
when: 'Single-candidate lookup by candidate_id returned no record',
|
|
66
|
+
recovery:
|
|
67
|
+
'Verify the candidate_id format (H/S/P + digits) or drop it and search by name, state, or cycle.',
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
|
|
56
71
|
input: z.object({
|
|
57
72
|
query: z.string().optional().describe('Full-text candidate name search.'),
|
|
58
73
|
candidate_id: z.string().optional().describe('FEC candidate ID (e.g., P00003392).'),
|
|
@@ -66,10 +81,14 @@ export const searchCandidates = tool('openfec_search_candidates', {
|
|
|
66
81
|
}),
|
|
67
82
|
async handler(input, ctx) {
|
|
68
83
|
const fec = getOpenFecService();
|
|
69
|
-
if (input.candidate_id
|
|
70
|
-
throw invalidParams('Invalid candidate ID format', { candidate_id: input.candidate_id });
|
|
71
|
-
}
|
|
84
|
+
if (input.candidate_id) validateCandidateId(input.candidate_id);
|
|
72
85
|
const result = await fec.searchCandidates(input, ctx);
|
|
86
|
+
if (input.candidate_id && result.candidates.length === 0) {
|
|
87
|
+
throw ctx.fail('candidate_not_found', `Candidate ${input.candidate_id} not found.`, {
|
|
88
|
+
candidate_id: input.candidate_id,
|
|
89
|
+
...ctx.recoveryFor('candidate_not_found'),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
73
92
|
ctx.log.info('Candidate search completed', { count: result.pagination.count });
|
|
74
93
|
return result;
|
|
75
94
|
},
|
|
@@ -167,24 +186,38 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
167
186
|
|
|
168
187
|
## Errors
|
|
169
188
|
|
|
170
|
-
Handlers throw — the framework catches, classifies, and formats.
|
|
189
|
+
Handlers throw — the framework catches, classifies, and formats.
|
|
190
|
+
|
|
191
|
+
**Recommended: typed error contract.** Declare `errors: [{ reason, code, when, recovery, retryable? }]` on `tool()` / `resource()`. The handler then receives `ctx.fail(reason, msg?, data?)` keyed against the contract reason union — `ctx.fail('typo')` is a TypeScript error. The framework auto-populates `data.reason`, the linter enforces conformance, and the `recovery` string (≥5 words) is the source of truth for the recovery hint that flows to the wire. Spread `ctx.recoveryFor('reason')` into `data` to opt the contract recovery onto the wire payload.
|
|
171
192
|
|
|
172
193
|
```ts
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
194
|
+
errors: [
|
|
195
|
+
{ reason: 'candidate_not_found', code: JsonRpcErrorCode.NotFound,
|
|
196
|
+
when: 'Single-candidate lookup returned no record',
|
|
197
|
+
recovery: 'Verify the candidate_id (H/S/P + digits) or drop it and search by name.' },
|
|
198
|
+
],
|
|
199
|
+
async handler(input, ctx) {
|
|
200
|
+
if (!found) {
|
|
201
|
+
throw ctx.fail('candidate_not_found', `Candidate ${id} not found.`, {
|
|
202
|
+
candidate_id: id,
|
|
203
|
+
...ctx.recoveryFor('candidate_not_found'),
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
176
208
|
|
|
177
|
-
|
|
178
|
-
import { notFound, validationError, forbidden, serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
|
|
179
|
-
throw notFound('Item not found', { itemId });
|
|
180
|
-
throw serviceUnavailable('API unavailable', { url }, { cause: err });
|
|
209
|
+
**Declare contracts inline on each tool**, even when reasons look similar across tools — per-tool repetition is the intended cost of locality.
|
|
181
210
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
211
|
+
**Fallback (no contract entry fits):** error factories or plain `Error`. Baseline codes (`InternalError`, `ServiceUnavailable`, `Timeout`, `ValidationError`, `SerializationError`) bubble freely without contract entries.
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
import { notFound, validationError, serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
|
|
215
|
+
throw validationError('Invalid query format', { field: 'query' }); // baseline — fine
|
|
216
|
+
throw serviceUnavailable('API unavailable', { url }, { cause: err });
|
|
217
|
+
throw new Error('Item not found'); // auto-classifies → NotFound
|
|
185
218
|
```
|
|
186
219
|
|
|
187
|
-
|
|
220
|
+
Note: `invalidParams` is for malformed JSON-RPC params (rare post-Zod). For semantic post-shape validation, use `validationError`. See the framework `api-errors` skill for the full reference.
|
|
188
221
|
|
|
189
222
|
---
|
|
190
223
|
|
|
@@ -236,7 +269,7 @@ src/
|
|
|
236
269
|
|
|
237
270
|
Skills are modular instructions in `skills/` at the project root. Read them directly when a task matches — e.g., `skills/add-tool/SKILL.md` when adding a tool.
|
|
238
271
|
|
|
239
|
-
**Agent skill directory:** Copy skills into the directory your agent discovers (Claude Code: `.claude/skills/`, others: equivalent). This makes skills available as context without needing to reference `skills/` paths manually. After framework updates, re-
|
|
272
|
+
**Agent skill directory:** Copy skills into the directory your agent discovers (Claude Code: `.claude/skills/`, others: equivalent). This makes skills available as context without needing to reference `skills/` paths manually. After framework updates, run the `maintenance` skill — it re-syncs the agent directory automatically (Phase B).
|
|
240
273
|
|
|
241
274
|
Available skills:
|
|
242
275
|
|
|
@@ -251,18 +284,25 @@ Available skills:
|
|
|
251
284
|
| `add-service` | Scaffold a new service integration |
|
|
252
285
|
| `add-test` | Scaffold test file for a tool, resource, or service |
|
|
253
286
|
| `field-test` | Exercise tools/resources/prompts with real inputs, verify behavior, report issues |
|
|
287
|
+
| `tool-defs-analysis` | Read-only audit of definition language across the surface (10 categories: voice, leaks, defaults, recovery, structure, …) |
|
|
288
|
+
| `security-pass` | Audit server for MCP-flavored security gaps: output injection, scope blast radius, input sinks, tenant isolation |
|
|
254
289
|
| `devcheck` | Lint, format, typecheck, audit |
|
|
255
290
|
| `polish-docs-meta` | Finalize docs, README, metadata, and agent protocol for shipping |
|
|
256
|
-
| `
|
|
291
|
+
| `release-and-publish` | Post-wrapup ship workflow: verification gate, push commits/tags, publish to npm + MCP Registry + GHCR |
|
|
292
|
+
| `maintenance` | Investigate changelogs, adopt upstream changes, sync skills and framework scripts |
|
|
293
|
+
| `migrate-mcp-ts-template` | Migrate a legacy template fork to use `@cyanheads/mcp-ts-core` as a package dependency |
|
|
257
294
|
| `report-issue-framework` | File a bug or feature request against `@cyanheads/mcp-ts-core` via `gh` CLI |
|
|
258
295
|
| `report-issue-local` | File a bug or feature request against this server's own repo via `gh` CLI |
|
|
259
296
|
| `api-auth` | Auth modes, scopes, JWT/OAuth |
|
|
297
|
+
| `api-canvas` | DataCanvas: register tabular data, run SQL, export, plus the `spillover()` helper for big result sets — Tier 3 opt-in |
|
|
260
298
|
| `api-config` | AppConfig, parseConfig, env vars |
|
|
261
|
-
| `api-context` | Context interface, logger, state, progress |
|
|
262
|
-
| `api-errors` | McpError, JsonRpcErrorCode, error
|
|
299
|
+
| `api-context` | Context interface, logger, state, progress, sessionId, recoveryFor |
|
|
300
|
+
| `api-errors` | McpError, JsonRpcErrorCode, typed error contracts, factories |
|
|
301
|
+
| `api-linter` | MCP definition lint rules reference — look here when devcheck flags `format-parity`, `schema-*`, `name-*`, `server-json-*`, etc. |
|
|
263
302
|
| `api-services` | LLM, Speech, Graph services |
|
|
303
|
+
| `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
|
|
264
304
|
| `api-testing` | createMockContext, test patterns |
|
|
265
|
-
| `api-utils` | Formatting, parsing, security, pagination, scheduling |
|
|
305
|
+
| `api-utils` | Formatting, parsing, security, pagination, scheduling, telemetry helpers |
|
|
266
306
|
| `api-workers` | Cloudflare Workers runtime |
|
|
267
307
|
|
|
268
308
|
When you complete a skill's checklist, check the boxes and add a completion timestamp at the end (e.g., `Completed: 2026-03-11`).
|
|
@@ -281,16 +321,17 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
281
321
|
| `bun run format` | Auto-fix formatting |
|
|
282
322
|
| `bun run lint:mcp` | Validate MCP tool/resource/prompt definitions |
|
|
283
323
|
| `bun run test` | Run tests |
|
|
284
|
-
| `bun run
|
|
285
|
-
| `bun run dev:http` | Dev mode (HTTP) |
|
|
324
|
+
| `bun run start` | Production mode (transport from `MCP_TRANSPORT_TYPE`) |
|
|
286
325
|
| `bun run start:stdio` | Production mode (stdio) |
|
|
287
326
|
| `bun run start:http` | Production mode (HTTP) |
|
|
288
327
|
|
|
328
|
+
For dev / smoke-testing, use `bun run rebuild && bun run start:stdio` (or `start:http`) — production-shape execution against the built `dist/`.
|
|
329
|
+
|
|
289
330
|
---
|
|
290
331
|
|
|
291
332
|
## Publishing
|
|
292
333
|
|
|
293
|
-
|
|
334
|
+
Run the `release-and-publish` skill for the full flow (verification gate, push, npm + MCP Registry + GHCR). Reference commands:
|
|
294
335
|
|
|
295
336
|
```bash
|
|
296
337
|
bun publish --access public
|
|
@@ -301,8 +342,6 @@ docker buildx build --platform linux/amd64,linux/arm64 \
|
|
|
301
342
|
--push .
|
|
302
343
|
```
|
|
303
344
|
|
|
304
|
-
Remind the user to run these after completing a release flow.
|
|
305
|
-
|
|
306
345
|
---
|
|
307
346
|
|
|
308
347
|
## Imports
|
|
@@ -320,12 +359,12 @@ import { getOpenFecService } from '@/services/openfec/openfec-service.js';
|
|
|
320
359
|
|
|
321
360
|
## Checklist
|
|
322
361
|
|
|
323
|
-
- [ ] Zod schemas: all fields have `.describe()
|
|
362
|
+
- [ ] Zod schemas: all fields have `.describe()` (including nested object fields and array element types), only JSON-Schema-serializable types (no `z.custom()`, `z.date()`, `z.transform()`, `z.bigint()`, `z.symbol()`, `z.void()`, `z.map()`, `z.set()`, `z.function()`, `z.nan()`)
|
|
324
363
|
- [ ] Optional nested objects: handler guards for empty inner values from form-based clients (`if (input.obj?.field && ...)`, not just `if (input.obj)`)
|
|
325
364
|
- [ ] JSDoc `@fileoverview` + `@module` on every file
|
|
326
365
|
- [ ] `ctx.log` for logging, `ctx.state` for storage
|
|
327
366
|
- [ ] Handlers throw on failure — error factories or plain `Error`, no try/catch
|
|
328
|
-
- [ ] `format()` renders all data the LLM needs — `content[]`
|
|
367
|
+
- [ ] `format()` renders all data the LLM needs — different clients forward different surfaces (Claude Code → `structuredContent`, Claude Desktop → `content[]`); both must carry the same data
|
|
329
368
|
- [ ] Registered in `createApp()` arrays (directly or via barrel exports)
|
|
330
369
|
- [ ] Tests use `createMockContext()` from `@cyanheads/mcp-ts-core/testing`
|
|
331
370
|
- [ ] `bun run devcheck` passes
|
package/README.md
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
<div align="center">
|
|
8
8
|
|
|
9
|
-
[](https://www.npmjs.com/package/@cyanheads/openfec-mcp-server) [](https://www.npmjs.com/package/@cyanheads/openfec-mcp-server) [](./CHANGELOG.md) [](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) [](https://modelcontextprotocol.io/)
|
|
10
10
|
|
|
11
|
-
[](./LICENSE) [](https://www.typescriptlang.org/) [](./LICENSE) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
12
12
|
|
|
13
13
|
</div>
|
|
14
14
|
|
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
* @module src/mcp-server/resources/definitions/candidate.resource
|
|
5
5
|
*/
|
|
6
6
|
import { z } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
8
|
export declare const candidateResource: import("@cyanheads/mcp-ts-core").ResourceDefinition<z.ZodObject<{
|
|
8
9
|
candidate_id: z.ZodString;
|
|
9
|
-
}, z.core.$strip>, undefined
|
|
10
|
+
}, z.core.$strip>, undefined, readonly [{
|
|
11
|
+
readonly reason: "candidate_not_found";
|
|
12
|
+
readonly code: JsonRpcErrorCode.NotFound;
|
|
13
|
+
readonly when: "No candidate exists for the supplied candidate_id";
|
|
14
|
+
readonly recovery: "Verify the candidate_id format (H/S/P + digits) or look up the candidate by name via openfec_search_candidates.";
|
|
15
|
+
}]>;
|
|
10
16
|
//# sourceMappingURL=candidate.resource.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"candidate.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/candidate.resource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAY,CAAC,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"candidate.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/candidate.resource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAY,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAIjE,eAAO,MAAM,iBAAiB;;;;;;;GAsC5B,CAAC"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* @module src/mcp-server/resources/definitions/candidate.resource
|
|
5
5
|
*/
|
|
6
6
|
import { resource, z } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
8
|
import { validateCandidateId } from '../../../mcp-server/tools/definitions/utils/id-validators.js';
|
|
8
9
|
import { getOpenFecService } from '../../../services/openfec/openfec-service.js';
|
|
9
10
|
export const candidateResource = resource('openfec://candidate/{candidate_id}', {
|
|
@@ -13,13 +14,25 @@ export const candidateResource = resource('openfec://candidate/{candidate_id}',
|
|
|
13
14
|
params: z.object({
|
|
14
15
|
candidate_id: z.string().describe('FEC candidate ID (e.g., P00003392, H2CO07170, S4AZ00345)'),
|
|
15
16
|
}),
|
|
17
|
+
errors: [
|
|
18
|
+
{
|
|
19
|
+
reason: 'candidate_not_found',
|
|
20
|
+
code: JsonRpcErrorCode.NotFound,
|
|
21
|
+
when: 'No candidate exists for the supplied candidate_id',
|
|
22
|
+
recovery: 'Verify the candidate_id format (H/S/P + digits) or look up the candidate by name via openfec_search_candidates.',
|
|
23
|
+
},
|
|
24
|
+
],
|
|
16
25
|
async handler(params, ctx) {
|
|
17
26
|
validateCandidateId(params.candidate_id);
|
|
18
27
|
const fec = getOpenFecService();
|
|
19
28
|
const candidateResult = await fec.getCandidate(params.candidate_id, ctx);
|
|
20
29
|
const candidate = candidateResult.results[0];
|
|
21
|
-
if (!candidate)
|
|
22
|
-
throw
|
|
30
|
+
if (!candidate) {
|
|
31
|
+
throw ctx.fail('candidate_not_found', `Candidate ${params.candidate_id} not found.`, {
|
|
32
|
+
candidate_id: params.candidate_id,
|
|
33
|
+
...ctx.recoveryFor('candidate_not_found'),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
23
36
|
const totalsResult = await fec.getCandidateTotals({ candidate_id: params.candidate_id }, ctx);
|
|
24
37
|
const totals = totalsResult.results[0];
|
|
25
38
|
ctx.log.info('Candidate resource fetched', { candidate_id: params.candidate_id });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"candidate.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/candidate.resource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uDAAuD,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAE1E,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,oCAAoC,EAAE;IAC9E,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EACT,uJAAuJ;IACzJ,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0DAA0D,CAAC;KAC9F,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG;QACvB,mBAAmB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAEzC,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;QAChC,MAAM,eAAe,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACzE,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,SAAS;
|
|
1
|
+
{"version":3,"file":"candidate.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/candidate.resource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uDAAuD,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAE1E,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,oCAAoC,EAAE;IAC9E,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EACT,uJAAuJ;IACzJ,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0DAA0D,CAAC;KAC9F,CAAC;IAEF,MAAM,EAAE;QACN;YACE,MAAM,EAAE,qBAAqB;YAC7B,IAAI,EAAE,gBAAgB,CAAC,QAAQ;YAC/B,IAAI,EAAE,mDAAmD;YACzD,QAAQ,EACN,iHAAiH;SACpH;KACF;IAED,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG;QACvB,mBAAmB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAEzC,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;QAChC,MAAM,eAAe,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACzE,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,GAAG,CAAC,IAAI,CAAC,qBAAqB,EAAE,aAAa,MAAM,CAAC,YAAY,aAAa,EAAE;gBACnF,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,GAAG,GAAG,CAAC,WAAW,CAAC,qBAAqB,CAAC;aAC1C,CAAC,CAAC;QACL,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,kBAAkB,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,EAAE,GAAG,CAAC,CAAC;QAC9F,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAEvC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,4BAA4B,EAAE,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;QAClF,OAAO,EAAE,GAAG,SAAS,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;IAC7C,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
* @module src/mcp-server/resources/definitions/committee.resource
|
|
5
5
|
*/
|
|
6
6
|
import { z } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
8
|
export declare const committeeResource: import("@cyanheads/mcp-ts-core").ResourceDefinition<z.ZodObject<{
|
|
8
9
|
committee_id: z.ZodString;
|
|
9
|
-
}, z.core.$strip>, undefined
|
|
10
|
+
}, z.core.$strip>, undefined, readonly [{
|
|
11
|
+
readonly reason: "committee_not_found";
|
|
12
|
+
readonly code: JsonRpcErrorCode.NotFound;
|
|
13
|
+
readonly when: "No committee exists for the supplied committee_id";
|
|
14
|
+
readonly recovery: "Verify the committee_id format (C + digits) or look up the committee by name via openfec_search_committees.";
|
|
15
|
+
}]>;
|
|
10
16
|
//# sourceMappingURL=committee.resource.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"committee.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/committee.resource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAY,CAAC,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"committee.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/committee.resource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAY,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAIjE,eAAO,MAAM,iBAAiB;;;;;;;GAmC5B,CAAC"}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* @module src/mcp-server/resources/definitions/committee.resource
|
|
5
5
|
*/
|
|
6
6
|
import { resource, z } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
8
|
+
import { validateCommitteeId } from '../../../mcp-server/tools/definitions/utils/id-validators.js';
|
|
7
9
|
import { getOpenFecService } from '../../../services/openfec/openfec-service.js';
|
|
8
10
|
export const committeeResource = resource('openfec://committee/{committee_id}', {
|
|
9
11
|
name: 'FEC Committee Profile',
|
|
@@ -12,12 +14,25 @@ export const committeeResource = resource('openfec://committee/{committee_id}',
|
|
|
12
14
|
params: z.object({
|
|
13
15
|
committee_id: z.string().describe('FEC committee ID (e.g., C00358796)'),
|
|
14
16
|
}),
|
|
17
|
+
errors: [
|
|
18
|
+
{
|
|
19
|
+
reason: 'committee_not_found',
|
|
20
|
+
code: JsonRpcErrorCode.NotFound,
|
|
21
|
+
when: 'No committee exists for the supplied committee_id',
|
|
22
|
+
recovery: 'Verify the committee_id format (C + digits) or look up the committee by name via openfec_search_committees.',
|
|
23
|
+
},
|
|
24
|
+
],
|
|
15
25
|
async handler(params, ctx) {
|
|
26
|
+
validateCommitteeId(params.committee_id);
|
|
16
27
|
const fec = getOpenFecService();
|
|
17
28
|
const result = await fec.getCommittee(params.committee_id, ctx);
|
|
18
29
|
const committee = result.results[0];
|
|
19
|
-
if (!committee)
|
|
20
|
-
throw
|
|
30
|
+
if (!committee) {
|
|
31
|
+
throw ctx.fail('committee_not_found', `Committee ${params.committee_id} not found.`, {
|
|
32
|
+
committee_id: params.committee_id,
|
|
33
|
+
...ctx.recoveryFor('committee_not_found'),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
21
36
|
ctx.log.info('Committee resource fetched', { committee_id: params.committee_id });
|
|
22
37
|
return committee;
|
|
23
38
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"committee.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/committee.resource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAE1E,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,oCAAoC,EAAE;IAC9E,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EACT,qJAAqJ;IACvJ,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;KACxE,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG;QACvB,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,SAAS;
|
|
1
|
+
{"version":3,"file":"committee.resource.js","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/committee.resource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uDAAuD,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAE1E,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,oCAAoC,EAAE;IAC9E,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EACT,qJAAqJ;IACvJ,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;KACxE,CAAC;IAEF,MAAM,EAAE;QACN;YACE,MAAM,EAAE,qBAAqB;YAC7B,IAAI,EAAE,gBAAgB,CAAC,QAAQ;YAC/B,IAAI,EAAE,mDAAmD;YACzD,QAAQ,EACN,6GAA6G;SAChH;KACF;IAED,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG;QACvB,mBAAmB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAEzC,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,GAAG,CAAC,IAAI,CAAC,qBAAqB,EAAE,aAAa,MAAM,CAAC,YAAY,aAAa,EAAE;gBACnF,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,GAAG,GAAG,CAAC,WAAW,CAAC,qBAAqB,CAAC;aAC1C,CAAC,CAAC;QACL,CAAC;QAED,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,4BAA4B,EAAE,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;QAClF,OAAO,SAAS,CAAC;IACnB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -8,18 +8,18 @@ import { z } from '@cyanheads/mcp-ts-core';
|
|
|
8
8
|
export declare const electionResource: import("@cyanheads/mcp-ts-core").ResourceDefinition<z.ZodObject<{
|
|
9
9
|
cycle: z.ZodString;
|
|
10
10
|
office: z.ZodString;
|
|
11
|
-
}, z.core.$strip>, undefined>;
|
|
11
|
+
}, z.core.$strip>, undefined, undefined>;
|
|
12
12
|
/** Senate races: openfec://election/2024/senate/AZ */
|
|
13
13
|
export declare const electionStateResource: import("@cyanheads/mcp-ts-core").ResourceDefinition<z.ZodObject<{
|
|
14
14
|
cycle: z.ZodString;
|
|
15
15
|
office: z.ZodString;
|
|
16
16
|
state: z.ZodString;
|
|
17
|
-
}, z.core.$strip>, undefined>;
|
|
17
|
+
}, z.core.$strip>, undefined, undefined>;
|
|
18
18
|
/** House races: openfec://election/2024/house/CA/12 */
|
|
19
19
|
export declare const electionDistrictResource: import("@cyanheads/mcp-ts-core").ResourceDefinition<z.ZodObject<{
|
|
20
20
|
cycle: z.ZodString;
|
|
21
21
|
office: z.ZodString;
|
|
22
22
|
state: z.ZodString;
|
|
23
23
|
district: z.ZodString;
|
|
24
|
-
}, z.core.$strip>, undefined>;
|
|
24
|
+
}, z.core.$strip>, undefined, undefined>;
|
|
25
25
|
//# sourceMappingURL=election.resource.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"election.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/election.resource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAY,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAmCrD,yEAAyE;AACzE,eAAO,MAAM,gBAAgB;;;
|
|
1
|
+
{"version":3,"file":"election.resource.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/election.resource.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAY,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAmCrD,yEAAyE;AACzE,eAAO,MAAM,gBAAgB;;;wCAU3B,CAAC;AAEH,sDAAsD;AACtD,eAAO,MAAM,qBAAqB;;;;wCAUhC,CAAC;AAEH,uDAAuD;AACvD,eAAO,MAAM,wBAAwB;;;;;wCAcpC,CAAC"}
|
|
@@ -7,10 +7,20 @@ export { committeeResource } from './committee.resource.js';
|
|
|
7
7
|
export { electionDistrictResource, electionResource, electionStateResource, } from './election.resource.js';
|
|
8
8
|
export declare const allResourceDefinitions: (import("@cyanheads/mcp-ts-core").ResourceDefinition<import("zod").ZodObject<{
|
|
9
9
|
candidate_id: import("zod").ZodString;
|
|
10
|
-
}, import("zod/v4/core").$strip>, undefined
|
|
10
|
+
}, import("zod/v4/core").$strip>, undefined, readonly [{
|
|
11
|
+
readonly reason: "candidate_not_found";
|
|
12
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
13
|
+
readonly when: "No candidate exists for the supplied candidate_id";
|
|
14
|
+
readonly recovery: "Verify the candidate_id format (H/S/P + digits) or look up the candidate by name via openfec_search_candidates.";
|
|
15
|
+
}]> | import("@cyanheads/mcp-ts-core").ResourceDefinition<import("zod").ZodObject<{
|
|
11
16
|
committee_id: import("zod").ZodString;
|
|
12
|
-
}, import("zod/v4/core").$strip>, undefined
|
|
17
|
+
}, import("zod/v4/core").$strip>, undefined, readonly [{
|
|
18
|
+
readonly reason: "committee_not_found";
|
|
19
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
20
|
+
readonly when: "No committee exists for the supplied committee_id";
|
|
21
|
+
readonly recovery: "Verify the committee_id format (C + digits) or look up the committee by name via openfec_search_committees.";
|
|
22
|
+
}]> | import("@cyanheads/mcp-ts-core").ResourceDefinition<import("zod").ZodObject<{
|
|
13
23
|
cycle: import("zod").ZodString;
|
|
14
24
|
office: import("zod").ZodString;
|
|
15
|
-
}, import("zod/v4/core").$strip>, undefined>)[];
|
|
25
|
+
}, import("zod/v4/core").$strip>, undefined, undefined>)[];
|
|
16
26
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAUhC,eAAO,MAAM,sBAAsB
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/resources/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAUhC,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;0DAMlC,CAAC"}
|
|
@@ -41,7 +41,7 @@ export declare const allToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolD
|
|
|
41
41
|
per_page: import("zod").ZodNumber;
|
|
42
42
|
}, import("zod/v4/core").$strip>;
|
|
43
43
|
search_criteria: import("zod").ZodOptional<import("zod").ZodObject<{}, import("zod/v4/core").$loose>>;
|
|
44
|
-
}, import("zod/v4/core").$strip
|
|
44
|
+
}, import("zod/v4/core").$strip>, undefined> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
45
45
|
mode: import("zod").ZodDefault<import("zod").ZodEnum<{
|
|
46
46
|
summary: "summary";
|
|
47
47
|
search: "search";
|
|
@@ -65,7 +65,27 @@ export declare const allToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolD
|
|
|
65
65
|
per_page: import("zod").ZodNumber;
|
|
66
66
|
}, import("zod/v4/core").$strip>;
|
|
67
67
|
search_criteria: import("zod").ZodOptional<import("zod").ZodObject<{}, import("zod/v4/core").$loose>>;
|
|
68
|
-
}, import("zod/v4/core").$strip
|
|
68
|
+
}, import("zod/v4/core").$strip>, readonly [{
|
|
69
|
+
readonly reason: "cycle_must_be_even";
|
|
70
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
71
|
+
readonly when: "Cycle is an odd year";
|
|
72
|
+
readonly recovery: "Federal election cycles are two-year periods ending in even years (e.g., 2024, 2026).";
|
|
73
|
+
}, {
|
|
74
|
+
readonly reason: "missing_state_for_office";
|
|
75
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
76
|
+
readonly when: "Senate or House office without a state and without a zip";
|
|
77
|
+
readonly recovery: "Provide a two-letter state code (e.g., AZ) or a zip code to scope the senate or house race.";
|
|
78
|
+
}, {
|
|
79
|
+
readonly reason: "missing_district_for_house";
|
|
80
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
81
|
+
readonly when: "House office without a district number and without a zip";
|
|
82
|
+
readonly recovery: "Provide a two-digit district number (e.g., \"07\") or a zip code to identify the House race.";
|
|
83
|
+
}, {
|
|
84
|
+
readonly reason: "summary_does_not_support_zip";
|
|
85
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
86
|
+
readonly when: "Summary mode invoked with a zip parameter";
|
|
87
|
+
readonly recovery: "Use mode \"search\" for ZIP-based lookups, or remove zip and use state and district for summary mode.";
|
|
88
|
+
}]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
69
89
|
query: import("zod").ZodOptional<import("zod").ZodString>;
|
|
70
90
|
candidate_id: import("zod").ZodOptional<import("zod").ZodString>;
|
|
71
91
|
state: import("zod").ZodOptional<import("zod").ZodString>;
|
|
@@ -103,7 +123,12 @@ export declare const allToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolD
|
|
|
103
123
|
per_page: import("zod").ZodNumber;
|
|
104
124
|
}, import("zod/v4/core").$strip>;
|
|
105
125
|
search_criteria: import("zod").ZodOptional<import("zod").ZodObject<{}, import("zod/v4/core").$loose>>;
|
|
106
|
-
}, import("zod/v4/core").$strip
|
|
126
|
+
}, import("zod/v4/core").$strip>, readonly [{
|
|
127
|
+
readonly reason: "candidate_not_found";
|
|
128
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
129
|
+
readonly when: "Single-candidate lookup by candidate_id returned no record";
|
|
130
|
+
readonly recovery: "Verify the candidate_id format (H/S/P + digits) or drop it and search by name, state, or cycle.";
|
|
131
|
+
}]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
107
132
|
query: import("zod").ZodOptional<import("zod").ZodString>;
|
|
108
133
|
committee_id: import("zod").ZodOptional<import("zod").ZodString>;
|
|
109
134
|
candidate_id: import("zod").ZodOptional<import("zod").ZodString>;
|
|
@@ -124,7 +149,12 @@ export declare const allToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolD
|
|
|
124
149
|
per_page: import("zod").ZodNumber;
|
|
125
150
|
}, import("zod/v4/core").$strip>;
|
|
126
151
|
search_criteria: import("zod").ZodOptional<import("zod").ZodObject<{}, import("zod/v4/core").$loose>>;
|
|
127
|
-
}, import("zod/v4/core").$strip
|
|
152
|
+
}, import("zod/v4/core").$strip>, readonly [{
|
|
153
|
+
readonly reason: "committee_not_found";
|
|
154
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
155
|
+
readonly when: "Single-committee lookup by committee_id returned no record";
|
|
156
|
+
readonly recovery: "Verify the committee_id format (C + digits) or drop it and search by name, candidate_id, or type.";
|
|
157
|
+
}]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
128
158
|
mode: import("zod").ZodDefault<import("zod").ZodEnum<{
|
|
129
159
|
by_size: "by_size";
|
|
130
160
|
by_state: "by_state";
|
|
@@ -163,7 +193,17 @@ export declare const allToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolD
|
|
|
163
193
|
per_page: import("zod").ZodNumber;
|
|
164
194
|
}, import("zod/v4/core").$strip>>;
|
|
165
195
|
search_criteria: import("zod").ZodOptional<import("zod").ZodObject<{}, import("zod/v4/core").$loose>>;
|
|
166
|
-
}, import("zod/v4/core").$strip
|
|
196
|
+
}, import("zod/v4/core").$strip>, readonly [{
|
|
197
|
+
readonly reason: "itemized_requires_committee_id";
|
|
198
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
199
|
+
readonly when: "Itemized mode invoked without a committee_id";
|
|
200
|
+
readonly recovery: "Provide a committee_id, switch to a by_size or by_state aggregate mode with candidate_id, or look up the candidate's committee with openfec_search_committees.";
|
|
201
|
+
}, {
|
|
202
|
+
readonly reason: "aggregate_requires_committee_id";
|
|
203
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
204
|
+
readonly when: "by_employer or by_occupation aggregate without a committee_id";
|
|
205
|
+
readonly recovery: "These aggregates roll up to a single committee — provide a committee_id for the spending committee.";
|
|
206
|
+
}]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
167
207
|
mode: import("zod").ZodDefault<import("zod").ZodEnum<{
|
|
168
208
|
by_purpose: "by_purpose";
|
|
169
209
|
by_recipient: "by_recipient";
|
|
@@ -199,7 +239,7 @@ export declare const allToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolD
|
|
|
199
239
|
per_page: import("zod").ZodNumber;
|
|
200
240
|
}, import("zod/v4/core").$strip>>;
|
|
201
241
|
search_criteria: import("zod").ZodOptional<import("zod").ZodObject<{}, import("zod/v4/core").$loose>>;
|
|
202
|
-
}, import("zod/v4/core").$strip
|
|
242
|
+
}, import("zod/v4/core").$strip>, undefined> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
203
243
|
mode: import("zod").ZodDefault<import("zod").ZodEnum<{
|
|
204
244
|
itemized: "itemized";
|
|
205
245
|
by_candidate: "by_candidate";
|
|
@@ -243,7 +283,12 @@ export declare const allToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolD
|
|
|
243
283
|
per_page: import("zod").ZodNumber;
|
|
244
284
|
}, import("zod/v4/core").$strip>>;
|
|
245
285
|
search_criteria: import("zod").ZodOptional<import("zod").ZodObject<{}, import("zod/v4/core").$loose>>;
|
|
246
|
-
}, import("zod/v4/core").$strip
|
|
286
|
+
}, import("zod/v4/core").$strip>, readonly [{
|
|
287
|
+
readonly reason: "by_candidate_requires_candidate_id";
|
|
288
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
289
|
+
readonly when: "by_candidate mode invoked without a candidate_id";
|
|
290
|
+
readonly recovery: "Find the candidate ID via openfec_search_candidates, then pass it here to see independent expenditures supporting or opposing that candidate.";
|
|
291
|
+
}]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
247
292
|
committee_id: import("zod").ZodOptional<import("zod").ZodString>;
|
|
248
293
|
candidate_id: import("zod").ZodOptional<import("zod").ZodString>;
|
|
249
294
|
filer_name: import("zod").ZodOptional<import("zod").ZodString>;
|
|
@@ -266,7 +311,7 @@ export declare const allToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolD
|
|
|
266
311
|
per_page: import("zod").ZodNumber;
|
|
267
312
|
}, import("zod/v4/core").$strip>;
|
|
268
313
|
search_criteria: import("zod").ZodOptional<import("zod").ZodObject<{}, import("zod/v4/core").$loose>>;
|
|
269
|
-
}, import("zod/v4/core").$strip
|
|
314
|
+
}, import("zod/v4/core").$strip>, undefined> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
270
315
|
query: import("zod").ZodOptional<import("zod").ZodString>;
|
|
271
316
|
type: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
272
317
|
advisory_opinions: "advisory_opinions";
|
|
@@ -290,5 +335,10 @@ export declare const allToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolD
|
|
|
290
335
|
results: import("zod").ZodArray<import("zod").ZodObject<{}, import("zod/v4/core").$loose>>;
|
|
291
336
|
total_count: import("zod").ZodNumber;
|
|
292
337
|
search_criteria: import("zod").ZodOptional<import("zod").ZodObject<{}, import("zod/v4/core").$loose>>;
|
|
293
|
-
}, import("zod/v4/core").$strip
|
|
338
|
+
}, import("zod/v4/core").$strip>, readonly [{
|
|
339
|
+
readonly reason: "missing_filter";
|
|
340
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
341
|
+
readonly when: "Called without query, type, or a specific identifier (ao_number / case_number)";
|
|
342
|
+
readonly recovery: "Provide at least a search query, document type, or specific identifier (ao_number, case_number) to scope the legal search.";
|
|
343
|
+
}]>)[];
|
|
294
344
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAYrD,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAYrD,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAU9B,CAAC"}
|
|
@@ -34,5 +34,5 @@ export declare const lookupCalendar: import("@cyanheads/mcp-ts-core").ToolDefini
|
|
|
34
34
|
per_page: z.ZodNumber;
|
|
35
35
|
}, z.core.$strip>;
|
|
36
36
|
search_criteria: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
|
|
37
|
-
}, z.core.$strip
|
|
37
|
+
}, z.core.$strip>, undefined>;
|
|
38
38
|
//# sourceMappingURL=lookup-calendar.tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lookup-calendar.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/lookup-calendar.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAUjD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"lookup-calendar.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/lookup-calendar.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAUjD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAuJzB,CAAC"}
|
|
@@ -46,7 +46,9 @@ export const lookupCalendar = tool('openfec_lookup_calendar', {
|
|
|
46
46
|
}),
|
|
47
47
|
output: z.object({
|
|
48
48
|
results: z
|
|
49
|
-
.array(z
|
|
49
|
+
.array(z
|
|
50
|
+
.looseObject({})
|
|
51
|
+
.describe('A calendar record (event, filing deadline, or election date depending on mode).'))
|
|
50
52
|
.describe('Calendar records — events, filing deadlines, or election dates depending on mode.'),
|
|
51
53
|
pagination: z
|
|
52
54
|
.object({
|