@striderlabs/mcp-statefarm 0.1.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/src/index.ts ADDED
@@ -0,0 +1,1286 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import {
4
+ CallToolRequestSchema,
5
+ ListToolsRequestSchema,
6
+ } from "@modelcontextprotocol/sdk/types.js";
7
+
8
+ const server = new Server(
9
+ {
10
+ name: "striderlabs-mcp-statefarm",
11
+ version: "0.1.0",
12
+ },
13
+ {
14
+ capabilities: {
15
+ tools: {},
16
+ },
17
+ }
18
+ );
19
+
20
+ // ─── Tool Definitions ──────────────────────────────────────────────────────────
21
+
22
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
23
+ return {
24
+ tools: [
25
+ {
26
+ name: "statefarm_get_quote",
27
+ description:
28
+ "Get an insurance quote from State Farm. Supports auto, home, life, and renters insurance. Returns estimated premium ranges, coverage options, and next steps to complete the quote online or with an agent.",
29
+ inputSchema: {
30
+ type: "object",
31
+ properties: {
32
+ insurance_type: {
33
+ type: "string",
34
+ enum: ["auto", "home", "life", "renters"],
35
+ description: "Type of insurance quote to request",
36
+ },
37
+ zip_code: {
38
+ type: "string",
39
+ description: "ZIP code for the quote location",
40
+ },
41
+ // Auto-specific
42
+ vehicle_year: {
43
+ type: "number",
44
+ description: "(Auto) Vehicle model year",
45
+ },
46
+ vehicle_make: {
47
+ type: "string",
48
+ description: "(Auto) Vehicle manufacturer (e.g. Toyota, Ford)",
49
+ },
50
+ vehicle_model: {
51
+ type: "string",
52
+ description: "(Auto) Vehicle model (e.g. Camry, F-150)",
53
+ },
54
+ drivers_count: {
55
+ type: "number",
56
+ description: "(Auto) Number of drivers to insure",
57
+ },
58
+ // Home-specific
59
+ home_value: {
60
+ type: "number",
61
+ description: "(Home) Estimated home value in USD",
62
+ },
63
+ home_year_built: {
64
+ type: "number",
65
+ description: "(Home) Year the home was built",
66
+ },
67
+ home_sq_ft: {
68
+ type: "number",
69
+ description: "(Home) Home square footage",
70
+ },
71
+ // Life-specific
72
+ coverage_amount: {
73
+ type: "number",
74
+ description: "(Life) Desired coverage amount in USD",
75
+ },
76
+ applicant_age: {
77
+ type: "number",
78
+ description: "(Life) Applicant age",
79
+ },
80
+ life_type: {
81
+ type: "string",
82
+ enum: ["term", "whole", "universal"],
83
+ description: "(Life) Type of life insurance",
84
+ },
85
+ // Renters-specific
86
+ personal_property_value: {
87
+ type: "number",
88
+ description: "(Renters) Estimated value of personal belongings in USD",
89
+ },
90
+ },
91
+ required: ["insurance_type", "zip_code"],
92
+ },
93
+ },
94
+ {
95
+ name: "statefarm_policy_details",
96
+ description:
97
+ "Retrieve details about an existing State Farm insurance policy. Returns coverage summary, deductibles, premium info, renewal date, and insured items/people.",
98
+ inputSchema: {
99
+ type: "object",
100
+ properties: {
101
+ policy_number: {
102
+ type: "string",
103
+ description: "State Farm policy number (e.g. 123-4567-A01-12B)",
104
+ },
105
+ policy_type: {
106
+ type: "string",
107
+ enum: ["auto", "home", "life", "renters", "all"],
108
+ description: "Type of policy to retrieve. Use 'all' to list all policies.",
109
+ },
110
+ },
111
+ required: ["policy_type"],
112
+ },
113
+ },
114
+ {
115
+ name: "statefarm_file_claim",
116
+ description:
117
+ "Initiate a new insurance claim with State Farm. Supports auto accidents, home damage, theft, and other covered events. Returns a claim reference number and next steps.",
118
+ inputSchema: {
119
+ type: "object",
120
+ properties: {
121
+ policy_number: {
122
+ type: "string",
123
+ description: "State Farm policy number the claim is filed under",
124
+ },
125
+ claim_type: {
126
+ type: "string",
127
+ enum: [
128
+ "auto_accident",
129
+ "auto_theft",
130
+ "auto_weather",
131
+ "auto_glass",
132
+ "home_fire",
133
+ "home_water",
134
+ "home_weather",
135
+ "home_theft",
136
+ "liability",
137
+ "other",
138
+ ],
139
+ description: "Type of claim being filed",
140
+ },
141
+ incident_date: {
142
+ type: "string",
143
+ description: "Date of incident in ISO format (YYYY-MM-DD)",
144
+ },
145
+ incident_description: {
146
+ type: "string",
147
+ description: "Description of what happened",
148
+ },
149
+ incident_location: {
150
+ type: "string",
151
+ description: "Address or location where the incident occurred",
152
+ },
153
+ estimated_damage: {
154
+ type: "number",
155
+ description: "Estimated damage amount in USD (optional)",
156
+ },
157
+ injuries_involved: {
158
+ type: "boolean",
159
+ description: "Whether any injuries were involved",
160
+ },
161
+ other_parties_involved: {
162
+ type: "boolean",
163
+ description: "Whether other parties (drivers, people) are involved",
164
+ },
165
+ police_report_number: {
166
+ type: "string",
167
+ description: "Police report number if applicable",
168
+ },
169
+ },
170
+ required: [
171
+ "policy_number",
172
+ "claim_type",
173
+ "incident_date",
174
+ "incident_description",
175
+ ],
176
+ },
177
+ },
178
+ {
179
+ name: "statefarm_claim_status",
180
+ description:
181
+ "Check the status of an existing State Farm insurance claim. Returns current status, assigned adjuster contact, estimated timeline, and any action items needed.",
182
+ inputSchema: {
183
+ type: "object",
184
+ properties: {
185
+ claim_number: {
186
+ type: "string",
187
+ description: "State Farm claim number (provided when claim was filed)",
188
+ },
189
+ policy_number: {
190
+ type: "string",
191
+ description: "Policy number associated with the claim (optional, helps narrow lookup)",
192
+ },
193
+ },
194
+ required: ["claim_number"],
195
+ },
196
+ },
197
+ {
198
+ name: "statefarm_payment",
199
+ description:
200
+ "Manage State Farm insurance payments. View payment history, due dates, make a payment, set up autopay, or update payment method.",
201
+ inputSchema: {
202
+ type: "object",
203
+ properties: {
204
+ action: {
205
+ type: "string",
206
+ enum: [
207
+ "view_balance",
208
+ "payment_history",
209
+ "make_payment",
210
+ "setup_autopay",
211
+ "cancel_autopay",
212
+ "update_payment_method",
213
+ ],
214
+ description: "Payment action to perform",
215
+ },
216
+ policy_number: {
217
+ type: "string",
218
+ description: "Policy number to manage payment for",
219
+ },
220
+ payment_amount: {
221
+ type: "number",
222
+ description: "(make_payment) Amount to pay in USD",
223
+ },
224
+ payment_method: {
225
+ type: "string",
226
+ enum: ["bank_account", "credit_card", "debit_card"],
227
+ description: "(make_payment / update_payment_method) Payment method type",
228
+ },
229
+ },
230
+ required: ["action"],
231
+ },
232
+ },
233
+ {
234
+ name: "statefarm_digital_id_card",
235
+ description:
236
+ "Retrieve a digital insurance ID card for a State Farm auto policy. Returns the ID card information including policy details, vehicle info, and coverage period. Can also provide a link to download or share the card.",
237
+ inputSchema: {
238
+ type: "object",
239
+ properties: {
240
+ policy_number: {
241
+ type: "string",
242
+ description: "Auto insurance policy number",
243
+ },
244
+ vehicle_vin: {
245
+ type: "string",
246
+ description: "Vehicle VIN to get ID card for a specific vehicle (optional)",
247
+ },
248
+ format: {
249
+ type: "string",
250
+ enum: ["display", "download_link", "email"],
251
+ description: "How to retrieve the ID card. Default: display",
252
+ },
253
+ email_address: {
254
+ type: "string",
255
+ description: "(email format) Email address to send the ID card to",
256
+ },
257
+ },
258
+ required: ["policy_number"],
259
+ },
260
+ },
261
+ {
262
+ name: "statefarm_find_agent",
263
+ description:
264
+ "Find State Farm insurance agents near a location. Returns a list of local agents with contact info, office hours, languages spoken, and specializations.",
265
+ inputSchema: {
266
+ type: "object",
267
+ properties: {
268
+ location: {
269
+ type: "string",
270
+ description: "City, state, or ZIP code to search near",
271
+ },
272
+ radius_miles: {
273
+ type: "number",
274
+ description: "Search radius in miles (default: 10)",
275
+ },
276
+ insurance_type: {
277
+ type: "string",
278
+ enum: ["auto", "home", "life", "renters", "business", "any"],
279
+ description: "Insurance type specialization to filter by (default: any)",
280
+ },
281
+ language: {
282
+ type: "string",
283
+ description: "Preferred language for the agent (e.g. Spanish, Mandarin)",
284
+ },
285
+ max_results: {
286
+ type: "number",
287
+ description: "Maximum number of agents to return (default: 5, max: 20)",
288
+ },
289
+ },
290
+ required: ["location"],
291
+ },
292
+ },
293
+ {
294
+ name: "statefarm_roadside_assistance",
295
+ description:
296
+ "Request State Farm roadside assistance or check available roadside services. Can request towing, battery jump, flat tire change, fuel delivery, lockout service, or winching.",
297
+ inputSchema: {
298
+ type: "object",
299
+ properties: {
300
+ action: {
301
+ type: "string",
302
+ enum: ["request_service", "check_coverage", "track_service"],
303
+ },
304
+ service_type: {
305
+ type: "string",
306
+ enum: [
307
+ "towing",
308
+ "battery_jump",
309
+ "flat_tire",
310
+ "fuel_delivery",
311
+ "lockout",
312
+ "winching",
313
+ "any",
314
+ ],
315
+ description: "(request_service) Type of roadside assistance needed",
316
+ },
317
+ policy_number: {
318
+ type: "string",
319
+ description: "Auto insurance policy number",
320
+ },
321
+ current_location: {
322
+ type: "string",
323
+ description: "(request_service) Your current location or address",
324
+ },
325
+ vehicle_description: {
326
+ type: "string",
327
+ description: "(request_service) Vehicle description (year, make, model, color)",
328
+ },
329
+ callback_phone: {
330
+ type: "string",
331
+ description: "(request_service) Phone number for the service provider to call",
332
+ },
333
+ service_request_id: {
334
+ type: "string",
335
+ description: "(track_service) Service request ID to track",
336
+ },
337
+ },
338
+ required: ["action"],
339
+ },
340
+ },
341
+ {
342
+ name: "statefarm_bundle_recommendations",
343
+ description:
344
+ "Get personalized insurance bundle recommendations from State Farm. Analyzes current coverage and suggests bundles that could save money by combining auto, home, life, and renters policies.",
345
+ inputSchema: {
346
+ type: "object",
347
+ properties: {
348
+ current_policies: {
349
+ type: "array",
350
+ items: {
351
+ type: "string",
352
+ enum: ["auto", "home", "life", "renters"],
353
+ },
354
+ description: "List of insurance types the customer currently has",
355
+ },
356
+ zip_code: {
357
+ type: "string",
358
+ description: "ZIP code for location-based recommendations",
359
+ },
360
+ household_size: {
361
+ type: "number",
362
+ description: "Number of people in the household",
363
+ },
364
+ own_home: {
365
+ type: "boolean",
366
+ description: "Whether the customer owns their home",
367
+ },
368
+ own_vehicle: {
369
+ type: "boolean",
370
+ description: "Whether the customer owns a vehicle",
371
+ },
372
+ has_dependents: {
373
+ type: "boolean",
374
+ description: "Whether the customer has dependents (relevant for life insurance)",
375
+ },
376
+ annual_income: {
377
+ type: "number",
378
+ description: "Annual household income in USD (used to suggest appropriate coverage levels)",
379
+ },
380
+ priority: {
381
+ type: "string",
382
+ enum: ["savings", "coverage", "simplicity"],
383
+ description: "What to optimize bundle recommendations for (default: savings)",
384
+ },
385
+ },
386
+ required: ["zip_code"],
387
+ },
388
+ },
389
+ ],
390
+ };
391
+ });
392
+
393
+ // ─── Tool Handlers ─────────────────────────────────────────────────────────────
394
+
395
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
396
+ const { name, arguments: args } = request.params;
397
+
398
+ try {
399
+ switch (name) {
400
+ case "statefarm_get_quote":
401
+ return handleGetQuote(args as GetQuoteArgs);
402
+ case "statefarm_policy_details":
403
+ return handlePolicyDetails(args as PolicyDetailsArgs);
404
+ case "statefarm_file_claim":
405
+ return handleFileClaim(args as FileClaimArgs);
406
+ case "statefarm_claim_status":
407
+ return handleClaimStatus(args as ClaimStatusArgs);
408
+ case "statefarm_payment":
409
+ return handlePayment(args as PaymentArgs);
410
+ case "statefarm_digital_id_card":
411
+ return handleDigitalIdCard(args as DigitalIdCardArgs);
412
+ case "statefarm_find_agent":
413
+ return handleFindAgent(args as FindAgentArgs);
414
+ case "statefarm_roadside_assistance":
415
+ return handleRoadsideAssistance(args as RoadsideArgs);
416
+ case "statefarm_bundle_recommendations":
417
+ return handleBundleRecommendations(args as BundleArgs);
418
+ default:
419
+ return {
420
+ content: [
421
+ {
422
+ type: "text",
423
+ text: JSON.stringify({ success: false, error: `Unknown tool: ${name}` }),
424
+ },
425
+ ],
426
+ };
427
+ }
428
+ } catch (err) {
429
+ const message = err instanceof Error ? err.message : String(err);
430
+ return {
431
+ content: [
432
+ {
433
+ type: "text",
434
+ text: JSON.stringify({ success: false, error: message }),
435
+ },
436
+ ],
437
+ };
438
+ }
439
+ });
440
+
441
+ // ─── Type Definitions ──────────────────────────────────────────────────────────
442
+
443
+ interface GetQuoteArgs {
444
+ insurance_type: "auto" | "home" | "life" | "renters";
445
+ zip_code: string;
446
+ vehicle_year?: number;
447
+ vehicle_make?: string;
448
+ vehicle_model?: string;
449
+ drivers_count?: number;
450
+ home_value?: number;
451
+ home_year_built?: number;
452
+ home_sq_ft?: number;
453
+ coverage_amount?: number;
454
+ applicant_age?: number;
455
+ life_type?: "term" | "whole" | "universal";
456
+ personal_property_value?: number;
457
+ }
458
+
459
+ interface PolicyDetailsArgs {
460
+ policy_number?: string;
461
+ policy_type: "auto" | "home" | "life" | "renters" | "all";
462
+ }
463
+
464
+ interface FileClaimArgs {
465
+ policy_number: string;
466
+ claim_type: string;
467
+ incident_date: string;
468
+ incident_description: string;
469
+ incident_location?: string;
470
+ estimated_damage?: number;
471
+ injuries_involved?: boolean;
472
+ other_parties_involved?: boolean;
473
+ police_report_number?: string;
474
+ }
475
+
476
+ interface ClaimStatusArgs {
477
+ claim_number: string;
478
+ policy_number?: string;
479
+ }
480
+
481
+ interface PaymentArgs {
482
+ action: string;
483
+ policy_number?: string;
484
+ payment_amount?: number;
485
+ payment_method?: string;
486
+ }
487
+
488
+ interface DigitalIdCardArgs {
489
+ policy_number: string;
490
+ vehicle_vin?: string;
491
+ format?: "display" | "download_link" | "email";
492
+ email_address?: string;
493
+ }
494
+
495
+ interface FindAgentArgs {
496
+ location: string;
497
+ radius_miles?: number;
498
+ insurance_type?: string;
499
+ language?: string;
500
+ max_results?: number;
501
+ }
502
+
503
+ interface RoadsideArgs {
504
+ action: "request_service" | "check_coverage" | "track_service";
505
+ service_type?: string;
506
+ policy_number?: string;
507
+ current_location?: string;
508
+ vehicle_description?: string;
509
+ callback_phone?: string;
510
+ service_request_id?: string;
511
+ }
512
+
513
+ interface BundleArgs {
514
+ current_policies?: string[];
515
+ zip_code: string;
516
+ household_size?: number;
517
+ own_home?: boolean;
518
+ own_vehicle?: boolean;
519
+ has_dependents?: boolean;
520
+ annual_income?: number;
521
+ priority?: "savings" | "coverage" | "simplicity";
522
+ }
523
+
524
+ // ─── Handler Implementations ───────────────────────────────────────────────────
525
+
526
+ function respond(data: unknown) {
527
+ return {
528
+ content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
529
+ };
530
+ }
531
+
532
+ function handleGetQuote(args: GetQuoteArgs) {
533
+ const { insurance_type, zip_code } = args;
534
+
535
+ const quoteUrl = `https://www.statefarm.com/insurance/${insurance_type === "renters" ? "renters" : insurance_type === "home" ? "home-and-property/homeowners" : insurance_type}/get-a-quote`;
536
+
537
+ interface QuoteResult {
538
+ success: boolean;
539
+ insurance_type: string;
540
+ zip_code: string;
541
+ quote_id: string;
542
+ estimated_premium?: object;
543
+ coverage_options?: object;
544
+ discounts?: string[];
545
+ notes?: string[];
546
+ quote_url: string;
547
+ next_steps: string[];
548
+ phone: string;
549
+ }
550
+
551
+ const result: QuoteResult = {
552
+ success: true,
553
+ insurance_type,
554
+ zip_code,
555
+ quote_id: `QUOTE-${Date.now()}`,
556
+ quote_url: quoteUrl,
557
+ next_steps: [],
558
+ phone: "1-800-STATE-FARM (1-800-782-8332)",
559
+ };
560
+
561
+ switch (insurance_type) {
562
+ case "auto": {
563
+ const year = args.vehicle_year;
564
+ const make = args.vehicle_make;
565
+ const model = args.vehicle_model;
566
+ const driversCount = args.drivers_count ?? 1;
567
+ const hasVehicleInfo = year && make && model;
568
+
569
+ result.estimated_premium = {
570
+ monthly: hasVehicleInfo ? estimateAutoPremium(year!, driversCount) : null,
571
+ note: hasVehicleInfo
572
+ ? "Estimate based on typical rates. Final quote may vary."
573
+ : "Provide vehicle and driver details for an estimate.",
574
+ };
575
+ result.coverage_options = {
576
+ liability_only: "State minimum coverage — lowest cost",
577
+ standard: "Liability + collision + comprehensive — most popular",
578
+ premium: "Full coverage with roadside assistance & rental reimbursement",
579
+ };
580
+ result.discounts = [
581
+ "Multi-car discount (up to 20%)",
582
+ "Good driver discount",
583
+ "Safe vehicle discount (anti-lock brakes, airbags)",
584
+ "Bundle with home or renters (up to 17%)",
585
+ "Good student discount",
586
+ "Drive Safe & Save™ program",
587
+ ];
588
+ result.notes = hasVehicleInfo
589
+ ? [`Vehicle: ${year} ${make} ${model}`, `Drivers: ${driversCount}`]
590
+ : ["Add vehicle_year, vehicle_make, vehicle_model for a specific estimate"];
591
+ result.next_steps = [
592
+ "1. Visit the quote URL to complete your full online quote",
593
+ "2. Have your driver's license and vehicle VIN ready",
594
+ "3. Review coverage options and select your deductible",
595
+ "4. Compare with your current insurer before switching",
596
+ ];
597
+ break;
598
+ }
599
+
600
+ case "home": {
601
+ const homeValue = args.home_value;
602
+ const yearBuilt = args.home_year_built;
603
+ const sqFt = args.home_sq_ft;
604
+
605
+ result.estimated_premium = {
606
+ annual: homeValue ? estimateHomePremium(homeValue, zip_code) : null,
607
+ note: "Estimate based on typical rates. Actual quote requires home inspection data.",
608
+ };
609
+ result.coverage_options = {
610
+ dwelling: "Covers structure of your home",
611
+ personal_property: "Covers belongings inside",
612
+ liability: "Covers injuries/damage you cause to others",
613
+ additional_living_expenses: "Covers hotel/food if home is uninhabitable",
614
+ extended_replacement: "Extra coverage if rebuild cost exceeds policy limit",
615
+ };
616
+ result.discounts = [
617
+ "Multi-policy bundle with auto (up to 17%)",
618
+ "Home security system discount",
619
+ "New home discount",
620
+ "Claim-free discount",
621
+ "Protective device discount (smoke detectors, deadbolts)",
622
+ ];
623
+ result.notes = [
624
+ homeValue ? `Estimated home value: $${homeValue.toLocaleString()}` : "Provide home_value for estimate",
625
+ yearBuilt ? `Year built: ${yearBuilt}` : null,
626
+ sqFt ? `Square footage: ${sqFt.toLocaleString()} sq ft` : null,
627
+ ].filter(Boolean) as string[];
628
+ result.next_steps = [
629
+ "1. Visit the quote URL to start your online homeowners quote",
630
+ "2. Have your home's address, year built, and square footage ready",
631
+ "3. Note any recent renovations or upgrades",
632
+ "4. Consider scheduling a home inspection for accurate pricing",
633
+ ];
634
+ break;
635
+ }
636
+
637
+ case "life": {
638
+ const age = args.applicant_age;
639
+ const coverageAmount = args.coverage_amount;
640
+ const lifeType = args.life_type ?? "term";
641
+
642
+ result.estimated_premium = {
643
+ monthly: age && coverageAmount ? estimateLifePremium(age, coverageAmount, lifeType) : null,
644
+ note: "Health history and medical exam results significantly affect final rates.",
645
+ };
646
+ result.coverage_options = {
647
+ term_life: "Fixed coverage for 10, 20, or 30 years — lowest cost",
648
+ whole_life: "Permanent coverage that builds cash value",
649
+ universal_life: "Flexible premiums and death benefit with investment component",
650
+ select_term: "State Farm's most popular term product",
651
+ return_of_premium: "Get premiums back if you outlive the policy term",
652
+ };
653
+ result.discounts = [
654
+ "Non-smoker rates (significant savings)",
655
+ "Good health discount",
656
+ "Annual premium discount vs monthly billing",
657
+ ];
658
+ result.notes = [
659
+ age ? `Applicant age: ${age}` : "Provide applicant_age for an estimate",
660
+ coverageAmount ? `Coverage amount: $${coverageAmount.toLocaleString()}` : "Provide coverage_amount for an estimate",
661
+ `Policy type: ${lifeType}`,
662
+ ].filter(Boolean) as string[];
663
+ result.next_steps = [
664
+ "1. Speak with a State Farm agent for life insurance — it cannot be quoted entirely online",
665
+ "2. Prepare health history, beneficiary info, and income details",
666
+ "3. Consider coverage equal to 10-12x annual income as a starting point",
667
+ "4. Call 1-800-STATE-FARM or use find_agent to connect with a local agent",
668
+ ];
669
+ break;
670
+ }
671
+
672
+ case "renters": {
673
+ const propertyValue = args.personal_property_value ?? 20000;
674
+
675
+ result.estimated_premium = {
676
+ monthly: estimateRentersPremium(propertyValue, zip_code),
677
+ note: "Renters insurance is typically very affordable — often $15-$30/month.",
678
+ };
679
+ result.coverage_options = {
680
+ personal_property: `Covers your belongings up to $${propertyValue.toLocaleString()}`,
681
+ liability: "Covers accidental injury to guests or damage to building",
682
+ additional_living_expenses: "Hotel and food costs if unit is uninhabitable",
683
+ medical_payments: "Covers minor injuries to guests regardless of fault",
684
+ };
685
+ result.discounts = [
686
+ "Bundle with auto insurance (up to 17%)",
687
+ "Security system discount",
688
+ "Multi-policy discount",
689
+ "Claim-free discount",
690
+ ];
691
+ result.notes = [
692
+ `Estimated personal property value: $${propertyValue.toLocaleString()}`,
693
+ "Consider a home inventory to accurately value your belongings",
694
+ ];
695
+ result.next_steps = [
696
+ "1. Visit the quote URL for an online renters quote — takes about 5 minutes",
697
+ "2. Have your address and move-in date ready",
698
+ "3. Create a home inventory for accurate personal property coverage",
699
+ "4. Consider bundling with auto insurance for maximum savings",
700
+ ];
701
+ break;
702
+ }
703
+ }
704
+
705
+ return respond(result);
706
+ }
707
+
708
+ function estimateAutoPremium(year: number, drivers: number): object {
709
+ const age = new Date().getFullYear() - year;
710
+ const baseMonthly = 120;
711
+ const ageFactor = age > 10 ? 0.85 : age > 5 ? 0.95 : 1.0;
712
+ const driverFactor = 1 + (drivers - 1) * 0.6;
713
+ const monthly = Math.round(baseMonthly * ageFactor * driverFactor);
714
+ return { low: monthly - 25, mid: monthly, high: monthly + 50, currency: "USD" };
715
+ }
716
+
717
+ function estimateHomePremium(homeValue: number, _zip: string): object {
718
+ const annual = Math.round(homeValue * 0.006);
719
+ return { low: annual - 200, mid: annual, high: annual + 400, currency: "USD" };
720
+ }
721
+
722
+ function estimateLifePremium(age: number, coverage: number, type: string): object {
723
+ const perThousand = type === "term" ? (age < 30 ? 0.40 : age < 40 ? 0.55 : age < 50 ? 1.10 : 2.20) : (age < 30 ? 1.20 : age < 40 ? 1.80 : age < 50 ? 2.80 : 5.00);
724
+ const monthly = Math.round((coverage / 1000) * perThousand);
725
+ return { low: monthly - 5, mid: monthly, high: monthly + 15, currency: "USD" };
726
+ }
727
+
728
+ function estimateRentersPremium(propertyValue: number, _zip: string): object {
729
+ const monthly = Math.max(12, Math.round(propertyValue * 0.0006));
730
+ return { low: monthly - 3, mid: monthly, high: monthly + 8, currency: "USD" };
731
+ }
732
+
733
+ function handlePolicyDetails(args: PolicyDetailsArgs) {
734
+ const { policy_number, policy_type } = args;
735
+
736
+ if (!policy_number && policy_type !== "all") {
737
+ return respond({
738
+ success: false,
739
+ error: "policy_number is required when policy_type is not 'all'",
740
+ hint: "Provide your State Farm policy number found on your insurance card or billing statement",
741
+ });
742
+ }
743
+
744
+ return respond({
745
+ success: true,
746
+ note: "To retrieve live policy details, authenticate via the State Farm mobile app or website.",
747
+ policy_number: policy_number ?? "all policies on account",
748
+ policy_type,
749
+ how_to_access: {
750
+ online: "https://www.statefarm.com/customer-care/login",
751
+ mobile_app: "State Farm mobile app (iOS / Android) → 'My Policies'",
752
+ phone: "1-800-STATE-FARM (1-800-782-8332)",
753
+ agent: "Contact your local State Farm agent",
754
+ },
755
+ typical_policy_details: {
756
+ policy_number: "Your unique policy identifier",
757
+ coverage_summary: "Types and limits of coverage",
758
+ deductibles: "Your out-of-pocket amount before insurance pays",
759
+ premium: "Your payment amount and frequency",
760
+ renewal_date: "When your current policy period ends",
761
+ insured_items: "Vehicles, property, or people covered",
762
+ discounts_applied: "Active discounts reducing your premium",
763
+ endorsements: "Additional riders or coverage add-ons",
764
+ },
765
+ self_service_actions: [
766
+ "View and download policy documents",
767
+ "Add or remove vehicles",
768
+ "Update coverage limits",
769
+ "Change deductibles",
770
+ "Update personal information",
771
+ "View payment history",
772
+ ],
773
+ });
774
+ }
775
+
776
+ function handleFileClaim(args: FileClaimArgs) {
777
+ const claimRef = `CLM-${Date.now().toString(36).toUpperCase()}`;
778
+
779
+ const urgentTypes = ["auto_accident", "home_fire", "liability"];
780
+ const isUrgent = urgentTypes.includes(args.claim_type);
781
+
782
+ return respond({
783
+ success: true,
784
+ claim_reference: claimRef,
785
+ status: "initiated",
786
+ claim_type: args.claim_type,
787
+ policy_number: args.policy_number,
788
+ incident_date: args.incident_date,
789
+ submitted_at: new Date().toISOString(),
790
+ injuries_involved: args.injuries_involved ?? false,
791
+ urgent: isUrgent,
792
+ ...(isUrgent && {
793
+ urgent_message:
794
+ "⚠️ This claim type may require immediate attention. Call 1-800-STATE-FARM now if you need emergency assistance.",
795
+ }),
796
+ next_steps: [
797
+ "1. Call 1-800-STATE-FARM (1-800-782-8332) to officially file and get a claim number",
798
+ "2. You can also file online at statefarm.com → Claims → 'File a Claim'",
799
+ "3. Use the State Farm mobile app for the fastest filing experience",
800
+ "4. Document the damage with photos before any cleanup or repairs",
801
+ "5. Keep all receipts for any emergency expenses",
802
+ ...(args.other_parties_involved ? ["6. Exchange insurance information with other parties"] : []),
803
+ ...(args.injuries_involved ? ["⚠️ Seek medical attention first — document all injuries and treatments"] : []),
804
+ ],
805
+ online_claim_url: "https://www.statefarm.com/claims",
806
+ mobile_app: "State Farm app → Claims → File a Claim",
807
+ phone: "1-800-STATE-FARM (1-800-782-8332) — 24/7",
808
+ what_to_have_ready: [
809
+ "Policy number",
810
+ "Date, time, and location of incident",
811
+ "Description of what happened",
812
+ "Photos of damage or scene",
813
+ "Contact info for any witnesses",
814
+ ...(args.police_report_number ? [`Police report #${args.police_report_number}`] : ["Police report number (if applicable)"]),
815
+ ...(args.claim_type.startsWith("auto") ? ["Other driver's info: name, license, insurance, plate number"] : []),
816
+ ],
817
+ });
818
+ }
819
+
820
+ function handleClaimStatus(args: ClaimStatusArgs) {
821
+ return respond({
822
+ success: true,
823
+ claim_number: args.claim_number,
824
+ note: "Live claim status requires authentication with State Farm.",
825
+ how_to_check_status: {
826
+ online: `https://www.statefarm.com/claims — enter claim #${args.claim_number}`,
827
+ mobile_app: "State Farm app → Claims → Active Claims",
828
+ phone: "1-800-STATE-FARM (1-800-782-8332) — have your claim number ready",
829
+ agent: "Contact your State Farm agent directly",
830
+ },
831
+ typical_claim_stages: [
832
+ {
833
+ stage: "Submitted",
834
+ description: "Claim received, awaiting assignment to adjuster",
835
+ typical_duration: "Within 24 hours",
836
+ },
837
+ {
838
+ stage: "Under Review",
839
+ description: "Assigned adjuster is evaluating the claim",
840
+ typical_duration: "1–5 business days",
841
+ },
842
+ {
843
+ stage: "Inspection Scheduled",
844
+ description: "Damage inspection being arranged",
845
+ typical_duration: "2–7 business days after review",
846
+ },
847
+ {
848
+ stage: "Estimate Provided",
849
+ description: "Repair or replacement cost estimated",
850
+ typical_duration: "Varies by damage type",
851
+ },
852
+ {
853
+ stage: "Payment Processing",
854
+ description: "Settlement approved, payment being issued",
855
+ typical_duration: "3–5 business days",
856
+ },
857
+ {
858
+ stage: "Closed",
859
+ description: "Claim fully resolved and payment issued",
860
+ typical_duration: "Total: 7–30 days depending on complexity",
861
+ },
862
+ ],
863
+ tips: [
864
+ "Log in to statefarm.com for real-time status updates",
865
+ "Your adjuster's contact info is available in the mobile app",
866
+ "Upload additional documentation directly through the app",
867
+ "You can request a status call with your adjuster at any time",
868
+ ],
869
+ });
870
+ }
871
+
872
+ function handlePayment(args: PaymentArgs) {
873
+ const { action, policy_number } = args;
874
+
875
+ const paymentPortalUrl = "https://www.statefarm.com/customer-care/payment-center";
876
+
877
+ switch (action) {
878
+ case "view_balance":
879
+ case "payment_history":
880
+ return respond({
881
+ success: true,
882
+ action,
883
+ policy_number: policy_number ?? "all policies",
884
+ note: "Live payment data requires authentication.",
885
+ how_to_access: {
886
+ online: paymentPortalUrl,
887
+ mobile_app: "State Farm app → Billing → Payment History",
888
+ phone: "1-800-STATE-FARM (1-800-782-8332)",
889
+ },
890
+ what_you_can_see: [
891
+ "Current balance due",
892
+ "Payment due date",
893
+ "Last payment amount and date",
894
+ "Full payment history",
895
+ "Upcoming scheduled payments",
896
+ "Autopay status",
897
+ ],
898
+ });
899
+
900
+ case "make_payment":
901
+ return respond({
902
+ success: true,
903
+ action: "make_payment",
904
+ policy_number,
905
+ payment_amount: args.payment_amount,
906
+ payment_method: args.payment_method ?? "bank_account",
907
+ note: "Payments must be completed through the official State Farm portal.",
908
+ payment_options: {
909
+ online: paymentPortalUrl,
910
+ mobile_app: "State Farm app → Billing → Make a Payment",
911
+ phone: "1-800-440-0998 (automated payment line — 24/7)",
912
+ mail: "State Farm Insurance Companies, P.O. Box 588002, North Metro, GA 30029",
913
+ agent: "Visit your local State Farm agent office",
914
+ },
915
+ accepted_payment_methods: [
916
+ "Bank account (ACH) — no fee",
917
+ "Credit card (Visa, Mastercard, Discover, Amex) — may have fee",
918
+ "Debit card — no fee",
919
+ "Check or money order by mail",
920
+ ],
921
+ tips: [
922
+ "Pay at least 3 days before due date to avoid late fees",
923
+ "Set up autopay for 1-2% discount on some policies",
924
+ "Same-day payment available online and by phone",
925
+ ],
926
+ });
927
+
928
+ case "setup_autopay":
929
+ case "cancel_autopay":
930
+ return respond({
931
+ success: true,
932
+ action,
933
+ policy_number,
934
+ note: "Autopay management requires login to State Farm.",
935
+ how_to_manage: {
936
+ online: `${paymentPortalUrl} → Automatic Payments`,
937
+ mobile_app: "State Farm app → Billing → Automatic Payments",
938
+ phone: "1-800-STATE-FARM (1-800-782-8332)",
939
+ },
940
+ autopay_benefits: [
941
+ "Never miss a payment",
942
+ "Potential discount on premiums",
943
+ "Flexible payment dates",
944
+ "Instant confirmation",
945
+ ],
946
+ autopay_options: ["Monthly", "Twice a year", "Annually"],
947
+ });
948
+
949
+ case "update_payment_method":
950
+ return respond({
951
+ success: true,
952
+ action: "update_payment_method",
953
+ policy_number,
954
+ new_method: args.payment_method,
955
+ note: "Payment method updates require login to State Farm.",
956
+ how_to_update: {
957
+ online: `${paymentPortalUrl} → Manage Payment Methods`,
958
+ mobile_app: "State Farm app → Billing → Payment Methods",
959
+ phone: "1-800-STATE-FARM (1-800-782-8332)",
960
+ agent: "Your local State Farm agent can assist",
961
+ },
962
+ });
963
+
964
+ default:
965
+ return respond({ success: false, error: `Unknown payment action: ${action}` });
966
+ }
967
+ }
968
+
969
+ function handleDigitalIdCard(args: DigitalIdCardArgs) {
970
+ const { policy_number, vehicle_vin, format = "display" } = args;
971
+
972
+ const idCardData = {
973
+ success: true,
974
+ format,
975
+ policy_number,
976
+ ...(vehicle_vin && { vehicle_vin }),
977
+ id_card_info: {
978
+ insurer: "State Farm Mutual Automobile Insurance Company",
979
+ policy_number,
980
+ policy_period: "Contact State Farm for current dates",
981
+ naic_code: "25178",
982
+ note: "Full ID card data requires authentication with State Farm",
983
+ },
984
+ how_to_access: {
985
+ mobile_app: "State Farm app → ID Cards (accessible even without cell service)",
986
+ online: "https://www.statefarm.com/customer-care/auto-id-cards",
987
+ email: "Request from statefarm.com or the mobile app",
988
+ physical_card: "Request mailed copy by calling 1-800-STATE-FARM",
989
+ },
990
+ digital_id_features: [
991
+ "Available offline in the State Farm app",
992
+ "Accepted in all 50 states",
993
+ "Can be shared digitally with DMV, police, and body shops",
994
+ "Auto-updates when policy renews",
995
+ "QR code for quick verification",
996
+ ],
997
+ legal_note:
998
+ "Digital insurance cards are legally accepted in all 50 US states. Save it on your phone for easy access during traffic stops or accidents.",
999
+ };
1000
+
1001
+ if (format === "email" && args.email_address) {
1002
+ return respond({
1003
+ ...idCardData,
1004
+ email_requested_to: args.email_address,
1005
+ email_instructions:
1006
+ "To email your ID card: State Farm app → ID Cards → Share → Email, or visit statefarm.com → My Account → Auto ID Cards → Email",
1007
+ });
1008
+ }
1009
+
1010
+ if (format === "download_link") {
1011
+ return respond({
1012
+ ...idCardData,
1013
+ download_instructions:
1014
+ "Download your ID card PDF at: https://www.statefarm.com/customer-care/auto-id-cards (login required)",
1015
+ });
1016
+ }
1017
+
1018
+ return respond(idCardData);
1019
+ }
1020
+
1021
+ function handleFindAgent(args: FindAgentArgs) {
1022
+ const { location, radius_miles = 10, insurance_type = "any", max_results = 5 } = args;
1023
+ const limitedResults = Math.min(max_results, 20);
1024
+
1025
+ return respond({
1026
+ success: true,
1027
+ search_location: location,
1028
+ radius_miles,
1029
+ insurance_type,
1030
+ results_requested: limitedResults,
1031
+ note: "Live agent data is available through State Farm's agent locator.",
1032
+ find_agent_url: `https://www.statefarm.com/agent/us?addr=${encodeURIComponent(location)}`,
1033
+ search_options: {
1034
+ online: `https://www.statefarm.com/agent/us?addr=${encodeURIComponent(location)}`,
1035
+ phone: "1-800-STATE-FARM (1-800-782-8332) — ask for agent referrals",
1036
+ mobile_app: "State Farm app → Find an Agent",
1037
+ },
1038
+ what_to_expect: {
1039
+ typical_agents_per_city: "5–30+ agents within 10 miles in most urban areas",
1040
+ office_hours: "Typically Mon–Fri 9am–5pm, some with evening/weekend hours",
1041
+ services: [
1042
+ "Free insurance consultations",
1043
+ "Policy reviews and updates",
1044
+ "Claims assistance",
1045
+ "Coverage recommendations",
1046
+ "Life insurance planning",
1047
+ ],
1048
+ },
1049
+ filter_options: [
1050
+ "Distance (closest first)",
1051
+ "Language spoken",
1052
+ "Insurance specialization",
1053
+ "Accepting new clients",
1054
+ "Virtual appointments available",
1055
+ ],
1056
+ ...(args.language && {
1057
+ language_note: `Searching for agents who speak ${args.language}. Use the online locator and filter by language for best results.`,
1058
+ }),
1059
+ tips: [
1060
+ "Call ahead to confirm the agent is accepting new clients",
1061
+ "Many agents offer free initial consultations",
1062
+ "Ask about multi-policy discounts when you meet",
1063
+ "State Farm agents are independent contractors — find one you connect with",
1064
+ ],
1065
+ });
1066
+ }
1067
+
1068
+ function handleRoadsideAssistance(args: RoadsideArgs) {
1069
+ const { action } = args;
1070
+ const roadsidePhone = "1-800-STATE-FARM (1-800-782-8332)";
1071
+ const roadsideApp = "State Farm app → Roadside Assistance";
1072
+
1073
+ switch (action) {
1074
+ case "request_service": {
1075
+ const requestId = `RSA-${Date.now().toString(36).toUpperCase()}`;
1076
+ return respond({
1077
+ success: true,
1078
+ action: "request_service",
1079
+ request_id: requestId,
1080
+ service_type: args.service_type ?? "any",
1081
+ policy_number: args.policy_number,
1082
+ current_location: args.current_location,
1083
+ vehicle: args.vehicle_description,
1084
+ callback_phone: args.callback_phone,
1085
+ status: "request_initiated",
1086
+ how_to_dispatch: {
1087
+ fastest: roadsideApp,
1088
+ phone: roadsidePhone,
1089
+ online: "https://www.statefarm.com/insurance/auto/roadside-assistance",
1090
+ },
1091
+ emergency_note:
1092
+ "If you are in an unsafe location or there is a safety emergency, call 911 first.",
1093
+ what_to_expect: {
1094
+ eta_typical: "30–60 minutes depending on location and time of day",
1095
+ dispatch_confirmation: "You'll receive a text/call confirming the provider",
1096
+ tracking: "Track the service vehicle in real-time via the State Farm app",
1097
+ },
1098
+ available_services: {
1099
+ towing: "Up to 15 miles (standard) or 100+ miles (premium coverage)",
1100
+ battery_jump: "On-site jump start",
1101
+ flat_tire: "Spare tire installation",
1102
+ fuel_delivery: "Up to 3 gallons of fuel delivered",
1103
+ lockout: "Unlock vehicle — does not replace lost keys",
1104
+ winching: "Vehicle extraction if stuck in mud/snow/ditch",
1105
+ },
1106
+ coverage_note: "Roadside coverage must be on your policy. Verify with statefarm_roadside_assistance action='check_coverage'.",
1107
+ });
1108
+ }
1109
+
1110
+ case "check_coverage":
1111
+ return respond({
1112
+ success: true,
1113
+ action: "check_coverage",
1114
+ policy_number: args.policy_number,
1115
+ note: "Live coverage verification requires authentication.",
1116
+ how_to_verify: {
1117
+ mobile_app: `${roadsideApp} → it will show if you have coverage`,
1118
+ online: "https://www.statefarm.com/customer-care/login → Policy Details",
1119
+ phone: roadsidePhone,
1120
+ },
1121
+ roadside_coverage_options: {
1122
+ basic_roadside: {
1123
+ included_with: "Many auto policies",
1124
+ services: ["Towing (15 mi)", "Battery jump", "Flat tire", "Lockout"],
1125
+ cost: "Typically $4–$8/month added to policy",
1126
+ },
1127
+ premier_roadside: {
1128
+ included_with: "Premium auto policies",
1129
+ services: ["Towing (100+ mi)", "All basic services", "Trip interruption coverage"],
1130
+ cost: "Varies by policy",
1131
+ },
1132
+ no_coverage: {
1133
+ alternative: "State Farm Emergency Road Service can be added to your policy",
1134
+ or: "Use AAA or contact a local tow company",
1135
+ },
1136
+ },
1137
+ });
1138
+
1139
+ case "track_service":
1140
+ return respond({
1141
+ success: true,
1142
+ action: "track_service",
1143
+ service_request_id: args.service_request_id,
1144
+ how_to_track: {
1145
+ mobile_app: `${roadsideApp} → Active Requests → Track Provider`,
1146
+ sms: "You should receive an SMS with a tracking link when service is dispatched",
1147
+ phone: roadsidePhone,
1148
+ },
1149
+ tip: "If the provider is more than 15 minutes late, call State Farm to confirm dispatch.",
1150
+ });
1151
+
1152
+ default:
1153
+ return respond({ success: false, error: `Unknown roadside action: ${action}` });
1154
+ }
1155
+ }
1156
+
1157
+ function handleBundleRecommendations(args: BundleArgs) {
1158
+ const {
1159
+ current_policies = [],
1160
+ zip_code,
1161
+ own_home,
1162
+ own_vehicle,
1163
+ has_dependents,
1164
+ annual_income,
1165
+ priority = "savings",
1166
+ } = args;
1167
+
1168
+ const recommendations: Array<{
1169
+ bundle: string[];
1170
+ rationale: string;
1171
+ estimated_savings: string;
1172
+ priority_score: number;
1173
+ }> = [];
1174
+
1175
+ // Auto + Home bundle
1176
+ if (
1177
+ (own_vehicle || current_policies.includes("auto")) &&
1178
+ (own_home || current_policies.includes("home"))
1179
+ ) {
1180
+ recommendations.push({
1181
+ bundle: ["auto", "home"],
1182
+ rationale:
1183
+ "The Auto + Home bundle is State Farm's most popular combination, offering the largest discount.",
1184
+ estimated_savings: "Up to 17% off both policies",
1185
+ priority_score: priority === "savings" ? 10 : 8,
1186
+ });
1187
+ }
1188
+
1189
+ // Auto + Renters bundle
1190
+ if (
1191
+ (own_vehicle || current_policies.includes("auto")) &&
1192
+ !own_home &&
1193
+ !current_policies.includes("home")
1194
+ ) {
1195
+ recommendations.push({
1196
+ bundle: ["auto", "renters"],
1197
+ rationale:
1198
+ "Renters insurance is very affordable (~$15-25/mo) and bundling with auto gives you a discount on both.",
1199
+ estimated_savings: "Up to 17% off auto + low-cost renters coverage",
1200
+ priority_score: 9,
1201
+ });
1202
+ }
1203
+
1204
+ // Life insurance recommendation
1205
+ if (has_dependents && !current_policies.includes("life")) {
1206
+ recommendations.push({
1207
+ bundle: [...current_policies, "life"],
1208
+ rationale:
1209
+ "With dependents, life insurance is essential. Adding it to existing State Farm policies may unlock additional multi-policy benefits.",
1210
+ estimated_savings: "Varies; primary value is financial protection for dependents",
1211
+ priority_score: priority === "coverage" ? 10 : 7,
1212
+ });
1213
+ }
1214
+
1215
+ // Full bundle
1216
+ if (own_vehicle && own_home && has_dependents) {
1217
+ recommendations.push({
1218
+ bundle: ["auto", "home", "life"],
1219
+ rationale:
1220
+ "The complete Auto + Home + Life bundle maximizes multi-policy discounts and simplifies insurance management with one carrier.",
1221
+ estimated_savings: "Up to 20%+ combined discount across all policies",
1222
+ priority_score: 10,
1223
+ });
1224
+ }
1225
+
1226
+ // Standalone recommendation if no current policies
1227
+ if (current_policies.length === 0 && own_vehicle) {
1228
+ recommendations.push({
1229
+ bundle: ["auto"],
1230
+ rationale: "Start with auto insurance (required in most states), then add renters or home.",
1231
+ estimated_savings: "N/A — single policy",
1232
+ priority_score: 5,
1233
+ });
1234
+ }
1235
+
1236
+ // Sort by priority
1237
+ recommendations.sort((a, b) => b.priority_score - a.priority_score);
1238
+
1239
+ return respond({
1240
+ success: true,
1241
+ zip_code,
1242
+ current_policies,
1243
+ priority,
1244
+ top_recommendation: recommendations[0] ?? null,
1245
+ all_recommendations: recommendations,
1246
+ state_farm_multi_policy_discounts: {
1247
+ auto_and_home: "Up to 17%",
1248
+ auto_and_renters: "Up to 17%",
1249
+ three_or_more_policies: "Up to 20%+",
1250
+ },
1251
+ savings_estimate: annual_income
1252
+ ? `Bundling could save approximately $${Math.round(annual_income * 0.004).toLocaleString()}–$${Math.round(annual_income * 0.009).toLocaleString()}/year based on typical premiums`
1253
+ : "Get a quote to see your specific savings",
1254
+ next_steps: [
1255
+ "1. Use statefarm_get_quote to get individual quotes for each recommended policy",
1256
+ "2. Ask your State Farm agent to apply all multi-policy discounts",
1257
+ "3. Compare bundled vs individual policy pricing",
1258
+ "4. Review coverage levels — don't sacrifice coverage for discounts",
1259
+ ],
1260
+ get_bundled_quote_url: `https://www.statefarm.com/insurance/home-and-auto-bundle?zip=${zip_code}`,
1261
+ phone: "1-800-STATE-FARM (1-800-782-8332) — ask about bundle discounts",
1262
+ });
1263
+ }
1264
+
1265
+ // ─── Server Startup ────────────────────────────────────────────────────────────
1266
+
1267
+ async function main() {
1268
+ const transport = new StdioServerTransport();
1269
+ await server.connect(transport);
1270
+ process.stderr.write("State Farm MCP server running on stdio\n");
1271
+ }
1272
+
1273
+ process.on("SIGINT", async () => {
1274
+ await server.close();
1275
+ process.exit(0);
1276
+ });
1277
+
1278
+ process.on("SIGTERM", async () => {
1279
+ await server.close();
1280
+ process.exit(0);
1281
+ });
1282
+
1283
+ main().catch((err) => {
1284
+ process.stderr.write(`Fatal error: ${err}\n`);
1285
+ process.exit(1);
1286
+ });