Skip to main content
Glama

@profullstack/proxy

Call the web through the residential proxies we pay for, with each provider's own authentication and targeting. One package, every surface:

surface

how

library

proxyFetch(url, init, { country, session }), proxyUrl(), exitIp(), status()

CLI

proxy <url>, proxy ip, proxy url, proxy status

API

proxy serve: a local forward proxy that holds the credentials, plus a JSON API

MCP

proxy mcp: tools proxy_fetch, proxy_ip, proxy_url, proxy_status

TUI

proxy tui: accounts, renewals, and a live exit test

Providers:

  • Proxiware Unlimited Residential (unlimited.proxiware.com:1337). Targeting rides in the username: -country-us, -state-…, -city-…, sticky -sid-<n>-ttl-<min>. Defaults to a US exit.

  • Webshare (p.webshare.io:80). -rotate, -US-rotate, or -<n> to pin proxy n. With only WEBSHARE_API_KEY, the proxy login is read from the API.

Install

npm install -g @profullstack/proxy     # the `proxy` command
npm install @profullstack/proxy        # the library

Node 22.19+ (or Bun). In the Profullstack fleet, cli-tools ships proxy with the shared vault keys already wired in.

Related MCP server: Novada Proxy

Credentials

Environment only; the package never reads or writes a file.

variable

PROXIWARE_PROXY_USER, PROXIWARE_PROXY_PASSWORD

proxy login (Proxiware dashboard, or GET /v1/unlimited/subscriptions)

PROXIWARE_API_KEY

account status (proxy status)

PROXIWARE_PROXY_HOST, PROXIWARE_PROXY_PORT

override unlimited.proxiware.com:1337

WEBSHARE_API_KEY

account status, and the proxy login when no user/password is set

WEBSHARE_PROXY_USER, WEBSHARE_PROXY_PASSWORD

proxy login, skips the API lookup

WEBSHARE_PROXY_HOST, WEBSHARE_PROXY_PORT

override p.webshare.io:80

PROXY_PROVIDER

default provider when several are configured (else proxiware, then webshare)

PROXY_SERVE_TOKEN

default --token for proxy serve

CLI

proxy https://example.com                    # body to stdout, US residential exit
proxy -i -c gb https://example.com           # status + headers, UK exit
proxy -s job42 --ttl 10 https://example.com  # sticky: same IP for 10 minutes
proxy -X POST -H 'content-type: application/json' -d @body.json https://api.example.com
proxy -o page.html https://example.com
proxy ip                                     # 75.179.96.136  US Ohio …  AS10796 Charter  (proxiware)
proxy url                                    # http://user-country-us:***@unlimited.proxiware.com:1337
export HTTPS_PROXY="$(proxy url --reveal)"   # hand the real URL to another tool
proxy status                                 # credit, plans, renewal, expiry
proxy -p webshare ip                         # a specific provider

The default User-Agent is curl/8.5.0 (+@profullstack/proxy): some APIs (ESPN) allowlist curl-like agents and refuse browser and runtime defaults whatever the exit IP. -A overrides it. Exit codes: 0 ok, 22 non-2xx response (curl's --fail), 3 no credentials, 2 bad arguments, 1 anything else.

proxy serve

proxy serve --port 8888                      # binds 127.0.0.1
HTTPS_PROXY=http://127.0.0.1:8888 curl https://ipinfo.io/json
curl http://127.0.0.1:8888/status            # JSON API: /status /ip /url /fetch?url=

Clients send no credentials; the server adds them on the hop upstream, so a tool with no proxy-auth support (or one you would rather not hand a password) still gets the paid exit. Per-connection overrides: X-Proxy-Country, X-Proxy-Session. Bind beyond localhost only with --token T, which clients then send as Proxy-Authorization: Bearer T (proxy traffic) or Authorization: Bearer T (API).

MCP

{ "mcpServers": { "proxy": { "command": "proxy", "args": ["mcp"] } } }

proxy_fetch (url, method, headers, body, max_bytes, provider, country, session), proxy_ip, proxy_url (masked unless reveal), proxy_status.

Library

import { proxyFetch, proxyUrl, exitIp, status } from '@profullstack/proxy';

const res = await proxyFetch('https://example.com', { headers: { accept: 'text/html' } }, { country: 'us' });
const url = await proxyUrl({ provider: 'proxiware', session: 'worker-3', ttl: 30 });
const { ip, org } = await exitIp({ country: 'gb' });

Under Node this is undici's fetch with a ProxyAgent (credentials sent as a Basic token, not URL userinfo, which some undici versions drop). Under Bun it is the built-in fetch with its per-request proxy option. createDispatcher() returns the undici agent for code that wants to keep one around.

Development

npm test                 # offline: fake upstream proxy, no credentials needed
scripts/smoke.sh --vault # live, against the real accounts (shared vault keys)

Releases publish to npm from GitHub when a release is published (.github/workflows/publish.yml).

MIT © Profullstack, Inc.

Related MCP Connectors

Related MCP Servers