Aluvia

Aluvia

The Aluvia MCP server exposes browser session management, geo-targeting, and account operations as Model Context Protocol tools for AI agents.

Category
Visit Server

README

Aluvia Node.js SDK

npm downloads license node

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.

Packages

This repository is organized as a monorepo with three packages:

  • @aluvia/sdk — Core SDK with AluviaClient, AluviaApi, framework adapters, and block detection
  • @aluvia/cli — Command-line tools for browser automation and session management
  • @aluvia/mcp — Model Context Protocol server for AI agent integration

Features

  • CLI for browser automation — launch headless Chromium sessions from the command line, with JSON output designed for AI agent frameworks
  • Automatic block detection and unblocking — the SDK detects 403s, WAF challenges, and CAPTCHAs, then reroutes through Aluvia and reloads the page automatically
  • Smart routing — proxy only the sites that block you; everything else goes direct to save cost and latency
  • Runtime rule updates — add hostnames to proxy rules on the fly, no restarts or redeployments
  • Adapters for every tool — Playwright, Puppeteer, Selenium, Axios, got, and Node's fetch
  • IP rotation and geo targeting — rotate IPs or target specific US regions at runtime
  • REST API wrapper — manage connections, check usage, and build custom tooling with AluviaApi

Table of contents


Quick start

1. Get Aluvia API key

Aluvia dashboard

2. Install

For programmatic use:

npm install @aluvia/sdk playwright
export ALUVIA_API_KEY="your-api-key"

For CLI use:

npm install -g @aluvia/cli
export ALUVIA_API_KEY="your-api-key"

For MCP integration:

npm install @aluvia/mcp

3. Run

Aluvia automatically detects website blocks and uses mobile IPs when necessary.

aluvia session start https://example.com --auto-unblock --run your-script.js

Skills

  • Claude code skill
  • OpenClaw skill

CLI reference

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.

session start — Launch a browser session

aluvia session start <url> [options]
Option Description
--auto-unblock Auto-detect blocks and reload through Aluvia
--run <script> Run a script with page, browser, context injected; exits when done
--headful Show the browser window (default: headless)
--browser-session <name> Name this session (auto-generated if omitted, e.g. swift-falcon)
--connection-id <id> Reuse an existing Aluvia connection
--disable-block-detection Disable block detection entirely

Examples:

# Launch with auto-unblocking
aluvia session start https://example.com --auto-unblock

# Run a script inline
aluvia session start https://example.com --auto-unblock --run scrape.mjs

# Debug with a visible browser window
aluvia session start https://example.com --headful

# Reuse an existing connection
aluvia session start https://example.com --connection-id 3449

session close — Stop a session

aluvia session close                              # auto-selects if only one is running
aluvia session close --browser-session swift-falcon  # close by name
aluvia session close --all                          # close all sessions

session list — List active sessions

aluvia session list
{
  "sessions": [
    {
      "browserSession": "swift-falcon",
      "pid": 12345,
      "startUrl": "https://example.com",
      "cdpUrl": "http://127.0.0.1:38209",
      "connectionId": 3449,
      "blockDetection": true,
      "autoUnblock": true
    }
  ],
  "count": 1
}

session get — Full session details

aluvia session get [--browser-session <name>]

Returns session info enriched with block detection history and the full connection object from the API.

session rotate-ip — Get a new IP

aluvia session rotate-ip [--browser-session <name>]

session set-geo — Target a specific country

aluvia session set-geo US                          # target United States
aluvia session set-geo GB                          # target United Kingdom
aluvia session set-geo --clear                     # clear country targeting

session set-rules — Update routing rules

aluvia session set-rules "example.com,api.example.com"    # add rules
aluvia session set-rules --remove "example.com"           # remove rules

Rules are comma-separated. By default rules are appended; use --remove to remove specific rules.

Account and other commands

aluvia account                # account info
aluvia account usage          # usage stats
aluvia account usage --start 2025-01-01T00:00:00Z --end 2025-02-01T00:00:00Z

aluvia geos                   # list available geo-targeting options
aluvia help                   # plain text help
aluvia help --json            # machine-readable help

Connecting to a running browser

There are two ways to run code against a browser session started by the CLI.

Option A: --run (simplest)

Pass a script to session start. The globals page, browser, and context are available — no imports needed:

aluvia session start https://example.com --auto-unblock --run script.mjs
// script.mjs
console.log("URL:", page.url());

const newPage = await context.newPage();
await newPage.goto("https://another-site.com");
console.log("Other site title:", await newPage.title());

The session starts, runs your script, and exits.

Option B: connect() (for AI agents and long-running processes)

Start a session as a background daemon, then connect from your application:

aluvia session start https://example.com --auto-unblock
import { connect } from "@aluvia/sdk";

// Auto-discovers the running session
const { page, browser, context, disconnect } = await connect();
console.log("URL:", page.url());

// When running multiple sessions, specify by name
const conn = await connect("swift-falcon");
console.log("URL:", conn.page.url());

