sc-elections-mcp 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/election-history-client.d.ts +32 -0
- package/dist/api/election-history-client.js +267 -0
- package/dist/api/election-history-client.js.map +1 -0
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/resolve-campaign-context.test.d.ts +1 -0
- package/dist/resolve-campaign-context.test.js +107 -0
- package/dist/resolve-campaign-context.test.js.map +1 -0
- package/dist/tools/campaign.js +1 -1
- package/dist/tools/campaign.js.map +1 -1
- package/dist/tools/election-results.d.ts +2 -0
- package/dist/tools/election-results.js +143 -0
- package/dist/tools/election-results.js.map +1 -0
- package/dist/types.d.ts +39 -0
- package/package.json +2 -2
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ElectionEvent, ContestResult, PrecinctResult } from '../types.js';
|
|
2
|
+
export declare function getEventSuggestions(year?: number): Promise<{
|
|
3
|
+
events: ElectionEvent[];
|
|
4
|
+
nContests: number;
|
|
5
|
+
nCandidates: number;
|
|
6
|
+
nEvents: number;
|
|
7
|
+
yearRange: {
|
|
8
|
+
minYear: number;
|
|
9
|
+
maxYear: number;
|
|
10
|
+
};
|
|
11
|
+
}>;
|
|
12
|
+
export declare function searchContests(eventIds: number[], options?: {
|
|
13
|
+
office?: string;
|
|
14
|
+
division?: string;
|
|
15
|
+
}): Promise<{
|
|
16
|
+
contests: ContestResult[];
|
|
17
|
+
totalResults: number;
|
|
18
|
+
}>;
|
|
19
|
+
export declare function getContestGranular(contestId: number, county?: string): Promise<{
|
|
20
|
+
contest: {
|
|
21
|
+
id: number;
|
|
22
|
+
office: string;
|
|
23
|
+
division: string;
|
|
24
|
+
} | null;
|
|
25
|
+
candidates: {
|
|
26
|
+
candidateId: number;
|
|
27
|
+
displayName: string;
|
|
28
|
+
party: string | null;
|
|
29
|
+
}[];
|
|
30
|
+
precincts: PrecinctResult[];
|
|
31
|
+
counties: string[];
|
|
32
|
+
}>;
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
const BASE = 'https://electionhistory.scvotes.gov/api/graphql_pr';
|
|
2
|
+
const PSEUDO_CANDIDATE_IDS = new Set([1, 4, 6, 10]);
|
|
3
|
+
// GraphQL query strings from SC Election Commission election history database.
|
|
4
|
+
// Source: https://electionhistory.scvotes.gov
|
|
5
|
+
const GET_EVENT_SUGGESTIONS = `query GetEventSuggestions($suggestionFilters: SearchFilters!) {
|
|
6
|
+
nContests
|
|
7
|
+
nCandidates
|
|
8
|
+
nEvents
|
|
9
|
+
yearRange { minYear maxYear }
|
|
10
|
+
searchSuggestions(filters: $suggestionFilters) {
|
|
11
|
+
events { id name group count }
|
|
12
|
+
}
|
|
13
|
+
}`;
|
|
14
|
+
const SEARCH_CONTESTS = `fragment PartyWithColor on Party { id name color }
|
|
15
|
+
fragment CandidateContestWithParties on CandidateInContest {
|
|
16
|
+
party { ...PartyWithColor }
|
|
17
|
+
party2 { ...PartyWithColor }
|
|
18
|
+
party3 { ...PartyWithColor }
|
|
19
|
+
party4 { ...PartyWithColor }
|
|
20
|
+
}
|
|
21
|
+
fragment CoreContest on Contest {
|
|
22
|
+
id nSeats isVoterStat isHideTotalVotes isHideTotalBallots ballotsCount
|
|
23
|
+
eventTypeDisplayName pctWinThreshold hasWinners isSpecial isRunoff verifiedAt
|
|
24
|
+
event { id startDate isSpecial hasBallots type { id name isShowCandidatePartyLabels } }
|
|
25
|
+
primaryParty { id name color }
|
|
26
|
+
officeId officeModifier
|
|
27
|
+
office { id name runoffType }
|
|
28
|
+
division { id displayName }
|
|
29
|
+
candidates {
|
|
30
|
+
id ...CandidateContestWithParties voteChannelId
|
|
31
|
+
candidate { id pseudocandidate showAsPercentOf displayName nickName firstName lastName slug }
|
|
32
|
+
shortDisplayName displayName nVotes pctCandidateVotes
|
|
33
|
+
pctRawVotes isWinner isWriteIn isMasked
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
query SearchContests($pagination: Pagination!, $filters: SearchFilters!) {
|
|
37
|
+
search(pagination: $pagination, filters: $filters) {
|
|
38
|
+
meta { currentPage totalPages totalResults }
|
|
39
|
+
results { ...CoreContest }
|
|
40
|
+
}
|
|
41
|
+
}`;
|
|
42
|
+
const GET_CONTEST_GRANULAR = `fragment granularDivision on Division { id name displayName divisionTypeName }
|
|
43
|
+
fragment PartyWithColor on Party { id name color }
|
|
44
|
+
fragment CandidateContestWithParties on CandidateInContest {
|
|
45
|
+
party { ...PartyWithColor }
|
|
46
|
+
party2 { ...PartyWithColor }
|
|
47
|
+
party3 { ...PartyWithColor }
|
|
48
|
+
party4 { ...PartyWithColor }
|
|
49
|
+
}
|
|
50
|
+
fragment CoreContest on Contest {
|
|
51
|
+
id nSeats isVoterStat isHideTotalVotes isHideTotalBallots ballotsCount
|
|
52
|
+
eventTypeDisplayName pctWinThreshold hasWinners isSpecial isRunoff verifiedAt
|
|
53
|
+
event { id startDate isSpecial hasBallots type { id name isShowCandidatePartyLabels } }
|
|
54
|
+
primaryParty { id name color }
|
|
55
|
+
officeId officeModifier
|
|
56
|
+
office { id name runoffType }
|
|
57
|
+
division { id displayName }
|
|
58
|
+
candidates {
|
|
59
|
+
id ...CandidateContestWithParties voteChannelId
|
|
60
|
+
candidate { id pseudocandidate showAsPercentOf displayName nickName firstName lastName slug }
|
|
61
|
+
shortDisplayName displayName nVotes pctCandidateVotes
|
|
62
|
+
pctRawVotes isWinner isWriteIn isMasked
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
query GetContestGranular($contestId: Int!, $divisionFilter: Int, $voteChannelFilter: Int, $voteChannels: Boolean!, $singleVoteChannel: Int, $splitParty: Boolean!) {
|
|
66
|
+
contestGranularData(
|
|
67
|
+
contestId: $contestId topDivision: $divisionFilter
|
|
68
|
+
voteChannels: $voteChannels singleVoteChannel: $singleVoteChannel splitParty: $splitParty
|
|
69
|
+
) {
|
|
70
|
+
hasVoteChannels
|
|
71
|
+
candidates {
|
|
72
|
+
id voteChannelId partyId candidateId
|
|
73
|
+
candidate { id showAsPercentOf pseudocandidate displayName nickName firstName lastName slug }
|
|
74
|
+
shortDisplayName displayName nVotes pctCandidateVotes pctRawVotes isWinner isWriteIn isMasked
|
|
75
|
+
}
|
|
76
|
+
divisions {
|
|
77
|
+
division { ...granularDivision }
|
|
78
|
+
granularRow { candidateId partyId voteChannelId votes pct winner masked }
|
|
79
|
+
children {
|
|
80
|
+
division { ...granularDivision }
|
|
81
|
+
granularRow { candidateId partyId voteChannelId votes pct winner masked }
|
|
82
|
+
children {
|
|
83
|
+
division { ...granularDivision }
|
|
84
|
+
granularRow { candidateId partyId voteChannelId votes pct winner masked }
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
contest(id: $contestId divisionFilter: $divisionFilter voteChannelFilter: $voteChannelFilter) {
|
|
90
|
+
id isMappable officeId ...CoreContest
|
|
91
|
+
}
|
|
92
|
+
}`;
|
|
93
|
+
async function queryGraphQL(operationName, variables, query) {
|
|
94
|
+
const response = await fetch(BASE, {
|
|
95
|
+
method: 'POST',
|
|
96
|
+
headers: { 'Content-Type': 'application/json' },
|
|
97
|
+
body: JSON.stringify({ operationName, variables, query }),
|
|
98
|
+
});
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
throw new Error(`Election history API returned ${response.status}`);
|
|
101
|
+
}
|
|
102
|
+
const json = await response.json();
|
|
103
|
+
if (json.errors?.length) {
|
|
104
|
+
throw new Error(`GraphQL error: ${json.errors[0].message}`);
|
|
105
|
+
}
|
|
106
|
+
return json.data;
|
|
107
|
+
}
|
|
108
|
+
const EMPTY_FILTERS = {
|
|
109
|
+
ballotQuestions: { text: '', types: [], number: '', divisions: [] },
|
|
110
|
+
contests: { candidates: [], offices: [], divisions: [] },
|
|
111
|
+
specialElectionsOnly: false,
|
|
112
|
+
voterStats: false,
|
|
113
|
+
stages: [],
|
|
114
|
+
};
|
|
115
|
+
export async function getEventSuggestions(year) {
|
|
116
|
+
const global = { events: [] };
|
|
117
|
+
if (year) {
|
|
118
|
+
global.years = { from: year, to: year };
|
|
119
|
+
}
|
|
120
|
+
const data = await queryGraphQL('GetEventSuggestions', {
|
|
121
|
+
suggestionFilters: { global, ...EMPTY_FILTERS },
|
|
122
|
+
}, GET_EVENT_SUGGESTIONS);
|
|
123
|
+
return {
|
|
124
|
+
events: (data.searchSuggestions?.events || []).map((e) => ({
|
|
125
|
+
id: e.id,
|
|
126
|
+
name: e.name,
|
|
127
|
+
group: e.group,
|
|
128
|
+
count: e.count,
|
|
129
|
+
})),
|
|
130
|
+
nContests: data.nContests,
|
|
131
|
+
nCandidates: data.nCandidates,
|
|
132
|
+
nEvents: data.nEvents,
|
|
133
|
+
yearRange: data.yearRange ? { minYear: data.yearRange.minYear, maxYear: data.yearRange.maxYear } : { minYear: 0, maxYear: 0 },
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
export async function searchContests(eventIds, options) {
|
|
137
|
+
const hasFilters = !!(options?.office || options?.division);
|
|
138
|
+
const pageSize = 200;
|
|
139
|
+
const maxPages = hasFilters ? 10 : 1;
|
|
140
|
+
let allResults = [];
|
|
141
|
+
let totalResults = 0;
|
|
142
|
+
for (let page = 1; page <= maxPages; page++) {
|
|
143
|
+
const data = await queryGraphQL('SearchContests', {
|
|
144
|
+
pagination: { page, size: pageSize },
|
|
145
|
+
filters: { global: { events: eventIds }, ...EMPTY_FILTERS },
|
|
146
|
+
}, SEARCH_CONTESTS);
|
|
147
|
+
const search = data.search || {};
|
|
148
|
+
const results = search.results || [];
|
|
149
|
+
totalResults = search.meta?.totalResults || 0;
|
|
150
|
+
const totalPages = search.meta?.totalPages || 1;
|
|
151
|
+
allResults = allResults.concat(results);
|
|
152
|
+
if (page >= totalPages)
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
let filtered = allResults.filter((r) => !r.isVoterStat);
|
|
156
|
+
if (options?.office) {
|
|
157
|
+
const needle = options.office.toLowerCase();
|
|
158
|
+
filtered = filtered.filter((r) => (r.office?.name || '').toLowerCase().includes(needle));
|
|
159
|
+
}
|
|
160
|
+
if (options?.division) {
|
|
161
|
+
const needle = options.division.toLowerCase();
|
|
162
|
+
filtered = filtered.filter((r) => (r.division?.displayName || '').toLowerCase().includes(needle));
|
|
163
|
+
}
|
|
164
|
+
const contests = filtered.map((r) => ({
|
|
165
|
+
id: r.id,
|
|
166
|
+
office: r.office?.name || '',
|
|
167
|
+
division: r.division?.displayName || '',
|
|
168
|
+
isSpecial: r.isSpecial || false,
|
|
169
|
+
isRunoff: r.isRunoff || false,
|
|
170
|
+
eventDate: r.event?.startDate || '',
|
|
171
|
+
candidates: (r.candidates || [])
|
|
172
|
+
.filter((c) => !c.candidate?.pseudocandidate && !PSEUDO_CANDIDATE_IDS.has(c.candidate?.id))
|
|
173
|
+
.map((c) => ({
|
|
174
|
+
candidateId: c.candidate?.id || 0,
|
|
175
|
+
displayName: c.displayName || '',
|
|
176
|
+
party: c.party?.name || null,
|
|
177
|
+
nVotes: c.nVotes || 0,
|
|
178
|
+
pctCandidateVotes: c.pctCandidateVotes || 0,
|
|
179
|
+
isWinner: c.isWinner || false,
|
|
180
|
+
isWriteIn: c.isWriteIn || false,
|
|
181
|
+
})),
|
|
182
|
+
}));
|
|
183
|
+
return {
|
|
184
|
+
contests,
|
|
185
|
+
totalResults,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
export async function getContestGranular(contestId, county) {
|
|
189
|
+
let data;
|
|
190
|
+
try {
|
|
191
|
+
data = await queryGraphQL('GetContestGranular', {
|
|
192
|
+
contestId,
|
|
193
|
+
divisionFilter: null,
|
|
194
|
+
splitParty: false,
|
|
195
|
+
voteChannels: false,
|
|
196
|
+
singleVoteChannel: null,
|
|
197
|
+
}, GET_CONTEST_GRANULAR);
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
if (err instanceof Error && err.message.includes('does not have a division')) {
|
|
201
|
+
throw new Error(`Contest ${contestId} not found or has no results data`);
|
|
202
|
+
}
|
|
203
|
+
throw err;
|
|
204
|
+
}
|
|
205
|
+
const granular = data.contestGranularData || {};
|
|
206
|
+
const contestInfo = data.contest;
|
|
207
|
+
const candidateMap = new Map();
|
|
208
|
+
for (const c of granular.candidates || []) {
|
|
209
|
+
if (c.candidate?.pseudocandidate || PSEUDO_CANDIDATE_IDS.has(c.candidateId))
|
|
210
|
+
continue;
|
|
211
|
+
candidateMap.set(c.candidateId, {
|
|
212
|
+
displayName: c.displayName || '',
|
|
213
|
+
party: null,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
const divisions = granular.divisions || {};
|
|
217
|
+
const topChildren = divisions.children || [];
|
|
218
|
+
const allCounties = topChildren.map((c) => c.division?.displayName || '').filter(Boolean);
|
|
219
|
+
let filteredCounties = topChildren;
|
|
220
|
+
if (county) {
|
|
221
|
+
const needle = county.toLowerCase();
|
|
222
|
+
filteredCounties = topChildren.filter((c) => (c.division?.displayName || '').toLowerCase().includes(needle));
|
|
223
|
+
}
|
|
224
|
+
const precincts = [];
|
|
225
|
+
for (const countyDiv of filteredCounties) {
|
|
226
|
+
for (const precinctDiv of countyDiv.children || []) {
|
|
227
|
+
const rawName = precinctDiv.division?.displayName || '';
|
|
228
|
+
const name = rawName.replace(/^Precinct\s+/i, '');
|
|
229
|
+
if (name.toLowerCase().includes('failsafe') || name.toLowerCase().includes('provisional'))
|
|
230
|
+
continue;
|
|
231
|
+
const rows = precinctDiv.granularRow || [];
|
|
232
|
+
const candidates = [];
|
|
233
|
+
for (const row of rows) {
|
|
234
|
+
if (PSEUDO_CANDIDATE_IDS.has(row.candidateId))
|
|
235
|
+
continue;
|
|
236
|
+
const cand = candidateMap.get(row.candidateId);
|
|
237
|
+
if (!cand)
|
|
238
|
+
continue;
|
|
239
|
+
candidates.push({
|
|
240
|
+
name: cand.displayName,
|
|
241
|
+
votes: row.votes,
|
|
242
|
+
pct: row.pct,
|
|
243
|
+
winner: row.winner,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
if (candidates.length > 0) {
|
|
247
|
+
candidates.sort((a, b) => b.votes - a.votes);
|
|
248
|
+
precincts.push({ precinct: name, candidates });
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
contest: contestInfo ? {
|
|
254
|
+
id: contestInfo.id,
|
|
255
|
+
office: contestInfo.office?.name || '',
|
|
256
|
+
division: contestInfo.division?.displayName || '',
|
|
257
|
+
} : null,
|
|
258
|
+
candidates: Array.from(candidateMap.entries()).map(([id, c]) => ({
|
|
259
|
+
candidateId: id,
|
|
260
|
+
displayName: c.displayName,
|
|
261
|
+
party: c.party,
|
|
262
|
+
})),
|
|
263
|
+
precincts,
|
|
264
|
+
counties: allCounties,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=election-history-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"election-history-client.js","sourceRoot":"","sources":["../../src/api/election-history-client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -8,9 +8,10 @@ import { registerSeiTools } from './tools/sei.js';
|
|
|
8
8
|
import { registerVremsTools } from './tools/vrems.js';
|
|
9
9
|
import { registerOverlapTools } from './tools/overlap.js';
|
|
10
10
|
import { registerCrossReferenceTools } from './tools/cross-reference.js';
|
|
11
|
+
import { registerElectionResultsTools } from './tools/election-results.js';
|
|
11
12
|
const server = new McpServer({
|
|
12
13
|
name: 'sc-elections-mcp',
|
|
13
|
-
version: '0.
|
|
14
|
+
version: '0.9.0',
|
|
14
15
|
});
|
|
15
16
|
// Ethics Commission tools (ethicsfiling.sc.gov)
|
|
16
17
|
registerSearchTools(server);
|
|
@@ -22,6 +23,8 @@ registerSeiTools(server);
|
|
|
22
23
|
registerVremsTools(server);
|
|
23
24
|
// Cross-system tools (Ethics + VREMS)
|
|
24
25
|
registerCrossReferenceTools(server);
|
|
26
|
+
// SC Election History tools (electionhistory.scvotes.gov)
|
|
27
|
+
registerElectionResultsTools(server);
|
|
25
28
|
async function main() {
|
|
26
29
|
const transport = new StdioServerTransport();
|
|
27
30
|
await server.connect(transport);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAA;AACxE,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAA;AAE1E,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,kBAAkB;IACxB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAA;AAEF,gDAAgD;AAChD,mBAAmB,CAAC,MAAM,CAAC,CAAA;AAC3B,qBAAqB,CAAC,MAAM,CAAC,CAAA;AAC7B,wBAAwB,CAAC,MAAM,CAAC,CAAA;AAChC,oBAAoB,CAAC,MAAM,CAAC,CAAA;AAC5B,gBAAgB,CAAC,MAAM,CAAC,CAAA;AAExB,gDAAgD;AAChD,kBAAkB,CAAC,MAAM,CAAC,CAAA;AAE1B,sCAAsC;AACtC,2BAA2B,CAAC,MAAM,CAAC,CAAA;AAEnC,0DAA0D;AAC1D,4BAA4B,CAAC,MAAM,CAAC,CAAA;AAEpC,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAA;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;AACjC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;IACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { resolveCampaignContext } from '../src/api/ethics-client.js';
|
|
3
|
+
function makeOffice(overrides = {}) {
|
|
4
|
+
return {
|
|
5
|
+
filerId: 100,
|
|
6
|
+
officeId: 1000,
|
|
7
|
+
officeName: 'County Council',
|
|
8
|
+
initialReportFiledDate: '2020-01-15T00:00:00',
|
|
9
|
+
lastReportSubmitted: 'Quarter 1, 2026 Report',
|
|
10
|
+
latestActivity: 'Report (April 01, 2026)',
|
|
11
|
+
balance: 5000,
|
|
12
|
+
officeClosedDate: null,
|
|
13
|
+
contributions: 15000,
|
|
14
|
+
...overrides,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
describe('resolveCampaignContext', () => {
|
|
18
|
+
it('resolves to the open campaign filerId, not the input candidateFilerId', () => {
|
|
19
|
+
const summary = {
|
|
20
|
+
name: 'Shaw, Steve',
|
|
21
|
+
address: null,
|
|
22
|
+
openReports: [
|
|
23
|
+
makeOffice({ filerId: 27934, officeId: 45412, officeName: 'Greenville County Council' }),
|
|
24
|
+
],
|
|
25
|
+
closedReports: [
|
|
26
|
+
makeOffice({
|
|
27
|
+
filerId: 50495, officeId: 74907, officeName: 'District 6 Senate',
|
|
28
|
+
balance: 0, officeClosedDate: '2024-03-20T00:00:00',
|
|
29
|
+
}),
|
|
30
|
+
],
|
|
31
|
+
};
|
|
32
|
+
// Pass the "wrong" candidateFilerId (50495 from search results)
|
|
33
|
+
const result = resolveCampaignContext(summary, 50495);
|
|
34
|
+
expect(result).not.toHaveProperty('error');
|
|
35
|
+
if ('error' in result)
|
|
36
|
+
throw new Error('unexpected error');
|
|
37
|
+
// Should resolve to the open campaign's filerId (27934), not the input (50495)
|
|
38
|
+
expect(result.resolvedFilerId).toBe(27934);
|
|
39
|
+
expect(result.resolvedCampaignId).toBe(45412);
|
|
40
|
+
expect(result.context.officeName).toBe('Greenville County Council');
|
|
41
|
+
expect(result.context.campaignStatus).toBe('open');
|
|
42
|
+
});
|
|
43
|
+
it('prefers open campaign over closed when both have the same office name', () => {
|
|
44
|
+
const summary = {
|
|
45
|
+
name: 'Bradley, Richard',
|
|
46
|
+
address: null,
|
|
47
|
+
openReports: [
|
|
48
|
+
makeOffice({ filerId: 44760, officeId: 71114, officeName: 'Greenville County Council District 26', balance: 8536 }),
|
|
49
|
+
],
|
|
50
|
+
closedReports: [
|
|
51
|
+
makeOffice({
|
|
52
|
+
filerId: 57372, officeId: 79432, officeName: 'Greenville County Council District 26',
|
|
53
|
+
balance: 0, officeClosedDate: '2026-04-06T00:00:00',
|
|
54
|
+
}),
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
const result = resolveCampaignContext(summary, 57372);
|
|
58
|
+
expect(result).not.toHaveProperty('error');
|
|
59
|
+
if ('error' in result)
|
|
60
|
+
throw new Error('unexpected error');
|
|
61
|
+
expect(result.resolvedFilerId).toBe(44760);
|
|
62
|
+
expect(result.resolvedCampaignId).toBe(71114);
|
|
63
|
+
});
|
|
64
|
+
it('returns error when no campaigns exist', () => {
|
|
65
|
+
const summary = {
|
|
66
|
+
name: null, address: null,
|
|
67
|
+
openReports: [], closedReports: [],
|
|
68
|
+
};
|
|
69
|
+
const result = resolveCampaignContext(summary, 100);
|
|
70
|
+
expect(result).toHaveProperty('error');
|
|
71
|
+
});
|
|
72
|
+
it('resolves by campaignId when explicitly provided', () => {
|
|
73
|
+
const summary = {
|
|
74
|
+
name: 'Test Person',
|
|
75
|
+
address: null,
|
|
76
|
+
openReports: [
|
|
77
|
+
makeOffice({ filerId: 100, officeId: 1000, officeName: 'Mayor' }),
|
|
78
|
+
makeOffice({ filerId: 200, officeId: 2000, officeName: 'County Council' }),
|
|
79
|
+
],
|
|
80
|
+
closedReports: [],
|
|
81
|
+
};
|
|
82
|
+
const result = resolveCampaignContext(summary, 999, 2000);
|
|
83
|
+
expect(result).not.toHaveProperty('error');
|
|
84
|
+
if ('error' in result)
|
|
85
|
+
throw new Error('unexpected error');
|
|
86
|
+
expect(result.resolvedFilerId).toBe(200);
|
|
87
|
+
expect(result.resolvedCampaignId).toBe(2000);
|
|
88
|
+
});
|
|
89
|
+
it('resolves by office hint when provided', () => {
|
|
90
|
+
const summary = {
|
|
91
|
+
name: 'Test Person',
|
|
92
|
+
address: null,
|
|
93
|
+
openReports: [
|
|
94
|
+
makeOffice({ filerId: 100, officeId: 1000, officeName: 'Mayor' }),
|
|
95
|
+
makeOffice({ filerId: 200, officeId: 2000, officeName: 'County Council' }),
|
|
96
|
+
],
|
|
97
|
+
closedReports: [],
|
|
98
|
+
};
|
|
99
|
+
const result = resolveCampaignContext(summary, 999, undefined, 'County Council');
|
|
100
|
+
expect(result).not.toHaveProperty('error');
|
|
101
|
+
if ('error' in result)
|
|
102
|
+
throw new Error('unexpected error');
|
|
103
|
+
expect(result.resolvedFilerId).toBe(200);
|
|
104
|
+
expect(result.context.officeName).toBe('County Council');
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
//# sourceMappingURL=resolve-campaign-context.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-campaign-context.test.js","sourceRoot":"","sources":["../src/resolve-campaign-context.test.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/campaign.js
CHANGED
|
@@ -31,7 +31,7 @@ export function registerCampaignTools(server) {
|
|
|
31
31
|
if ('error' in resolved) {
|
|
32
32
|
return { content: [{ type: 'text', text: resolved.error }], isError: true };
|
|
33
33
|
}
|
|
34
|
-
const reports = await getCampaignReports(resolved.resolvedCampaignId,
|
|
34
|
+
const reports = await getCampaignReports(resolved.resolvedCampaignId, resolved.resolvedFilerId);
|
|
35
35
|
const header = `Campaign: ${resolved.context.candidateName} — ${resolved.context.officeName} (campaignId: ${resolved.context.campaignId}, status: ${resolved.context.campaignStatus})`;
|
|
36
36
|
return {
|
|
37
37
|
content: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"campaign.js","sourceRoot":"","sources":["../../src/tools/campaign.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,yBAAyB,CAAA;AAGhC,SAAS,YAAY,CAAC,OAAwB,EAAE,KAAa,EAAE,UAAkB,EAAE,WAAmB;IACpG,OAAO,aAAa,OAAO,CAAC,aAAa,MAAM,OAAO,CAAC,UAAU,iBAAiB,OAAO,CAAC,UAAU,uBAAuB,OAAO,CAAC,gBAAgB,aAAa,OAAO,CAAC,cAAc,MAAM,KAAK,IAAI,UAAU,cAAc,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAA;AAC5P,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACrD,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,ohBAAohB,EACphB;QACE,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;KACvF,EACD,KAAK,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE;QAC/B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,kBAAkB,CAAC,CAAA;YAC5D,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aAC7E,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;gBAC9G,OAAO,EAAE,IAAI;aACd,CAAA;QACH,CAAC;IACH,CAAC,CACF,CAAA;IAED,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,oLAAoL,EACpL;QACE,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;QACtF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;QACjH,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+FAA+F,CAAC;KACxI,EACD,KAAK,EAAE,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE;QACpD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,kBAAkB,CAAC,CAAA;YAClE,MAAM,QAAQ,GAAG,sBAAsB,CAAC,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,CAAC,CAAA;YACzF,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;gBACxB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;YACtF,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,QAAQ,CAAC,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"campaign.js","sourceRoot":"","sources":["../../src/tools/campaign.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { getEventSuggestions, searchContests, getContestGranular } from '../api/election-history-client.js';
|
|
3
|
+
export function registerElectionResultsTools(server) {
|
|
4
|
+
server.tool('list_election_events', 'List available SC elections from the certified results database (2008-present). Returns event IDs needed for search_election_results. Covers statewide generals, primaries, runoffs, and some municipals. Recent municipal elections may not be available yet. Known event IDs: 58=2024 General, 20=2020 General, 29=2018 General, 12=2022 General, 8=2024 R Presidential Primary.', {
|
|
5
|
+
year: z.number().optional().describe('Filter to a specific year. Omit for all available elections.'),
|
|
6
|
+
}, async ({ year }) => {
|
|
7
|
+
try {
|
|
8
|
+
const result = await getEventSuggestions(year);
|
|
9
|
+
if (result.events.length === 0) {
|
|
10
|
+
return {
|
|
11
|
+
content: [{ type: 'text', text: year ? `No elections found for ${year}` : 'No elections found' }],
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const lines = [
|
|
15
|
+
`${result.events.length} election(s) found${year ? ` for ${year}` : ''} (database covers ${result.yearRange.minYear}-${result.yearRange.maxYear}, ${result.nContests.toLocaleString()} total contests):`,
|
|
16
|
+
'',
|
|
17
|
+
...result.events.map(e => ` Event ${e.id}: ${e.name} (${e.group}) — ${e.count} contests`),
|
|
18
|
+
];
|
|
19
|
+
return {
|
|
20
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
return {
|
|
25
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
|
|
26
|
+
isError: true,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
server.tool('search_election_results', 'Search certified election results — candidates, vote totals, percentages, winner. Get event_id from list_election_events. Returns contest IDs needed for get_precinct_results. Filters by office name and division/district substring. Results are from the SC Election Commission certified database.', {
|
|
31
|
+
event_id: z.number().describe('Election event ID from list_election_events'),
|
|
32
|
+
office: z.string().optional().describe('Filter by office name substring. Exact names in the database: "President of the United States", "U.S. House", "State Senate", "State House", "County Council Member", "Clerk of Court", "Register of Deeds", plus county-specific offices (Sheriff, Coroner, etc.). Case-insensitive substring match, so "State House" matches "State House". When filtering, all pages are searched automatically.'),
|
|
33
|
+
division: z.string().optional().describe('Filter by division/district substring (e.g. "District 24", "Greenville", "Congressional District 4"). Case-insensitive.'),
|
|
34
|
+
limit: z.number().optional().describe('Max results to return (default 50). The API returns up to 200 per page.'),
|
|
35
|
+
}, async ({ event_id, office, division, limit }) => {
|
|
36
|
+
try {
|
|
37
|
+
const effectiveLimit = limit || 50;
|
|
38
|
+
const result = await searchContests([event_id], { office, division });
|
|
39
|
+
if (result.contests.length === 0) {
|
|
40
|
+
const filters = [office && `office="${office}"`, division && `division="${division}"`].filter(Boolean).join(', ');
|
|
41
|
+
return {
|
|
42
|
+
content: [{ type: 'text', text: `No contests found for event ${event_id}${filters ? ` matching ${filters}` : ''}` }],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const limited = result.contests.slice(0, effectiveLimit);
|
|
46
|
+
const lines = [
|
|
47
|
+
`${result.totalResults} contest(s) found${limited.length < result.totalResults ? ` (showing ${limited.length})` : ''}:`,
|
|
48
|
+
];
|
|
49
|
+
for (const contest of limited) {
|
|
50
|
+
lines.push('');
|
|
51
|
+
lines.push(`Contest ${contest.id}: ${contest.office} — ${contest.division}${contest.isSpecial ? ' (Special)' : ''}${contest.isRunoff ? ' (Runoff)' : ''}`);
|
|
52
|
+
for (const c of contest.candidates) {
|
|
53
|
+
const pct = (c.pctCandidateVotes * 100).toFixed(1);
|
|
54
|
+
const party = c.party ? ` (${c.party})` : '';
|
|
55
|
+
const winner = c.isWinner ? ' WINNER' : '';
|
|
56
|
+
const writeIn = c.isWriteIn ? ' [Write-In]' : '';
|
|
57
|
+
lines.push(` ${c.displayName}${party}: ${c.nVotes.toLocaleString()} votes (${pct}%)${winner}${writeIn}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
return {
|
|
66
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
|
|
67
|
+
isError: true,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
server.tool('get_precinct_results', 'Get precinct-level certified vote data for a specific contest. Returns per-precinct candidate vote counts and percentages. Get contest_id from search_election_results. For statewide races (President, Governor, US Senate), you MUST specify a county — otherwise the response would include all 46 counties. Filters out failsafe/provisional precincts.', {
|
|
72
|
+
contest_id: z.number().describe('Contest ID from search_election_results. Must be a number.'),
|
|
73
|
+
county: z.string().optional().describe('Filter to a specific county (e.g. "Greenville", "Richland"). Required for statewide races. Case-insensitive substring match.'),
|
|
74
|
+
top_candidates: z.number().optional().describe('Show only the top N candidates per precinct (default: all for small races, top 2 for large multi-candidate races). Totals always show all candidates.'),
|
|
75
|
+
}, async ({ contest_id, county, top_candidates }) => {
|
|
76
|
+
try {
|
|
77
|
+
const result = await getContestGranular(contest_id, county);
|
|
78
|
+
if (!result.contest) {
|
|
79
|
+
return {
|
|
80
|
+
content: [{ type: 'text', text: `No contest found with ID ${contest_id}` }],
|
|
81
|
+
isError: true,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
if (!county && result.counties.length > 10) {
|
|
85
|
+
return {
|
|
86
|
+
content: [{ type: 'text', text: [
|
|
87
|
+
`This is a statewide/multi-county contest (${result.contest.office} — ${result.contest.division}) with ${result.counties.length} counties.`,
|
|
88
|
+
'Please specify a county parameter to get precinct-level results. Available counties:',
|
|
89
|
+
'',
|
|
90
|
+
...result.counties.map(c => ` ${c}`),
|
|
91
|
+
].join('\n') }],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
if (result.precincts.length === 0) {
|
|
95
|
+
return {
|
|
96
|
+
content: [{ type: 'text', text: `No precinct results found for contest ${contest_id}${county ? ` in "${county}"` : ''}` }],
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const nCandidates = result.precincts[0]?.candidates.length || 0;
|
|
100
|
+
const nPrecincts = result.precincts.length;
|
|
101
|
+
const effectiveTopN = top_candidates || (nCandidates > 3 && nPrecincts > 50 ? 2 : nCandidates);
|
|
102
|
+
const truncated = effectiveTopN < nCandidates;
|
|
103
|
+
const lines = [
|
|
104
|
+
`${result.contest.office} — ${result.contest.division}`,
|
|
105
|
+
`${nPrecincts} precincts${county ? ` in ${county}` : ''}${truncated ? ` (showing top ${effectiveTopN} of ${nCandidates} candidates per precinct)` : ''}:`,
|
|
106
|
+
'',
|
|
107
|
+
];
|
|
108
|
+
for (const p of result.precincts) {
|
|
109
|
+
lines.push(`${p.precinct}:`);
|
|
110
|
+
const displayCandidates = p.candidates.slice(0, effectiveTopN);
|
|
111
|
+
for (const c of displayCandidates) {
|
|
112
|
+
const pct = (c.pct * 100).toFixed(1);
|
|
113
|
+
const winner = c.winner ? ' WINNER' : '';
|
|
114
|
+
lines.push(` ${c.name}: ${c.votes.toLocaleString()} (${pct}%)${winner}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const totals = {};
|
|
118
|
+
for (const p of result.precincts) {
|
|
119
|
+
for (const c of p.candidates) {
|
|
120
|
+
totals[c.name] = (totals[c.name] || 0) + c.votes;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const totalVotes = Object.values(totals).reduce((a, b) => a + b, 0);
|
|
124
|
+
lines.push('');
|
|
125
|
+
lines.push('TOTALS:');
|
|
126
|
+
for (const [name, votes] of Object.entries(totals).sort((a, b) => b[1] - a[1])) {
|
|
127
|
+
const pct = totalVotes > 0 ? ((votes / totalVotes) * 100).toFixed(1) : '0.0';
|
|
128
|
+
lines.push(` ${name}: ${votes.toLocaleString()} (${pct}%)`);
|
|
129
|
+
}
|
|
130
|
+
lines.push(` Total votes: ${totalVotes.toLocaleString()}`);
|
|
131
|
+
return {
|
|
132
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
return {
|
|
137
|
+
content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
|
|
138
|
+
isError: true,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=election-results.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"election-results.js","sourceRoot":"","sources":["../../src/tools/election-results.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -444,3 +444,42 @@ export interface CandidateSearchParams {
|
|
|
444
444
|
party?: string;
|
|
445
445
|
filingLocation?: string;
|
|
446
446
|
}
|
|
447
|
+
export interface ElectionEvent {
|
|
448
|
+
id: number;
|
|
449
|
+
name: string;
|
|
450
|
+
group: string;
|
|
451
|
+
count: number;
|
|
452
|
+
}
|
|
453
|
+
export interface ContestCandidate {
|
|
454
|
+
candidateId: number;
|
|
455
|
+
displayName: string;
|
|
456
|
+
party: string | null;
|
|
457
|
+
nVotes: number;
|
|
458
|
+
pctCandidateVotes: number;
|
|
459
|
+
isWinner: boolean;
|
|
460
|
+
isWriteIn: boolean;
|
|
461
|
+
}
|
|
462
|
+
export interface ContestResult {
|
|
463
|
+
id: number;
|
|
464
|
+
office: string;
|
|
465
|
+
division: string;
|
|
466
|
+
isSpecial: boolean;
|
|
467
|
+
isRunoff: boolean;
|
|
468
|
+
eventDate: string;
|
|
469
|
+
candidates: ContestCandidate[];
|
|
470
|
+
}
|
|
471
|
+
export interface GranularRow {
|
|
472
|
+
candidateId: number;
|
|
473
|
+
votes: number;
|
|
474
|
+
pct: number;
|
|
475
|
+
winner: boolean;
|
|
476
|
+
}
|
|
477
|
+
export interface PrecinctResult {
|
|
478
|
+
precinct: string;
|
|
479
|
+
candidates: {
|
|
480
|
+
name: string;
|
|
481
|
+
votes: number;
|
|
482
|
+
pct: number;
|
|
483
|
+
winner: boolean;
|
|
484
|
+
}[];
|
|
485
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sc-elections-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "MCP server for South Carolina elections: campaign finance, contributions, expenditures, SEI disclosures, and
|
|
3
|
+
"version": "0.9.0",
|
|
4
|
+
"description": "MCP server for South Carolina elections: campaign finance, contributions, expenditures, SEI disclosures, candidate filings, and certified election results",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"sc-elections-mcp": "dist/index.js"
|