@cyanheads/openfec-mcp-server 0.2.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 +328 -0
- package/Dockerfile +99 -0
- package/LICENSE +191 -0
- package/README.md +297 -0
- package/dist/config/server-config.d.ts +17 -0
- package/dist/config/server-config.d.ts.map +1 -0
- package/dist/config/server-config.js +31 -0
- package/dist/config/server-config.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/campaign-analysis.prompt.d.ts +13 -0
- package/dist/mcp-server/prompts/definitions/campaign-analysis.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/campaign-analysis.prompt.js +79 -0
- package/dist/mcp-server/prompts/definitions/campaign-analysis.prompt.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/index.d.ts +12 -0
- package/dist/mcp-server/prompts/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/index.js +10 -0
- package/dist/mcp-server/prompts/definitions/index.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/money-trail.prompt.d.ts +13 -0
- package/dist/mcp-server/prompts/definitions/money-trail.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/money-trail.prompt.js +78 -0
- package/dist/mcp-server/prompts/definitions/money-trail.prompt.js.map +1 -0
- package/dist/mcp-server/resources/definitions/candidate.resource.d.ts +10 -0
- package/dist/mcp-server/resources/definitions/candidate.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/candidate.resource.js +28 -0
- package/dist/mcp-server/resources/definitions/candidate.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/committee.resource.d.ts +10 -0
- package/dist/mcp-server/resources/definitions/committee.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/committee.resource.js +26 -0
- package/dist/mcp-server/resources/definitions/committee.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/election.resource.d.ts +25 -0
- package/dist/mcp-server/resources/definitions/election.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/election.resource.js +73 -0
- package/dist/mcp-server/resources/definitions/election.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/index.d.ts +16 -0
- package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/index.js +18 -0
- package/dist/mcp-server/resources/definitions/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/index.d.ts +285 -0
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/index.js +34 -0
- package/dist/mcp-server/tools/definitions/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/lookup-calendar.tool.d.ts +37 -0
- package/dist/mcp-server/tools/definitions/lookup-calendar.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/lookup-calendar.tool.js +172 -0
- package/dist/mcp-server/tools/definitions/lookup-calendar.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/lookup-elections.tool.d.ts +31 -0
- package/dist/mcp-server/tools/definitions/lookup-elections.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/lookup-elections.tool.js +134 -0
- package/dist/mcp-server/tools/definitions/lookup-elections.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-candidates.tool.d.ts +46 -0
- package/dist/mcp-server/tools/definitions/search-candidates.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-candidates.tool.js +170 -0
- package/dist/mcp-server/tools/definitions/search-candidates.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-committees.tool.d.ts +29 -0
- package/dist/mcp-server/tools/definitions/search-committees.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-committees.tool.js +120 -0
- package/dist/mcp-server/tools/definitions/search-committees.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-contributions.tool.d.ts +47 -0
- package/dist/mcp-server/tools/definitions/search-contributions.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-contributions.tool.js +252 -0
- package/dist/mcp-server/tools/definitions/search-contributions.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-disbursements.tool.d.ts +43 -0
- package/dist/mcp-server/tools/definitions/search-disbursements.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-disbursements.tool.js +212 -0
- package/dist/mcp-server/tools/definitions/search-disbursements.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-expenditures.tool.d.ts +52 -0
- package/dist/mcp-server/tools/definitions/search-expenditures.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-expenditures.tool.js +247 -0
- package/dist/mcp-server/tools/definitions/search-expenditures.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-filings.tool.d.ts +31 -0
- package/dist/mcp-server/tools/definitions/search-filings.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-filings.tool.js +123 -0
- package/dist/mcp-server/tools/definitions/search-filings.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-legal.tool.d.ts +32 -0
- package/dist/mcp-server/tools/definitions/search-legal.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-legal.tool.js +179 -0
- package/dist/mcp-server/tools/definitions/search-legal.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/utils/format-helpers.d.ts +19 -0
- package/dist/mcp-server/tools/definitions/utils/format-helpers.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/utils/format-helpers.js +19 -0
- package/dist/mcp-server/tools/definitions/utils/format-helpers.js.map +1 -0
- package/dist/mcp-server/tools/definitions/utils/id-validators.d.ts +11 -0
- package/dist/mcp-server/tools/definitions/utils/id-validators.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/utils/id-validators.js +22 -0
- package/dist/mcp-server/tools/definitions/utils/id-validators.js.map +1 -0
- package/dist/services/openfec/openfec-service.d.ts +54 -0
- package/dist/services/openfec/openfec-service.d.ts.map +1 -0
- package/dist/services/openfec/openfec-service.js +384 -0
- package/dist/services/openfec/openfec-service.js.map +1 -0
- package/dist/services/openfec/types.d.ts +86 -0
- package/dist/services/openfec/types.d.ts.map +1 -0
- package/dist/services/openfec/types.js +8 -0
- package/dist/services/openfec/types.js.map +1 -0
- package/package.json +91 -0
- package/server.json +97 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Calendar lookup tool — FEC calendar events, filing deadlines,
|
|
3
|
+
* and election dates.
|
|
4
|
+
* @module mcp-server/tools/definitions/lookup-calendar.tool
|
|
5
|
+
*/
|
|
6
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
import { getOpenFecService } from '../../../services/openfec/openfec-service.js';
|
|
8
|
+
export const lookupCalendar = tool('openfec_lookup_calendar', {
|
|
9
|
+
description: 'Look up FEC calendar events, filing deadlines, and election dates.',
|
|
10
|
+
annotations: { readOnlyHint: true, idempotentHint: true },
|
|
11
|
+
input: z.object({
|
|
12
|
+
mode: z
|
|
13
|
+
.enum(['events', 'filing_deadlines', 'election_dates'])
|
|
14
|
+
.default('events')
|
|
15
|
+
.describe('events = FEC calendar events. filing_deadlines = report due dates. election_dates = upcoming/past elections.'),
|
|
16
|
+
state: z
|
|
17
|
+
.string()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe('Two-letter state code (e.g., AZ, CA). Primarily for election_dates mode.'),
|
|
20
|
+
office: z
|
|
21
|
+
.enum(['H', 'S', 'P'])
|
|
22
|
+
.optional()
|
|
23
|
+
.describe('Office sought (H=House, S=Senate, P=President). Election dates mode.'),
|
|
24
|
+
report_type: z
|
|
25
|
+
.string()
|
|
26
|
+
.optional()
|
|
27
|
+
.describe('Report type code (e.g. "Q1", "Q2"). Filing deadlines mode only.'),
|
|
28
|
+
report_year: z.number().int().optional().describe('Report year. Filing deadlines mode.'),
|
|
29
|
+
category: z
|
|
30
|
+
.string()
|
|
31
|
+
.optional()
|
|
32
|
+
.describe('Calendar category ID for events mode. Common values: "32" (reporting deadlines), "33" (election dates), "34" (quarterly filings). Events mode only.'),
|
|
33
|
+
election_year: z.number().int().optional().describe('Election year. Election dates mode.'),
|
|
34
|
+
description: z.string().optional().describe('Full-text event description search. Events mode.'),
|
|
35
|
+
min_date: z.string().optional().describe('Earliest date (YYYY-MM-DD).'),
|
|
36
|
+
max_date: z.string().optional().describe('Latest date (YYYY-MM-DD).'),
|
|
37
|
+
page: z.number().int().min(1).default(1).describe('Page number (1-indexed). Default 1.'),
|
|
38
|
+
per_page: z
|
|
39
|
+
.number()
|
|
40
|
+
.int()
|
|
41
|
+
.min(1)
|
|
42
|
+
.max(100)
|
|
43
|
+
.default(20)
|
|
44
|
+
.describe('Results per page. Default 20, max 100.'),
|
|
45
|
+
}),
|
|
46
|
+
output: z.object({
|
|
47
|
+
results: z
|
|
48
|
+
.array(z.record(z.string(), z.unknown()))
|
|
49
|
+
.describe('Calendar records — events, filing deadlines, or election dates depending on mode.'),
|
|
50
|
+
pagination: z
|
|
51
|
+
.object({
|
|
52
|
+
page: z.number().describe('Current page number.'),
|
|
53
|
+
pages: z.number().describe('Total pages available.'),
|
|
54
|
+
count: z.number().describe('Total result count.'),
|
|
55
|
+
per_page: z.number().describe('Results per page.'),
|
|
56
|
+
})
|
|
57
|
+
.describe('Page-based pagination metadata.'),
|
|
58
|
+
}),
|
|
59
|
+
async handler(input, ctx) {
|
|
60
|
+
const fec = getOpenFecService();
|
|
61
|
+
const params = {
|
|
62
|
+
page: input.page,
|
|
63
|
+
per_page: input.per_page,
|
|
64
|
+
};
|
|
65
|
+
if (input.mode === 'filing_deadlines') {
|
|
66
|
+
// /reporting-dates/ uses min_due_date / max_due_date
|
|
67
|
+
if (input.min_date)
|
|
68
|
+
params.min_due_date = input.min_date;
|
|
69
|
+
if (input.max_date)
|
|
70
|
+
params.max_due_date = input.max_date;
|
|
71
|
+
if (input.report_type)
|
|
72
|
+
params.report_type = input.report_type;
|
|
73
|
+
if (input.report_year)
|
|
74
|
+
params.report_year = input.report_year;
|
|
75
|
+
ctx.log.info('Fetching filing deadlines', {
|
|
76
|
+
report_type: input.report_type,
|
|
77
|
+
report_year: input.report_year,
|
|
78
|
+
});
|
|
79
|
+
const data = await fec.getReportingDates(params, ctx);
|
|
80
|
+
return { results: data.results, pagination: data.pagination };
|
|
81
|
+
}
|
|
82
|
+
if (input.mode === 'election_dates') {
|
|
83
|
+
// /election-dates/ uses min_election_date / max_election_date
|
|
84
|
+
if (input.min_date)
|
|
85
|
+
params.min_election_date = input.min_date;
|
|
86
|
+
if (input.max_date)
|
|
87
|
+
params.max_election_date = input.max_date;
|
|
88
|
+
if (input.state)
|
|
89
|
+
params.election_state = input.state;
|
|
90
|
+
if (input.office)
|
|
91
|
+
params.office_sought = input.office;
|
|
92
|
+
if (input.election_year)
|
|
93
|
+
params.election_year = input.election_year;
|
|
94
|
+
ctx.log.info('Fetching election dates', {
|
|
95
|
+
state: input.state,
|
|
96
|
+
election_year: input.election_year,
|
|
97
|
+
});
|
|
98
|
+
const data = await fec.getElectionDates(params, ctx);
|
|
99
|
+
return { results: data.results, pagination: data.pagination };
|
|
100
|
+
}
|
|
101
|
+
/* Default: events mode — /calendar-dates/ uses min_start_date / max_start_date */
|
|
102
|
+
if (input.min_date)
|
|
103
|
+
params.min_start_date = input.min_date;
|
|
104
|
+
if (input.max_date)
|
|
105
|
+
params.max_start_date = input.max_date;
|
|
106
|
+
if (input.description)
|
|
107
|
+
params.description = input.description;
|
|
108
|
+
if (input.category)
|
|
109
|
+
params.calendar_category_id = input.category;
|
|
110
|
+
ctx.log.info('Fetching calendar events', { description: input.description });
|
|
111
|
+
const data = await fec.getCalendarDates(params, ctx);
|
|
112
|
+
return { results: data.results, pagination: data.pagination };
|
|
113
|
+
},
|
|
114
|
+
format: (result) => {
|
|
115
|
+
if (result.results.length === 0) {
|
|
116
|
+
return [
|
|
117
|
+
{
|
|
118
|
+
type: 'text',
|
|
119
|
+
text: 'No calendar entries found. Try widening the date range, removing filters, or checking a different mode (events, filing_deadlines, election_dates).',
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
const lines = result.results.map((r) => {
|
|
124
|
+
/**
|
|
125
|
+
* Unified formatting across all three modes. Each mode returns different
|
|
126
|
+
* field names; we pull from whichever fields are present.
|
|
127
|
+
*/
|
|
128
|
+
const summary = r.summary ?? r.report_type ?? r.election_type_full ?? '';
|
|
129
|
+
const description = r.description ?? '';
|
|
130
|
+
const date = r.start_date ?? r.due_date ?? r.election_date ?? r.event_date ?? '';
|
|
131
|
+
const endDate = r.end_date ?? '';
|
|
132
|
+
const state = r.election_state ?? r.state ?? '';
|
|
133
|
+
const office = r.office_sought ?? '';
|
|
134
|
+
const year = r.report_year ?? r.election_year ?? '';
|
|
135
|
+
const category = r.category ?? '';
|
|
136
|
+
const location = r.location ?? '';
|
|
137
|
+
const url = r.url ?? '';
|
|
138
|
+
const parts = [];
|
|
139
|
+
if (summary)
|
|
140
|
+
parts.push(`**${summary}**`);
|
|
141
|
+
if (description && description !== summary)
|
|
142
|
+
parts.push(String(description));
|
|
143
|
+
const meta = [];
|
|
144
|
+
if (date)
|
|
145
|
+
meta.push(`Date: ${date}${endDate && endDate !== date ? ` to ${endDate}` : ''}`);
|
|
146
|
+
if (state)
|
|
147
|
+
meta.push(`State: ${state}`);
|
|
148
|
+
if (office)
|
|
149
|
+
meta.push(`Office: ${office}`);
|
|
150
|
+
if (year)
|
|
151
|
+
meta.push(`Year: ${year}`);
|
|
152
|
+
if (category)
|
|
153
|
+
meta.push(`Category: ${category}`);
|
|
154
|
+
if (location)
|
|
155
|
+
meta.push(`Location: ${location}`);
|
|
156
|
+
if (meta.length > 0)
|
|
157
|
+
parts.push(meta.join(' | '));
|
|
158
|
+
if (url)
|
|
159
|
+
parts.push(`[Link](${url})`);
|
|
160
|
+
/** Coverage period for filing deadlines. */
|
|
161
|
+
const covStart = r.coverage_start_date;
|
|
162
|
+
const covEnd = r.coverage_end_date;
|
|
163
|
+
if (covStart && covEnd)
|
|
164
|
+
parts.push(`Coverage: ${covStart} to ${covEnd}`);
|
|
165
|
+
return parts.join('\n ');
|
|
166
|
+
});
|
|
167
|
+
const { page, pages, count } = result.pagination;
|
|
168
|
+
lines.push(`\n_${count} result(s) — page ${page}/${pages}_`);
|
|
169
|
+
return [{ type: 'text', text: lines.join('\n\n') }];
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
//# sourceMappingURL=lookup-calendar.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookup-calendar.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/lookup-calendar.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Election lookup tool — find federal election races and candidate
|
|
3
|
+
* financial summaries by office, cycle, state, and district.
|
|
4
|
+
* @module mcp-server/tools/definitions/lookup-elections.tool
|
|
5
|
+
*/
|
|
6
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
export declare const lookupElections: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
8
|
+
mode: z.ZodDefault<z.ZodEnum<{
|
|
9
|
+
summary: "summary";
|
|
10
|
+
search: "search";
|
|
11
|
+
}>>;
|
|
12
|
+
office: z.ZodEnum<{
|
|
13
|
+
president: "president";
|
|
14
|
+
senate: "senate";
|
|
15
|
+
house: "house";
|
|
16
|
+
}>;
|
|
17
|
+
cycle: z.ZodNumber;
|
|
18
|
+
state: z.ZodOptional<z.ZodString>;
|
|
19
|
+
district: z.ZodOptional<z.ZodString>;
|
|
20
|
+
zip: z.ZodOptional<z.ZodString>;
|
|
21
|
+
election_full: z.ZodDefault<z.ZodBoolean>;
|
|
22
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
23
|
+
results: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
24
|
+
pagination: z.ZodObject<{
|
|
25
|
+
page: z.ZodNumber;
|
|
26
|
+
pages: z.ZodNumber;
|
|
27
|
+
count: z.ZodNumber;
|
|
28
|
+
per_page: z.ZodNumber;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
}, z.core.$strip>>;
|
|
31
|
+
//# sourceMappingURL=lookup-elections.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookup-elections.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/lookup-elections.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAMjD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;kBA2I1B,CAAC"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Election lookup tool — find federal election races and candidate
|
|
3
|
+
* financial summaries by office, cycle, state, and district.
|
|
4
|
+
* @module mcp-server/tools/definitions/lookup-elections.tool
|
|
5
|
+
*/
|
|
6
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
import { invalidParams } from '@cyanheads/mcp-ts-core/errors';
|
|
8
|
+
import { getOpenFecService } from '../../../services/openfec/openfec-service.js';
|
|
9
|
+
import { fmt$ } from './utils/format-helpers.js';
|
|
10
|
+
export const lookupElections = tool('openfec_lookup_elections', {
|
|
11
|
+
description: 'Look up federal election races and candidate financial summaries. ' +
|
|
12
|
+
"Find who's running in a race with fundraising totals, or get an aggregate race summary.",
|
|
13
|
+
annotations: { readOnlyHint: true, idempotentHint: true },
|
|
14
|
+
input: z.object({
|
|
15
|
+
mode: z
|
|
16
|
+
.enum(['search', 'summary'])
|
|
17
|
+
.default('search')
|
|
18
|
+
.describe('search = candidates in a race with financial totals. summary = aggregate race financial summary.'),
|
|
19
|
+
office: z
|
|
20
|
+
.enum(['president', 'senate', 'house'])
|
|
21
|
+
.describe('Office sought: president, senate, or house.'),
|
|
22
|
+
cycle: z.number().int().describe('Election cycle year (even years only, e.g. 2024).'),
|
|
23
|
+
state: z
|
|
24
|
+
.string()
|
|
25
|
+
.optional()
|
|
26
|
+
.describe('Two-letter US state code (e.g., AZ, CA). Required for senate and house races.'),
|
|
27
|
+
district: z
|
|
28
|
+
.string()
|
|
29
|
+
.optional()
|
|
30
|
+
.describe('Two-digit district number (e.g. "07"). Required for house races.'),
|
|
31
|
+
zip: z
|
|
32
|
+
.string()
|
|
33
|
+
.optional()
|
|
34
|
+
.describe('ZIP code — finds races covering this ZIP. Search mode only.'),
|
|
35
|
+
election_full: z
|
|
36
|
+
.boolean()
|
|
37
|
+
.default(true)
|
|
38
|
+
.describe('Expand to full election period (4yr president, 6yr senate, 2yr house). Default true.'),
|
|
39
|
+
}),
|
|
40
|
+
output: z.object({
|
|
41
|
+
results: z
|
|
42
|
+
.array(z.record(z.string(), z.unknown()))
|
|
43
|
+
.describe('Election race records — candidates with financial data, or aggregate summary.'),
|
|
44
|
+
pagination: z
|
|
45
|
+
.object({
|
|
46
|
+
page: z.number().describe('Current page number.'),
|
|
47
|
+
pages: z.number().describe('Total pages available.'),
|
|
48
|
+
count: z.number().describe('Total result count.'),
|
|
49
|
+
per_page: z.number().describe('Results per page.'),
|
|
50
|
+
})
|
|
51
|
+
.describe('Page-based pagination metadata.'),
|
|
52
|
+
}),
|
|
53
|
+
async handler(input, ctx) {
|
|
54
|
+
if (input.cycle % 2 !== 0) {
|
|
55
|
+
throw invalidParams('Election cycles are even years (e.g., 2024, 2026).');
|
|
56
|
+
}
|
|
57
|
+
if ((input.office === 'senate' || input.office === 'house') && !input.state) {
|
|
58
|
+
throw invalidParams('Senate and House election lookups require a state.');
|
|
59
|
+
}
|
|
60
|
+
if (input.office === 'house' && !input.district) {
|
|
61
|
+
throw invalidParams('House election lookups require a district number.');
|
|
62
|
+
}
|
|
63
|
+
const fec = getOpenFecService();
|
|
64
|
+
const params = {
|
|
65
|
+
office: input.office,
|
|
66
|
+
cycle: input.cycle,
|
|
67
|
+
election_full: input.election_full,
|
|
68
|
+
};
|
|
69
|
+
if (input.state)
|
|
70
|
+
params.state = input.state;
|
|
71
|
+
if (input.district)
|
|
72
|
+
params.district = input.district;
|
|
73
|
+
if (input.zip)
|
|
74
|
+
params.zip = input.zip;
|
|
75
|
+
if (input.mode === 'summary') {
|
|
76
|
+
ctx.log.info('Fetching election summary', { office: input.office, cycle: input.cycle });
|
|
77
|
+
const summary = await fec.getElectionSummary(params, ctx);
|
|
78
|
+
return {
|
|
79
|
+
results: [summary],
|
|
80
|
+
pagination: { page: 1, pages: 1, count: 1, per_page: 1 },
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
ctx.log.info('Searching elections', { office: input.office, cycle: input.cycle });
|
|
84
|
+
const data = await fec.searchElections(params, ctx);
|
|
85
|
+
return { results: data.results, pagination: data.pagination };
|
|
86
|
+
},
|
|
87
|
+
format: (result) => {
|
|
88
|
+
if (result.results.length === 0) {
|
|
89
|
+
return [
|
|
90
|
+
{
|
|
91
|
+
type: 'text',
|
|
92
|
+
text: 'No election results found. Verify the cycle is an even year, the state code is correct for senate/house races, and the district exists for the given state.',
|
|
93
|
+
},
|
|
94
|
+
];
|
|
95
|
+
}
|
|
96
|
+
// Summary mode returns a single flat object with aggregate totals
|
|
97
|
+
const first = result.results[0];
|
|
98
|
+
if (first &&
|
|
99
|
+
'receipts' in first &&
|
|
100
|
+
'disbursements' in first &&
|
|
101
|
+
'independent_expenditures' in first) {
|
|
102
|
+
const lines = [
|
|
103
|
+
'**Election Summary**',
|
|
104
|
+
`Candidates: ${first.count ?? 'N/A'}`,
|
|
105
|
+
`Total Raised: ${fmt$(first.receipts)}`,
|
|
106
|
+
`Total Spent: ${fmt$(first.disbursements)}`,
|
|
107
|
+
`Independent Expenditures: ${fmt$(first.independent_expenditures)}`,
|
|
108
|
+
];
|
|
109
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
110
|
+
}
|
|
111
|
+
const lines = result.results.map((r) => {
|
|
112
|
+
const name = r.candidate_name ?? r.candidate_id ?? 'Unknown';
|
|
113
|
+
const party = r.party_full ?? r.party ?? '';
|
|
114
|
+
const status = r.incumbent_challenge_full ?? '';
|
|
115
|
+
const receipts = fmt$(r.total_receipts);
|
|
116
|
+
const disbursements = fmt$(r.total_disbursements);
|
|
117
|
+
const cash = fmt$(r.cash_on_hand_end_period);
|
|
118
|
+
const parts = [`**${name}**`];
|
|
119
|
+
if (party)
|
|
120
|
+
parts.push(`(${party})`);
|
|
121
|
+
if (status)
|
|
122
|
+
parts.push(`— ${status}`);
|
|
123
|
+
parts.push(`\n Raised: ${receipts} | Spent: ${disbursements} | Cash on hand: ${cash}`);
|
|
124
|
+
const coverage = r.coverage_end_date;
|
|
125
|
+
if (coverage)
|
|
126
|
+
parts.push(`| Through: ${coverage}`);
|
|
127
|
+
return parts.join(' ');
|
|
128
|
+
});
|
|
129
|
+
const { page, pages, count } = result.pagination;
|
|
130
|
+
lines.push(`\n_${count} result(s) — page ${page}/${pages}_`);
|
|
131
|
+
return [{ type: 'text', text: lines.join('\n\n') }];
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
//# sourceMappingURL=lookup-elections.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookup-elections.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/lookup-elections.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool for searching and retrieving FEC candidate records.
|
|
3
|
+
* Supports full-text search, single-candidate lookup by ID, and optional
|
|
4
|
+
* financial totals merging from the /candidates/totals/ endpoint.
|
|
5
|
+
* @module mcp-server/tools/definitions/search-candidates.tool
|
|
6
|
+
*/
|
|
7
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
8
|
+
export declare const searchCandidates: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
9
|
+
query: z.ZodOptional<z.ZodString>;
|
|
10
|
+
candidate_id: z.ZodOptional<z.ZodString>;
|
|
11
|
+
state: z.ZodOptional<z.ZodString>;
|
|
12
|
+
district: z.ZodOptional<z.ZodString>;
|
|
13
|
+
office: z.ZodOptional<z.ZodEnum<{
|
|
14
|
+
H: "H";
|
|
15
|
+
S: "S";
|
|
16
|
+
P: "P";
|
|
17
|
+
}>>;
|
|
18
|
+
party: z.ZodOptional<z.ZodString>;
|
|
19
|
+
cycle: z.ZodOptional<z.ZodNumber>;
|
|
20
|
+
election_year: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
incumbent_challenge: z.ZodOptional<z.ZodEnum<{
|
|
22
|
+
I: "I";
|
|
23
|
+
C: "C";
|
|
24
|
+
O: "O";
|
|
25
|
+
}>>;
|
|
26
|
+
candidate_status: z.ZodOptional<z.ZodEnum<{
|
|
27
|
+
P: "P";
|
|
28
|
+
C: "C";
|
|
29
|
+
F: "F";
|
|
30
|
+
N: "N";
|
|
31
|
+
}>>;
|
|
32
|
+
has_raised_funds: z.ZodOptional<z.ZodBoolean>;
|
|
33
|
+
include_totals: z.ZodOptional<z.ZodBoolean>;
|
|
34
|
+
page: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
per_page: z.ZodOptional<z.ZodNumber>;
|
|
36
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
37
|
+
candidates: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
38
|
+
totals: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
39
|
+
pagination: z.ZodObject<{
|
|
40
|
+
page: z.ZodNumber;
|
|
41
|
+
pages: z.ZodNumber;
|
|
42
|
+
count: z.ZodNumber;
|
|
43
|
+
per_page: z.ZodNumber;
|
|
44
|
+
}, z.core.$strip>;
|
|
45
|
+
}, z.core.$strip>>;
|
|
46
|
+
//# sourceMappingURL=search-candidates.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-candidates.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-candidates.tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAOjD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAsL3B,CAAC"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool for searching and retrieving FEC candidate records.
|
|
3
|
+
* Supports full-text search, single-candidate lookup by ID, and optional
|
|
4
|
+
* financial totals merging from the /candidates/totals/ endpoint.
|
|
5
|
+
* @module mcp-server/tools/definitions/search-candidates.tool
|
|
6
|
+
*/
|
|
7
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
8
|
+
import { notFound } from '@cyanheads/mcp-ts-core/errors';
|
|
9
|
+
import { getOpenFecService } from '../../../services/openfec/openfec-service.js';
|
|
10
|
+
import { fmt$, PaginationSchema, str } from './utils/format-helpers.js';
|
|
11
|
+
import { validateCandidateId } from './utils/id-validators.js';
|
|
12
|
+
export const searchCandidates = tool('openfec_search_candidates', {
|
|
13
|
+
description: 'Find federal candidates by name, state, office, party, or cycle. ' +
|
|
14
|
+
'Retrieve a specific candidate by FEC ID with financial totals. ' +
|
|
15
|
+
'Candidate IDs start with H (House), S (Senate), or P (President) followed by digits.',
|
|
16
|
+
annotations: { readOnlyHint: true, idempotentHint: true },
|
|
17
|
+
input: z.object({
|
|
18
|
+
query: z.string().optional().describe('Full-text candidate name search.'),
|
|
19
|
+
candidate_id: z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe('FEC candidate ID (e.g., P00003392, H2CO07170). When provided, returns a single candidate with full detail.'),
|
|
23
|
+
state: z.string().optional().describe('Two-letter US state code (e.g., AZ, CA).'),
|
|
24
|
+
district: z.string().optional().describe('Two-digit district number for House candidates.'),
|
|
25
|
+
office: z
|
|
26
|
+
.enum(['H', 'S', 'P'])
|
|
27
|
+
.optional()
|
|
28
|
+
.describe('Filter by office: H=House, S=Senate, P=President.'),
|
|
29
|
+
party: z.string().optional().describe('Three-letter party code (e.g., DEM, REP, LIB).'),
|
|
30
|
+
cycle: z.number().optional().describe('Two-year election cycle (even year, e.g., 2024).'),
|
|
31
|
+
election_year: z.number().optional().describe('Specific election year the candidate ran in.'),
|
|
32
|
+
incumbent_challenge: z
|
|
33
|
+
.enum(['I', 'C', 'O'])
|
|
34
|
+
.optional()
|
|
35
|
+
.describe('Incumbent status: I=incumbent, C=challenger, O=open seat.'),
|
|
36
|
+
candidate_status: z
|
|
37
|
+
.enum(['C', 'F', 'N', 'P'])
|
|
38
|
+
.optional()
|
|
39
|
+
.describe('Candidate status: C=present, F=future, N=not yet, P=prior.'),
|
|
40
|
+
has_raised_funds: z
|
|
41
|
+
.boolean()
|
|
42
|
+
.optional()
|
|
43
|
+
.describe('Only candidates whose committee has received receipts.'),
|
|
44
|
+
include_totals: z
|
|
45
|
+
.boolean()
|
|
46
|
+
.optional()
|
|
47
|
+
.describe('Include financial totals (receipts, disbursements, cash on hand). Defaults to true when fetching by candidate_id. Adds a second API call.'),
|
|
48
|
+
page: z.number().optional().describe('Page number (1-indexed). Default 1.'),
|
|
49
|
+
per_page: z.number().optional().describe('Results per page. Default 20, max 100.'),
|
|
50
|
+
}),
|
|
51
|
+
output: z.object({
|
|
52
|
+
candidates: z
|
|
53
|
+
.array(z.record(z.string(), z.unknown()))
|
|
54
|
+
.describe('Candidate records with candidate_id, name, party, state, office, cycles, etc.'),
|
|
55
|
+
totals: z
|
|
56
|
+
.array(z.record(z.string(), z.unknown()))
|
|
57
|
+
.optional()
|
|
58
|
+
.describe('Financial totals (receipts, disbursements, cash_on_hand) when include_totals is true.'),
|
|
59
|
+
pagination: PaginationSchema.describe('Page-based pagination metadata.'),
|
|
60
|
+
}),
|
|
61
|
+
async handler(input, ctx) {
|
|
62
|
+
const fec = getOpenFecService();
|
|
63
|
+
if (input.candidate_id)
|
|
64
|
+
validateCandidateId(input.candidate_id);
|
|
65
|
+
const shouldIncludeTotals = input.include_totals ?? !!input.candidate_id;
|
|
66
|
+
let candidateResult;
|
|
67
|
+
if (input.candidate_id) {
|
|
68
|
+
// Single candidate lookup
|
|
69
|
+
ctx.log.info('Fetching candidate by ID', { candidate_id: input.candidate_id });
|
|
70
|
+
candidateResult = await fec.getCandidate(input.candidate_id, ctx);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
// Search with filters
|
|
74
|
+
const params = {
|
|
75
|
+
q: input.query,
|
|
76
|
+
state: input.state,
|
|
77
|
+
district: input.district,
|
|
78
|
+
office: input.office,
|
|
79
|
+
party: input.party,
|
|
80
|
+
cycle: input.cycle,
|
|
81
|
+
election_year: input.election_year,
|
|
82
|
+
incumbent_challenge: input.incumbent_challenge,
|
|
83
|
+
candidate_status: input.candidate_status,
|
|
84
|
+
has_raised_funds: input.has_raised_funds,
|
|
85
|
+
page: input.page,
|
|
86
|
+
per_page: input.per_page,
|
|
87
|
+
};
|
|
88
|
+
ctx.log.info('Searching candidates', { query: input.query, state: input.state });
|
|
89
|
+
candidateResult = await fec.searchCandidates(params, ctx);
|
|
90
|
+
}
|
|
91
|
+
const candidates = candidateResult.results;
|
|
92
|
+
if (input.candidate_id && candidates.length === 0) {
|
|
93
|
+
throw notFound(`Candidate ${input.candidate_id} not found.`, {
|
|
94
|
+
candidate_id: input.candidate_id,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// Fetch financial totals if requested
|
|
98
|
+
let totals;
|
|
99
|
+
if (shouldIncludeTotals && candidates.length > 0) {
|
|
100
|
+
const totalsParams = {
|
|
101
|
+
candidate_id: input.candidate_id,
|
|
102
|
+
cycle: input.cycle,
|
|
103
|
+
election_year: input.election_year,
|
|
104
|
+
page: input.page,
|
|
105
|
+
per_page: input.per_page,
|
|
106
|
+
};
|
|
107
|
+
// For search results, collect all candidate IDs for the totals call
|
|
108
|
+
if (!input.candidate_id) {
|
|
109
|
+
const ids = candidates.map((c) => str(c, 'candidate_id')).filter(Boolean);
|
|
110
|
+
if (ids.length > 0) {
|
|
111
|
+
// The API accepts repeated candidate_id params (?candidate_id=X&candidate_id=Y)
|
|
112
|
+
totalsParams.candidate_id = ids;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
ctx.log.info('Fetching candidate totals', { candidate_id: totalsParams.candidate_id });
|
|
116
|
+
const totalsResult = await fec.getCandidateTotals(totalsParams, ctx);
|
|
117
|
+
totals = totalsResult.results;
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
candidates,
|
|
121
|
+
totals,
|
|
122
|
+
pagination: candidateResult.pagination,
|
|
123
|
+
};
|
|
124
|
+
},
|
|
125
|
+
format(result) {
|
|
126
|
+
if (result.candidates.length === 0) {
|
|
127
|
+
return [
|
|
128
|
+
{
|
|
129
|
+
type: 'text',
|
|
130
|
+
text: 'No candidates found. Try broadening your search — use a partial name, remove filters like state or office, or check a different election cycle.',
|
|
131
|
+
},
|
|
132
|
+
];
|
|
133
|
+
}
|
|
134
|
+
// Build a lookup of totals by candidate_id for merging
|
|
135
|
+
const totalsMap = new Map();
|
|
136
|
+
if (result.totals) {
|
|
137
|
+
for (const t of result.totals) {
|
|
138
|
+
const id = str(t, 'candidate_id');
|
|
139
|
+
if (id)
|
|
140
|
+
totalsMap.set(id, t);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const lines = result.candidates.map((c) => {
|
|
144
|
+
const id = str(c, 'candidate_id');
|
|
145
|
+
const name = str(c, 'name');
|
|
146
|
+
const party = str(c, 'party_full') || str(c, 'party');
|
|
147
|
+
const state = str(c, 'state');
|
|
148
|
+
const office = str(c, 'office_full') || str(c, 'office');
|
|
149
|
+
const status = str(c, 'incumbent_challenge_full') || str(c, 'incumbent_challenge');
|
|
150
|
+
const district = typeof c.district_number === 'number'
|
|
151
|
+
? `-${String(c.district_number).padStart(2, '0')}`
|
|
152
|
+
: '';
|
|
153
|
+
let line = `**${name}** (${id})\n ${party} | ${office}${district ? ` ${district}` : ''} | ${state} | ${status}`;
|
|
154
|
+
const t = totalsMap.get(id);
|
|
155
|
+
if (t) {
|
|
156
|
+
line +=
|
|
157
|
+
`\n Receipts: ${fmt$(t.receipts)} | Disbursements: ${fmt$(t.disbursements)}` +
|
|
158
|
+
`\n Cash on Hand: ${fmt$(t.cash_on_hand_end_period)} | Debt: ${fmt$(t.debts_owed_by_committee)}`;
|
|
159
|
+
const coverageEnd = str(t, 'coverage_end_date');
|
|
160
|
+
if (coverageEnd)
|
|
161
|
+
line += ` | Through: ${coverageEnd}`;
|
|
162
|
+
}
|
|
163
|
+
return line;
|
|
164
|
+
});
|
|
165
|
+
const { page, pages, count } = result.pagination;
|
|
166
|
+
lines.push(`\n---\nPage ${page} of ${pages} (${count} total)`);
|
|
167
|
+
return [{ type: 'text', text: lines.join('\n\n') }];
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
//# sourceMappingURL=search-candidates.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-candidates.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-candidates.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool for searching and retrieving FEC committee records.
|
|
3
|
+
* Supports full-text search, single-committee lookup by ID, and filtering
|
|
4
|
+
* by candidate affiliation, type, designation, state, and party.
|
|
5
|
+
* @module mcp-server/tools/definitions/search-committees.tool
|
|
6
|
+
*/
|
|
7
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
8
|
+
export declare const searchCommittees: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
9
|
+
query: z.ZodOptional<z.ZodString>;
|
|
10
|
+
committee_id: z.ZodOptional<z.ZodString>;
|
|
11
|
+
candidate_id: z.ZodOptional<z.ZodString>;
|
|
12
|
+
state: z.ZodOptional<z.ZodString>;
|
|
13
|
+
party: z.ZodOptional<z.ZodString>;
|
|
14
|
+
committee_type: z.ZodOptional<z.ZodString>;
|
|
15
|
+
designation: z.ZodOptional<z.ZodString>;
|
|
16
|
+
cycle: z.ZodOptional<z.ZodNumber>;
|
|
17
|
+
treasurer_name: z.ZodOptional<z.ZodString>;
|
|
18
|
+
page: z.ZodOptional<z.ZodNumber>;
|
|
19
|
+
per_page: z.ZodOptional<z.ZodNumber>;
|
|
20
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
21
|
+
committees: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
22
|
+
pagination: z.ZodObject<{
|
|
23
|
+
page: z.ZodNumber;
|
|
24
|
+
pages: z.ZodNumber;
|
|
25
|
+
count: z.ZodNumber;
|
|
26
|
+
per_page: z.ZodNumber;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
}, z.core.$strip>>;
|
|
29
|
+
//# sourceMappingURL=search-committees.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-committees.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-committees.tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAOjD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;kBA6H3B,CAAC"}
|