// Disconnect when done (the session keeps running)
await disconnect();

Use this when your agent generates automation code dynamically at runtime or needs a persistent browser across multiple operations.


Programmatic usage

For full control, use AluviaClient directly instead of the CLI.

Basic example

import { AluviaClient } from "@aluvia/sdk";
import { chromium } from "playwright";

const client = new AluviaClient({
  apiKey: process.env.ALUVIA_API_KEY!,
});

const connection = await client.start();
const browser = await chromium.launch({ proxy: connection.asPlaywright() });
const page = await browser.newPage();
await page.goto("https://example.com");

// ... do your work ...

await browser.close();
await connection.close();

With auto-launched browser

const client = new AluviaClient({
  apiKey: process.env.ALUVIA_API_KEY!,
  startPlaywright: true,
  blockDetection: {
    enabled: true,
    autoUnblock: true,
  },
});

const connection = await client.start();
const page = await connection.browser.newPage();
await page.goto("https://example.com"); // auto-reloads through Aluvia if blocked

await connection.close(); // stops proxy, closes browser, releases resources

Runtime updates

While your agent is running, update routing, rotate IPs, or change geo — no restarts needed:

await client.updateRules(["blocked-site.com"]); // proxy this hostname
await client.updateSessionId("new-session-id"); // rotate to a new IP
await client.updateTargetGeo("us"); // target United States IPs

Constructor options

new AluviaClient({
  apiKey: string;                        // Required
  connectionId?: number;                 // Reuse an existing connection
  startPlaywright?: boolean;             // Auto-launch Chromium browser
  headless?: boolean;                    // Default: true (only with startPlaywright)
  blockDetection?: BlockDetectionConfig; // See "Block detection" section
  localPort?: number;                    // Local proxy port (auto-assigned if omitted)
  gatewayProtocol?: "http" | "https";    // Default: "http"
  gatewayPort?: number;                  // Default: 8080 (http) or 8443 (https)
  pollIntervalMs?: number;               // Config poll interval (default: 5000ms)
  timeoutMs?: number;                    // API request timeout
  logLevel?: "silent" | "info" | "debug";
  strict?: boolean;                      // Throw if config fails to load (default: true)
  apiBaseUrl?: string;                   // Default: "https://api.aluvia.io/v1"
});

For all options in detail, see the Client Technical Guide.


Routing rules

The local proxy routes each request based on hostname rules. Only hostnames matching a rule go through Aluvia; everything else goes direct.

Why this matters

  • Save money — proxy only the sites that block you
  • Lower latency — non-blocked sites skip the proxy entirely
  • Adapt on the fly — rules update at runtime, no restarts needed

Rule patterns

Pattern Matches
* All hostnames
example.com Exact match
*.example.com Subdomains of example.com
google.* google.com, google.co.uk, etc.
-example.com Exclude from proxying

Examples

// Proxy all traffic
await client.updateRules(["*"]);

// Proxy specific hosts only
await client.updateRules(["target-site.com", "*.google.com"]);

// Proxy everything except Stripe
await client.updateRules(["*", "-api.stripe.com"]);

// Route all traffic direct (no proxy)
await client.updateRules([]);

Or from the CLI:

aluvia session set-rules "target-site.com,*.google.com"
aluvia session set-rules --remove "target-site.com"

Block detection and auto-unblocking

Most proxy solutions require you to decide upfront which sites to proxy. If a site blocks you later, you're stuck.

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.

Automatic unblocking (recommended)

When a block is detected, the SDK adds the hostname to proxy rules and reloads the page through Aluvia:

const client = new AluviaClient({
  apiKey: process.env.ALUVIA_API_KEY!,
  startPlaywright: true,
  blockDetection: {
    enabled: true,
    autoUnblock: true,
    onDetection: (result, page) => {
      console.log(
        `${result.blockStatus} on ${result.hostname} (score: ${result.score})`,
      );
    },
  },
});

Or from the CLI:

aluvia session start https://example.com --auto-unblock

Detection-only mode

Run detection without automatic remediation. Your agent inspects the results and decides what to do:

blockDetection: {
  enabled: true,
  onDetection: (result, page) => {
    if (result.blockStatus === "blocked") {
      // Agent decides: retry, rotate IP, update rules, etc.
    }
  },
}

Block status scores

Each page analysis produces a score from 0.0 to 1.0:

Score Status Meaning
>= 0.7 "blocked" High confidence block. Auto-reloads when autoUnblock: true.
>= 0.4 "suspected" Possible block. Reloads only if autoUnblockOnSuspected: true.
< 0.4 "clear" No block detected.

Scores use probabilistic combination (1 - product(1 - weight)) so weak signals don't stack into false positives.

How detection works

Detection runs in two passes:

  1. Fast pass (at domcontentloaded) — checks HTTP status codes and WAF response headers. High-confidence blocks (score >= 0.9) trigger immediate remediation.
  2. Full pass (after networkidle) — analyzes page title, visible text, challenge selectors, meta refreshes, and redirect chains.

