cdp-connect-kit 0.3.1__tar.gz

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 (34) hide show
  1. cdp_connect_kit-0.3.1/.github/workflows/ci.yml +31 -0
  2. cdp_connect_kit-0.3.1/.github/workflows/release.yml +54 -0
  3. cdp_connect_kit-0.3.1/.gitignore +12 -0
  4. cdp_connect_kit-0.3.1/CHANGELOG.md +51 -0
  5. cdp_connect_kit-0.3.1/LICENSE +21 -0
  6. cdp_connect_kit-0.3.1/PKG-INFO +245 -0
  7. cdp_connect_kit-0.3.1/README.md +208 -0
  8. cdp_connect_kit-0.3.1/cdp_connect_kit/__init__.py +15 -0
  9. cdp_connect_kit-0.3.1/cdp_connect_kit/cdp/__init__.py +14 -0
  10. cdp_connect_kit-0.3.1/cdp_connect_kit/cdp/client.py +105 -0
  11. cdp_connect_kit-0.3.1/cdp_connect_kit/cdp/models.py +43 -0
  12. cdp_connect_kit-0.3.1/cdp_connect_kit/cdp/url.py +77 -0
  13. cdp_connect_kit-0.3.1/cdp_connect_kit/cli.py +211 -0
  14. cdp_connect_kit-0.3.1/cdp_connect_kit/connect.py +97 -0
  15. cdp_connect_kit-0.3.1/cdp_connect_kit/deal.py +25 -0
  16. cdp_connect_kit-0.3.1/cdp_connect_kit/mlx.py +367 -0
  17. cdp_connect_kit-0.3.1/cdp_connect_kit/mlx_cli.py +142 -0
  18. cdp_connect_kit-0.3.1/cdp_connect_kit/retry.py +45 -0
  19. cdp_connect_kit-0.3.1/cdp_connect_kit/watch.py +66 -0
  20. cdp_connect_kit-0.3.1/docs/AFFILIATE.md +58 -0
  21. cdp_connect_kit-0.3.1/docs/ENV.md +36 -0
  22. cdp_connect_kit-0.3.1/docs/FAQ.md +33 -0
  23. cdp_connect_kit-0.3.1/docs/MLX_INTEGRATION.md +193 -0
  24. cdp_connect_kit-0.3.1/docs/MLX_LAUNCHER.md +104 -0
  25. cdp_connect_kit-0.3.1/pyproject.toml +83 -0
  26. cdp_connect_kit-0.3.1/tests/test_cdp_client.py +43 -0
  27. cdp_connect_kit-0.3.1/tests/test_cdp_url.py +44 -0
  28. cdp_connect_kit-0.3.1/tests/test_cli.py +77 -0
  29. cdp_connect_kit-0.3.1/tests/test_connect.py +36 -0
  30. cdp_connect_kit-0.3.1/tests/test_integration_cdp.py +44 -0
  31. cdp_connect_kit-0.3.1/tests/test_mlx.py +219 -0
  32. cdp_connect_kit-0.3.1/tests/test_mlx_cli.py +108 -0
  33. cdp_connect_kit-0.3.1/tests/test_retry.py +35 -0
  34. cdp_connect_kit-0.3.1/tests/test_watch.py +49 -0
