Metadata-Version: 2.4
Name: cdp-connect-kit
Version: 0.3.5
Summary: Playwright connect_over_cdp — parse endpoints, MLX Launcher start, CDP health + retry. CLI: cdp-connect.
Project-URL: Homepage, https://github.com/cdp-connect-kit/cdp-connect-kit
Project-URL: Documentation, https://github.com/cdp-connect-kit/cdp-connect-kit#readme
Project-URL: Repository, https://github.com/cdp-connect-kit/cdp-connect-kit
Project-URL: Issues, https://github.com/cdp-connect-kit/cdp-connect-kit/issues
Author: cdp-connect-kit contributors
License-Expression: MIT
License-File: LICENSE
Keywords: antidetect-cdp,browser-debugging,cdp-connect,cdp-endpoint,cdp-health,cdp-retry,chrome-devtools-protocol,connect-over-cdp,devtools-websocket,endpoint-watch,mlx-start,multilogin-launcher,playwright-cdp,playwright-connect-over-cdp,remote-debugging
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: click>=8.1
Requires-Dist: playwright>=1.40
Provides-Extra: dev
Requires-Dist: httpx>=0.27; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest-httpx>=0.34; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.8; extra == 'dev'
Provides-Extra: mlx
Requires-Dist: httpx>=0.27; extra == 'mlx'
Description-Content-Type: text/markdown

# cdp-connect-kit

**Playwright connect_over_cdp kit** — parse MLX Launcher ports, health-check CDP, retry Playwright attach with metrics.

