@aluvia/sdk 1.4.0 → 2.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +188 -0
  2. package/README.md +162 -477
  3. package/dist/cjs/api/apiUtils.js +4 -1
  4. package/dist/cjs/client/AluviaClient.js +30 -32
  5. package/dist/cjs/client/BlockDetection.js +69 -87
  6. package/dist/cjs/client/rules.js +12 -2
  7. package/dist/cjs/connect.js +2 -2
  8. package/dist/cjs/index.js +12 -1
  9. package/dist/cjs/session/lock.js +40 -4
  10. package/dist/esm/api/apiUtils.js +4 -1
  11. package/dist/esm/client/AluviaClient.js +38 -40
  12. package/dist/esm/client/BlockDetection.js +69 -87
  13. package/dist/esm/client/rules.js +12 -2
  14. package/dist/esm/connect.js +2 -2
  15. package/dist/esm/index.js +6 -4
  16. package/dist/esm/session/lock.js +40 -4
  17. package/dist/types/client/AluviaClient.d.ts +2 -2
  18. package/dist/types/client/BlockDetection.d.ts +4 -4
  19. package/dist/types/client/types.d.ts +11 -11
  20. package/dist/types/index.d.ts +9 -7
  21. package/package.json +15 -23
  22. package/dist/cjs/bin/account.js +0 -31
  23. package/dist/cjs/bin/api-helpers.js +0 -58
  24. package/dist/cjs/bin/cli-adapter.js +0 -16
  25. package/dist/cjs/bin/cli.js +0 -245
  26. package/dist/cjs/bin/close.js +0 -120
  27. package/dist/cjs/bin/geos.js +0 -10
  28. package/dist/cjs/bin/mcp-helpers.js +0 -57
  29. package/dist/cjs/bin/mcp-server.js +0 -220
  30. package/dist/cjs/bin/mcp-tools.js +0 -90
  31. package/dist/cjs/bin/open.js +0 -293
  32. package/dist/cjs/bin/session.js +0 -259
  33. package/dist/cjs/client/PageLoadDetection.js +0 -175
  34. package/dist/esm/bin/account.js +0 -28
  35. package/dist/esm/bin/api-helpers.js +0 -53
  36. package/dist/esm/bin/cli-adapter.js +0 -8
  37. package/dist/esm/bin/cli.js +0 -242
  38. package/dist/esm/bin/close.js +0 -117
  39. package/dist/esm/bin/geos.js +0 -7
  40. package/dist/esm/bin/mcp-helpers.js +0 -51
  41. package/dist/esm/bin/mcp-server.js +0 -185
  42. package/dist/esm/bin/mcp-tools.js +0 -78
  43. package/dist/esm/bin/open.js +0 -256
  44. package/dist/esm/bin/session.js +0 -252
  45. package/dist/esm/client/PageLoadDetection.js +0 -171
  46. package/dist/types/bin/account.d.ts +0 -1
  47. package/dist/types/bin/api-helpers.d.ts +0 -20
  48. package/dist/types/bin/cli-adapter.d.ts +0 -8
  49. package/dist/types/bin/cli.d.ts +0 -2
  50. package/dist/types/bin/close.d.ts +0 -1
  51. package/dist/types/bin/geos.d.ts +0 -1
  52. package/dist/types/bin/mcp-helpers.d.ts +0 -28
  53. package/dist/types/bin/mcp-server.d.ts +0 -2
  54. package/dist/types/bin/mcp-tools.d.ts +0 -46
  55. package/dist/types/bin/open.d.ts +0 -21
  56. package/dist/types/bin/session.d.ts +0 -11
  57. package/dist/types/client/PageLoadDetection.d.ts +0 -93
package/README.md CHANGED
@@ -1,239 +1,55 @@
1
- # Aluvia Node.js SDK
1
+ # @aluvia/sdk
2
2
 
