alterlab-mcp-server 1.7.0 → 1.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/README.md +75 -33
- package/dist/auth.d.ts +30 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +423 -0
- package/dist/auth.js.map +1 -0
- package/dist/client.d.ts +23 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +61 -3
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +21 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +85 -8
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +6 -4
- package/dist/errors.js.map +1 -1
- package/dist/format.d.ts +20 -2
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +187 -9
- package/dist/format.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +66 -2
- package/dist/index.js.map +1 -1
- package/dist/tools/balance.d.ts.map +1 -1
- package/dist/tools/balance.js +4 -2
- package/dist/tools/balance.js.map +1 -1
- package/dist/tools/batch.d.ts +1221 -25
- package/dist/tools/batch.d.ts.map +1 -1
- package/dist/tools/batch.js +123 -34
- package/dist/tools/batch.js.map +1 -1
- package/dist/tools/common.d.ts +313 -0
- package/dist/tools/common.d.ts.map +1 -0
- package/dist/tools/common.js +336 -0
- package/dist/tools/common.js.map +1 -0
- package/dist/tools/crawl.d.ts +165 -10
- package/dist/tools/crawl.d.ts.map +1 -1
- package/dist/tools/crawl.js +191 -43
- package/dist/tools/crawl.js.map +1 -1
- package/dist/tools/estimate.d.ts +21 -6
- package/dist/tools/estimate.d.ts.map +1 -1
- package/dist/tools/estimate.js +28 -35
- package/dist/tools/estimate.js.map +1 -1
- package/dist/tools/extract.d.ts +5 -5
- package/dist/tools/extract.d.ts.map +1 -1
- package/dist/tools/extract.js +16 -12
- package/dist/tools/extract.js.map +1 -1
- package/dist/tools/job.d.ts +13 -0
- package/dist/tools/job.d.ts.map +1 -0
- package/dist/tools/job.js +62 -0
- package/dist/tools/job.js.map +1 -0
- package/dist/tools/map.d.ts +5 -2
- package/dist/tools/map.d.ts.map +1 -1
- package/dist/tools/map.js +16 -5
- package/dist/tools/map.js.map +1 -1
- package/dist/tools/scrape.d.ts +431 -49
- package/dist/tools/scrape.d.ts.map +1 -1
- package/dist/tools/scrape.js +267 -135
- package/dist/tools/scrape.js.map +1 -1
- package/dist/tools/screenshot.d.ts +33 -0
- package/dist/tools/screenshot.d.ts.map +1 -1
- package/dist/tools/screenshot.js +60 -10
- package/dist/tools/screenshot.js.map +1 -1
- package/dist/tools/search.d.ts +11 -5
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +22 -6
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/sessions.d.ts +180 -12
- package/dist/tools/sessions.d.ts.map +1 -1
- package/dist/tools/sessions.js +75 -21
- package/dist/tools/sessions.js.map +1 -1
- package/dist/tools/simple_batch.d.ts +28 -0
- package/dist/tools/simple_batch.d.ts.map +1 -0
- package/dist/tools/simple_batch.js +142 -0
- package/dist/tools/simple_batch.js.map +1 -0
- package/dist/tools/usage.d.ts +7 -0
- package/dist/tools/usage.d.ts.map +1 -0
- package/dist/tools/usage.js +42 -0
- package/dist/tools/usage.js.map +1 -0
- package/dist/types.d.ts +219 -21
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +5 -3
- package/server.json +40 -4
package/dist/auth.js
ADDED
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OAuth 2.0 Device Authorization Grant (RFC 8628) client-side flow.
|
|
4
|
+
*
|
|
5
|
+
* Authentication priority chain:
|
|
6
|
+
* 1. ALTERLAB_API_KEY environment variable
|
|
7
|
+
* 2. ~/.alterlab/config.json
|
|
8
|
+
* 3. Interactive auth (TTY only):
|
|
9
|
+
* a. 5-second countdown — press any key to switch to manual paste
|
|
10
|
+
* b. Device flow (POST /auth/device → open browser → poll /auth/token)
|
|
11
|
+
* c. Fallback: manual API key paste
|
|
12
|
+
*
|
|
13
|
+
* All user-facing output goes to stderr — stdout is reserved for MCP protocol.
|
|
14
|
+
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.ensureAuth = ensureAuth;
|
|
50
|
+
const https = __importStar(require("https"));
|
|
51
|
+
const http = __importStar(require("http"));
|
|
52
|
+
const readline = __importStar(require("readline"));
|
|
53
|
+
const child_process_1 = require("child_process");
|
|
54
|
+
const config_js_1 = require("./config.js");
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// HTTP helper — wraps Node's built-in https/http for simple JSON requests
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
function postJson(url, body) {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
const payload = JSON.stringify(body);
|
|
61
|
+
const parsed = new URL(url);
|
|
62
|
+
const options = {
|
|
63
|
+
hostname: parsed.hostname,
|
|
64
|
+
port: parsed.port || (parsed.protocol === "https:" ? 443 : 80),
|
|
65
|
+
path: parsed.pathname + parsed.search,
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: {
|
|
68
|
+
"Content-Type": "application/json",
|
|
69
|
+
"Content-Length": Buffer.byteLength(payload),
|
|
70
|
+
"User-Agent": "alterlab-mcp-server",
|
|
71
|
+
Accept: "application/json",
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
const transport = parsed.protocol === "https:" ? https : http;
|
|
75
|
+
const req = transport.request(options, (res) => {
|
|
76
|
+
let raw = "";
|
|
77
|
+
res.on("data", (chunk) => {
|
|
78
|
+
raw += chunk.toString();
|
|
79
|
+
});
|
|
80
|
+
res.on("end", () => {
|
|
81
|
+
try {
|
|
82
|
+
resolve({ status: res.statusCode ?? 0, data: JSON.parse(raw) });
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
resolve({ status: res.statusCode ?? 0, data: raw });
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
req.on("error", reject);
|
|
90
|
+
req.setTimeout(15_000, () => {
|
|
91
|
+
req.destroy(new Error("Request timed out"));
|
|
92
|
+
});
|
|
93
|
+
req.write(payload);
|
|
94
|
+
req.end();
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Browser launcher
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
function openBrowser(url) {
|
|
101
|
+
// Validate URL before passing to shell — accept only http(s) schemes to
|
|
102
|
+
// prevent shell injection if the device server returns a malicious URL.
|
|
103
|
+
let parsed;
|
|
104
|
+
try {
|
|
105
|
+
parsed = new URL(url);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
process.stderr.write(` (Could not parse browser URL — copy and open manually)\n`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
112
|
+
process.stderr.write(` (Unexpected URL scheme '${parsed.protocol}' — skipping auto-open)\n`);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
// Use execFile (not exec) to avoid shell interpretation of the URL.
|
|
116
|
+
// The URL is passed as a standalone argument — no shell quoting needed.
|
|
117
|
+
const platform = process.platform;
|
|
118
|
+
let bin;
|
|
119
|
+
if (platform === "win32") {
|
|
120
|
+
bin = "cmd";
|
|
121
|
+
}
|
|
122
|
+
else if (platform === "darwin") {
|
|
123
|
+
bin = "open";
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
bin = "xdg-open";
|
|
127
|
+
}
|
|
128
|
+
const args = platform === "win32" ? ["/c", "start", "", url] : [url];
|
|
129
|
+
(0, child_process_1.execFile)(bin, args, () => {
|
|
130
|
+
// Ignore errors — if the browser doesn't open, the user can copy the URL
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// Device flow
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
async function runDeviceFlow(apiUrl) {
|
|
137
|
+
process.stderr.write("\n Attempting device authorization flow...\n");
|
|
138
|
+
// Step 1: Request device & user codes
|
|
139
|
+
let deviceResp;
|
|
140
|
+
try {
|
|
141
|
+
deviceResp = await postJson(`${apiUrl}/auth/device`, {
|
|
142
|
+
client_id: "alterlab-mcp-server",
|
|
143
|
+
scope: "api_key:create",
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
process.stderr.write(` Device flow unavailable (network error: ${String(err)})\n`);
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
if (deviceResp.status === 404) {
|
|
151
|
+
// Backend endpoints not yet live — caller will fall back to manual paste
|
|
152
|
+
process.stderr.write(" Device flow not yet available on this server — falling back to manual entry.\n");
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
if (deviceResp.status !== 200) {
|
|
156
|
+
process.stderr.write(` Device flow returned unexpected status ${deviceResp.status} — falling back to manual entry.\n`);
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
const device = deviceResp.data;
|
|
160
|
+
if (!device.device_code || !device.user_code || !device.verification_url) {
|
|
161
|
+
process.stderr.write(" Device flow response missing required fields — falling back to manual entry.\n");
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
// Step 2: Show the user what to do
|
|
165
|
+
const verifyUrl = device.verification_url_complete ?? device.verification_url;
|
|
166
|
+
process.stderr.write([
|
|
167
|
+
"",
|
|
168
|
+
" ── AlterLab Authentication ─────────────────────────────",
|
|
169
|
+
` Open this link to authenticate:`,
|
|
170
|
+
` ${verifyUrl}`,
|
|
171
|
+
"",
|
|
172
|
+
` Your device code: ${device.user_code}`,
|
|
173
|
+
" ──────────────────────────────────────────────────────────",
|
|
174
|
+
"",
|
|
175
|
+
].join("\n"));
|
|
176
|
+
// Step 3: Open browser automatically
|
|
177
|
+
openBrowser(verifyUrl);
|
|
178
|
+
// Step 4: Poll /auth/token until success, expiry, or error
|
|
179
|
+
const pollInterval = Math.max((device.interval ?? 5) * 1_000, 5_000);
|
|
180
|
+
const expiresAt = Date.now() + (device.expires_in ?? 900) * 1_000;
|
|
181
|
+
process.stderr.write(" Waiting for authentication");
|
|
182
|
+
while (Date.now() < expiresAt) {
|
|
183
|
+
await new Promise((r) => setTimeout(r, pollInterval));
|
|
184
|
+
process.stderr.write(".");
|
|
185
|
+
let tokenResp;
|
|
186
|
+
try {
|
|
187
|
+
tokenResp = await postJson(`${apiUrl}/auth/token`, {
|
|
188
|
+
client_id: "alterlab-mcp-server",
|
|
189
|
+
device_code: device.device_code,
|
|
190
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
// Network hiccup — keep polling
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
const tokenData = tokenResp.data;
|
|
198
|
+
if (tokenResp.status === 200 && "api_key" in tokenData) {
|
|
199
|
+
process.stderr.write(" ✓\n\n");
|
|
200
|
+
return tokenData.api_key;
|
|
201
|
+
}
|
|
202
|
+
if ("error" in tokenData) {
|
|
203
|
+
const err = tokenData.error;
|
|
204
|
+
if (err === "authorization_pending") {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (err === "slow_down") {
|
|
208
|
+
await new Promise((r) => setTimeout(r, pollInterval));
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
// expired_token, access_denied, or unknown error
|
|
212
|
+
process.stderr.write(`\n Authentication failed: ${err}\n`);
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
process.stderr.write("\n Authentication timed out.\n");
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
// ---------------------------------------------------------------------------
|
|
220
|
+
// Manual paste fallback
|
|
221
|
+
// ---------------------------------------------------------------------------
|
|
222
|
+
function promptForApiKey() {
|
|
223
|
+
return new Promise((resolve) => {
|
|
224
|
+
const rl = readline.createInterface({
|
|
225
|
+
input: process.stdin,
|
|
226
|
+
output: process.stderr, // write prompt to stderr
|
|
227
|
+
terminal: false,
|
|
228
|
+
});
|
|
229
|
+
process.stderr.write([
|
|
230
|
+
"",
|
|
231
|
+
" ── AlterLab API Key Setup ─────────────────────────────",
|
|
232
|
+
" Get your API key at: https://alterlab.io/dashboard/api-keys",
|
|
233
|
+
"",
|
|
234
|
+
" Paste your API key: ",
|
|
235
|
+
].join("\n"));
|
|
236
|
+
rl.once("line", (line) => {
|
|
237
|
+
rl.close();
|
|
238
|
+
resolve(line.trim());
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
// ---------------------------------------------------------------------------
|
|
243
|
+
// Countdown with keypress detection
|
|
244
|
+
// ---------------------------------------------------------------------------
|
|
245
|
+
/**
|
|
246
|
+
* Display a countdown on stderr and return true if the user presses a key
|
|
247
|
+
* before the timeout expires, or false if the timeout expires with no input.
|
|
248
|
+
*
|
|
249
|
+
* Uses raw mode stdin so that a single keypress (no Enter required) is enough
|
|
250
|
+
* to interrupt the countdown. stdin is always restored to non-raw mode inside
|
|
251
|
+
* finish() before the promise resolves.
|
|
252
|
+
*
|
|
253
|
+
* Safe to call only when process.stdin.isTTY is true — setRawMode is not
|
|
254
|
+
* available in non-TTY contexts and will throw otherwise.
|
|
255
|
+
*
|
|
256
|
+
* @param timeoutMs - Total countdown duration in milliseconds (default 5000)
|
|
257
|
+
* @returns true if keypress detected before timeout, false if timeout expired
|
|
258
|
+
*/
|
|
259
|
+
async function waitForKeypressOrTimeout(timeoutMs = 5_000) {
|
|
260
|
+
const TICK_MS = 100; // update interval for progress display
|
|
261
|
+
const BAR_WIDTH = 10; // width of the progress bar in characters
|
|
262
|
+
let keypressDetected = false;
|
|
263
|
+
// Enable raw mode so we receive individual keypresses without Enter.
|
|
264
|
+
// Guard with isTTY (caller must also check) and a try/catch in case the
|
|
265
|
+
// terminal does not support raw mode (e.g., some CI pseudo-TTYs).
|
|
266
|
+
let rawModeEnabled = false;
|
|
267
|
+
try {
|
|
268
|
+
process.stdin.setRawMode(true);
|
|
269
|
+
rawModeEnabled = true;
|
|
270
|
+
}
|
|
271
|
+
catch {
|
|
272
|
+
// setRawMode unavailable — fall through without keypress detection.
|
|
273
|
+
// The countdown will still display and expire normally.
|
|
274
|
+
}
|
|
275
|
+
return new Promise((resolve) => {
|
|
276
|
+
let ticksDone = 0;
|
|
277
|
+
let resolved = false;
|
|
278
|
+
const finish = (pressed) => {
|
|
279
|
+
if (resolved)
|
|
280
|
+
return;
|
|
281
|
+
resolved = true;
|
|
282
|
+
// Clear the countdown line from stderr
|
|
283
|
+
process.stderr.write("\r\x1b[K");
|
|
284
|
+
// Restore stdin before resolving
|
|
285
|
+
try {
|
|
286
|
+
if (rawModeEnabled) {
|
|
287
|
+
process.stdin.setRawMode(false);
|
|
288
|
+
}
|
|
289
|
+
process.stdin.pause();
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
// ignore cleanup errors
|
|
293
|
+
}
|
|
294
|
+
keypressDetected = pressed;
|
|
295
|
+
resolve(pressed);
|
|
296
|
+
};
|
|
297
|
+
// Keypress handler — any key press interrupts the countdown
|
|
298
|
+
const onData = (_chunk) => {
|
|
299
|
+
finish(true);
|
|
300
|
+
};
|
|
301
|
+
if (rawModeEnabled) {
|
|
302
|
+
process.stdin.resume();
|
|
303
|
+
process.stdin.once("data", onData);
|
|
304
|
+
}
|
|
305
|
+
// Tick function — renders the countdown progress bar on stderr
|
|
306
|
+
const tick = () => {
|
|
307
|
+
if (resolved)
|
|
308
|
+
return;
|
|
309
|
+
ticksDone += 1;
|
|
310
|
+
const elapsed = ticksDone * TICK_MS;
|
|
311
|
+
const remaining = Math.max(0, timeoutMs - elapsed);
|
|
312
|
+
const remainingSeconds = Math.ceil(remaining / 1_000);
|
|
313
|
+
const filled = Math.round((elapsed / timeoutMs) * BAR_WIDTH);
|
|
314
|
+
const empty = BAR_WIDTH - filled;
|
|
315
|
+
const bar = "█".repeat(filled) + "░".repeat(empty);
|
|
316
|
+
process.stderr.write(`\r [${bar}] ${remainingSeconds}s — press any key to enter an existing key instead`);
|
|
317
|
+
if (elapsed >= timeoutMs) {
|
|
318
|
+
if (rawModeEnabled) {
|
|
319
|
+
process.stdin.removeListener("data", onData);
|
|
320
|
+
}
|
|
321
|
+
finish(false);
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
setTimeout(tick, TICK_MS);
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
// Initial render before first tick
|
|
328
|
+
const bar0 = "░".repeat(BAR_WIDTH);
|
|
329
|
+
const secs0 = Math.ceil(timeoutMs / 1_000);
|
|
330
|
+
process.stderr.write(`\r [${bar0}] ${secs0}s — press any key to enter an existing key instead`);
|
|
331
|
+
setTimeout(tick, TICK_MS);
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
// ---------------------------------------------------------------------------
|
|
335
|
+
// Main exported function
|
|
336
|
+
// ---------------------------------------------------------------------------
|
|
337
|
+
/**
|
|
338
|
+
* Ensure a valid AlterLab API key is available and return a Config object.
|
|
339
|
+
*
|
|
340
|
+
* Resolution order:
|
|
341
|
+
* 1. ALTERLAB_API_KEY environment variable
|
|
342
|
+
* 2. ~/.alterlab/config.json
|
|
343
|
+
* 3. Interactive auth (only when running in a TTY):
|
|
344
|
+
* a. 5-second countdown — press any key to switch to manual paste
|
|
345
|
+
* b. OAuth 2.0 Device Authorization Grant flow (if countdown expires)
|
|
346
|
+
* c. Manual API key paste (if keypress during countdown, or device flow fails)
|
|
347
|
+
*
|
|
348
|
+
* When not running in a TTY (e.g., as an MCP server subprocess), emits a
|
|
349
|
+
* helpful error on stderr and exits with code 1 if no key is found.
|
|
350
|
+
*/
|
|
351
|
+
async function ensureAuth() {
|
|
352
|
+
// 1. Environment variable (highest priority — existing behavior)
|
|
353
|
+
const envConfig = (0, config_js_1.loadConfig)();
|
|
354
|
+
if (envConfig) {
|
|
355
|
+
return envConfig;
|
|
356
|
+
}
|
|
357
|
+
// 2. Config file
|
|
358
|
+
const fileConfig = (0, config_js_1.loadConfigFromFile)();
|
|
359
|
+
if (fileConfig) {
|
|
360
|
+
return fileConfig;
|
|
361
|
+
}
|
|
362
|
+
const apiUrl = (0, config_js_1.getApiUrl)();
|
|
363
|
+
// 3. Interactive auth — only possible in a TTY
|
|
364
|
+
if (!process.stdin.isTTY) {
|
|
365
|
+
process.stderr.write([
|
|
366
|
+
"",
|
|
367
|
+
" Error: No API key found for AlterLab MCP Server.",
|
|
368
|
+
"",
|
|
369
|
+
" Add your API key to your MCP client config:",
|
|
370
|
+
' "env": { "ALTERLAB_API_KEY": "sk_live_..." }',
|
|
371
|
+
"",
|
|
372
|
+
" Or run the server interactively once to authenticate:",
|
|
373
|
+
" npx -y alterlab-mcp-server",
|
|
374
|
+
"",
|
|
375
|
+
" Get your API key at: https://alterlab.io/dashboard/api-keys",
|
|
376
|
+
"",
|
|
377
|
+
].join("\n"));
|
|
378
|
+
process.exit(1);
|
|
379
|
+
}
|
|
380
|
+
// Running interactively — show welcome banner
|
|
381
|
+
process.stderr.write([
|
|
382
|
+
"",
|
|
383
|
+
" ╔══════════════════════════════════════════════════════╗",
|
|
384
|
+
" ║ AlterLab MCP Server — First Run Setup ║",
|
|
385
|
+
" ╚══════════════════════════════════════════════════════╝",
|
|
386
|
+
"",
|
|
387
|
+
" No API key found. Let's get you authenticated.",
|
|
388
|
+
"",
|
|
389
|
+
" → A browser will open to authenticate in 5 seconds...",
|
|
390
|
+
"",
|
|
391
|
+
].join("\n"));
|
|
392
|
+
// 3a. 5-second countdown — lets the user interrupt before device flow starts
|
|
393
|
+
const userPressedKey = await waitForKeypressOrTimeout(5_000);
|
|
394
|
+
let apiKey = null;
|
|
395
|
+
if (userPressedKey) {
|
|
396
|
+
// User pressed a key — skip device flow, go straight to manual paste
|
|
397
|
+
process.stderr.write(" (Switching to manual key entry)\n\n");
|
|
398
|
+
apiKey = await promptForApiKey();
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
// Countdown expired — attempt device flow
|
|
402
|
+
const deviceApiKey = await runDeviceFlow(apiUrl);
|
|
403
|
+
apiKey = deviceApiKey;
|
|
404
|
+
// 3b. Fallback to manual paste if device flow failed or unavailable
|
|
405
|
+
if (!apiKey) {
|
|
406
|
+
apiKey = await promptForApiKey();
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
if (!apiKey) {
|
|
410
|
+
process.stderr.write("\n Error: No API key provided. Exiting.\n\n");
|
|
411
|
+
process.exit(1);
|
|
412
|
+
}
|
|
413
|
+
// Persist for future runs
|
|
414
|
+
try {
|
|
415
|
+
(0, config_js_1.saveConfigToFile)(apiKey);
|
|
416
|
+
process.stderr.write(` ✓ API key saved to ~/.alterlab/config.json\n\n`);
|
|
417
|
+
}
|
|
418
|
+
catch (err) {
|
|
419
|
+
process.stderr.write(` Warning: Could not save config file: ${String(err)}\n`);
|
|
420
|
+
}
|
|
421
|
+
return { apiKey, apiUrl };
|
|
422
|
+
}
|
|
423
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiZH,gCA0FC;AAzeD,6CAA+B;AAC/B,2CAA6B;AAC7B,mDAAqC;AACrC,iDAAyC;AACzC,2CAMqB;AAkCrB,8EAA8E;AAC9E,0EAA0E;AAC1E,8EAA8E;AAE9E,SAAS,QAAQ,CACf,GAAW,EACX,IAA4B;IAE5B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,OAAO,GAAwB;YACnC,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,IAAI,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM;YACrC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC5C,YAAY,EAAE,qBAAqB;gBACnC,MAAM,EAAE,kBAAkB;aAC3B;SACF,CAAC;QAEF,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9D,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YAC7C,IAAI,GAAG,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBAC/B,GAAG,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC1B,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,IAAI,CAAC;oBACH,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,UAAU,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAClE,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,UAAU,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxB,GAAG,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE;YAC1B,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnB,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,SAAS,WAAW,CAAC,GAAW;IAC9B,wEAAwE;IACxE,wEAAwE;IACxE,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;QACnF,OAAO;IACT,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,MAAM,CAAC,QAAQ,2BAA2B,CAAC,CAAC;QAC9F,OAAO;IACT,CAAC;IAED,oEAAoE;IACpE,wEAAwE;IACxE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,IAAI,GAAW,CAAC;IAChB,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,GAAG,GAAG,KAAK,CAAC;IACd,CAAC;SAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;SAAM,CAAC;QACN,GAAG,GAAG,UAAU,CAAC;IACnB,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACrE,IAAA,wBAAQ,EAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE;QACvB,yEAAyE;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC;AAED,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,KAAK,UAAU,aAAa,CAAC,MAAc;IACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,+CAA+C,CAChD,CAAC;IAEF,sCAAsC;IACtC,IAAI,UAA6C,CAAC;IAClD,IAAI,CAAC;QACH,UAAU,GAAG,MAAM,QAAQ,CAAC,GAAG,MAAM,cAAc,EAAE;YACnD,SAAS,EAAE,qBAAqB;YAChC,KAAK,EAAE,gBAAgB;SACxB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,6CAA6C,MAAM,CAAC,GAAG,CAAC,KAAK,CAC9D,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC9B,yEAAyE;QACzE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,kFAAkF,CACnF,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,4CAA4C,UAAU,CAAC,MAAM,oCAAoC,CAClG,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,IAA0B,CAAC;IACrD,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;QACzE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,kFAAkF,CACnF,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mCAAmC;IACnC,MAAM,SAAS,GAAG,MAAM,CAAC,yBAAyB,IAAI,MAAM,CAAC,gBAAgB,CAAC;IAC9E,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB;QACE,EAAE;QACF,4DAA4D;QAC5D,mCAAmC;QACnC,KAAK,SAAS,EAAE;QAChB,EAAE;QACF,uBAAuB,MAAM,CAAC,SAAS,EAAE;QACzC,8DAA8D;QAC9D,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,qCAAqC;IACrC,WAAW,CAAC,SAAS,CAAC,CAAC;IAEvB,2DAA2D;IAC3D,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,CAAC;IACrE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC;IAElE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAErD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC;QAC9B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE1B,IAAI,SAA4C,CAAC;QACjD,IAAI,CAAC;YACH,SAAS,GAAG,MAAM,QAAQ,CAAC,GAAG,MAAM,aAAa,EAAE;gBACjD,SAAS,EAAE,qBAAqB;gBAChC,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,UAAU,EAAE,8CAA8C;aAC3D,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;YAChC,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,SAAS,CAAC,IAAqB,CAAC;QAElD,IAAI,SAAS,CAAC,MAAM,KAAK,GAAG,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;YACvD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC/B,OAAQ,SAAkC,CAAC,OAAO,CAAC;QACrD,CAAC;QAED,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;YACzB,MAAM,GAAG,GAAI,SAAuD,CAAC,KAAK,CAAC;YAC3E,IAAI,GAAG,KAAK,uBAAuB,EAAE,CAAC;gBACpC,SAAS;YACX,CAAC;YACD,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;gBACxB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;gBACtD,SAAS;YACX,CAAC;YACD,iDAAiD;YACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,8BAA8B,GAAG,IAAI,CACtC,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACxD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,SAAS,eAAe;IACtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;YAClC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,yBAAyB;YACjD,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;QAEH,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB;YACE,EAAE;YACF,2DAA2D;YAC3D,+DAA+D;YAC/D,EAAE;YACF,wBAAwB;SACzB,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QAEF,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACvB,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,8EAA8E;AAC9E,oCAAoC;AACpC,8EAA8E;AAE9E;;;;;;;;;;;;;GAaG;AACH,KAAK,UAAU,wBAAwB,CAAC,SAAS,GAAG,KAAK;IACvD,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,uCAAuC;IAC5D,MAAM,SAAS,GAAG,EAAE,CAAC,CAAC,0CAA0C;IAEhE,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAE7B,qEAAqE;IACrE,wEAAwE;IACxE,kEAAkE;IAClE,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,IAAI,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC/B,cAAc,GAAG,IAAI,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;QACpE,wDAAwD;IAC1D,CAAC;IAED,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;QACtC,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,MAAM,MAAM,GAAG,CAAC,OAAgB,EAAQ,EAAE;YACxC,IAAI,QAAQ;gBAAE,OAAO;YACrB,QAAQ,GAAG,IAAI,CAAC;YAEhB,uCAAuC;YACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAEjC,iCAAiC;YACjC,IAAI,CAAC;gBACH,IAAI,cAAc,EAAE,CAAC;oBACnB,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;gBAClC,CAAC;gBACD,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,wBAAwB;YAC1B,CAAC;YAED,gBAAgB,GAAG,OAAO,CAAC;YAC3B,OAAO,CAAC,OAAO,CAAC,CAAC;QACnB,CAAC,CAAC;QAEF,4DAA4D;QAC5D,MAAM,MAAM,GAAG,CAAC,MAAc,EAAQ,EAAE;YACtC,MAAM,CAAC,IAAI,CAAC,CAAC;QACf,CAAC,CAAC;QAEF,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,CAAC;QAED,+DAA+D;QAC/D,MAAM,IAAI,GAAG,GAAS,EAAE;YACtB,IAAI,QAAQ;gBAAE,OAAO;YAErB,SAAS,IAAI,CAAC,CAAC;YACf,MAAM,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;YACpC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,CAAC;YACnD,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC;YAEtD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC;YAC7D,MAAM,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;YACjC,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAEnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,QAAQ,GAAG,KAAK,gBAAgB,oDAAoD,CACrF,CAAC;YAEF,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;gBACzB,IAAI,cAAc,EAAE,CAAC;oBACnB,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAC/C,CAAC;gBACD,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;iBAAM,CAAC;gBACN,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC,CAAC;QAEF,mCAAmC;QACnC,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC;QAC3C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,QAAQ,IAAI,KAAK,KAAK,oDAAoD,CAC3E,CAAC;QAEF,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAE9E;;;;;;;;;;;;;GAaG;AACI,KAAK,UAAU,UAAU;IAC9B,iEAAiE;IACjE,MAAM,SAAS,GAAG,IAAA,sBAAU,GAAE,CAAC;IAC/B,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,iBAAiB;IACjB,MAAM,UAAU,GAAG,IAAA,8BAAkB,GAAE,CAAC;IACxC,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,MAAM,GAAG,IAAA,qBAAS,GAAE,CAAC;IAE3B,+CAA+C;IAC/C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB;YACE,EAAE;YACF,oDAAoD;YACpD,EAAE;YACF,+CAA+C;YAC/C,kDAAkD;YAClD,EAAE;YACF,yDAAyD;YACzD,gCAAgC;YAChC,EAAE;YACF,+DAA+D;YAC/D,EAAE;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,8CAA8C;IAC9C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB;QACE,EAAE;QACF,4DAA4D;QAC5D,2DAA2D;QAC3D,4DAA4D;QAC5D,EAAE;QACF,kDAAkD;QAClD,EAAE;QACF,yDAAyD;QACzD,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,6EAA6E;IAC7E,MAAM,cAAc,GAAG,MAAM,wBAAwB,CAAC,KAAK,CAAC,CAAC;IAE7D,IAAI,MAAM,GAAkB,IAAI,CAAC;IAEjC,IAAI,cAAc,EAAE,CAAC;QACnB,qEAAqE;QACrE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC9D,MAAM,GAAG,MAAM,eAAe,EAAE,CAAC;IACnC,CAAC;SAAM,CAAC;QACN,0CAA0C;QAC1C,MAAM,YAAY,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC;QACjD,MAAM,GAAG,YAAY,CAAC;QAEtB,oEAAoE;QACpE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,MAAM,eAAe,EAAE,CAAC;QACnC,CAAC;IACH,CAAC;IAED,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,8CAA8C,CAC/C,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,0BAA0B;IAC1B,IAAI,CAAC;QACH,IAAA,4BAAgB,EAAC,MAAM,CAAC,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,kDAAkD,CACnD,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,0CAA0C,MAAM,CAAC,GAAG,CAAC,IAAI,CAC1D,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC"}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,14 +1,36 @@
|
|
|
1
1
|
import { type Config } from "./config.js";
|
|
2
|
-
import { type BalanceResponse, type BatchRequest, type BatchResponse, type BatchStatusResponse, type BetaFeatureListResponse, type BetaFeatureMyResponse, type BetaFeatureToggleResponse, type CostEstimate, type CrawlCancelResponse, type CrawlRequest, type CrawlResponse, type CrawlStatusResponse, type ExtractRequest, type ExtractResponse, type MapRequest, type MapResponse, type SearchRequest, type SearchResponse, type SessionCreateRequest, type SessionCreateResponse, type SessionDetailResponse, type SessionListResponse, type SessionRefreshRequest, type SessionUpdateRequest, type SessionValidateResponse, type UnifiedScrapeRequest, type UnifiedScrapeResponse } from "./types.js";
|
|
2
|
+
import { type BalanceResponse, type BalanceWarning, type BatchRequest, type BatchResponse, type BatchStatusResponse, type BetaFeatureListResponse, type BetaFeatureMyResponse, type BetaFeatureToggleResponse, type CostEstimate, type CrawlCancelResponse, type CrawlRequest, type CrawlResponse, type CrawlStatusResponse, type ExtractRequest, type ExtractResponse, type MapRequest, type MapResponse, type SearchRequest, type SearchResponse, type SessionCreateRequest, type SessionCreateResponse, type SessionDetailResponse, type SessionListResponse, type SessionRefreshRequest, type SessionUpdateRequest, type SessionValidateResponse, type JobStatusResponse, type UnifiedScrapeRequest, type UnifiedScrapeResponse, type UsageResponse } from "./types.js";
|
|
3
3
|
export declare class AlterLabClient {
|
|
4
4
|
private apiKey;
|
|
5
5
|
private apiUrl;
|
|
6
6
|
private userAgent;
|
|
7
|
+
private sourceHeader;
|
|
8
|
+
/**
|
|
9
|
+
* Stores the most recent balance warning parsed from response headers.
|
|
10
|
+
* Updated after every successful API call. Null when no warning headers
|
|
11
|
+
* were present in the last response, or before the first call.
|
|
12
|
+
*/
|
|
13
|
+
private _lastBalanceWarning;
|
|
7
14
|
constructor(config: Config);
|
|
15
|
+
/**
|
|
16
|
+
* Returns the balance warning from the most recent API response, or null
|
|
17
|
+
* if no warning headers were present. Tool handlers call this after each
|
|
18
|
+
* API request to append a proactive warning when balance is low.
|
|
19
|
+
*/
|
|
20
|
+
getLastBalanceWarning(): BalanceWarning | null;
|
|
21
|
+
/**
|
|
22
|
+
* Parse X-AlterLab-Balance and X-AlterLab-Balance-Warning headers from an
|
|
23
|
+
* HTTP response and store the result. Both headers must be present and the
|
|
24
|
+
* warning level must be 'low', 'critical', or 'exhausted' — otherwise the
|
|
25
|
+
* stored warning is cleared to null (healthy balance = no warning).
|
|
26
|
+
*/
|
|
27
|
+
private parseBalanceWarningHeaders;
|
|
8
28
|
private request;
|
|
9
29
|
scrape(params: UnifiedScrapeRequest): Promise<UnifiedScrapeResponse>;
|
|
30
|
+
getJob(jobId: string): Promise<JobStatusResponse>;
|
|
10
31
|
estimate(params: UnifiedScrapeRequest): Promise<CostEstimate>;
|
|
11
32
|
getBalance(): Promise<BalanceResponse>;
|
|
33
|
+
getUsage(): Promise<UsageResponse>;
|
|
12
34
|
listSessions(): Promise<SessionListResponse>;
|
|
13
35
|
createSession(params: SessionCreateRequest): Promise<SessionCreateResponse>;
|
|
14
36
|
validateSession(sessionId: string): Promise<SessionValidateResponse>;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,cAAc,EAEnB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -3,22 +3,68 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AlterLabClient = void 0;
|
|
4
4
|
// Read version from package.json at build time is complex with ESM,
|
|
5
5
|
// so we hardcode it and keep in sync with package.json.
|
|
6
|
-
const VERSION = "1.
|
|
6
|
+
const VERSION = "1.9.0";
|
|
7
7
|
const MAX_RETRIES = 2;
|
|
8
8
|
class AlterLabClient {
|
|
9
9
|
apiKey;
|
|
10
10
|
apiUrl;
|
|
11
11
|
userAgent;
|
|
12
|
+
sourceHeader;
|
|
13
|
+
/**
|
|
14
|
+
* Stores the most recent balance warning parsed from response headers.
|
|
15
|
+
* Updated after every successful API call. Null when no warning headers
|
|
16
|
+
* were present in the last response, or before the first call.
|
|
17
|
+
*/
|
|
18
|
+
_lastBalanceWarning = null;
|
|
12
19
|
constructor(config) {
|
|
13
20
|
this.apiKey = config.apiKey;
|
|
14
21
|
this.apiUrl = config.apiUrl;
|
|
15
22
|
this.userAgent = `alterlab-mcp-server/${VERSION}`;
|
|
23
|
+
this.sourceHeader = `mcp-server/${VERSION}`;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Returns the balance warning from the most recent API response, or null
|
|
27
|
+
* if no warning headers were present. Tool handlers call this after each
|
|
28
|
+
* API request to append a proactive warning when balance is low.
|
|
29
|
+
*/
|
|
30
|
+
getLastBalanceWarning() {
|
|
31
|
+
return this._lastBalanceWarning;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Parse X-AlterLab-Balance and X-AlterLab-Balance-Warning headers from an
|
|
35
|
+
* HTTP response and store the result. Both headers must be present and the
|
|
36
|
+
* warning level must be 'low', 'critical', or 'exhausted' — otherwise the
|
|
37
|
+
* stored warning is cleared to null (healthy balance = no warning).
|
|
38
|
+
*/
|
|
39
|
+
parseBalanceWarningHeaders(response) {
|
|
40
|
+
const balanceHeader = response.headers.get("X-AlterLab-Balance");
|
|
41
|
+
const warningHeader = response.headers.get("X-AlterLab-Balance-Warning");
|
|
42
|
+
if (!balanceHeader || !warningHeader) {
|
|
43
|
+
this._lastBalanceWarning = null;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const level = warningHeader.trim().toLowerCase();
|
|
47
|
+
if (level !== "low" && level !== "critical" && level !== "exhausted") {
|
|
48
|
+
// Healthy balance or unknown level — clear warning
|
|
49
|
+
this._lastBalanceWarning = null;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
// Parse the dollar amount from the balance header (e.g. '$0.42')
|
|
53
|
+
const balanceStr = balanceHeader.trim();
|
|
54
|
+
const parsed = parseFloat(balanceStr.replace(/[^0-9.]/g, ""));
|
|
55
|
+
const balance_usd = isNaN(parsed) ? null : parsed;
|
|
56
|
+
this._lastBalanceWarning = {
|
|
57
|
+
level: level,
|
|
58
|
+
balance: balanceStr,
|
|
59
|
+
balance_usd,
|
|
60
|
+
};
|
|
16
61
|
}
|
|
17
62
|
async request(method, path, body, retryCount = 0) {
|
|
18
63
|
const url = `${this.apiUrl}${path}`;
|
|
19
64
|
const headers = {
|
|
20
65
|
"X-API-Key": this.apiKey,
|
|
21
66
|
"User-Agent": this.userAgent,
|
|
67
|
+
"X-AlterLab-Source": this.sourceHeader,
|
|
22
68
|
"Content-Type": "application/json",
|
|
23
69
|
};
|
|
24
70
|
const response = await fetch(url, {
|
|
@@ -37,6 +83,9 @@ class AlterLabClient {
|
|
|
37
83
|
return this.request(method, path, body, retryCount + 1);
|
|
38
84
|
}
|
|
39
85
|
if (!response.ok) {
|
|
86
|
+
// Still parse balance warning headers on error responses — the server may
|
|
87
|
+
// send them even on 402/4xx to alert about the balance state.
|
|
88
|
+
this.parseBalanceWarningHeaders(response);
|
|
40
89
|
let detail;
|
|
41
90
|
try {
|
|
42
91
|
const errorBody = await response.json();
|
|
@@ -51,22 +100,30 @@ class AlterLabClient {
|
|
|
51
100
|
const apiError = { status: response.status, detail };
|
|
52
101
|
throw apiError;
|
|
53
102
|
}
|
|
103
|
+
// Parse balance warning headers from successful responses
|
|
104
|
+
this.parseBalanceWarningHeaders(response);
|
|
54
105
|
return (await response.json());
|
|
55
106
|
}
|
|
56
107
|
async scrape(params) {
|
|
57
108
|
return this.request("POST", "/api/v1/scrape", params);
|
|
58
109
|
}
|
|
110
|
+
async getJob(jobId) {
|
|
111
|
+
return this.request("GET", `/api/v1/jobs/${encodeURIComponent(jobId)}`);
|
|
112
|
+
}
|
|
59
113
|
async estimate(params) {
|
|
60
114
|
return this.request("POST", "/api/v1/scrape/estimate", params);
|
|
61
115
|
}
|
|
62
116
|
async getBalance() {
|
|
63
117
|
return this.request("GET", "/api/v1/billing/balance");
|
|
64
118
|
}
|
|
119
|
+
async getUsage() {
|
|
120
|
+
return this.request("GET", "/api/v1/usage");
|
|
121
|
+
}
|
|
65
122
|
async listSessions() {
|
|
66
|
-
return this.request("GET", "/api/v1/sessions
|
|
123
|
+
return this.request("GET", "/api/v1/sessions");
|
|
67
124
|
}
|
|
68
125
|
async createSession(params) {
|
|
69
|
-
return this.request("POST", "/api/v1/sessions
|
|
126
|
+
return this.request("POST", "/api/v1/sessions", params);
|
|
70
127
|
}
|
|
71
128
|
async validateSession(sessionId) {
|
|
72
129
|
return this.request("POST", `/api/v1/sessions/${sessionId}/validate`);
|
|
@@ -149,6 +206,7 @@ class AlterLabClient {
|
|
|
149
206
|
headers: {
|
|
150
207
|
"X-API-Key": this.apiKey,
|
|
151
208
|
"User-Agent": this.userAgent,
|
|
209
|
+
"X-AlterLab-Source": this.sourceHeader,
|
|
152
210
|
},
|
|
153
211
|
});
|
|
154
212
|
if (!response.ok) {
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|