tn-elections-mcp 0.5.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/README.md +87 -0
- package/dist/api/easyvote-client.d.ts +51 -0
- package/dist/api/easyvote-client.js +254 -0
- package/dist/api/easyvote-client.js.map +1 -0
- package/dist/api/easyvote-client.test.d.ts +1 -0
- package/dist/api/easyvote-client.test.js +47 -0
- package/dist/api/easyvote-client.test.js.map +1 -0
- package/dist/api/gemini-pdf.d.ts +23 -0
- package/dist/api/gemini-pdf.js +261 -0
- package/dist/api/gemini-pdf.js.map +1 -0
- package/dist/api/sos-client.d.ts +15 -0
- package/dist/api/sos-client.js +74 -0
- package/dist/api/sos-client.js.map +1 -0
- package/dist/api/sumner-client.d.ts +12 -0
- package/dist/api/sumner-client.js +57 -0
- package/dist/api/sumner-client.js.map +1 -0
- package/dist/api/tncamp-client.d.ts +61 -0
- package/dist/api/tncamp-client.js +310 -0
- package/dist/api/tncamp-client.js.map +1 -0
- package/dist/data/sumner-cycles.d.ts +3 -0
- package/dist/data/sumner-cycles.js +19 -0
- package/dist/data/sumner-cycles.js.map +1 -0
- package/dist/data/sumner-cycles.test.d.ts +1 -0
- package/dist/data/sumner-cycles.test.js +29 -0
- package/dist/data/sumner-cycles.test.js.map +1 -0
- package/dist/data/tn-counties.d.ts +23 -0
- package/dist/data/tn-counties.js +162 -0
- package/dist/data/tn-counties.js.map +1 -0
- package/dist/data/tn-counties.test.d.ts +1 -0
- package/dist/data/tn-counties.test.js +71 -0
- package/dist/data/tn-counties.test.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/sos-xlsx.d.ts +24 -0
- package/dist/parsers/sos-xlsx.js +149 -0
- package/dist/parsers/sos-xlsx.js.map +1 -0
- package/dist/parsers/sos-xlsx.test.d.ts +1 -0
- package/dist/parsers/sos-xlsx.test.js +111 -0
- package/dist/parsers/sos-xlsx.test.js.map +1 -0
- package/dist/parsers/sumner-html.d.ts +8 -0
- package/dist/parsers/sumner-html.js +200 -0
- package/dist/parsers/sumner-html.js.map +1 -0
- package/dist/parsers/sumner-html.test.d.ts +1 -0
- package/dist/parsers/sumner-html.test.js +79 -0
- package/dist/parsers/sumner-html.test.js.map +1 -0
- package/dist/parsers/tncamp-form.d.ts +15 -0
- package/dist/parsers/tncamp-form.js +54 -0
- package/dist/parsers/tncamp-form.js.map +1 -0
- package/dist/parsers/tncamp-form.test.d.ts +1 -0
- package/dist/parsers/tncamp-form.test.js +114 -0
- package/dist/parsers/tncamp-form.test.js.map +1 -0
- package/dist/parsers/tncamp-report.d.ts +6 -0
- package/dist/parsers/tncamp-report.js +189 -0
- package/dist/parsers/tncamp-report.js.map +1 -0
- package/dist/parsers/tncamp-results.d.ts +10 -0
- package/dist/parsers/tncamp-results.js +113 -0
- package/dist/parsers/tncamp-results.js.map +1 -0
- package/dist/parsers/tncamp-results.test.d.ts +1 -0
- package/dist/parsers/tncamp-results.test.js +86 -0
- package/dist/parsers/tncamp-results.test.js.map +1 -0
- package/dist/tools/easyvote.d.ts +2 -0
- package/dist/tools/easyvote.js +382 -0
- package/dist/tools/easyvote.js.map +1 -0
- package/dist/tools/sos.d.ts +2 -0
- package/dist/tools/sos.js +130 -0
- package/dist/tools/sos.js.map +1 -0
- package/dist/tools/sumner.d.ts +2 -0
- package/dist/tools/sumner.js +134 -0
- package/dist/tools/sumner.js.map +1 -0
- package/dist/tools/tncamp.d.ts +2 -0
- package/dist/tools/tncamp.js +401 -0
- package/dist/tools/tncamp.js.map +1 -0
- package/dist/types.d.ts +270 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +47 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/** Auth context returned by bootstrap endpoint */
|
|
2
|
+
export interface EasyVoteAuthContext {
|
|
3
|
+
UserId: string;
|
|
4
|
+
CustomerId: string;
|
|
5
|
+
ZumoToken: null;
|
|
6
|
+
}
|
|
7
|
+
/** Filer document from documentsearch endpoint */
|
|
8
|
+
export interface EasyVoteDocument {
|
|
9
|
+
documentnameid: [string, string] | null;
|
|
10
|
+
documentid: string;
|
|
11
|
+
documentname: string;
|
|
12
|
+
datesubmitted: string;
|
|
13
|
+
documenttype: string;
|
|
14
|
+
electionname: string | null;
|
|
15
|
+
}
|
|
16
|
+
/** Filer from documentsearch endpoint */
|
|
17
|
+
export interface EasyVoteFiler {
|
|
18
|
+
filerid: string;
|
|
19
|
+
firstname: string;
|
|
20
|
+
middlename: string | null;
|
|
21
|
+
lastname: string;
|
|
22
|
+
committeename: string;
|
|
23
|
+
filertype: string;
|
|
24
|
+
status: string;
|
|
25
|
+
displayname: string;
|
|
26
|
+
officename: string;
|
|
27
|
+
imgurl: string | null;
|
|
28
|
+
documents: EasyVoteDocument[];
|
|
29
|
+
}
|
|
30
|
+
/** Office from offices endpoint */
|
|
31
|
+
export interface EasyVoteOffice {
|
|
32
|
+
guid: string;
|
|
33
|
+
name: string;
|
|
34
|
+
}
|
|
35
|
+
/** Contribution record from advancedsearch endpoint (34 fields) */
|
|
36
|
+
export interface EasyVoteContribution {
|
|
37
|
+
DocumentFilingId: string;
|
|
38
|
+
DocumentId: string | null;
|
|
39
|
+
DocumentType: string;
|
|
40
|
+
ItemizedListType: string;
|
|
41
|
+
RecipientFirstName: string;
|
|
42
|
+
RecipientMiddleInitial: string | null;
|
|
43
|
+
RecipientLastName: string;
|
|
44
|
+
RecipientCommitteeName: string;
|
|
45
|
+
OfficeGuid: string;
|
|
46
|
+
OfficeName: string;
|
|
47
|
+
ContributorFullName: string | null;
|
|
48
|
+
ContributorFirstName: string;
|
|
49
|
+
ContributorMiddleName: string | null;
|
|
50
|
+
ContributorLastName: string;
|
|
51
|
+
ContributorOrganizationName: string | null;
|
|
52
|
+
ContributorAddress: string;
|
|
53
|
+
ContributorCity: string;
|
|
54
|
+
ContributorState: string;
|
|
55
|
+
ContributorZip: string;
|
|
56
|
+
ContributionDate: string;
|
|
57
|
+
ContributionAmount: number;
|
|
58
|
+
ContributionDateDate: string;
|
|
59
|
+
CustomSearchResultFields: unknown | null;
|
|
60
|
+
}
|
|
61
|
+
/** Distribution/expenditure record from advancedsearch/distributions endpoint */
|
|
62
|
+
export interface EasyVoteDistribution {
|
|
63
|
+
DocumentFilingId: string;
|
|
64
|
+
DocumentType: string;
|
|
65
|
+
ItemizedListType: string;
|
|
66
|
+
CandidateFirstName: string;
|
|
67
|
+
CandidateMiddleInitial: string | null;
|
|
68
|
+
CandidateLastName: string;
|
|
69
|
+
CandidateCommitteeName: string;
|
|
70
|
+
OfficeGuid: string;
|
|
71
|
+
OfficeName: string;
|
|
72
|
+
PayeeFirstName: string | null;
|
|
73
|
+
PayeeLastName: string;
|
|
74
|
+
PayeeOrganizationName: string | null;
|
|
75
|
+
PayeeAddress: string;
|
|
76
|
+
PayeeCity: string;
|
|
77
|
+
PayeeState: string;
|
|
78
|
+
PayeeZip: string;
|
|
79
|
+
DistributionDate: string | null;
|
|
80
|
+
DistributionAmount: number;
|
|
81
|
+
DistributionDateDate: string | null;
|
|
82
|
+
CustomSearchResultFields: unknown | null;
|
|
83
|
+
}
|
|
84
|
+
/** Office from cpsearch form dropdown */
|
|
85
|
+
export interface TncampOffice {
|
|
86
|
+
id: string;
|
|
87
|
+
name: string;
|
|
88
|
+
}
|
|
89
|
+
/** District from districts.htm JSON endpoint */
|
|
90
|
+
export interface TncampDistrict {
|
|
91
|
+
id: string;
|
|
92
|
+
label: string;
|
|
93
|
+
officeId: string;
|
|
94
|
+
}
|
|
95
|
+
/** Election year from cpsearch form dropdown */
|
|
96
|
+
export interface TncampElectionYear {
|
|
97
|
+
id: string;
|
|
98
|
+
label: string;
|
|
99
|
+
}
|
|
100
|
+
/** Parsed dropdowns from cpsearch.htm form page */
|
|
101
|
+
export interface TncampFormOptions {
|
|
102
|
+
offices: TncampOffice[];
|
|
103
|
+
electionYears: TncampElectionYear[];
|
|
104
|
+
parties: {
|
|
105
|
+
id: string;
|
|
106
|
+
name: string;
|
|
107
|
+
}[];
|
|
108
|
+
}
|
|
109
|
+
/** Candidate/PAC from cpsearch results */
|
|
110
|
+
export interface TncampCandidate {
|
|
111
|
+
name: string;
|
|
112
|
+
party: string;
|
|
113
|
+
officeSought: string;
|
|
114
|
+
district: string;
|
|
115
|
+
electionYear: string;
|
|
116
|
+
candidateId: number;
|
|
117
|
+
reportListUrl: string;
|
|
118
|
+
}
|
|
119
|
+
/** Report entry from replist.htm */
|
|
120
|
+
export interface TncampReport {
|
|
121
|
+
election: string;
|
|
122
|
+
reportName: string;
|
|
123
|
+
isAmendment: boolean;
|
|
124
|
+
submittedOn: string;
|
|
125
|
+
reportId: number;
|
|
126
|
+
reportUrl: string;
|
|
127
|
+
}
|
|
128
|
+
/** Line item in a report's itemized section (receipts, disbursements, loans) */
|
|
129
|
+
export interface TncampLineItem {
|
|
130
|
+
name: string;
|
|
131
|
+
address: string;
|
|
132
|
+
date: string;
|
|
133
|
+
amount: number;
|
|
134
|
+
employer?: string;
|
|
135
|
+
occupation?: string;
|
|
136
|
+
purpose?: string;
|
|
137
|
+
}
|
|
138
|
+
/** Full parsed report from report_full.htm */
|
|
139
|
+
export interface TncampReportDetail {
|
|
140
|
+
reportId: number;
|
|
141
|
+
candidateName: string;
|
|
142
|
+
reportTitle: string;
|
|
143
|
+
beginningBalance: number;
|
|
144
|
+
totalContributions: number;
|
|
145
|
+
totalReceipts: number;
|
|
146
|
+
totalExpenditures: number;
|
|
147
|
+
totalDisbursements: number;
|
|
148
|
+
endingBalance: number;
|
|
149
|
+
totalOutstandingLoans: number;
|
|
150
|
+
receipts: TncampLineItem[];
|
|
151
|
+
disbursements: TncampLineItem[];
|
|
152
|
+
inKindContributions: TncampLineItem[];
|
|
153
|
+
loans: TncampLineItem[];
|
|
154
|
+
obligations: TncampLineItem[];
|
|
155
|
+
}
|
|
156
|
+
/** Contribution from cesearch results */
|
|
157
|
+
export interface TncampContribution {
|
|
158
|
+
type: string;
|
|
159
|
+
amount: number;
|
|
160
|
+
date: string;
|
|
161
|
+
electionYear: string;
|
|
162
|
+
recipientName: string;
|
|
163
|
+
contributorName: string;
|
|
164
|
+
contributorAddress: string;
|
|
165
|
+
contributorOccupation: string;
|
|
166
|
+
contributorEmployer: string;
|
|
167
|
+
}
|
|
168
|
+
/** Expenditure from cesearch results */
|
|
169
|
+
export interface TncampExpenditure {
|
|
170
|
+
type: string;
|
|
171
|
+
amount: number;
|
|
172
|
+
date: string;
|
|
173
|
+
vendorName: string;
|
|
174
|
+
vendorAddress: string;
|
|
175
|
+
purpose: string;
|
|
176
|
+
candidateFor: string;
|
|
177
|
+
}
|
|
178
|
+
/** Pagination metadata from DisplayTag results pages */
|
|
179
|
+
export interface TncampPaginationInfo {
|
|
180
|
+
totalItems: number;
|
|
181
|
+
currentPage: number;
|
|
182
|
+
totalPages: number;
|
|
183
|
+
itemsPerPage: number;
|
|
184
|
+
paginationParam: string;
|
|
185
|
+
}
|
|
186
|
+
export interface SumnerElectionCycle {
|
|
187
|
+
year: string;
|
|
188
|
+
url: string;
|
|
189
|
+
label: string;
|
|
190
|
+
}
|
|
191
|
+
export interface SumnerOffice {
|
|
192
|
+
name: string;
|
|
193
|
+
district?: string;
|
|
194
|
+
isMunicipal: boolean;
|
|
195
|
+
municipality?: string;
|
|
196
|
+
}
|
|
197
|
+
export interface SumnerReportLink {
|
|
198
|
+
reportName: string;
|
|
199
|
+
pdfUrl: string;
|
|
200
|
+
}
|
|
201
|
+
export interface SumnerCandidate {
|
|
202
|
+
name: string;
|
|
203
|
+
office: SumnerOffice;
|
|
204
|
+
reports: SumnerReportLink[];
|
|
205
|
+
cycle: string;
|
|
206
|
+
}
|
|
207
|
+
export interface SumnerNonDisclosure {
|
|
208
|
+
name: string;
|
|
209
|
+
cycle: string;
|
|
210
|
+
}
|
|
211
|
+
export interface SumnerCyclePage {
|
|
212
|
+
cycle: SumnerElectionCycle;
|
|
213
|
+
candidates: SumnerCandidate[];
|
|
214
|
+
nonDisclosures: SumnerNonDisclosure[];
|
|
215
|
+
scrapedAt: string;
|
|
216
|
+
}
|
|
217
|
+
export interface SumnerContribution {
|
|
218
|
+
date: string;
|
|
219
|
+
name: string;
|
|
220
|
+
address: string;
|
|
221
|
+
amount: number;
|
|
222
|
+
type: string;
|
|
223
|
+
employer?: string;
|
|
224
|
+
occupation?: string;
|
|
225
|
+
}
|
|
226
|
+
export interface SumnerExpenditure {
|
|
227
|
+
date: string;
|
|
228
|
+
payee: string;
|
|
229
|
+
address: string;
|
|
230
|
+
amount: number;
|
|
231
|
+
purpose?: string;
|
|
232
|
+
}
|
|
233
|
+
export interface SumnerReportData {
|
|
234
|
+
candidateName: string;
|
|
235
|
+
officeSought: string;
|
|
236
|
+
reportPeriod: string;
|
|
237
|
+
beginningBalance: number;
|
|
238
|
+
totalContributions: number;
|
|
239
|
+
totalExpenditures: number;
|
|
240
|
+
endingBalance: number;
|
|
241
|
+
contributions: SumnerContribution[];
|
|
242
|
+
expenditures: SumnerExpenditure[];
|
|
243
|
+
extractionModel: string;
|
|
244
|
+
extractionConfidence: 'high' | 'medium' | 'low';
|
|
245
|
+
warnings: string[];
|
|
246
|
+
}
|
|
247
|
+
/** Official filed candidate from SOS Excel spreadsheet */
|
|
248
|
+
export interface SosFiledCandidate {
|
|
249
|
+
office: string;
|
|
250
|
+
candidateName: string;
|
|
251
|
+
party: string;
|
|
252
|
+
city: string;
|
|
253
|
+
filingDate: string;
|
|
254
|
+
status: string;
|
|
255
|
+
officeCategory: string;
|
|
256
|
+
}
|
|
257
|
+
/** Office category from SOS candidate list page */
|
|
258
|
+
export interface SosOfficeCategory {
|
|
259
|
+
name: string;
|
|
260
|
+
xlsxUrl: string;
|
|
261
|
+
pdfUrl: string;
|
|
262
|
+
candidateCount: number;
|
|
263
|
+
}
|
|
264
|
+
/** Full cached result from SOS page scrape + xlsx parsing */
|
|
265
|
+
export interface SosCandidateIndex {
|
|
266
|
+
year: number;
|
|
267
|
+
offices: SosOfficeCategory[];
|
|
268
|
+
candidates: SosFiledCandidate[];
|
|
269
|
+
fetchedAt: number;
|
|
270
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,2CAA2C;AAC3C,+DAA+D"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tn-elections-mcp",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "MCP server for Tennessee elections: county campaign finance, state campaign finance, and financial disclosures",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"tn-elections-mcp": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc && chmod +x dist/index.js",
|
|
15
|
+
"start": "node dist/index.js",
|
|
16
|
+
"dev": "tsx src/index.ts",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"prepare": "npm run build"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"mcp",
|
|
22
|
+
"tennessee",
|
|
23
|
+
"elections",
|
|
24
|
+
"campaign-finance",
|
|
25
|
+
"easyvote"
|
|
26
|
+
],
|
|
27
|
+
"author": "Alex Reynolds",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/asreynolds1000/tn-elections-mcp.git"
|
|
31
|
+
},
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
35
|
+
"node-html-parser": "^7.0.2",
|
|
36
|
+
"xlsx": "^0.18.5"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^20",
|
|
40
|
+
"tsx": "^4.19.4",
|
|
41
|
+
"typescript": "^5",
|
|
42
|
+
"vitest": "^3.2.4"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=20"
|
|
46
|
+
}
|
|
47
|
+
}
|