3
- [![npm](https://img.shields.io/npm/v/@aluvia/sdk.svg)](https://www.npmjs.com/package/@aluvia/sdk)
4
- [![downloads](https://img.shields.io/npm/dm/@aluvia/sdk.svg)](https://www.npmjs.com/package/@aluvia/sdk)
5
- [![license](https://img.shields.io/npm/l/@aluvia/sdk.svg)](./LICENSE)
6
- [![node](https://img.shields.io/node/v/@aluvia/sdk.svg)](./package.json)
3
+ Core SDK for Aluvia — a local smart proxy for automation workloads and AI agents. Route traffic through premium US mobile carrier IPs and bypass 403s, CAPTCHAs, and WAFs.
7
4
 
8
- **Stop getting blocked.** Aluvia routes your AI agent's web traffic through premium US mobile carrier IPs — the same IPs used by real people on their phones. Websites trust them, so your agent stops hitting 403s, CAPTCHAs, and rate limits.
9
-
10
- This SDK gives you everything you need:
11
-
12
- - **CLI for browser automation** — launch headless Chromium sessions from the command line, with JSON output designed for AI agent frameworks
13
- - **Automatic block detection and unblocking** — the SDK detects 403s, WAF challenges, and CAPTCHAs, then reroutes through Aluvia and reloads the page automatically
14
- - **Smart routing** — proxy only the sites that block you; everything else goes direct to save cost and latency
15
- - **Runtime rule updates** — add hostnames to proxy rules on the fly, no restarts or redeployments
16
- - **Adapters for every tool** — Playwright, Puppeteer, Selenium, Axios, got, and Node's fetch
17
- - **IP rotation and geo targeting** — rotate IPs or target specific US regions at runtime
18
- - **REST API wrapper** — manage connections, check usage, and build custom tooling with `AluviaApi`
19
- - **MCP server** — for Model Context Protocol (MCP) only, use the separate package: `npm install @aluvia/mcp` and run `npx aluvia-mcp`. See [mcp/README.md](mcp/README.md) and [MCP Server Guide](docs/mcp-server-guide.md).
5
+ This package provides the programmatic API: `AluviaClient`, `AluviaApi`, `connect()`, and framework adapters (Playwright, Puppeteer, Selenium, Axios, got, fetch).
20
6
 
21
7
  ---
22
8
 
23
- ## Table of contents
24
-
25
- - [Quick start](#quick-start)
26
- - [CLI reference](#cli-reference)
27
- - [Connecting to a running browser](#connecting-to-a-running-browser)
28
- - [Programmatic usage (AluviaClient)](#programmatic-usage)
29
- - [Routing rules](#routing-rules)
30
- - [Block detection and auto-unblocking](#block-detection-and-auto-unblocking)
31
- - [Tool integration adapters](#tool-integration-adapters)
32
- - [REST API (AluviaApi)](#rest-api)
33
- - [Architecture](#architecture)
9
+ ## Table of Contents
10
+
11
+ - [Get an Aluvia API Key](#get-an-aluvia-api-key)
12
+ - [Installation](#installation)
13
+ - [Quick Start](#quick-start)
14
+ - [What's Included](#whats-included)
15
+ - [AluviaClient](#aluviaclient)
16
+ - [AluviaApi](#aluviaapi)
17
+ - [connect()](#connect)
18
+ - [Framework Adapters](#framework-adapters)
19
+ - [Error Classes](#error-classes)
20
+ - [CLI and MCP](#cli-and-mcp)
21
+ - [Documentation](#documentation)
22
+ - [License](#license)
34
23
 
35
24
  ---
36
25
 
37
- ## Quick start
38
-
39
- ### 1. Get Aluvia API key
40
-
41
- [Aluvia dashboard](https://dashboard.aluvia.io)
42
-
43
- ### 2. Install
44
-
45
- ```bash
46
- npm install @aluvia/sdk playwright
47
- export ALUVIA_API_KEY="your-api-key"
48
- ```
49
-
50
- ### 3. Run
51
-
52
- Aluvia automatically detects website blocks and uses mobile IPs when necessary.
53
-
54
- ```bash
55
- aluvia session start https://example.com --auto-unblock --run your-script.js
56
- ```
57
-
58
- ---
59
-
60
- ## Skills
61
-
62
- - Claude code skill
63
- - OpenClaw skill
64
-
65
- ---
66
-
67
- ## CLI reference
68
-
69
- The CLI outputs JSON for easy integration with AI agent frameworks. All commands are available via the `aluvia` binary. Run `aluvia help --json` for machine-readable help.
70
-
71
- ### `session start` — Launch a browser session
72
-
73
- ```bash
74
- aluvia session start <url> [options]
75
- ```
76
-
77
- | Option | Description |
78
- | --------------------------- | ------------------------------------------------------------------------ |
79
- | `--auto-unblock` | Auto-detect blocks and reload through Aluvia |
80
- | `--run <script>` | Run a script with `page`, `browser`, `context` injected; exits when done |
81
- | `--headful` | Show the browser window (default: headless) |
82
- | `--browser-session <name>` | Name this session (auto-generated if omitted, e.g. `swift-falcon`) |
83
- | `--connection-id <id>` | Reuse an existing Aluvia connection |
84
- | `--disable-block-detection` | Disable block detection entirely |
85
-
86
- **Examples:**
87
-
88
- ```bash
89
- # Launch with auto-unblocking
90
- aluvia session start https://example.com --auto-unblock
91
-
92
- # Run a script inline
93
- aluvia session start https://example.com --auto-unblock --run scrape.mjs
94
-
95
- # Debug with a visible browser window
96
- aluvia session start https://example.com --headful
97
-
98
- # Reuse an existing connection
99
- aluvia session start https://example.com --connection-id 3449
100
- ```
101
-
102
- ### `session close` — Stop a session
103
-
104
- ```bash
105
- aluvia session close # auto-selects if only one is running
106
- aluvia session close --browser-session swift-falcon # close by name
107
- aluvia session close --all # close all sessions
108
- ```
109
-
110
- ### `session list` — List active sessions
111
-
112
- ```bash
113
- aluvia session list
114
- ```
115
-
116
- ```json
117
- {
118
- "sessions": [
119
- {
120
- "browserSession": "swift-falcon",
121
- "pid": 12345,
122
- "startUrl": "https://example.com",
123
- "cdpUrl": "http://127.0.0.1:38209",
124
- "connectionId": 3449,
125
- "blockDetection": true,
126
- "autoUnblock": true
127
- }
128
- ],
129
- "count": 1
130
- }
131
- ```
132
-
133
- ### `session get` — Full session details
134
-
135
- ```bash
136
- aluvia session get [--browser-session <name>]
137
- ```
138
-
139
- Returns session info enriched with block detection history and the full connection object from the API.
140
-
141
- ### `session rotate-ip` — Get a new IP
26
+ ## Get an Aluvia API Key
142
27
 
143
- ```bash
144
- aluvia session rotate-ip [--browser-session <name>]
145
- ```
146
-
147
- ### `session set-geo` — Target a specific region
28
+ You need an API key to use the SDK. Get one from the [Aluvia dashboard](https://dashboard.aluvia.io):
148
29
 
149
- ```bash
150
- aluvia session set-geo US # target US IPs
151
- aluvia session set-geo us_ca # target California
152
- aluvia session set-geo --clear # clear geo targeting
153
- ```
30
+ 1. Sign up or sign in at [dashboard.aluvia.io](https://dashboard.aluvia.io)
31
+ 2. In your account, open the API & SDKs section
32
+ 3. Copy your API key
154
33
 
155
- ### `session set-rules` Update routing rules
156
-
157
- ```bash
158
- aluvia session set-rules "example.com,api.example.com" # add rules
159
- aluvia session set-rules --remove "example.com" # remove rules
160
- ```
161
-
162
- Rules are comma-separated. By default rules are appended; use `--remove` to remove specific rules.
163
-
164
- ### Account and other commands
165
-
166
- ```bash
167
- aluvia account # account info
168
- aluvia account usage # usage stats
169
- aluvia account usage --start 2025-01-01T00:00:00Z --end 2025-02-01T00:00:00Z
170
-
171
- aluvia geos # list available geo-targeting options
172
- aluvia help # plain text help
173
- aluvia help --json # machine-readable help
174
- ```
34
+ Use it as an environment variable: `export ALUVIA_API_KEY="your-api-key"` or add `ALUVIA_API_KEY=your-api-key` to a `.env` file (never commit it).
175
35
 
176
36
  ---
177
37
 
178
- ## Connecting to a running browser
179
-
180
- There are two ways to run code against a browser session started by the CLI.
181
-
182
- ### Option A: `--run` (simplest)
183
-
184
- Pass a script to `session start`. The globals `page`, `browser`, and `context` are available — no imports needed:
38
+ ## Installation
185
39
 
186
40
  ```bash
187
- aluvia session start https://example.com --auto-unblock --run script.mjs
188
- ```
189
-
190
- ```js
191
- // script.mjs
192
- console.log("URL:", page.url());
193
-
194
- const newPage = await context.newPage();
195
- await newPage.goto("https://another-site.com");
196
- console.log("Other site title:", await newPage.title());
197
- ```
198
-
199
- The session starts, runs your script, and exits.
200
-
201
- ### Option B: `connect()` (for AI agents and long-running processes)
202
-
203
- Start a session as a background daemon, then connect from your application:
204
-
205
- ```bash
206
- aluvia session start https://example.com --auto-unblock
207
- ```
208
-
209
- ```ts
210
- import { connect } from "@aluvia/sdk";
211
-
212
- // Auto-discovers the running session
213
- const { page, browser, context, disconnect } = await connect();
214
- console.log("URL:", page.url());
215
-
216
- // When running multiple sessions, specify by name
217
- const conn = await connect("swift-falcon");
218
- console.log("URL:", conn.page.url());
219
-
220
- // Disconnect when done (the session keeps running)
221
- await disconnect();
41
+ npm install @aluvia/sdk playwright
222
42
  ```
223
43
 
224
- Use this when your agent generates automation code dynamically at runtime or needs a persistent browser across multiple operations.
44
+ Playwright is required for browser automation. For HTTP clients only (Axios, got, fetch), omit Playwright.
225
45
 
226
46
  ---
227
47
 
228
- ## Programmatic usage
229
-
230
- For full control, use `AluviaClient` directly instead of the CLI.
48
+ ## Quick Start
231
49
 
232
- ### Basic example
233
-
234
- ```ts
235
- import { AluviaClient } from "@aluvia/sdk";
236
- import { chromium } from "playwright";
50
+ ```typescript
51
+ import { AluviaClient } from '@aluvia/sdk';
52
+ import { chromium } from 'playwright';
237
53
 
238
54
  const client = new AluviaClient({
239
55
  apiKey: process.env.ALUVIA_API_KEY!,
@@ -242,7 +58,7 @@ const client = new AluviaClient({
242
58
  const connection = await client.start();
243
59
  const browser = await chromium.launch({ proxy: connection.asPlaywright() });
244
60
  const page = await browser.newPage();
245
- await page.goto("https://example.com");
61
+ await page.goto('https://example.com');
246
62
 
247
63
  // ... do your work ...
248
64
 
@@ -250,223 +66,151 @@ await browser.close();
250
66
  await connection.close();
251
67
  ```
252
68
 
253
- ### With auto-launched browser
69
+ With auto-launched browser and block detection:
254
70
 
255
- ```ts
71
+ ```typescript
256
72
  const client = new AluviaClient({
257
73
  apiKey: process.env.ALUVIA_API_KEY!,
258
74
  startPlaywright: true,
259
- blockDetection: {
260
- enabled: true,
261
- autoUnblock: true,
262
- },
75
+ blockDetection: { enabled: true, autoUnblock: true },
263
76
  });
264
77
 
265
78
  const connection = await client.start();
266
- const page = await connection.browser.newPage();
267
- await page.goto("https://example.com"); // auto-reloads through Aluvia if blocked
268
-
269
- await connection.close(); // stops proxy, closes browser, releases resources
270
- ```
271
-
272
- ### Runtime updates
79
+ const page = await connection.browser!.newPage();
80
+ await page.goto('https://example.com'); // auto-reloads through Aluvia if blocked
273
81
 
274
- While your agent is running, update routing, rotate IPs, or change geo — no restarts needed:
275
-
276
- ```ts
277
- await client.updateRules(["blocked-site.com"]); // proxy this hostname
278
- await client.updateSessionId("new-session-id"); // rotate to a new IP
279
- await client.updateTargetGeo("us_ca"); // target California IPs
280
- ```
281
-
282
- ### Constructor options
283
-
284
- ```ts
285
- new AluviaClient({
286
- apiKey: string; // Required
287
- connectionId?: number; // Reuse an existing connection
288
- startPlaywright?: boolean; // Auto-launch Chromium browser
289
- headless?: boolean; // Default: true (only with startPlaywright)
290
- blockDetection?: BlockDetectionConfig; // See "Block detection" section
291
- localPort?: number; // Local proxy port (auto-assigned if omitted)
292
- gatewayProtocol?: "http" | "https"; // Default: "http"
293
- gatewayPort?: number; // Default: 8080 (http) or 8443 (https)
294
- pollIntervalMs?: number; // Config poll interval (default: 5000ms)
295
- timeoutMs?: number; // API request timeout
296
- logLevel?: "silent" | "info" | "debug";
297
- strict?: boolean; // Throw if config fails to load (default: true)
298
- apiBaseUrl?: string; // Default: "https://api.aluvia.io/v1"
299
- });
82
+ await connection.close();
300
83
  ```
301
84
 
302
- For all options in detail, see the [Client Technical Guide](docs/client-technical-guide.md#constructor-options).
303
-
304
85
  ---
305
86
 
306
- ## Routing rules
307
-
308
- The local proxy routes each request based on hostname rules. Only hostnames matching a rule go through Aluvia; everything else goes direct.
87
+ ## What's Included
309
88
 
310
- ### Why this matters
89
+ | Component | Description |
90
+ | ----------------- | ------------------------------------------------------------------------------------------------ |
91
+ | **AluviaClient** | Core proxy client. Manages local proxy, config polling, block detection, and framework adapters. |
92
+ | **AluviaApi** | REST API wrapper for account info, connections, usage, and geo-targeting. |
93
+ | **connect()** | Helper to connect to a browser session started by the CLI (`aluvia session start`). |
94
+ | **Adapters** | Proxy config for Playwright, Puppeteer, Selenium, Axios, got, Node fetch. |
95
+ | **Error classes** | `MissingApiKeyError`, `InvalidApiKeyError`, `ApiError`, `ProxyStartError`, `ConnectError`. |
311
96
 
312
- - **Save money** — proxy only the sites that block you
313
- - **Lower latency** — non-blocked sites skip the proxy entirely
314
- - **Adapt on the fly** — rules update at runtime, no restarts needed
97
+ ---
315
98
 
316
- ### Rule patterns
99
+ ## AluviaClient
317
100
 
318
- | Pattern | Matches |
319
- | --------------- | ------------------------------ |
320
- | `*` | All hostnames |
321
- | `example.com` | Exact match |
322
- | `*.example.com` | Subdomains of example.com |
323
- | `google.*` | google.com, google.co.uk, etc. |
324
- | `-example.com` | Exclude from proxying |
101
+ Create a client, call `start()` to get a connection, then use adapters or the auto-launched browser.
325
102
 
326
- ### Examples
103
+ ### Constructor options
327
104
 
328
- ```ts
329
- // Proxy all traffic
330
- await client.updateRules(["*"]);
105
+ | Option | Type | Default | Description |
106
+ | ----------------- | ------------------------------- | ---------------------------- | -------------------------------------------- |
107
+ | `apiKey` | string | — | **Required.** Your Aluvia API key. |
108
+ | `connectionId` | number | — | Reuse an existing Aluvia connection. |
109
+ | `startPlaywright` | boolean | false | Auto-launch Chromium browser. |
110
+ | `headless` | boolean | true | Only with `startPlaywright`. |
111
+ | `blockDetection` | BlockDetectionConfig | — | Enable/configure block detection. |
112
+ | `localPort` | number | — | Local proxy port (auto-assigned if omitted). |
113
+ | `gatewayProtocol` | `"http" \| "https"` | `"http"` | Gateway protocol. |
114
+ | `gatewayPort` | number | 8080 / 8443 | Gateway port. |
115
+ | `pollIntervalMs` | number | 5000 | Config poll interval. |
116
+ | `timeoutMs` | number | — | API request timeout. |
117
+ | `logLevel` | `"silent" \| "info" \| "debug"` | `"info"` | Log verbosity. |
118
+ | `strict` | boolean | true | Throw if config fails to load. |
119
+ | `apiBaseUrl` | string | `"https://api.aluvia.io/v1"` | API base URL. |
331
120
 
332
- // Proxy specific hosts only
333
- await client.updateRules(["target-site.com", "*.google.com"]);
121
+ ### Runtime updates
334
122
 
335
- // Proxy everything except Stripe
336
- await client.updateRules(["*", "-api.stripe.com"]);
123
+ Update rules, rotate IP, or change geo without restarting:
337
124
 
338
- // Route all traffic direct (no proxy)
339
- await client.updateRules([]);
125
+ ```typescript
126
+ await client.updateRules(['blocked-site.com']);
127
+ await client.updateSessionId('new-session-id');
128
+ await client.updateTargetGeo('us_ca');
340
129
  ```
341
130
 
342
- Or from the CLI:
131
+ ### Rule patterns
343
132
 
344
- ```bash
345
- aluvia session set-rules "target-site.com,*.google.com"
346
- aluvia session set-rules --remove "target-site.com"
347
- ```
133
+ | Pattern | Matches |
134
+ | --------------- | --------------------- |
135
+ | `*` | All hostnames |
136
+ | `example.com` | Exact match |
137
+ | `*.example.com` | Subdomains |
138
+ | `-example.com` | Exclude from proxying |
348
139
 
349
140
  ---
350
141
 
351
- ## Block detection and auto-unblocking
352
-
353
- Most proxy solutions require you to decide upfront which sites to proxy. If a site blocks you later, you're stuck.
142
+ ## AluviaApi
354
143
 
355
- Aluvia detects blocks automatically and can unblock your agent on the fly. The SDK analyzes every page load using a weighted scoring system across multiple signals — HTTP status codes, WAF headers, CAPTCHA selectors, page content, redirect chains, and more.
144
+ Use `AluviaApi` for account/connection management without starting a proxy. Also available as `client.api` when using `AluviaClient`.
356
145
 
357
- ### Automatic unblocking (recommended)
358
-
359
- When a block is detected, the SDK adds the hostname to proxy rules and reloads the page through Aluvia:
146
+ ### Endpoints
360
147
 
361
- ```ts
362
- const client = new AluviaClient({
363
- apiKey: process.env.ALUVIA_API_KEY!,
364
- startPlaywright: true,
365
- blockDetection: {
366
- enabled: true,
367
- autoUnblock: true,
368
- onDetection: (result, page) => {
369
- console.log(
370
- `${result.blockStatus} on ${result.hostname} (score: ${result.score})`,
371
- );
372
- },
373
- },
374
- });
375
- ```
148
+ | Method | Description |
149
+ | ----------------------------------------- | --------------------------------------- |
150
+ | `api.account.get()` | Account info (balance, usage) |
151
+ | `api.account.connections.list()` | List all connections |
152
+ | `api.account.connections.create(body)` | Create a connection |
153
+ | `api.account.connections.get(id)` | Get connection details |
154
+ | `api.account.connections.patch(id, body)` | Update connection (rules, geo, session) |
155
+ | `api.account.connections.delete(id)` | Delete a connection |
156
+ | `api.account.usage.get(params?)` | Usage stats for date range |
157
+ | `api.geos.list()` | List geo-targeting options |
376
158
 
377
- Or from the CLI:
159
+ ### Example
378
160
 
379
- ```bash
380
- aluvia session start https://example.com --auto-unblock
381
- ```
161
+ ```typescript
162
+ import { AluviaApi } from '@aluvia/sdk';
382
163
 
383
- ### Detection-only mode
164
+ const api = new AluviaApi({ apiKey: process.env.ALUVIA_API_KEY! });
384
165
 
385
- Run detection without automatic remediation. Your agent inspects the results and decides what to do:
166
+ const account = await api.account.get();
167
+ console.log('Balance:', account.balance_gb, 'GB');
386
168
 
387
- ```ts
388
- blockDetection: {
389
- enabled: true,
390
- onDetection: (result, page) => {
391
- if (result.blockStatus === "blocked") {
392
- // Agent decides: retry, rotate IP, update rules, etc.
393
- }
394
- },
395
- }
169
+ const geos = await api.geos.list();
170
+ console.log(
171
+ 'Geos:',
172
+ geos.map((g) => g.code),
173
+ );
396
174
  ```
397
175
 
398
- ### Block status scores
399
-
400
- Each page analysis produces a score from 0.0 to 1.0:
401
-
402
- | Score | Status | Meaning |
403
- | ------ | ------------- | --------------------------------------------------------------- |
404
- | >= 0.7 | `"blocked"` | High confidence block. Auto-reloads when `autoUnblock: true`. |
405
- | >= 0.4 | `"suspected"` | Possible block. Reloads only if `autoUnblockOnSuspected: true`. |
406
- | < 0.4 | `"clear"` | No block detected. |
407
-
408
- Scores use probabilistic combination (`1 - product(1 - weight)`) so weak signals don't stack into false positives.
409
-
410
- ### How detection works
411
-
412
- Detection runs in two passes:
413
-
414
- 1. **Fast pass** (at `domcontentloaded`) — checks HTTP status codes and WAF response headers. High-confidence blocks (score >= 0.9) trigger immediate remediation.
415
- 2. **Full pass** (after `networkidle`) — analyzes page title, visible text, challenge selectors, meta refreshes, and redirect chains.
416
-
417
- The SDK also detects SPA navigations and tracks persistent blocks per hostname to prevent infinite retry loops.
176
+ ---
418
177
 
419
- ### Detection config options
178
+ ## connect()
420
179
 
421
- ```ts
422
- blockDetection: {
423
- enabled?: boolean; // Default: true
424
- autoUnblock?: boolean; // Auto-remediate blocked pages
425
- autoUnblockOnSuspected?: boolean; // Also remediate "suspected" pages
426
- challengeSelectors?: string[]; // Custom CSS selectors for challenge detection
427
- extraKeywords?: string[]; // Additional keywords for text analysis
428
- extraStatusCodes?: number[]; // Additional HTTP status codes to flag
429
- networkIdleTimeoutMs?: number; // Default: 3000ms
430
- onDetection?: (result, page) => void | Promise<void>;
431
- }
432
- ```
180
+ Connect to a browser session started by the CLI (`aluvia session start`). Useful for AI agents that generate automation code at runtime.
433
181
 
434
- ### Manual detection
182
+ ```typescript
183
+ import { connect } from '@aluvia/sdk';
435
184
 
436
- You can also check responses yourself and update rules on the fly:
185
+ const { page, browser, context, disconnect } = await connect();
186
+ console.log('URL:', page.url());
437
187
 
438
- ```ts
439
- const response = await page.goto(url);
188
+ // With multiple sessions
189
+ const conn = await connect('swift-falcon');
440
190
 
441
- if (response?.status() === 403) {
442
- await client.updateRules([...currentRules, new URL(url).hostname]);
443
- await page.goto(url); // retried through Aluvia
444
- }
191
+ // Disconnect when done (session keeps running)
192
+ await disconnect();
445
193
  ```
446
194
 
447
- For the full list of signal detectors and weights, see the [Client Technical Guide](docs/client-technical-guide.md#signal-detectors).
448
-
449
195
  ---
450
196
 
451
- ## Tool integration adapters
197
+ ## Framework Adapters
452
198
 
453
- The SDK handles proxy configuration for every major tool:
199
+ The connection returned by `client.start()` exposes adapter methods:
454
200
 
455
- | Tool | Method | Returns |
456
- | ------------ | ---------------------------- | ----------------------------------------------------- |
457
- | Playwright | `connection.asPlaywright()` | `{ server, username?, password? }` |
458
- | Playwright | `connection.browser` | Auto-launched Chromium (with `startPlaywright: true`) |
459
- | Playwright | `connection.cdpUrl` | CDP endpoint for `connectOverCDP()` |
460
- | Puppeteer | `connection.asPuppeteer()` | `['--proxy-server=...']` |
461
- | Selenium | `connection.asSelenium()` | `'--proxy-server=...'` |
462
- | Axios | `connection.asAxiosConfig()` | `{ proxy: false, httpAgent, httpsAgent }` |
463
- | got | `connection.asGotOptions()` | `{ agent: { http, https } }` |
464
- | fetch | `connection.asUndiciFetch()` | Proxy-enabled `fetch` function |
465
- | Node.js http | `connection.asNodeAgents()` | `{ http: Agent, https: Agent }` |
201
+ | Tool | Method | Returns |
202
+ | ---------- | ---------------------------- | ----------------------------------------- |
203
+ | Playwright | `connection.asPlaywright()` | `{ server, username?, password? }` |
204
+ | Puppeteer | `connection.asPuppeteer()` | `['--proxy-server=...']` |
205
+ | Selenium | `connection.asSelenium()` | `'--proxy-server=...'` |
206
+ | Axios | `connection.asAxiosConfig()` | `{ proxy: false, httpAgent, httpsAgent }` |
207
+ | got | `connection.asGotOptions()` | `{ agent: { http, https } }` |
208
+ | fetch | `connection.asUndiciFetch()` | Proxy-enabled `fetch` function |
209
+ | Node http | `connection.asNodeAgents()` | `{ http: Agent, https: Agent }` |
466
210
 
467
211
  ### Examples
468
212
 
469
- ```ts
213
+ ```typescript
470
214
  // Playwright
471
215
  const browser = await chromium.launch({ proxy: connection.asPlaywright() });
472
216
 
@@ -475,119 +219,60 @@ const browser = await puppeteer.launch({ args: connection.asPuppeteer() });
475
219
 
476
220
  // Axios
477
221
  const axiosClient = axios.create(connection.asAxiosConfig());
478
- await axiosClient.get("https://example.com");
222
+ await axiosClient.get('https://example.com');
479
223
 
480
- // got
481
- const gotClient = got.extend(connection.asGotOptions());
482
- await gotClient("https://example.com");
483
-
484
- // Node's fetch (via undici)
224
+ // Node fetch
485
225
  const myFetch = connection.asUndiciFetch();
486
- await myFetch("https://example.com");
226
+ await myFetch('https://example.com');
487
227
  ```
488
228
 
489
- For more details, see the [Client Technical Guide](docs/client-technical-guide.md#tool-adapters).
490
-
491
229
  ---
492
230
 
493
- ## REST API
494
-
495
- `AluviaApi` is a typed wrapper for the Aluvia REST API. Use it to manage connections, check account info, or build custom tooling — without starting a proxy.
496
-
497
- ### Endpoints
498
-
499
- | Method | Description |
500
- | ----------------------------------------- | --------------------------------------- |
501
- | `api.account.get()` | Get account info (balance, usage) |
502
- | `api.account.connections.list()` | List all connections |
503
- | `api.account.connections.create(body)` | Create a new connection |
504
- | `api.account.connections.get(id)` | Get connection details |
505
- | `api.account.connections.patch(id, body)` | Update connection (rules, geo, session) |
506
- | `api.account.connections.delete(id)` | Delete a connection |
507
- | `api.account.usage.get(params?)` | Get usage stats |
508
- | `api.geos.list()` | List available geo-targeting options |
509
-
510
- ### Example
511
-
512
- ```ts
513
- import { AluviaApi } from "@aluvia/sdk";
514
-
515
- const api = new AluviaApi({ apiKey: process.env.ALUVIA_API_KEY! });
516
-
517
- // Check account balance
518
- const account = await api.account.get();
519
- console.log("Balance:", account.balance_gb, "GB");
520
-
521
- // Create a connection for a new agent
522
- const conn = await api.account.connections.create({
523
- description: "pricing-scraper",
524
- rules: ["competitor-site.com"],
525
- target_geo: "us_ca",
526
- });
527
- console.log("Created connection:", conn.connection_id);
528
-
529
- // List available geos
530
- const geos = await api.geos.list();
531
- console.log(
532
- "Geos:",
533
- geos.map((g) => g.code),
534
- );
231
+ ## Error Classes
232
+
233
+ | Class | When thrown |
234
+ | -------------------- | -------------------------------------- |
235
+ | `MissingApiKeyError` | `apiKey` not provided or empty |
236
+ | `InvalidApiKeyError` | API key rejected by server |
237
+ | `ApiError` | REST API error (includes status, body) |
238
+ | `ProxyStartError` | Failed to start local proxy |
239
+ | `ConnectError` | Failed to connect to running session |
240
+
241
+ ```typescript
242
+ import { MissingApiKeyError, ApiError } from '@aluvia/sdk';
243
+
244
+ try {
245
+ const client = new AluviaClient({ apiKey: process.env.ALUVIA_API_KEY! });
246
+ await client.start();
247
+ } catch (err) {
248
+ if (err instanceof MissingApiKeyError) {
249
+ console.error('Set ALUVIA_API_KEY');
250
+ } else if (err instanceof ApiError) {
251
+ console.error('API error:', err.status, err.body);
252
+ }
253
+ }
535
254
  ```
536
255
 
537
- `AluviaApi` is also available as `client.api` when using `AluviaClient`.
538
-
539
- For the complete API reference, see the [API Technical Guide](docs/api-technical-guide.md).
540
-
541
256
  ---
542
257
 
543
- ## Architecture
258
+ ## CLI and MCP
544
259
 
545
- The client is split into two independent planes:
546
-
547
- ```
548
- ┌─────────────────────────────────────────────────────────────────┐
549
- │ AluviaClient │
550
- ├─────────────────────────────┬───────────────────────────────────┤
551
- │ Control Plane │ Data Plane │
552
- │ (ConfigManager) │ (ProxyServer) │
553
- ├─────────────────────────────┼───────────────────────────────────┤
554
- │ • Fetches/creates config │ • Local HTTP proxy (proxy-chain) │
555
- │ • Polls for updates (ETag) │ • Per-request routing decisions │
556
- │ • PATCH updates (rules, │ • Uses rules engine to decide: │
557
- │ session, geo) │ direct vs gateway │
558
- └─────────────────────────────┴───────────────────────────────────┘
559
- ```
260
+ - **CLI** `npm install -g @aluvia/cli` for `aluvia session start`, `aluvia session close`, etc.
261
+ - **MCP** — `npm install @aluvia/mcp` for Model Context Protocol integration with Claude, Cursor, etc.
560
262
 
561
- **Control Plane (ConfigManager)** — communicates with the Aluvia REST API to fetch proxy credentials and routing rules, polls for configuration updates using ETags, and pushes updates (rules, session ID, geo).
263
+ ---
562
264
 
563
- **Data Plane (ProxyServer)** — runs a local HTTP proxy on `127.0.0.1` that reads the latest config per-request, so rule updates take effect immediately without restarts.
265
+ ## Documentation
564
266
 
565
- ```
566
- ┌──────────────────┐ ┌──────────────────────────┐ ┌──────────────────────┐
567
- │ │ │ │ │ │
568
- │ Your Agent │─────▶│ Aluvia Client │─────▶│ gateway.aluvia.io │
569
- │ │ │ 127.0.0.1:port │ │ (Mobile IPs) │
570
- │ │ │ │ │ │
571
- └──────────────────┘ │ Per-request routing: │ └──────────────────────┘
572
- │ │
573
- │ not-blocked.com ──────────────▶ Direct
574
- │ blocked-site.com ─────────────▶ Via Aluvia
575
- │ │
576
- └──────────────────────────┘
577
- ```
267
+ | Resource | URL |
268
+ | -------------------------- | --------------------------------------------------------------------------------------------------------------------- |
269
+ | **Main SDK README** | [github.com/aluvia-connect/sdk-node](https://github.com/aluvia-connect/sdk-node) |
270
+ | **Client Technical Guide** | [docs/client-technical-guide.md](https://github.com/aluvia-connect/sdk-node/blob/main/docs/client-technical-guide.md) |
271
+ | **API Technical Guide** | [docs/api-technical-guide.md](https://github.com/aluvia-connect/sdk-node/blob/main/docs/api-technical-guide.md) |
272
+ | **Aluvia Dashboard** | [dashboard.aluvia.io](https://dashboard.aluvia.io) |
578
273
 
579
274
  ---
580
275
 
581
- ## Learn more
582
-
583
- - [What is Aluvia?](https://docs.aluvia.io/)
584
- - [Understanding connections](https://docs.aluvia.io/fundamentals/connections)
585
- - [Playwright integration guide](https://docs.aluvia.io/integrations/integration-playwright)
586
- - [Puppeteer](https://docs.aluvia.io/integrations/integration-puppeteer), [Selenium](https://docs.aluvia.io/integrations/integration-selenium), [Axios](https://docs.aluvia.io/integrations/integration-axios), [got](https://docs.aluvia.io/integrations/integration-got), [fetch](https://docs.aluvia.io/integrations/integration-fetch)
587
- - [CLI Technical Guide](docs/cli-technical-guide.md)
588
- - [Client Technical Guide](docs/client-technical-guide.md)
589
- - [API Technical Guide](docs/api-technical-guide.md)
590
-
591
276
  ## License
592
277
 
593
- MIT — see [LICENSE](./LICENSE)
278
+ MIT