@@ -0,0 +1,31 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+
6
+ jobs:
7
+ test:
8
+ runs-on: ubuntu-latest
9
+ strategy:
10
+ fail-fast: false
11
+ matrix:
12
+ python-version: ["3.10", "3.11", "3.12"]
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Set up Python ${{ matrix.python-version }}
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+
21
+ - name: Install package and dev deps
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ pip install -e ".[dev]"
25
+ playwright install chromium
26
+
27
+ - name: Ruff
28
+ run: ruff check .
29
+
30
+ - name: Pytest
31
+ run: pytest
@@ -0,0 +1,54 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - name: Set up Python 3.12
15
+ uses: actions/setup-python@v5
16
+ with:
17
+ python-version: "3.12"
18
+
19
+ - name: Install package and dev deps
20
+ run: |
21
+ python -m pip install --upgrade pip
22
+ pip install -e ".[dev]"
23
+ playwright install chromium
24
+
25
+ - name: Ruff
26
+ run: ruff check .
27
+
28
+ - name: Pytest
29
+ run: pytest
30
+
31
+ publish:
32
+ needs: test
33
+ runs-on: ubuntu-latest
34
+ steps:
35
+ - uses: actions/checkout@v4
36
+
37
+ - name: Set up Python 3.12
38
+ uses: actions/setup-python@v5
39
+ with:
40
+ python-version: "3.12"
41
+
42
+ - name: Install build tools
43
+ run: python -m pip install --upgrade pip build twine
44
+
45
+ - name: Build
46
+ run: python -m build
47
+
48
+ - name: Twine check
49
+ run: twine check dist/*
50
+
51
+ - name: Publish to PyPI
52
+ uses: pypa/gh-action-pypi-publish@release/v1
53
+ with:
54
+ password: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,12 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.egg-info/
5
+ .eggs/
6
+ dist/
7
+ build/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .venv/
11
+ venv/
12
+ .env
@@ -0,0 +1,51 @@
1
+ # Changelog
2
+
3
+ ## v0.3.1 — 2026-06-11
4
+
5
+ ### Changed
6
+
7
+ - PyPI README: SEO subtitle (connect_over_cdp + MLX Launcher), CDP failure playbook, contextual affiliate note
8
+ - `pyproject.toml`: keywords (`playwright-connect-over-cdp`, `multilogin-launcher`)
9
+ - `--show-deal`: contextual Launcher CDP copy with affiliate disclosure
10
+ - FAQ: +3 SEO questions (connect_over_cdp, farm health-check, affiliate opt-in)
11
+
12
+ ## v0.3.0 — 2026-06-11
13
+
14
+ ### Added
15
+
16
+ - `mlx-list` — list running Launcher sessions (`/api/v2/profile/active`)
17
+ - `mlx-start --print-cdp-url` — CDP HTTP URL on stdout for shell scripting
18
+ - `mlx-start --wait-timeout` (default 120s) — poll CDP until ready
19
+ - `mlx-start --connect` — optional Playwright connect + metrics JSON
20
+ - `MlxLauncher.list_running_sessions()`, `start_profile_and_wait()`, `wait_for_cdp()`
21
+ - Already-running profile reuse via active-session lookup
22
+ - Idempotent `mlx-stop` (default); `--strict` for hard errors
23
+ - `MLX_LAUNCHER_URL` env (preferred over `MLX_LAUNCHER_HOST`)
24
+ - `docs/MLX_INTEGRATION.md` — definitive monorepo MLX bridge guide
25
+ - 15+ mocked MLX unit/CLI tests (timeout, already running, idempotent stop)
26
+
27
+ ### Changed
28
+
29
+ - `mlx-start` no longer connects Playwright unless `--connect` is passed
30
+ - MLX CLI logic moved to `cdp_connect_kit.mlx_cli`
31
+
32
+ ## v0.2.0 — 2026-06-11
33
+
34
+ ### Added
35
+
36
+ - Robust CDP URL parser: `http://`, `https://`, `ws://`, `wss://`, `host:port` (default port **9222**)
37
+ - `watch` emits **JSON Lines** (`--format jsonl`, default) for piping to farm-runner
38
+ - Exponential backoff retries (`--max-retries` on `playwright` and `mlx-start`)
39
+ - Integration test with mocked `/json/version` (no real browser)
40
+ - README mermaid sequence: MLX Launcher → CDP URL → Playwright
41
+ - `docs/ENV.md` — `MLX_TOKEN`, `MLX_LAUNCHER_HOST`, `MLX_FOLDER_ID`
42
+ - GitHub Actions CI (Python 3.10–3.12)
43
+
44
+ ### Changed
45
+
46
+ - `watch --format plain` restores human-readable `UP`/`DOWN` lines
47
+ - `MlxLauncher` reads `MLX_LAUNCHER_HOST` when `--launcher-host` is omitted
48
+
49
+ ## v0.1.0 — 2026-06-01
50
+
51
+ - Initial release: CDP ping, Playwright connect, watch, MLX launcher helpers
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 cdp-connect-kit contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,245 @@
1
+ Metadata-Version: 2.4
2
+ Name: cdp-connect-kit
3
+ Version: 0.3.1
4
+ Summary: Playwright connect_over_cdp — parse endpoints, MLX Launcher start, CDP health + retry. CLI: cdp-connect.
5
+ Project-URL: Homepage, https://github.com/cdp-connect-kit/cdp-connect-kit
6
+ Project-URL: Documentation, https://github.com/cdp-connect-kit/cdp-connect-kit#readme
7
+ Project-URL: Repository, https://github.com/cdp-connect-kit/cdp-connect-kit
8
+ Project-URL: Issues, https://github.com/cdp-connect-kit/cdp-connect-kit/issues
9
+ Author: cdp-connect-kit contributors
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ 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
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
23
+ Classifier: Topic :: Software Development :: Quality Assurance
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.10
26
+ Requires-Dist: click>=8.1
27
+ Requires-Dist: playwright>=1.40
28
+ Provides-Extra: dev
29
+ Requires-Dist: httpx>=0.27; extra == 'dev'
30
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
31
+ Requires-Dist: pytest-httpx>=0.34; extra == 'dev'
32
+ Requires-Dist: pytest>=8.0; extra == 'dev'
33
+ Requires-Dist: ruff>=0.8; extra == 'dev'
34
+ Provides-Extra: mlx
35
+ Requires-Dist: httpx>=0.27; extra == 'mlx'
36
+ Description-Content-Type: text/markdown
37
+
38
+ # cdp-connect-kit
39
+
40
+ **Playwright connect_over_cdp kit** — parse MLX Launcher ports, health-check CDP, retry Playwright attach with metrics.
41
+
42
+ [![PyPI version](https://img.shields.io/pypi/v/cdp-connect-kit.svg)](https://pypi.org/project/cdp-connect-kit/)
43
+ [![Python versions](https://img.shields.io/pypi/pyversions/cdp-connect-kit.svg)](https://pypi.org/project/cdp-connect-kit/)
44
+ [![License: MIT](https://img.shields.io/pypi/l/cdp-connect-kit.svg)](https://pypi.org/project/cdp-connect-kit/)
45
+
46
+ ```bash
47
+ pip install cdp-connect-kit
48
+ cdp-connect ping 127.0.0.1:9222
49
+ ```
50
+
51
+ CLI: **`cdp-connect`** · Python **3.10+** · optional **`[mlx]`** for Launcher helpers
52
+
53
+ **CDP connection toolkit** — parse Chrome DevTools Protocol endpoints, validate WebSocket URLs, connect Playwright with **retry + timeout + health metrics**, and watch endpoint uptime.
54
+
55
+ Optional `[mlx]` extra: start Multilogin X profiles via Launcher API → auto `connect_over_cdp`.
56
+
57
+ ## Problem
58
+
59
+ Connecting Playwright to a remote or antidetect browser over CDP fails for predictable reasons:
60
+
61
+ - Wrong URL shape (`ws://` vs `http://127.0.0.1:PORT`)
62
+ - Browser not finished starting
63
+ - Fragile one-shot `connect_over_cdp` with no metrics
64
+
65
+ `cdp-connect` normalizes endpoints, waits for `/json/version`, retries connections, and reports health.
66
+
67
+ ## Install
68
+
69
+ ```bash
70
+ pip install cdp-connect-kit
71
+ playwright install chromium
72
+ ```
73
+
74
+ MLX Launcher integration:
75
+
76
+ ```bash
77
+ pip install cdp-connect-kit[mlx]
78
+ ```
79
+
80
+ ## Quick start
81
+
82
+ ```bash
83
+ # Ping a CDP endpoint (HTTP or WebSocket URL)
84
+ cdp-connect ping ws://127.0.0.1:9222/devtools/browser/abc
85
+
86
+ # Connect Playwright and screenshot
87
+ cdp-connect playwright --endpoint http://127.0.0.1:9222 --screenshot out.png
88
+
89
+ # Watch health — JSON Lines for farm-runner piping
90
+ cdp-connect watch --endpoint 127.0.0.1:9222 --interval 5 | tee health.jsonl
91
+ ```
92
+
93
+ ## Connection flow
94
+
95
+ ```mermaid
96
+ sequenceDiagram
97
+ participant MLX as MLX Launcher
98
+ participant CDP as CDP HTTP :PORT
99
+ participant PW as Playwright
100
+
101
+ MLX->>MLX: GET /profile/.../start
102
+ MLX-->>CDP: data.port → http://127.0.0.1:PORT
103
+ PW->>CDP: GET /json/version
104
+ CDP-->>PW: webSocketDebuggerUrl
105
+ PW->>PW: connect_over_cdp(http://127.0.0.1:PORT)
106
+ ```
107
+
108
+ ## CLI
109
+
110
+ | Command | Description |
111
+ |---------|-------------|
112
+ | `cdp-connect ping ENDPOINT` | Validate `/json/version`, print WebSocket URL |
113
+ | `cdp-connect playwright --endpoint URL [--screenshot FILE]` | Connect with retry, emit metrics JSON |
114
+ | `cdp-connect watch --endpoint URL` | Poll health as **JSON Lines** (default) |
115
+ | `cdp-connect watch --format plain` | Human-readable `UP`/`DOWN` lines |
116
+ | `cdp-connect playwright --max-retries N` | Connect with exponential backoff |
117
+ | `cdp-connect mlx-start --profile-id UUID [--print-cdp-url]` | Start MLX profile, wait for CDP (`[mlx]`) |
118
+ | `cdp-connect mlx-stop --profile-id UUID` | Stop MLX profile — idempotent (`[mlx]`) |
119
+ | `cdp-connect mlx-list` | List running Launcher sessions (`[mlx]`) |
120
+
121
+ **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).
122
+
123
+ ### MLX launcher flow
124
+
125
+ 1. `GET launcher.mlx.yt:45001/api/v2/profile/f/{folder}/p/{profile}/start?automation_type=playwright`
126
+ 2. Read `data.port` from JSON response
127
+ 3. CDP HTTP base = `http://127.0.0.1:{port}`
128
+ 4. `GET /json/version` → `webSocketDebuggerUrl`
129
+ 5. `playwright.chromium.connect_over_cdp(http://127.0.0.1:{port})`
130
+
131
+ **Canonical MLX bridge for the monorepo:** [docs/MLX_INTEGRATION.md](docs/MLX_INTEGRATION.md) · Env: [docs/ENV.md](docs/ENV.md)
132
+
133
+ ```bash
134
+ export MLX_TOKEN="..."
135
+ export MLX_FOLDER_ID="..."
136
+ export MLX_LAUNCHER_URL="https://launcher.mlx.yt:45001" # optional
137
+
138
+ # Scripting: CDP URL on stdout
139
+ CDP_URL=$(cdp-connect mlx-start --profile-id PROFILE_UUID --print-cdp-url)
140
+
141
+ cdp-connect mlx-list
142
+ cdp-connect mlx-stop --profile-id PROFILE_UUID
143
+ ```
144
+
145
+ ## API
146
+
147
+ ```python
148
+ from cdp_connect_kit import CdpClient, connect_playwright, parse_endpoint
149
+ import asyncio
150
+
151
+ async def main():
152
+ client = CdpClient("127.0.0.1:9222")
153
+ print(client.resolve_websocket_url())
154
+ browser, pw, metrics = await connect_playwright("127.0.0.1:9222", max_retries=5)
155
+ print(metrics.to_dict())
156
+ await browser.close()
157
+ await pw.stop()
158
+
159
+ asyncio.run(main())
160
+ ```
161
+
162
+ | Symbol | Description |
163
+ |--------|-------------|
164
+ | `parse_endpoint(url)` | Normalize HTTP / WS / host:port |
165
+ | `CdpClient` | `/json/version`, `/json/list`, `health_snapshot()` |
166
+ | `connect_playwright(endpoint)` | Retry wrapper → `(browser, playwright, ConnectMetrics)` |
167
+ | `watch_endpoint(endpoint)` | Async health polling |
168
+
169
+ ### ConnectMetrics
170
+
171
+ ```json
172
+ {
173
+ "endpoint": "http://127.0.0.1:9222",
174
+ "web_socket_url": "ws://127.0.0.1:9222/devtools/browser/...",
175
+ "attempts": 1,
176
+ "connect_ms": 842.1,
177
+ "ready_ms": 120.5,
178
+ "target_count": 3
179
+ }
180
+ ```
181
+
182
+ ## When `connect_over_cdp` keeps failing (playbook)
183
+
184
+ Most failures are **endpoint shape** or **browser not ready** — not Playwright bugs.
185
+
186
+ | Error pattern | Likely cause | Fix |
187
+ |---------------|--------------|-----|
188
+ | `Connection refused` | Port not open yet | `cdp-connect ping` in a loop; MLX: `mlx-start --wait-timeout` |
189
+ | `Invalid URL` / WS mismatch | Passed raw `ws://…` without version fetch | Use HTTP base `http://127.0.0.1:PORT`; let client resolve WS |
190
+ | Works once, flaky in farm | Race on profile start | `watch --endpoint URL` → JSONL for `farm-runner`; retry `connect_playwright` |
191
+ | Chrome 136+ local profile | Default `user-data-dir` blocks CDP | Custom profile dir or antidetect Launcher port |
192
+ | MLX 401 / timeout | Agent not running or wrong token | `MLX_TOKEN`, desktop agent up; see `docs/ENV.md` |
193
+
194
+ **MLX → Playwright pipeline:**
195
+
196
+ ```bash
197
+ export MLX_TOKEN=... MLX_FOLDER_ID=...
198
+ CDP_URL=$(cdp-connect mlx-start --profile-id PROFILE_UUID --print-cdp-url)
199
+ cdp-connect ping "$CDP_URL"
200
+ cdp-connect playwright --endpoint "$CDP_URL" --max-retries 5
201
+ # farm scripts: export CDP_URL for child processes
202
+ cdp-probe run --cdp-endpoint "$CDP_URL" --url https://example.com
203
+ cdp-connect mlx-stop --profile-id PROFILE_UUID
204
+ ```
205
+
206
+ Canonical API details: [docs/MLX_INTEGRATION.md](docs/MLX_INTEGRATION.md).
207
+
208
+ ## Limitations
209
+
210
+ - **Chromium CDP only** — `connect_over_cdp` targets Chromium-based browsers.
211
+ - **MLX requires local agent** — Launcher API needs Multilogin desktop running.
212
+ - **Watch mode** uses HTTP discovery only; JSONL output is designed for `automation-farm-runner` ingestion.
213
+ - **Not a fingerprint tool** — connects to browsers; does not modify profiles.
214
+
215
+ ## Production
216
+
217
+ 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.
218
+
219
+ **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/?ref=SAAS50) — verify terms before checkout. `ping` / `playwright` / `watch` work on any CDP server without MLX. Full disclosure: [docs/AFFILIATE.md](docs/AFFILIATE.md). Coupon details only via `cdp-connect --show-deal` (never printed by default).
220
+
221
+ **FAQ:** [docs/FAQ.md](docs/FAQ.md) — Playwright connect_over_cdp, Multilogin Launcher, CDP health check.
222
+
223
+
224
+
225
+
226
+
227
+ ## Related tools (on PyPI)
228
+
229
+ | Package | CLI | Role |
230
+ |---------|-----|------|
231
+ | [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) | `cdp-probe` | CDP / WebDriver exposure score |
232
+ | [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) | `cookie-bridge` | Netscape ↔ Playwright cookies |
233
+ | [proxy-lane-checker](https://pypi.org/project/proxy-lane-checker/) | `proxy-lane` | Proxy TCP / HTTP / geo / DNSBL |
234
+ | [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) | `fp-coherence` | UA / screen / timezone lint |
235
+
236
+ **Toolkit pipeline:** `proxy-lane check` → `fp-coherence audit` → automate → `cdp-probe run` → `cookie-bridge validate`
237
+
238
+ ## License
239
+
240
+ MIT
241
+
242
+ ---
243
+
244
+ **Production antidetect:** [Multilogin X](https://multilogin.com/?ref=SAAS50) · Code `SAAS50` (-50% browser) · `MIN50` (-50% cloud phone)
245
+ More scripts: [@Multilogin_Scripts_Bot](https://t.me/Multilogin_Scripts_Bot) · [Coupons](https://anti-detect.github.io/)
@@ -0,0 +1,208 @@
1
+ # cdp-connect-kit
2
+
3
+ **Playwright connect_over_cdp kit** — parse MLX Launcher ports, health-check CDP, retry Playwright attach with metrics.
4
+
5
+ [![PyPI version](https://img.shields.io/pypi/v/cdp-connect-kit.svg)](https://pypi.org/project/cdp-connect-kit/)
6
+ [![Python versions](https://img.shields.io/pypi/pyversions/cdp-connect-kit.svg)](https://pypi.org/project/cdp-connect-kit/)
7
+ [![License: MIT](https://img.shields.io/pypi/l/cdp-connect-kit.svg)](https://pypi.org/project/cdp-connect-kit/)
8
+
9
+ ```bash
10
+ pip install cdp-connect-kit
11
+ cdp-connect ping 127.0.0.1:9222
12
+ ```
13
+
14
+ CLI: **`cdp-connect`** · Python **3.10+** · optional **`[mlx]`** for Launcher helpers
15
+
16
+ **CDP connection toolkit** — parse Chrome DevTools Protocol endpoints, validate WebSocket URLs, connect Playwright with **retry + timeout + health metrics**, and watch endpoint uptime.
17
+
18
+ Optional `[mlx]` extra: start Multilogin X profiles via Launcher API → auto `connect_over_cdp`.
19
+
20
+ ## Problem
21
+
22
+ Connecting Playwright to a remote or antidetect browser over CDP fails for predictable reasons:
23
+
24
+ - Wrong URL shape (`ws://` vs `http://127.0.0.1:PORT`)
25
+ - Browser not finished starting
26
+ - Fragile one-shot `connect_over_cdp` with no metrics
27
+
28
+ `cdp-connect` normalizes endpoints, waits for `/json/version`, retries connections, and reports health.
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ pip install cdp-connect-kit
34
+ playwright install chromium
35
+ ```
36
+
37
+ MLX Launcher integration:
38
+
39
+ ```bash
40
+ pip install cdp-connect-kit[mlx]
41
+ ```
42
+
43
+ ## Quick start
44
+
45
+ ```bash
46
+ # Ping a CDP endpoint (HTTP or WebSocket URL)
47
+ cdp-connect ping ws://127.0.0.1:9222/devtools/browser/abc
48
+
49
+ # Connect Playwright and screenshot
50
+ cdp-connect playwright --endpoint http://127.0.0.1:9222 --screenshot out.png
51
+
52
+ # Watch health — JSON Lines for farm-runner piping
53
+ cdp-connect watch --endpoint 127.0.0.1:9222 --interval 5 | tee health.jsonl
54
+ ```
55
+
56
+ ## Connection flow
57
+
58
+ ```mermaid
59
+ sequenceDiagram
60
+ participant MLX as MLX Launcher
61
+ participant CDP as CDP HTTP :PORT
62
+ participant PW as Playwright
63
+
64
+ MLX->>MLX: GET /profile/.../start
65
+ MLX-->>CDP: data.port → http://127.0.0.1:PORT
66
+ PW->>CDP: GET /json/version
67
+ CDP-->>PW: webSocketDebuggerUrl
68
+ PW->>PW: connect_over_cdp(http://127.0.0.1:PORT)
69
+ ```
70
+
71
+ ## CLI
72
+
73
+ | Command | Description |
74
+ |---------|-------------|
75
+ | `cdp-connect ping ENDPOINT` | Validate `/json/version`, print WebSocket URL |
76
+ | `cdp-connect playwright --endpoint URL [--screenshot FILE]` | Connect with retry, emit metrics JSON |
77
+ | `cdp-connect watch --endpoint URL` | Poll health as **JSON Lines** (default) |
78
+ | `cdp-connect watch --format plain` | Human-readable `UP`/`DOWN` lines |
79
+ | `cdp-connect playwright --max-retries N` | Connect with exponential backoff |
80
+ | `cdp-connect mlx-start --profile-id UUID [--print-cdp-url]` | Start MLX profile, wait for CDP (`[mlx]`) |
81
+ | `cdp-connect mlx-stop --profile-id UUID` | Stop MLX profile — idempotent (`[mlx]`) |
82
+ | `cdp-connect mlx-list` | List running Launcher sessions (`[mlx]`) |
83
+
84
+ **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).
85
+
86
+ ### MLX launcher flow
87
+
88
+ 1. `GET launcher.mlx.yt:45001/api/v2/profile/f/{folder}/p/{profile}/start?automation_type=playwright`
89
+ 2. Read `data.port` from JSON response
90
+ 3. CDP HTTP base = `http://127.0.0.1:{port}`
91
+ 4. `GET /json/version` → `webSocketDebuggerUrl`
92
+ 5. `playwright.chromium.connect_over_cdp(http://127.0.0.1:{port})`
93
+
94
+ **Canonical MLX bridge for the monorepo:** [docs/MLX_INTEGRATION.md](docs/MLX_INTEGRATION.md) · Env: [docs/ENV.md](docs/ENV.md)
95
+
96
+ ```bash
97
+ export MLX_TOKEN="..."
98
+ export MLX_FOLDER_ID="..."
99
+ export MLX_LAUNCHER_URL="https://launcher.mlx.yt:45001" # optional
100
+
101
+ # Scripting: CDP URL on stdout
102
+ CDP_URL=$(cdp-connect mlx-start --profile-id PROFILE_UUID --print-cdp-url)
103
+
104
+ cdp-connect mlx-list
105
+ cdp-connect mlx-stop --profile-id PROFILE_UUID
106
+ ```
107
+
108
+ ## API
109
+
110
+ ```python
111
+ from cdp_connect_kit import CdpClient, connect_playwright, parse_endpoint
112
+ import asyncio
113
+
114
+ async def main():
115
+ client = CdpClient("127.0.0.1:9222")
116
+ print(client.resolve_websocket_url())
117
+ browser, pw, metrics = await connect_playwright("127.0.0.1:9222", max_retries=5)
118
+ print(metrics.to_dict())
119
+ await browser.close()
120
+ await pw.stop()
121
+
122
+ asyncio.run(main())
123
+ ```
124
+
125
+ | Symbol | Description |
126
+ |--------|-------------|
127
+ | `parse_endpoint(url)` | Normalize HTTP / WS / host:port |
128
+ | `CdpClient` | `/json/version`, `/json/list`, `health_snapshot()` |
129
+ | `connect_playwright(endpoint)` | Retry wrapper → `(browser, playwright, ConnectMetrics)` |
130
+ | `watch_endpoint(endpoint)` | Async health polling |
131
+
132
+ ### ConnectMetrics
133
+
134
+ ```json
135
+ {
136
+ "endpoint": "http://127.0.0.1:9222",
137
+ "web_socket_url": "ws://127.0.0.1:9222/devtools/browser/...",
138
+ "attempts": 1,
139
+ "connect_ms": 842.1,
140
+ "ready_ms": 120.5,
141
+ "target_count": 3
142
+ }
143
+ ```
144
+
145
+ ## When `connect_over_cdp` keeps failing (playbook)
146
+
147
+ Most failures are **endpoint shape** or **browser not ready** — not Playwright bugs.
148
+
149
+ | Error pattern | Likely cause | Fix |
150
+ |---------------|--------------|-----|
151
+ | `Connection refused` | Port not open yet | `cdp-connect ping` in a loop; MLX: `mlx-start --wait-timeout` |
152
+ | `Invalid URL` / WS mismatch | Passed raw `ws://…` without version fetch | Use HTTP base `http://127.0.0.1:PORT`; let client resolve WS |
153
+ | Works once, flaky in farm | Race on profile start | `watch --endpoint URL` → JSONL for `farm-runner`; retry `connect_playwright` |
154
+ | Chrome 136+ local profile | Default `user-data-dir` blocks CDP | Custom profile dir or antidetect Launcher port |
155
+ | MLX 401 / timeout | Agent not running or wrong token | `MLX_TOKEN`, desktop agent up; see `docs/ENV.md` |
156
+
157
+ **MLX → Playwright pipeline:**
158
+
159
+ ```bash
160
+ export MLX_TOKEN=... MLX_FOLDER_ID=...
161
+ CDP_URL=$(cdp-connect mlx-start --profile-id PROFILE_UUID --print-cdp-url)
162
+ cdp-connect ping "$CDP_URL"
163
+ cdp-connect playwright --endpoint "$CDP_URL" --max-retries 5
164
+ # farm scripts: export CDP_URL for child processes
165
+ cdp-probe run --cdp-endpoint "$CDP_URL" --url https://example.com
166
+ cdp-connect mlx-stop --profile-id PROFILE_UUID
167
+ ```
168
+
169
+ Canonical API details: [docs/MLX_INTEGRATION.md](docs/MLX_INTEGRATION.md).
170
+
171
+ ## Limitations
172
+
173
+ - **Chromium CDP only** — `connect_over_cdp` targets Chromium-based browsers.
174
+ - **MLX requires local agent** — Launcher API needs Multilogin desktop running.
175
+ - **Watch mode** uses HTTP discovery only; JSONL output is designed for `automation-farm-runner` ingestion.
176
+ - **Not a fingerprint tool** — connects to browsers; does not modify profiles.
177
+
178
+ ## Production
179
+
180
+ 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.
181
+
182
+ **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/?ref=SAAS50) — verify terms before checkout. `ping` / `playwright` / `watch` work on any CDP server without MLX. Full disclosure: [docs/AFFILIATE.md](docs/AFFILIATE.md). Coupon details only via `cdp-connect --show-deal` (never printed by default).
183
+
184
+ **FAQ:** [docs/FAQ.md](docs/FAQ.md) — Playwright connect_over_cdp, Multilogin Launcher, CDP health check.
185
+
186
+
187
+
188
+
189
+
190
+ ## Related tools (on PyPI)
191
+
192
+ | Package | CLI | Role |
193
+ |---------|-----|------|
194
+ | [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) | `cdp-probe` | CDP / WebDriver exposure score |
195
+ | [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) | `cookie-bridge` | Netscape ↔ Playwright cookies |
196
+ | [proxy-lane-checker](https://pypi.org/project/proxy-lane-checker/) | `proxy-lane` | Proxy TCP / HTTP / geo / DNSBL |
197
+ | [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) | `fp-coherence` | UA / screen / timezone lint |
198
+
199
+ **Toolkit pipeline:** `proxy-lane check` → `fp-coherence audit` → automate → `cdp-probe run` → `cookie-bridge validate`
200
+
201
+ ## License
202
+
203
+ MIT
204
+
205
+ ---
206
+
207
+ **Production antidetect:** [Multilogin X](https://multilogin.com/?ref=SAAS50) · Code `SAAS50` (-50% browser) · `MIN50` (-50% cloud phone)
208
+ More scripts: [@Multilogin_Scripts_Bot](https://t.me/Multilogin_Scripts_Bot) · [Coupons](https://anti-detect.github.io/)
@@ -0,0 +1,15 @@
1
+ """CDP connection toolkit with Playwright integration."""
2
+
3
+ from cdp_connect_kit.cdp.client import CdpClient, CdpError
4
+ from cdp_connect_kit.cdp.url import CdpEndpoint, parse_endpoint
5
+ from cdp_connect_kit.connect import ConnectMetrics, connect_playwright
6
+
7
+ __all__ = [
8
+ "CdpClient",
9
+ "CdpEndpoint",
10
+ "CdpError",
11
+ "ConnectMetrics",
12
+ "connect_playwright",
13
+ "parse_endpoint",
14
+ ]
15
+ __version__ = "0.3.1"
@@ -0,0 +1,14 @@
1
+ """CDP HTTP discovery."""
2
+
3
+ from cdp_connect_kit.cdp.client import CdpClient, CdpError
4
+ from cdp_connect_kit.cdp.models import BrowserInfo, HealthSnapshot
5
+ from cdp_connect_kit.cdp.url import CdpEndpoint, parse_endpoint
6
+
7
+ __all__ = [
8
+ "BrowserInfo",
9
+ "CdpClient",
10
+ "CdpEndpoint",
11
+ "CdpError",
12
+ "HealthSnapshot",
13
+ "parse_endpoint",
14
+ ]