The SDK also detects SPA navigations and tracks persistent blocks per hostname to prevent infinite retry loops.

Detection config options

blockDetection: {
  enabled?: boolean;                 // Default: true
  autoUnblock?: boolean;             // Auto-remediate blocked pages
  autoUnblockOnSuspected?: boolean;  // Also remediate "suspected" pages
  challengeSelectors?: string[];     // Custom CSS selectors for challenge detection
  extraKeywords?: string[];          // Additional keywords for text analysis
  extraStatusCodes?: number[];       // Additional HTTP status codes to flag
  networkIdleTimeoutMs?: number;     // Default: 3000ms
  onDetection?: (result, page) => void | Promise<void>;
}

Manual detection

You can also check responses yourself and update rules on the fly:

const response = await page.goto(url);

if (response?.status() === 403) {
  await client.updateRules([...currentRules, new URL(url).hostname]);
  await page.goto(url); // retried through Aluvia
}

For the full list of signal detectors and weights, see the Client Technical Guide.


Tool integration adapters

The SDK handles proxy configuration for every major tool:

Tool Method Returns
Playwright connection.asPlaywright() { server, username?, password? }
Playwright connection.browser Auto-launched Chromium (with startPlaywright: true)
Playwright connection.cdpUrl CDP endpoint for connectOverCDP()
Puppeteer connection.asPuppeteer() ['--proxy-server=...']
Selenium connection.asSelenium() '--proxy-server=...'
Axios connection.asAxiosConfig() { proxy: false, httpAgent, httpsAgent }
got connection.asGotOptions() { agent: { http, https } }
fetch connection.asUndiciFetch() Proxy-enabled fetch function
Node.js http connection.asNodeAgents() { http: Agent, https: Agent }

Examples

// Playwright
const browser = await chromium.launch({ proxy: connection.asPlaywright() });

// Puppeteer
const browser = await puppeteer.launch({ args: connection.asPuppeteer() });

// Axios
const axiosClient = axios.create(connection.asAxiosConfig());
await axiosClient.get("https://example.com");

// got
const gotClient = got.extend(connection.asGotOptions());
await gotClient("https://example.com");

// Node's fetch (via undici)
const myFetch = connection.asUndiciFetch();
await myFetch("https://example.com");

For more details, see the Client Technical Guide.


REST API

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.

Endpoints

Method Description
api.account.get() Get account info (balance, usage)
api.account.connections.list() List all connections
api.account.connections.create(body) Create a new connection
api.account.connections.get(id) Get connection details
api.account.connections.patch(id, body) Update connection (rules, geo, session)
api.account.connections.delete(id) Delete a connection
api.account.usage.get(params?) Get usage stats
api.geos.list() List available geo-targeting options

Example

import { AluviaApi } from "@aluvia/sdk";

const api = new AluviaApi({ apiKey: process.env.ALUVIA_API_KEY! });

// Check account balance
const account = await api.account.get();
console.log("Balance:", account.balance_gb, "GB");

// Create a connection for a new agent
const conn = await api.account.connections.create({
  description: "pricing-scraper",
  rules: ["competitor-site.com"],
  target_geo: "us",
});
console.log("Created connection:", conn.connection_id);

// List available geos
const geos = await api.geos.list();
console.log(
  "Geos:",
  geos.map((g) => g.code),
);

AluviaApi is also available as client.api when using AluviaClient.

For the complete API reference, see the API Technical Guide.


Architecture

The client is split into two independent planes:

┌─────────────────────────────────────────────────────────────────┐
│                        AluviaClient                             │
├─────────────────────────────┬───────────────────────────────────┤
│       Control Plane         │          Data Plane               │
│       (ConfigManager)       │          (ProxyServer)            │
├─────────────────────────────┼───────────────────────────────────┤
│ • Fetches/creates config    │ • Local HTTP proxy (proxy-chain)  │
│ • Polls for updates (ETag)  │ • Per-request routing decisions   │
│ • PATCH updates (rules,     │ • Uses rules engine to decide:    │
│   session, geo)             │   direct vs gateway               │
└─────────────────────────────┴───────────────────────────────────┘

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).

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.

┌──────────────────┐      ┌──────────────────────────┐      ┌──────────────────────┐
│                  │      │                          │      │                      │
│    Your Agent    │─────▶│     Aluvia Client        │─────▶│  gateway.aluvia.io   │
│                  │      │     127.0.0.1:port       │      │    (Mobile IPs)      │
│                  │      │                          │      │                      │
└──────────────────┘      │  Per-request routing:    │      └──────────────────────┘
                          │                          │
                          │  not-blocked.com ──────────────▶ Direct
                          │  blocked-site.com ─────────────▶ Via Aluvia
                          │                          │
                          └──────────────────────────┘

Learn more

License

MIT — see LICENSE

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured