mithwire-mcp 0.1.0__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.
- mithwire_mcp-0.1.0/LICENSE +21 -0
- mithwire_mcp-0.1.0/PKG-INFO +435 -0
- mithwire_mcp-0.1.0/README.md +421 -0
- mithwire_mcp-0.1.0/mithwire_mcp/__init__.py +5 -0
- mithwire_mcp-0.1.0/mithwire_mcp/__main__.py +4 -0
- mithwire_mcp-0.1.0/mithwire_mcp/actions.py +1395 -0
- mithwire_mcp-0.1.0/mithwire_mcp/browser.py +2192 -0
- mithwire_mcp-0.1.0/mithwire_mcp/cookies.py +34 -0
- mithwire_mcp-0.1.0/mithwire_mcp/dashboard/__init__.py +19 -0
- mithwire_mcp-0.1.0/mithwire_mcp/dashboard/app.py +196 -0
- mithwire_mcp-0.1.0/mithwire_mcp/dashboard/auth.py +108 -0
- mithwire_mcp-0.1.0/mithwire_mcp/dashboard/events.py +120 -0
- mithwire_mcp-0.1.0/mithwire_mcp/dashboard/routes.py +620 -0
- mithwire_mcp-0.1.0/mithwire_mcp/fingerprint.py +341 -0
- mithwire_mcp-0.1.0/mithwire_mcp/local_proxy.py +191 -0
- mithwire_mcp-0.1.0/mithwire_mcp/proxy.py +308 -0
- mithwire_mcp-0.1.0/mithwire_mcp/proxy_health.py +333 -0
- mithwire_mcp-0.1.0/mithwire_mcp/runtime.py +1497 -0
- mithwire_mcp-0.1.0/mithwire_mcp/server.py +1523 -0
- mithwire_mcp-0.1.0/mithwire_mcp/state_store.py +466 -0
- mithwire_mcp-0.1.0/mithwire_mcp.egg-info/PKG-INFO +435 -0
- mithwire_mcp-0.1.0/mithwire_mcp.egg-info/SOURCES.txt +38 -0
- mithwire_mcp-0.1.0/mithwire_mcp.egg-info/dependency_links.txt +1 -0
- mithwire_mcp-0.1.0/mithwire_mcp.egg-info/entry_points.txt +2 -0
- mithwire_mcp-0.1.0/mithwire_mcp.egg-info/requires.txt +3 -0
- mithwire_mcp-0.1.0/mithwire_mcp.egg-info/top_level.txt +1 -0
- mithwire_mcp-0.1.0/pyproject.toml +61 -0
- mithwire_mcp-0.1.0/setup.cfg +4 -0
- mithwire_mcp-0.1.0/tests/test_actions.py +693 -0
- mithwire_mcp-0.1.0/tests/test_align_timezone_retry.py +193 -0
- mithwire_mcp-0.1.0/tests/test_browser.py +197 -0
- mithwire_mcp-0.1.0/tests/test_dashboard_routes.py +267 -0
- mithwire_mcp-0.1.0/tests/test_fingerprint_application.py +341 -0
- mithwire_mcp-0.1.0/tests/test_fingerprint_consistency.py +280 -0
- mithwire_mcp-0.1.0/tests/test_proxy.py +250 -0
- mithwire_mcp-0.1.0/tests/test_proxy_health.py +358 -0
- mithwire_mcp-0.1.0/tests/test_runtime.py +364 -0
- mithwire_mcp-0.1.0/tests/test_runtime_proxy_preflight.py +652 -0
- mithwire_mcp-0.1.0/tests/test_server_parser.py +79 -0
- mithwire_mcp-0.1.0/tests/test_state_store.py +218 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
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,435 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mithwire-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP browser bridge that gives AI clients full access to a live browser environment.
|
|
5
|
+
Author: codeisalifestyle
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: mcp<2,>=1.26.0
|
|
11
|
+
Requires-Dist: mithwire<0.60,>=0.50
|
|
12
|
+
Requires-Dist: opencv-python<5,>=4.8
|
|
13
|
+
Dynamic: license-file
|
|
14
|
+
|
|
15
|
+
# mithwire-mcp
|
|
16
|
+
|
|
17
|
+
🚀 MCP server that gives AI clients full access to a live Chromium browser environment.
|
|
18
|
+
|
|
19
|
+
Your AI client launches fresh, isolated browser sessions — ephemeral by default, or backed by a persistent managed profile when you need a durable logged-in identity. It is built for autonomous automation, developer workflows, and production-style browser operations, powered by `mithwire`.
|
|
20
|
+
|
|
21
|
+
## Demo Video
|
|
22
|
+
|
|
23
|
+
[Watch demo video](https://gumlet.tv/watch/69c5aa1eb365493ac0849b50/)
|
|
24
|
+
|
|
25
|
+
## 🌟 Product Highlights
|
|
26
|
+
|
|
27
|
+
`mithwire-mcp` turns browser automation into a reliable MCP service your agents can trust in real workflows, not just demos.
|
|
28
|
+
|
|
29
|
+
### 🧠 Intelligent Chromium orchestration
|
|
30
|
+
|
|
31
|
+
- Launch fresh sessions instantly with `session_start` — always a brand-new, isolated browser process.
|
|
32
|
+
- One simple choice: ephemeral (default) or a persistent managed `profile`. No flaky attach/clone paths to reason about.
|
|
33
|
+
- Run with confidence using robust session lifecycle controls (`start`, `list`, `get`, `stop`, `stop_all`) and per-session action locking.
|
|
34
|
+
- Stay out of the user's way: the MCP never touches, attaches to, or tears down a browser it didn't spawn.
|
|
35
|
+
|
|
36
|
+
### 🤖 Built for autonomous agents and fast-moving teams
|
|
37
|
+
|
|
38
|
+
- Give agents deterministic control over navigate/query/click/type/wait/evaluate/screenshot flows.
|
|
39
|
+
- Ship faster with first-class support for E2E prototyping, scraping pipelines, regression checks, and interactive debugging.
|
|
40
|
+
- Get live operational visibility with console output, request metadata, and CDP-level network capture.
|
|
41
|
+
- Reduce flaky runs and shorten feedback loops across development and QA.
|
|
42
|
+
|
|
43
|
+
### 👤 Durable browser identity and session state
|
|
44
|
+
|
|
45
|
+
- Centralize reusable browser state under one roof: `profiles/` and `configs/`.
|
|
46
|
+
- A managed `profile` persists its own cookies and storage natively across runs — no separate cookie bookkeeping required.
|
|
47
|
+
- Fine-tune launch behavior with configurable browser flags, executable paths, headless/sandbox settings, and first-class proxy support (incl. authenticated HTTP/HTTPS proxies).
|
|
48
|
+
- Preserve realistic, persistent browser identity across sessions for multi-account and high-continuity automation.
|
|
49
|
+
|
|
50
|
+
### 🕵️ Stealth foundation with mithwire + CDP
|
|
51
|
+
|
|
52
|
+
- Powered by `mithwire`: a maintained no-WebDriver/no-Selenium Chromium automation runtime.
|
|
53
|
+
- Includes anti-bot oriented capabilities, including Cloudflare Turnstile solving through `browser_solve_cloudflare`.
|
|
54
|
+
- **Control the full identity**: IP (authenticated proxy via local relay), location (proxy-aligned timezone), language, and device profile (fingerprint spoofing) — kept internally consistent across workers and headers.
|
|
55
|
+
- **WebRTC leak protection** stops the host's real IP from leaking around the proxy.
|
|
56
|
+
- Built on direct CDP control for low-level precision, observability, and flexibility.
|
|
57
|
+
- Better suited for modern websites where reliability under anti-automation pressure matters.
|
|
58
|
+
|
|
59
|
+
## Quick Start (recommended)
|
|
60
|
+
|
|
61
|
+
### 1) Install prerequisites
|
|
62
|
+
|
|
63
|
+
- Python `>=3.10` (Python `3.14+` is supported with the latest `mithwire`)
|
|
64
|
+
- A Chromium-based browser installed (Chrome, Brave or Edge)
|
|
65
|
+
- Optional but recommended: `pipx` (for easy isolated CLI installs)
|
|
66
|
+
|
|
67
|
+
Install `pipx` (optional, recommended) on macOS:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
brew install pipx
|
|
71
|
+
pipx ensurepath
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Install `pipx` (optional, recommended) on Linux:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
python3 -m pip install --user pipx
|
|
78
|
+
python3 -m pipx ensurepath
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Install `pipx` (optional, recommended) on Windows (PowerShell):
|
|
82
|
+
|
|
83
|
+
```powershell
|
|
84
|
+
py -m pip install --user pipx
|
|
85
|
+
py -m pipx ensurepath
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 2) Install `mithwire-mcp`
|
|
89
|
+
|
|
90
|
+
Option A (recommended): install with `pipx`
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pipx install "git+https://github.com/codeisalifestyle/mithwire.git#subdirectory=packages/mithwire-mcp"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Option B (no `pipx`): install in a dedicated virtual environment
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
python3 -m venv ~/.venvs/mithwire-mcp
|
|
100
|
+
source ~/.venvs/mithwire-mcp/bin/activate
|
|
101
|
+
pip install "git+https://github.com/codeisalifestyle/mithwire.git#subdirectory=packages/mithwire-mcp"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
> **Note:** `mithwire-mcp` lives inside the [`mithwire`](https://github.com/codeisalifestyle/mithwire) monorepo as of v0.2. The install URL points at the `packages/mithwire-mcp` subdirectory of that repo.
|
|
105
|
+
|
|
106
|
+
Verify:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
mithwire-mcp --help
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 3) Add it to your MCP client
|
|
113
|
+
|
|
114
|
+
Most MCP-enabled clients accept a config shaped like this:
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"mcpServers": {
|
|
119
|
+
"mithwire-mcp": {
|
|
120
|
+
"command": "mithwire-mcp",
|
|
121
|
+
"args": ["--transport", "stdio"]
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
If your client cannot find the command, use an absolute path:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# macOS / Linux
|
|
131
|
+
which mithwire-mcp
|
|
132
|
+
|
|
133
|
+
# Windows (PowerShell)
|
|
134
|
+
where.exe mithwire-mcp
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Then set `"command"` to that full path.
|
|
138
|
+
|
|
139
|
+
If you used Option B, your command path is typically:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
~/.venvs/mithwire-mcp/bin/mithwire-mcp
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 4) First-use test in your AI client
|
|
146
|
+
|
|
147
|
+
After reloading/restarting your AI client, ask it:
|
|
148
|
+
|
|
149
|
+
1. "Call `session_start` with default settings."
|
|
150
|
+
2. "Call `browser_navigate` to `https://example.com`."
|
|
151
|
+
3. "Call `browser_snapshot`."
|
|
152
|
+
4. "Call `session_stop`."
|
|
153
|
+
|
|
154
|
+
If these succeed, installation is complete.
|
|
155
|
+
|
|
156
|
+
## Launching a session
|
|
157
|
+
|
|
158
|
+
The MCP **always spawns a brand-new, isolated browser process**. It never
|
|
159
|
+
attaches to, takes over, or shuts down a browser it didn't launch. There are no
|
|
160
|
+
"modes" to memorize — `session_start` has exactly two shapes:
|
|
161
|
+
|
|
162
|
+
| Goal | Call | What you get |
|
|
163
|
+
| --- | --- | --- |
|
|
164
|
+
| Throwaway browser (default) | `{}` | A fresh ephemeral browser with no saved state. Ideal for scraping and E2E. |
|
|
165
|
+
| Persistent identity | `{ "profile": "twitter_main" }` | A managed profile whose cookies/storage persist across runs. |
|
|
166
|
+
|
|
167
|
+
Everything else is an optional flag layered on top of those two:
|
|
168
|
+
|
|
169
|
+
| Option | Default | Purpose |
|
|
170
|
+
| --- | --- | --- |
|
|
171
|
+
| `headless` | `false` (headful) | Run without a visible window (e.g. CI). |
|
|
172
|
+
| `proxy` | none | Route traffic through an upstream proxy (see below). |
|
|
173
|
+
| `fingerprint` | none | Identity overrides — timezone, locale/languages, geo, user agent, platform, hardware, screen, WebGL (see below). |
|
|
174
|
+
| `webrtc_leak_protection` | `auto` | Guard WebRTC against real-IP leaks: `auto` / `filter` / `disable` / `off` (see below). |
|
|
175
|
+
| `start_url` | none | Navigate here right after launch. |
|
|
176
|
+
| `cookie_file` | none | One-shot injection of cookies from a JSON file at launch. |
|
|
177
|
+
| `sandbox` | `true` | Keep Chromium's sandbox on (recommended; `--no-sandbox` is easily bot-detected). |
|
|
178
|
+
| `launch_config` | `default` | Apply a saved set of launch settings. |
|
|
179
|
+
|
|
180
|
+
### Proxy support
|
|
181
|
+
|
|
182
|
+
`proxy` accepts several common spellings and normalizes them:
|
|
183
|
+
|
|
184
|
+
- `http://host:port` or `http://user:pass@host:port`
|
|
185
|
+
- the provider `scheme:host:port:user:pass` form
|
|
186
|
+
- `socks5://host:port`
|
|
187
|
+
- an object: `{ "server": "http://host:port", "username": "...", "password": "...", "rotation_url": "https://api.provider.com/rotate?token=..." }`
|
|
188
|
+
|
|
189
|
+
`rotation_url` is optional. It's a provider endpoint that rotates the upstream
|
|
190
|
+
exit IP when hit. The MCP stores it on the proxy object at launch; call
|
|
191
|
+
`session_rotate_proxy` to trigger a rotation — it hits the endpoint, waits a
|
|
192
|
+
short settle window, re-probes through the proxy to confirm the new egress,
|
|
193
|
+
and (by default) re-aligns the browser identity (timezone, locale, languages,
|
|
194
|
+
geolocation) to match. Any field you pinned via `fingerprint` at launch (or
|
|
195
|
+
`session_set_fingerprint` since) keeps winning over the proxy-derived default.
|
|
196
|
+
Rotation URLs frequently embed a secret token in their query string, so the
|
|
197
|
+
URL is **redacted** anywhere it appears in session metadata or logs (userinfo
|
|
198
|
+
and query are stripped to `?***`); the literal URL stays in-memory only.
|
|
199
|
+
|
|
200
|
+
Authenticated **HTTP/HTTPS** proxies are fully supported. Rather than answering
|
|
201
|
+
the proxy challenge per request over CDP (which floods the event loop and stalls
|
|
202
|
+
heavy page loads), the MCP starts a small **local authenticating relay**:
|
|
203
|
+
Chromium is pointed at `127.0.0.1`, and the relay injects the upstream
|
|
204
|
+
`Proxy-Authorization` header and pipes bytes through to the real proxy. The
|
|
205
|
+
browser never sees a `407`. Unauthenticated HTTP/HTTPS and SOCKS proxies go
|
|
206
|
+
straight to `--proxy-server`. Authenticated **SOCKS** is rejected up front
|
|
207
|
+
(Chromium's `--proxy-server` can't carry SOCKS credentials) — use the provider's
|
|
208
|
+
HTTP/HTTPS endpoint instead.
|
|
209
|
+
|
|
210
|
+
**Pre-launch proxy health check.** A session that asks for a proxy is **refused
|
|
211
|
+
before any browser is spawned** if that proxy is unreachable or rejects the
|
|
212
|
+
credentials. The MCP issues a single absolute-form `GET http://api.ipapi.is/`
|
|
213
|
+
to the proxy (with `Proxy-Authorization` when present) and only proceeds on a
|
|
214
|
+
clean 2xx with parseable JSON. There is **no fallback to the host's direct
|
|
215
|
+
connection** — that would silently leak the real IP into login flows and
|
|
216
|
+
cross-contaminate any persistent profile. A bad proxy fails fast with an
|
|
217
|
+
actionable error (timeout / refused TCP / `HTTP 407` etc.); the browser process
|
|
218
|
+
is never started.
|
|
219
|
+
|
|
220
|
+
**Identity defaults aligned to the proxy egress.** The same probe doubles as
|
|
221
|
+
the egress lookup: when a proxy is set, the session defaults its identity —
|
|
222
|
+
**timezone, locale, languages, Accept-Language, and geolocation** — to the
|
|
223
|
+
proxy's egress IP so the two never disagree. Anything explicitly set in
|
|
224
|
+
`fingerprint={...}` or in the profile's `launch_overrides` wins over the
|
|
225
|
+
proxy-derived default, so profiles can pin a stable identity (e.g. a fixed
|
|
226
|
+
language) and still use rotating proxies. SOCKS proxies get a TCP-only
|
|
227
|
+
liveness check, with timezone alignment falling back to the in-browser
|
|
228
|
+
ipapi.is lookup (no auto-derived language for SOCKS). The detected egress
|
|
229
|
+
(`ip`, `timezone`, `city`, `country`, `country_code`) is recorded in the
|
|
230
|
+
session metadata under `proxy_exit`.
|
|
231
|
+
|
|
232
|
+
### Fingerprint / identity spoofing
|
|
233
|
+
|
|
234
|
+
Pass a `fingerprint` object to `session_start` (or apply one to a live session
|
|
235
|
+
with `session_set_fingerprint`) to control the identity the browser presents.
|
|
236
|
+
All fields are optional; anything unset is left untouched:
|
|
237
|
+
|
|
238
|
+
- `timezone_id`, `locale`, `languages`, `accept_language`
|
|
239
|
+
- `latitude`, `longitude`, `geo_accuracy`
|
|
240
|
+
- `user_agent`, `platform`, `hardware_concurrency`, `device_memory` (GB)
|
|
241
|
+
- `screen` — `width`, `height`, `device_scale_factor`, `mobile`, `max_touch_points`
|
|
242
|
+
- `webgl_vendor`, `webgl_renderer`
|
|
243
|
+
|
|
244
|
+
Overrides are applied at the **engine level via CDP `Emulation.*` wherever
|
|
245
|
+
Chromium supports it**, so they propagate to Web Workers and HTTP request
|
|
246
|
+
headers — not just the main document — keeping every signal internally
|
|
247
|
+
consistent (a mismatched override is worse than none). The handful of properties
|
|
248
|
+
with no CDP equivalent (`navigator.deviceMemory`, and the WebGL strings when
|
|
249
|
+
requested) fall back to injected JS.
|
|
250
|
+
|
|
251
|
+
Two consistency rules matter: keep overrides **same-OS-family** (don't claim a
|
|
252
|
+
Windows UA on a macOS host), and if you spoof geo/timezone, **back it with a
|
|
253
|
+
matching proxy** so the egress IP agrees.
|
|
254
|
+
|
|
255
|
+
### WebRTC leak protection
|
|
256
|
+
|
|
257
|
+
WebRTC can open a STUN connection that reveals the host's real local and public
|
|
258
|
+
IPs directly, **bypassing the proxy entirely** (UDP isn't proxied) — the single
|
|
259
|
+
biggest de-anonymization leak for a proxied browser. The `webrtc_leak_protection`
|
|
260
|
+
option controls the guard:
|
|
261
|
+
|
|
262
|
+
| Mode | Behavior |
|
|
263
|
+
| --- | --- |
|
|
264
|
+
| `auto` (default) | Filter leaky ICE candidates when a proxy is set; otherwise leave WebRTC intact. |
|
|
265
|
+
| `filter` | Always drop public, non-egress ICE candidates and scrub SDP. |
|
|
266
|
+
| `disable` | Remove `RTCPeerConnection` entirely (no WebRTC at all). |
|
|
267
|
+
| `off` | No protection (real IP can leak). |
|
|
268
|
+
|
|
269
|
+
### Verifying stealth
|
|
270
|
+
|
|
271
|
+
`scripts/verify_mcp.py` launches a real session (the same `BridgeBrowser` path the
|
|
272
|
+
MCP uses) against public bot-detection services and asserts the critical signals
|
|
273
|
+
are clean — useful as a regression check after touching launch/stealth/proxy code:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
python3 scripts/verify_mcp.py --headless # deviceinfo + fingerprint
|
|
277
|
+
python3 scripts/verify_mcp.py --site deviceinfo
|
|
278
|
+
python3 scripts/verify_mcp.py --proxy "http://user:pass@host:port" # also checks TZ alignment
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Cookies
|
|
282
|
+
|
|
283
|
+
A managed `profile` stores its cookies in Chromium's native cookie store, so
|
|
284
|
+
they persist automatically — there is nothing extra to manage. The only
|
|
285
|
+
separate cookie operations are **injection** (`cookie_file` at launch, or
|
|
286
|
+
`browser_cookies_set` at runtime) and **export** (`browser_cookies_get` /
|
|
287
|
+
`browser_cookies_save`).
|
|
288
|
+
|
|
289
|
+
## Centralized browser state store
|
|
290
|
+
|
|
291
|
+
`mithwire-mcp` now keeps reusable browser state in one place:
|
|
292
|
+
|
|
293
|
+
- Default root: `~/.mithwire-mcp`
|
|
294
|
+
- Override with env var: `MITHWIRE_MCP_HOME=/custom/path`
|
|
295
|
+
- Override per server run: `mithwire-mcp --state-root /custom/path`
|
|
296
|
+
|
|
297
|
+
Within that root:
|
|
298
|
+
|
|
299
|
+
- `profiles/` stores persistent Chromium profile directories (user data dirs)
|
|
300
|
+
- `configs/` stores launch configs used by `session_start`
|
|
301
|
+
|
|
302
|
+
`session_start` supports optional `profile` and `launch_config` inputs.
|
|
303
|
+
It resolves launch settings in this order:
|
|
304
|
+
|
|
305
|
+
1. Built-in defaults
|
|
306
|
+
2. Saved default launch config (`configs/default.json`)
|
|
307
|
+
3. Profile-linked launch config (if profile defines one)
|
|
308
|
+
4. Selected `launch_config` (if provided)
|
|
309
|
+
5. Profile `launch_overrides`
|
|
310
|
+
6. Explicit `session_start` arguments
|
|
311
|
+
|
|
312
|
+
This lets your AI client map account-oriented tasks to stable browser identities (profile + cookies + launch settings) without repeatedly passing raw paths.
|
|
313
|
+
|
|
314
|
+
## Development setup
|
|
315
|
+
|
|
316
|
+
`mithwire-mcp` is developed inside the [`mithwire`](https://github.com/codeisalifestyle/mithwire) `uv` workspace, so the engine and the MCP can be edited together with no pin-bumping.
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
git clone https://github.com/codeisalifestyle/mithwire.git
|
|
320
|
+
cd mithwire
|
|
321
|
+
uv sync # creates .venv at repo root, installs both packages editable
|
|
322
|
+
uv run pytest packages/mithwire-mcp/tests -q
|
|
323
|
+
uv run mithwire-mcp --transport stdio
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Client config for this mode:
|
|
327
|
+
|
|
328
|
+
```json
|
|
329
|
+
{
|
|
330
|
+
"mcpServers": {
|
|
331
|
+
"mithwire-mcp": {
|
|
332
|
+
"command": "/absolute/path/to/mithwire-mcp",
|
|
333
|
+
"args": ["--transport", "stdio"]
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Core tools exposed
|
|
340
|
+
|
|
341
|
+
### Session lifecycle
|
|
342
|
+
|
|
343
|
+
- `session_start`
|
|
344
|
+
- `session_list`
|
|
345
|
+
- `session_get`
|
|
346
|
+
- `session_state_paths`
|
|
347
|
+
- `session_profile_list`
|
|
348
|
+
- `session_profile_get`
|
|
349
|
+
- `session_profile_set`
|
|
350
|
+
- `session_profile_delete`
|
|
351
|
+
- `session_launch_config_list`
|
|
352
|
+
- `session_launch_config_get`
|
|
353
|
+
- `session_launch_config_set`
|
|
354
|
+
- `session_launch_config_delete`
|
|
355
|
+
- `session_set_fingerprint`
|
|
356
|
+
- `session_rotate_proxy`
|
|
357
|
+
- `session_set_policy`
|
|
358
|
+
- `session_get_policy`
|
|
359
|
+
- `session_set_download_dir`
|
|
360
|
+
- `session_trace_start`
|
|
361
|
+
- `session_trace_stop`
|
|
362
|
+
- `session_trace_get`
|
|
363
|
+
- `session_trace_export`
|
|
364
|
+
- `session_trace_replay`
|
|
365
|
+
- `session_stop`
|
|
366
|
+
- `session_stop_all`
|
|
367
|
+
|
|
368
|
+
### Browser actions
|
|
369
|
+
|
|
370
|
+
- `browser_url`
|
|
371
|
+
- `browser_navigate`
|
|
372
|
+
- `browser_back`
|
|
373
|
+
- `browser_forward`
|
|
374
|
+
- `browser_reload`
|
|
375
|
+
- `browser_tab_list`
|
|
376
|
+
- `browser_tab_new`
|
|
377
|
+
- `browser_tab_switch`
|
|
378
|
+
- `browser_tab_close`
|
|
379
|
+
- `browser_tab_current`
|
|
380
|
+
- `browser_snapshot`
|
|
381
|
+
- `browser_query`
|
|
382
|
+
- `browser_click`
|
|
383
|
+
- `browser_type`
|
|
384
|
+
- `browser_handle_dialog`
|
|
385
|
+
- `browser_set_file_input`
|
|
386
|
+
- `browser_scroll`
|
|
387
|
+
- `browser_wait`
|
|
388
|
+
- `browser_wait_for_selector`
|
|
389
|
+
- `browser_wait_for_url`
|
|
390
|
+
- `browser_wait_for_text`
|
|
391
|
+
- `browser_wait_for_function`
|
|
392
|
+
- `browser_wait_for_network_idle`
|
|
393
|
+
- `browser_html`
|
|
394
|
+
- `browser_console_messages`
|
|
395
|
+
- `browser_network_requests`
|
|
396
|
+
- `browser_network_capture_start`
|
|
397
|
+
- `browser_network_capture_get`
|
|
398
|
+
- `browser_network_capture_stop`
|
|
399
|
+
- `browser_network_capture_status`
|
|
400
|
+
- `browser_downloads`
|
|
401
|
+
- `browser_cookies_get`
|
|
402
|
+
- `browser_cookies_set`
|
|
403
|
+
- `browser_cookies_save`
|
|
404
|
+
- `browser_cookies_clear`
|
|
405
|
+
- `browser_storage_get`
|
|
406
|
+
- `browser_storage_set`
|
|
407
|
+
- `browser_storage_clear`
|
|
408
|
+
- `browser_take_screenshot`
|
|
409
|
+
- `browser_evaluate`
|
|
410
|
+
- `browser_solve_cloudflare`
|
|
411
|
+
|
|
412
|
+
## Project docs
|
|
413
|
+
|
|
414
|
+
- Architecture: `docs/architecture.md`
|
|
415
|
+
|
|
416
|
+
## Troubleshooting
|
|
417
|
+
|
|
418
|
+
- **"command not found: mithwire-mcp"**
|
|
419
|
+
- Run `pipx ensurepath`, restart terminal and AI client, then retry.
|
|
420
|
+
- Use absolute command path from `which mithwire-mcp`.
|
|
421
|
+
- **Python version mismatch**
|
|
422
|
+
- Use a supported Python (`>=3.10`) and reinstall/upgrade the package in your MCP environment.
|
|
423
|
+
- **Browser fails to launch in restricted environments**
|
|
424
|
+
- Try `session_start` with `sandbox=false`.
|
|
425
|
+
- **MCP client does not show tools**
|
|
426
|
+
- Confirm JSON syntax is valid.
|
|
427
|
+
- Confirm transport is `stdio`.
|
|
428
|
+
- Fully restart the AI client after editing MCP config.
|
|
429
|
+
|
|
430
|
+
## Safety notes
|
|
431
|
+
|
|
432
|
+
- Use this only on sites and accounts where you are authorized.
|
|
433
|
+
- Respect website Terms of Service and local regulations.
|
|
434
|
+
- Be cautious with high-frequency automation.
|
|
435
|
+
|