[![PyPI version](https://img.shields.io/pypi/v/cdp-connect-kit.svg)](https://pypi.org/project/cdp-connect-kit/)
[![Python versions](https://img.shields.io/pypi/pyversions/cdp-connect-kit.svg)](https://pypi.org/project/cdp-connect-kit/)
[![License: MIT](https://img.shields.io/pypi/l/cdp-connect-kit.svg)](https://pypi.org/project/cdp-connect-kit/)

```bash
pip install cdp-connect-kit
cdp-connect ping 127.0.0.1:9222
```

CLI: **`cdp-connect`** · Python **3.10+** · optional **`[mlx]`** for Launcher helpers

**CDP connection toolkit** — parse Chrome DevTools Protocol endpoints, validate WebSocket URLs, connect Playwright with **retry + timeout + health metrics**, and watch endpoint uptime.

Optional `[mlx]` extra: start Multilogin X profiles via Launcher API → auto `connect_over_cdp`.

> **Partner (optional):** Production CDP attach goes through **MLX Launcher** (isolated profiles). [Multilogin X](https://multilogin.com?a_aid=saas) · `SAAS50` / `MIN50` on eligible new purchases. `ping` / `playwright` work on any CDP server without MLX. [Affiliate disclosure](docs/AFFILIATE.md) · [Multilogin promo codes](https://anti-detect.github.io/).

## Problem

Connecting Playwright to a remote or antidetect browser over CDP fails for predictable reasons:

- Wrong URL shape (`ws://` vs `http://127.0.0.1:PORT`)
- Browser not finished starting
- Fragile one-shot `connect_over_cdp` with no metrics

`cdp-connect` normalizes endpoints, waits for `/json/version`, retries connections, and reports health.

## Install

```bash
pip install cdp-connect-kit
playwright install chromium
```

MLX Launcher integration:

```bash
pip install cdp-connect-kit[mlx]
```

## Quick start

```bash
# Ping a CDP endpoint (HTTP or WebSocket URL)
cdp-connect ping ws://127.0.0.1:9222/devtools/browser/abc

# Connect Playwright and screenshot
cdp-connect playwright --endpoint http://127.0.0.1:9222 --screenshot out.png

# Watch health — JSON Lines for farm-runner piping
cdp-connect watch --endpoint 127.0.0.1:9222 --interval 5 | tee health.jsonl
```

## Connection flow

```mermaid
sequenceDiagram
    participant MLX as MLX Launcher
    participant CDP as CDP HTTP :PORT
    participant PW as Playwright

    MLX->>MLX: GET /profile/.../start
    MLX-->>CDP: data.port → http://127.0.0.1:PORT
    PW->>CDP: GET /json/version
    CDP-->>PW: webSocketDebuggerUrl
    PW->>PW: connect_over_cdp(http://127.0.0.1:PORT)
```

## CLI

| Command | Description |
|---------|-------------|
| `cdp-connect ping ENDPOINT` | Validate `/json/version`, print WebSocket URL |
| `cdp-connect playwright --endpoint URL [--screenshot FILE]` | Connect with retry, emit metrics JSON |
| `cdp-connect watch --endpoint URL` | Poll health as **JSON Lines** (default) |
| `cdp-connect watch --format plain` | Human-readable `UP`/`DOWN` lines |
| `cdp-connect playwright --max-retries N` | Connect with exponential backoff |
| `cdp-connect mlx-start --profile-id UUID [--print-cdp-url]` | Start MLX profile, wait for CDP (`[mlx]`) |
| `cdp-connect mlx-stop --profile-id UUID` | Stop MLX profile — idempotent (`[mlx]`) |
| `cdp-connect mlx-list` | List running Launcher sessions (`[mlx]`) |

**Endpoint formats:** `http://127.0.0.1:9222`, `ws://127.0.0.1:9222/devtools/browser/…`, `127.0.0.1:9222` (shorthand; default port 9222).

### MLX launcher flow

1. `GET launcher.mlx.yt:45001/api/v2/profile/f/{folder}/p/{profile}/start?automation_type=playwright`
2. Read `data.port` from JSON response
3. CDP HTTP base = `http://127.0.0.1:{port}`
4. `GET /json/version` → `webSocketDebuggerUrl`
5. `playwright.chromium.connect_over_cdp(http://127.0.0.1:{port})`

**Canonical MLX bridge for the monorepo:** [docs/MLX_INTEGRATION.md](docs/MLX_INTEGRATION.md) · Env: [docs/ENV.md](docs/ENV.md)

```bash
export MLX_TOKEN="..."
export MLX_FOLDER_ID="..."
export MLX_LAUNCHER_URL="https://launcher.mlx.yt:45001"   # optional

# Scripting: CDP URL on stdout
CDP_URL=$(cdp-connect mlx-start --profile-id PROFILE_UUID --print-cdp-url)

cdp-connect mlx-list
cdp-connect mlx-stop --profile-id PROFILE_UUID
```

## API

```python
from cdp_connect_kit import CdpClient, connect_playwright, parse_endpoint
import asyncio

async def main():
    client = CdpClient("127.0.0.1:9222")
    print(client.resolve_websocket_url())
    browser, pw, metrics = await connect_playwright("127.0.0.1:9222", max_retries=5)
    print(metrics.to_dict())
    await browser.close()
    await pw.stop()

asyncio.run(main())
```

| Symbol | Description |
|--------|-------------|
| `parse_endpoint(url)` | Normalize HTTP / WS / host:port |
| `CdpClient` | `/json/version`, `/json/list`, `health_snapshot()` |
| `connect_playwright(endpoint)` | Retry wrapper → `(browser, playwright, ConnectMetrics)` |
| `watch_endpoint(endpoint)` | Async health polling |

### ConnectMetrics

```json
{
  "endpoint": "http://127.0.0.1:9222",
  "web_socket_url": "ws://127.0.0.1:9222/devtools/browser/...",
  "attempts": 1,
  "connect_ms": 842.1,
  "ready_ms": 120.5,
  "target_count": 3
}
```

## When `connect_over_cdp` keeps failing (playbook)

Most failures are **endpoint shape** or **browser not ready** — not Playwright bugs.

| Error pattern | Likely cause | Fix |
|---------------|--------------|-----|
| `Connection refused` | Port not open yet | `cdp-connect ping` in a loop; MLX: `mlx-start --wait-timeout` |
| `Invalid URL` / WS mismatch | Passed raw `ws://…` without version fetch | Use HTTP base `http://127.0.0.1:PORT`; let client resolve WS |
| Works once, flaky in farm | Race on profile start | `watch --endpoint URL` → JSONL for `farm-runner`; retry `connect_playwright` |
| Chrome 136+ local profile | Default `user-data-dir` blocks CDP | Custom profile dir or antidetect Launcher port |
| MLX 401 / timeout | Agent not running or wrong token | `MLX_TOKEN`, desktop agent up; see `docs/ENV.md` |

**MLX → Playwright pipeline:**

```bash
export MLX_TOKEN=... MLX_FOLDER_ID=...
CDP_URL=$(cdp-connect mlx-start --profile-id PROFILE_UUID --print-cdp-url)
cdp-connect ping "$CDP_URL"
cdp-connect playwright --endpoint "$CDP_URL" --max-retries 5
# farm scripts: export CDP_URL for child processes
cdp-probe run --cdp-endpoint "$CDP_URL" --url https://example.com
cdp-connect mlx-stop --profile-id PROFILE_UUID
```


**Coupon hub:** [Multilogin promo codes](https://anti-detect.github.io/) — guides for `SAAS50` / `MIN50`, pricing comparisons, and workflow playbooks.
**Farm-scale partner note:** Folder pools need stable Launcher CDP — [Multilogin X](https://multilogin.com?a_aid=saas) is the `[mlx]` target stack. Code `SAAS50` (browser) · coupons: `cdp-connect --show-deal`.

Canonical API details: [docs/MLX_INTEGRATION.md](docs/MLX_INTEGRATION.md).

## Limitations

- **Chromium CDP only** — `connect_over_cdp` targets Chromium-based browsers.
- **MLX requires local agent** — Launcher API needs Multilogin desktop running.
- **Watch mode** uses HTTP discovery only; JSONL output is designed for `automation-farm-runner` ingestion.
- **Not a fingerprint tool** — connects to browsers; does not modify profiles.

## Production

Use `cdp-connect mlx-start` → `connect_playwright` in farm scripts and probes; pair with `farm-runner` (`automation-farm-runner`) for folder pools. Export `CDP_URL` for `human-input-kit` warmup and `playwright-cdp-probe` checks on the same Launcher session.

**Partner note (affiliate):** When Playwright must attach to **Multilogin X Launcher** CDP ports (not vanilla `--remote-debugging-port`), isolated profiles are the intended production path. Eligible new browser purchases may accept code **`SAAS50`** at [multilogin.com](https://multilogin.com?a_aid=saas) — verify terms before checkout. `ping` / `playwright` / `watch` work on any CDP server without MLX. Full disclosure: [docs/AFFILIATE.md](docs/AFFILIATE.md). Deals hub: [anti-detect.github.io](https://anti-detect.github.io/). Coupon details only via `cdp-connect --show-deal` (never printed by default).

**FAQ:** [docs/FAQ.md](docs/FAQ.md) — Playwright connect_over_cdp, Multilogin Launcher, CDP health check.





## Related tools (on PyPI)

| Package | CLI | Role |
|---------|-----|------|
| [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) | `cdp-probe` | CDP / WebDriver exposure score |
| [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) | `cookie-bridge` | Netscape ↔ Playwright cookies |
| [proxy-lane-checker](https://pypi.org/project/proxy-lane-checker/) | `proxy-lane` | Proxy TCP / HTTP / geo / DNSBL |
| [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) | `fp-coherence` | UA / screen / timezone lint |

**Toolkit pipeline:** `proxy-lane check` → `fp-coherence audit` → automate → `cdp-probe run` → `cookie-bridge validate`

## License

MIT

---

**Production antidetect (partner):** [Multilogin X](https://multilogin.com?a_aid=saas) · Code `SAAS50` (-50% browser) · `MIN50` (-50% cloud phone)  
Affiliate disclosure — we may earn a commission; offers change on the vendor site. More scripts: [@Multilogin_Scripts_Bot](https://t.me/Multilogin_Scripts_Bot) · [Multilogin promo codes](https://anti-detect.github.io/)
