@striderlabs/mcp-spectrum 1.0.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 +151 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +549 -0
- package/dist/index.js.map +1 -0
- package/package.json +25 -0
- package/src/index.ts +733 -0
- package/tsconfig.json +19 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
5
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
6
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
7
|
+
const playwright_1 = require("playwright");
|
|
8
|
+
// ── Constants ──────────────────────────────────────────────────────────────────
|
|
9
|
+
const SPECTRUM_BASE = "https://www.spectrum.com";
|
|
10
|
+
const SPECTRUM_MY_ACCOUNT = "https://www.spectrum.net/login";
|
|
11
|
+
const SPECTRUM_ACCOUNT_OVERVIEW = "https://www.spectrum.net/account/overview";
|
|
12
|
+
const SPECTRUM_BILL = "https://www.spectrum.net/account/billing";
|
|
13
|
+
const SPECTRUM_SERVICES = "https://www.spectrum.net/account/services";
|
|
14
|
+
const SPECTRUM_SUPPORT = "https://www.spectrum.net/support";
|
|
15
|
+
const SPECTRUM_OUTAGES = "https://www.spectrum.net/support/internet/spectrum-internet-outages";
|
|
16
|
+
const SPECTRUM_SCHEDULE = "https://www.spectrum.net/account/services/schedule";
|
|
17
|
+
// ── Browser helper ─────────────────────────────────────────────────────────────
|
|
18
|
+
async function getBrowser() {
|
|
19
|
+
const cdpUrl = process.env.BROWSERBASE_CDP_URL;
|
|
20
|
+
if (!cdpUrl) {
|
|
21
|
+
throw new Error("BROWSERBASE_CDP_URL environment variable is required. " +
|
|
22
|
+
"Set it to your Browserbase CDP WebSocket URL.");
|
|
23
|
+
}
|
|
24
|
+
return playwright_1.chromium.connectOverCDP(cdpUrl);
|
|
25
|
+
}
|
|
26
|
+
async function getPage(browser) {
|
|
27
|
+
const contexts = browser.contexts();
|
|
28
|
+
const ctx = contexts.length > 0 ? contexts[0] : await browser.newContext();
|
|
29
|
+
const pages = ctx.pages();
|
|
30
|
+
return pages.length > 0 ? pages[0] : await ctx.newPage();
|
|
31
|
+
}
|
|
32
|
+
/** Navigate and wait for network idle */
|
|
33
|
+
async function navigate(page, url) {
|
|
34
|
+
await page.goto(url, { waitUntil: "domcontentloaded", timeout: 30000 });
|
|
35
|
+
}
|
|
36
|
+
/** Login helper — reuses session if already logged in */
|
|
37
|
+
async function ensureLoggedIn(page, username, password) {
|
|
38
|
+
const currentUrl = page.url();
|
|
39
|
+
if (currentUrl.includes("spectrum.net/account")) {
|
|
40
|
+
// Already on account pages — likely logged in
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
await navigate(page, SPECTRUM_MY_ACCOUNT);
|
|
44
|
+
// Check if already redirected past login
|
|
45
|
+
await page.waitForTimeout(1500);
|
|
46
|
+
if (page.url().includes("/account")) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// Fill login form
|
|
50
|
+
await page.fill('input[name="IDToken1"], input[type="text"][id*="username"], #IDToken1', username);
|
|
51
|
+
await page.fill('input[name="IDToken2"], input[type="password"], #IDToken2', password);
|
|
52
|
+
await page.click('button[type="submit"], input[type="submit"], button:has-text("Sign In"), button:has-text("Log In")');
|
|
53
|
+
// Wait for redirect after login
|
|
54
|
+
await page.waitForURL(/spectrum\.net\/(account|my-account)/, { timeout: 20000 }).catch(() => {
|
|
55
|
+
// May redirect to different page — ignore timeout and check url
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/** Extract visible text from a selector, or return a fallback */
|
|
59
|
+
async function safeText(page, selector, fallback = "") {
|
|
60
|
+
try {
|
|
61
|
+
return (await page.textContent(selector, { timeout: 3000 }))?.trim() ?? fallback;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return fallback;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// ── Tool implementations ───────────────────────────────────────────────────────
|
|
68
|
+
async function getAccountOverview(args) {
|
|
69
|
+
let browser = null;
|
|
70
|
+
try {
|
|
71
|
+
browser = await getBrowser();
|
|
72
|
+
const page = await getPage(browser);
|
|
73
|
+
await ensureLoggedIn(page, args.username, args.password);
|
|
74
|
+
await navigate(page, SPECTRUM_ACCOUNT_OVERVIEW);
|
|
75
|
+
// Wait for content to load
|
|
76
|
+
await page.waitForTimeout(2000);
|
|
77
|
+
// Scrape account summary
|
|
78
|
+
const pageText = await page.evaluate(() => document.body.innerText);
|
|
79
|
+
// Extract key info using regex patterns
|
|
80
|
+
const planMatch = pageText.match(/(?:plan|package|service)[:\s]+([^\n]+)/i);
|
|
81
|
+
const balanceMatch = pageText.match(/(?:balance|amount due|total due)[:\s]*\$?([\d,.]+)/i);
|
|
82
|
+
const dueDateMatch = pageText.match(/(?:due date|payment due)[:\s]+([^\n]+)/i);
|
|
83
|
+
const dataUsageMatch = pageText.match(/(?:data usage|data used)[:\s]*([\d.]+\s*(?:GB|MB|TB))/i);
|
|
84
|
+
const result = {
|
|
85
|
+
account_url: page.url(),
|
|
86
|
+
current_plan: planMatch?.[1]?.trim() ?? "Unable to retrieve",
|
|
87
|
+
balance_due: balanceMatch?.[1] ? `$${balanceMatch[1]}` : "Unable to retrieve",
|
|
88
|
+
payment_due_date: dueDateMatch?.[1]?.trim() ?? "Unable to retrieve",
|
|
89
|
+
data_usage: dataUsageMatch?.[1]?.trim() ?? "Unable to retrieve",
|
|
90
|
+
raw_summary: pageText.slice(0, 2000),
|
|
91
|
+
};
|
|
92
|
+
return JSON.stringify(result, null, 2);
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
if (browser)
|
|
96
|
+
await browser.close();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async function getServiceDetails(args) {
|
|
100
|
+
let browser = null;
|
|
101
|
+
try {
|
|
102
|
+
browser = await getBrowser();
|
|
103
|
+
const page = await getPage(browser);
|
|
104
|
+
await ensureLoggedIn(page, args.username, args.password);
|
|
105
|
+
await navigate(page, SPECTRUM_SERVICES);
|
|
106
|
+
await page.waitForTimeout(2000);
|
|
107
|
+
const pageText = await page.evaluate(() => document.body.innerText);
|
|
108
|
+
// Parse out service sections
|
|
109
|
+
const services = {};
|
|
110
|
+
const serviceTypes = ["internet", "tv", "voice", "phone", "mobile"];
|
|
111
|
+
for (const svc of serviceTypes) {
|
|
112
|
+
if (!args.service_type ||
|
|
113
|
+
args.service_type.toLowerCase() === svc) {
|
|
114
|
+
const svcRegex = new RegExp(`${svc}[^\\n]*\\n([\\s\\S]{0,500})`, "i");
|
|
115
|
+
const match = pageText.match(svcRegex);
|
|
116
|
+
if (match) {
|
|
117
|
+
services[svc] = match[1].trim().slice(0, 300);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return JSON.stringify({
|
|
122
|
+
services_url: page.url(),
|
|
123
|
+
service_type_filter: args.service_type ?? "all",
|
|
124
|
+
services,
|
|
125
|
+
raw_content: pageText.slice(0, 3000),
|
|
126
|
+
}, null, 2);
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
if (browser)
|
|
130
|
+
await browser.close();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
async function payBill(args) {
|
|
134
|
+
let browser = null;
|
|
135
|
+
try {
|
|
136
|
+
browser = await getBrowser();
|
|
137
|
+
const page = await getPage(browser);
|
|
138
|
+
await ensureLoggedIn(page, args.username, args.password);
|
|
139
|
+
await navigate(page, SPECTRUM_BILL);
|
|
140
|
+
await page.waitForTimeout(2000);
|
|
141
|
+
// Look for "Make a Payment" or "Pay Now" button
|
|
142
|
+
const payButton = await page
|
|
143
|
+
.locator('button:has-text("Make a Payment"), a:has-text("Make a Payment"), button:has-text("Pay Now"), a:has-text("Pay Now")')
|
|
144
|
+
.first();
|
|
145
|
+
const payButtonExists = (await payButton.count()) > 0;
|
|
146
|
+
if (!payButtonExists) {
|
|
147
|
+
const pageText = await page.evaluate(() => document.body.innerText);
|
|
148
|
+
return JSON.stringify({
|
|
149
|
+
status: "navigation_required",
|
|
150
|
+
message: "Could not locate the payment button automatically. Manual navigation required.",
|
|
151
|
+
billing_url: page.url(),
|
|
152
|
+
page_content_preview: pageText.slice(0, 500),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
await payButton.click();
|
|
156
|
+
await page.waitForTimeout(2000);
|
|
157
|
+
// Try to fill amount if field exists
|
|
158
|
+
const amountField = page.locator('input[name*="amount"], input[placeholder*="amount"], input[id*="amount"]').first();
|
|
159
|
+
if ((await amountField.count()) > 0) {
|
|
160
|
+
await amountField.clear();
|
|
161
|
+
await amountField.fill(args.amount);
|
|
162
|
+
}
|
|
163
|
+
// Select payment method if specified
|
|
164
|
+
if (args.payment_method) {
|
|
165
|
+
const pmSelect = page.locator('select[name*="payment"], select[id*="payment"]').first();
|
|
166
|
+
if ((await pmSelect.count()) > 0) {
|
|
167
|
+
await pmSelect.selectOption({ label: args.payment_method });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const currentUrl = page.url();
|
|
171
|
+
const pageText = await page.evaluate(() => document.body.innerText);
|
|
172
|
+
return JSON.stringify({
|
|
173
|
+
status: "payment_form_ready",
|
|
174
|
+
message: `Payment form loaded. Amount field populated with $${args.amount}. Review and confirm to complete payment.`,
|
|
175
|
+
payment_url: currentUrl,
|
|
176
|
+
amount_entered: args.amount,
|
|
177
|
+
payment_method: args.payment_method ?? "default on file",
|
|
178
|
+
page_content_preview: pageText.slice(0, 500),
|
|
179
|
+
warning: "Payment has NOT been submitted. You must click the final confirm/submit button to complete payment.",
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
finally {
|
|
183
|
+
if (browser)
|
|
184
|
+
await browser.close();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
async function getBillHistory(args) {
|
|
188
|
+
let browser = null;
|
|
189
|
+
try {
|
|
190
|
+
browser = await getBrowser();
|
|
191
|
+
const page = await getPage(browser);
|
|
192
|
+
await ensureLoggedIn(page, args.username, args.password);
|
|
193
|
+
await navigate(page, SPECTRUM_BILL);
|
|
194
|
+
await page.waitForTimeout(2000);
|
|
195
|
+
// Look for bill history section
|
|
196
|
+
const historyLink = page.locator('a:has-text("Bill History"), a:has-text("Billing History"), a:has-text("View All"), button:has-text("Bill History")').first();
|
|
197
|
+
if ((await historyLink.count()) > 0) {
|
|
198
|
+
await historyLink.click();
|
|
199
|
+
await page.waitForTimeout(2000);
|
|
200
|
+
}
|
|
201
|
+
const pageText = await page.evaluate(() => document.body.innerText);
|
|
202
|
+
// Try to parse bill entries from table or list
|
|
203
|
+
const bills = [];
|
|
204
|
+
const billPattern = /(\w+\s+\d{1,2},?\s+\d{4})[^\n]*\$([\d,.]+)[^\n]*\n?([^\n]*(?:paid|pending|due|payment)[^\n]*)?/gi;
|
|
205
|
+
let match;
|
|
206
|
+
const maxBills = (args.months ?? 12) * 2; // rough upper bound
|
|
207
|
+
while ((match = billPattern.exec(pageText)) !== null && bills.length < maxBills) {
|
|
208
|
+
bills.push({
|
|
209
|
+
date: match[1].trim(),
|
|
210
|
+
amount: `$${match[2]}`,
|
|
211
|
+
status: match[3]?.trim() ?? "unknown",
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return JSON.stringify({
|
|
215
|
+
billing_url: page.url(),
|
|
216
|
+
months_requested: args.months ?? 12,
|
|
217
|
+
bills_found: bills.length,
|
|
218
|
+
bill_history: bills,
|
|
219
|
+
raw_content: pageText.slice(0, 4000),
|
|
220
|
+
}, null, 2);
|
|
221
|
+
}
|
|
222
|
+
finally {
|
|
223
|
+
if (browser)
|
|
224
|
+
await browser.close();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
async function checkOutages(args) {
|
|
228
|
+
let browser = null;
|
|
229
|
+
try {
|
|
230
|
+
browser = await getBrowser();
|
|
231
|
+
const page = await getPage(browser);
|
|
232
|
+
// Outage check can work without login if zip is provided
|
|
233
|
+
if (args.username && args.password) {
|
|
234
|
+
await ensureLoggedIn(page, args.username, args.password);
|
|
235
|
+
}
|
|
236
|
+
await navigate(page, SPECTRUM_OUTAGES);
|
|
237
|
+
await page.waitForTimeout(2000);
|
|
238
|
+
// If zip code provided, try to fill the outage checker
|
|
239
|
+
if (args.zip_code) {
|
|
240
|
+
const zipField = page.locator('input[placeholder*="zip"], input[name*="zip"], input[id*="zip"], input[placeholder*="ZIP"], input[type="text"]').first();
|
|
241
|
+
if ((await zipField.count()) > 0) {
|
|
242
|
+
await zipField.fill(args.zip_code);
|
|
243
|
+
await page.keyboard.press("Enter");
|
|
244
|
+
await page.waitForTimeout(3000);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const pageText = await page.evaluate(() => document.body.innerText);
|
|
248
|
+
// Look for outage indicators
|
|
249
|
+
const hasOutage = /outage|service disruption|service interruption|we.?re aware/i.test(pageText);
|
|
250
|
+
const noOutage = /no outage|no known outage|service is operating normally|no current outage/i.test(pageText);
|
|
251
|
+
// Extract any outage details
|
|
252
|
+
const outageMatch = pageText.match(/(outage|disruption)[^\n.]*[.\n][^\n.]*/i);
|
|
253
|
+
return JSON.stringify({
|
|
254
|
+
outage_check_url: page.url(),
|
|
255
|
+
zip_code: args.zip_code ?? "not provided",
|
|
256
|
+
address: args.address ?? "not provided",
|
|
257
|
+
outage_detected: hasOutage && !noOutage,
|
|
258
|
+
service_normal: noOutage,
|
|
259
|
+
status_summary: outageMatch?.[0]?.trim() ?? (noOutage ? "No outages detected" : "Unable to determine outage status"),
|
|
260
|
+
raw_content: pageText.slice(0, 3000),
|
|
261
|
+
}, null, 2);
|
|
262
|
+
}
|
|
263
|
+
finally {
|
|
264
|
+
if (browser)
|
|
265
|
+
await browser.close();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
async function scheduleTechnician(args) {
|
|
269
|
+
let browser = null;
|
|
270
|
+
try {
|
|
271
|
+
browser = await getBrowser();
|
|
272
|
+
const page = await getPage(browser);
|
|
273
|
+
await ensureLoggedIn(page, args.username, args.password);
|
|
274
|
+
// Try scheduling URL first, fall back to support
|
|
275
|
+
await navigate(page, SPECTRUM_SCHEDULE);
|
|
276
|
+
await page.waitForTimeout(2000);
|
|
277
|
+
if (!page.url().includes("schedule")) {
|
|
278
|
+
// Try support flow
|
|
279
|
+
await navigate(page, SPECTRUM_SUPPORT);
|
|
280
|
+
await page.waitForTimeout(2000);
|
|
281
|
+
const scheduleLink = page.locator('a:has-text("Schedule"), a:has-text("Technician"), button:has-text("Schedule Appointment")').first();
|
|
282
|
+
if ((await scheduleLink.count()) > 0) {
|
|
283
|
+
await scheduleLink.click();
|
|
284
|
+
await page.waitForTimeout(2000);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const pageText = await page.evaluate(() => document.body.innerText);
|
|
288
|
+
// Try to fill in scheduling form fields if present
|
|
289
|
+
const issueField = page.locator('textarea, input[name*="description"], input[placeholder*="describe"], textarea[placeholder*="issue"]').first();
|
|
290
|
+
if ((await issueField.count()) > 0) {
|
|
291
|
+
await issueField.fill(args.issue_description);
|
|
292
|
+
}
|
|
293
|
+
if (args.preferred_date) {
|
|
294
|
+
const dateField = page.locator('input[type="date"], input[name*="date"], input[placeholder*="date"]').first();
|
|
295
|
+
if ((await dateField.count()) > 0) {
|
|
296
|
+
await dateField.fill(args.preferred_date);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
if (args.preferred_time) {
|
|
300
|
+
const timeSelect = page.locator('select[name*="time"], select[id*="time"]').first();
|
|
301
|
+
if ((await timeSelect.count()) > 0) {
|
|
302
|
+
await timeSelect.selectOption({ label: args.preferred_time });
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (args.contact_phone) {
|
|
306
|
+
const phoneField = page.locator('input[type="tel"], input[name*="phone"], input[placeholder*="phone"]').first();
|
|
307
|
+
if ((await phoneField.count()) > 0) {
|
|
308
|
+
await phoneField.fill(args.contact_phone);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return JSON.stringify({
|
|
312
|
+
scheduling_url: page.url(),
|
|
313
|
+
status: "form_ready",
|
|
314
|
+
issue_description: args.issue_description,
|
|
315
|
+
preferred_date: args.preferred_date ?? "not specified",
|
|
316
|
+
preferred_time: args.preferred_time ?? "not specified",
|
|
317
|
+
contact_phone: args.contact_phone ?? "not provided",
|
|
318
|
+
message: "Scheduling form has been populated. Review the form and click the submit/confirm button to complete scheduling.",
|
|
319
|
+
warning: "Appointment has NOT been submitted yet. Manual confirmation required.",
|
|
320
|
+
page_content_preview: pageText.slice(0, 500),
|
|
321
|
+
}, null, 2);
|
|
322
|
+
}
|
|
323
|
+
finally {
|
|
324
|
+
if (browser)
|
|
325
|
+
await browser.close();
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// ── Tool definitions ───────────────────────────────────────────────────────────
|
|
329
|
+
const TOOLS = [
|
|
330
|
+
{
|
|
331
|
+
name: "get_account_overview",
|
|
332
|
+
description: "Get Spectrum account overview including current plan, balance due, payment due date, and data usage summary.",
|
|
333
|
+
inputSchema: {
|
|
334
|
+
type: "object",
|
|
335
|
+
properties: {
|
|
336
|
+
username: {
|
|
337
|
+
type: "string",
|
|
338
|
+
description: "Spectrum account username or email address",
|
|
339
|
+
},
|
|
340
|
+
password: {
|
|
341
|
+
type: "string",
|
|
342
|
+
description: "Spectrum account password",
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
required: ["username", "password"],
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
name: "get_service_details",
|
|
350
|
+
description: "Get details about active Spectrum services (internet, TV, phone/voice, mobile). Optionally filter by service type.",
|
|
351
|
+
inputSchema: {
|
|
352
|
+
type: "object",
|
|
353
|
+
properties: {
|
|
354
|
+
username: {
|
|
355
|
+
type: "string",
|
|
356
|
+
description: "Spectrum account username or email address",
|
|
357
|
+
},
|
|
358
|
+
password: {
|
|
359
|
+
type: "string",
|
|
360
|
+
description: "Spectrum account password",
|
|
361
|
+
},
|
|
362
|
+
service_type: {
|
|
363
|
+
type: "string",
|
|
364
|
+
enum: ["internet", "tv", "phone", "voice", "mobile"],
|
|
365
|
+
description: "Filter to a specific service type. Omit to retrieve all services.",
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
required: ["username", "password"],
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
name: "pay_bill",
|
|
373
|
+
description: "Initiate a one-time bill payment for a Spectrum account. Loads the payment form with the specified amount. Note: final submission requires user confirmation.",
|
|
374
|
+
inputSchema: {
|
|
375
|
+
type: "object",
|
|
376
|
+
properties: {
|
|
377
|
+
username: {
|
|
378
|
+
type: "string",
|
|
379
|
+
description: "Spectrum account username or email address",
|
|
380
|
+
},
|
|
381
|
+
password: {
|
|
382
|
+
type: "string",
|
|
383
|
+
description: "Spectrum account password",
|
|
384
|
+
},
|
|
385
|
+
amount: {
|
|
386
|
+
type: "string",
|
|
387
|
+
description: "Payment amount in dollars (e.g., '89.99'). Do not include the $ sign.",
|
|
388
|
+
},
|
|
389
|
+
payment_method: {
|
|
390
|
+
type: "string",
|
|
391
|
+
description: "Payment method label as it appears on the account (e.g., 'Visa ending in 4242'). Omit to use the default payment method on file.",
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
required: ["username", "password", "amount"],
|
|
395
|
+
},
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
name: "get_bill_history",
|
|
399
|
+
description: "Retrieve past billing history for a Spectrum account, including bill dates, amounts, and payment status.",
|
|
400
|
+
inputSchema: {
|
|
401
|
+
type: "object",
|
|
402
|
+
properties: {
|
|
403
|
+
username: {
|
|
404
|
+
type: "string",
|
|
405
|
+
description: "Spectrum account username or email address",
|
|
406
|
+
},
|
|
407
|
+
password: {
|
|
408
|
+
type: "string",
|
|
409
|
+
description: "Spectrum account password",
|
|
410
|
+
},
|
|
411
|
+
months: {
|
|
412
|
+
type: "number",
|
|
413
|
+
description: "Number of months of history to retrieve (default: 12, max: 24)",
|
|
414
|
+
minimum: 1,
|
|
415
|
+
maximum: 24,
|
|
416
|
+
},
|
|
417
|
+
},
|
|
418
|
+
required: ["username", "password"],
|
|
419
|
+
},
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
name: "check_outages",
|
|
423
|
+
description: "Check for active Spectrum service outages in a given area by ZIP code or address. Login is optional but provides account-specific outage info.",
|
|
424
|
+
inputSchema: {
|
|
425
|
+
type: "object",
|
|
426
|
+
properties: {
|
|
427
|
+
zip_code: {
|
|
428
|
+
type: "string",
|
|
429
|
+
description: "ZIP/postal code to check for outages (e.g., '90210')",
|
|
430
|
+
},
|
|
431
|
+
address: {
|
|
432
|
+
type: "string",
|
|
433
|
+
description: "Full service address to check for outages",
|
|
434
|
+
},
|
|
435
|
+
username: {
|
|
436
|
+
type: "string",
|
|
437
|
+
description: "Optional: Spectrum account username for account-specific outage check",
|
|
438
|
+
},
|
|
439
|
+
password: {
|
|
440
|
+
type: "string",
|
|
441
|
+
description: "Optional: Spectrum account password",
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
name: "schedule_technician",
|
|
448
|
+
description: "Schedule a Spectrum technician visit for service issues, installation, or equipment problems. Populates the scheduling form; final submission requires user confirmation.",
|
|
449
|
+
inputSchema: {
|
|
450
|
+
type: "object",
|
|
451
|
+
properties: {
|
|
452
|
+
username: {
|
|
453
|
+
type: "string",
|
|
454
|
+
description: "Spectrum account username or email address",
|
|
455
|
+
},
|
|
456
|
+
password: {
|
|
457
|
+
type: "string",
|
|
458
|
+
description: "Spectrum account password",
|
|
459
|
+
},
|
|
460
|
+
issue_description: {
|
|
461
|
+
type: "string",
|
|
462
|
+
description: "Description of the issue requiring a technician visit (e.g., 'Internet dropping intermittently', 'TV signal pixelating on all channels')",
|
|
463
|
+
},
|
|
464
|
+
preferred_date: {
|
|
465
|
+
type: "string",
|
|
466
|
+
description: "Preferred appointment date in YYYY-MM-DD format (e.g., '2025-03-20')",
|
|
467
|
+
},
|
|
468
|
+
preferred_time: {
|
|
469
|
+
type: "string",
|
|
470
|
+
description: "Preferred time window (e.g., 'Morning (8am-12pm)', 'Afternoon (1pm-5pm)', 'Evening (5pm-8pm)')",
|
|
471
|
+
},
|
|
472
|
+
contact_phone: {
|
|
473
|
+
type: "string",
|
|
474
|
+
description: "Contact phone number for the technician appointment (e.g., '555-123-4567')",
|
|
475
|
+
},
|
|
476
|
+
},
|
|
477
|
+
required: ["username", "password", "issue_description"],
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
];
|
|
481
|
+
// ── MCP Server ─────────────────────────────────────────────────────────────────
|
|
482
|
+
const server = new index_js_1.Server({
|
|
483
|
+
name: "@striderlabs/mcp-spectrum",
|
|
484
|
+
version: "1.0.0",
|
|
485
|
+
}, {
|
|
486
|
+
capabilities: {
|
|
487
|
+
tools: {},
|
|
488
|
+
},
|
|
489
|
+
});
|
|
490
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
|
491
|
+
tools: TOOLS,
|
|
492
|
+
}));
|
|
493
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
494
|
+
const { name, arguments: args } = request.params;
|
|
495
|
+
try {
|
|
496
|
+
let result;
|
|
497
|
+
switch (name) {
|
|
498
|
+
case "get_account_overview":
|
|
499
|
+
result = await getAccountOverview(args);
|
|
500
|
+
break;
|
|
501
|
+
case "get_service_details":
|
|
502
|
+
result = await getServiceDetails(args);
|
|
503
|
+
break;
|
|
504
|
+
case "pay_bill":
|
|
505
|
+
result = await payBill(args);
|
|
506
|
+
break;
|
|
507
|
+
case "get_bill_history":
|
|
508
|
+
result = await getBillHistory(args);
|
|
509
|
+
break;
|
|
510
|
+
case "check_outages":
|
|
511
|
+
result = await checkOutages(args);
|
|
512
|
+
break;
|
|
513
|
+
case "schedule_technician":
|
|
514
|
+
result = await scheduleTechnician(args);
|
|
515
|
+
break;
|
|
516
|
+
default:
|
|
517
|
+
return {
|
|
518
|
+
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
|
519
|
+
isError: true,
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
return {
|
|
523
|
+
content: [{ type: "text", text: result }],
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
catch (error) {
|
|
527
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
528
|
+
return {
|
|
529
|
+
content: [
|
|
530
|
+
{
|
|
531
|
+
type: "text",
|
|
532
|
+
text: JSON.stringify({ error: message, tool: name }, null, 2),
|
|
533
|
+
},
|
|
534
|
+
],
|
|
535
|
+
isError: true,
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
// ── Entrypoint ─────────────────────────────────────────────────────────────────
|
|
540
|
+
async function main() {
|
|
541
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
542
|
+
await server.connect(transport);
|
|
543
|
+
console.error("@striderlabs/mcp-spectrum MCP server running on stdio");
|
|
544
|
+
}
|
|
545
|
+
main().catch((err) => {
|
|
546
|
+
console.error("Fatal error:", err);
|
|
547
|
+
process.exit(1);
|
|
548
|
+
});
|
|
549
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@striderlabs/mcp-spectrum",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for Spectrum/Charter ISP account management",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"mcp-spectrum": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"start": "node dist/index.js",
|
|
12
|
+
"dev": "ts-node src/index.ts"
|
|
13
|
+
},
|
|
14
|
+
"keywords": ["mcp", "spectrum", "charter", "isp", "broadband"],
|
|
15
|
+
"author": "StrikerLabs",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
19
|
+
"playwright": "^1.40.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^20.0.0",
|
|
23
|
+
"typescript": "^5.0.0"
|
|
24
|
+
}
|
|
25
|
+
}
|