Skip to main content
Glama
README.md
# HotspotSniffer MCP

**Service-level iPhone app traffic capture on Windows, exposed as an MCP server and a CLI.**

HotspotSniffer turns a Windows laptop into a controlled Wi-Fi hotspot for an iPhone, combines passive packet capture with an HTTPS interception proxy, and stores one record per app service or submenu in SQLite. An MCP client can drive the workflow: confirm the app, start a service record, wait for the user to finish the operation, stop the record, generate a focused report and read the result.

> **Authorized use only.** Use this only with devices and accounts you own or are explicitly authorized to inspect. The hotspot is a real network and the local CA can impersonate HTTPS sites for devices that trust it. Read [SECURITY.md](SECURITY.md) before installing the CA.

[中文快速开始](README.zh-CN.md) · [MCP server guide](docs/MCP.md) · [Security](SECURITY.md)

---

## Why two capture channels

| Channel | What it gives you | Works with |
|---|---|---|
| Passive (`dumpcap` + `tshark`) | DNS, TLS SNI, ALPN, destination IP/port, QUIC Initial, cleartext HTTP, CONNECT targets | Every app, including apps that pin certificates |
| Active (`mitmproxy`) | Full URL, method, status code, MIME type, timing | Apps that honor the system proxy and trust the user CA |

The passive channel answers "which real domains/IPs does this app contact?" even when the app rejects the proxy certificate. The active channel adds complete request paths when the app accepts the CA. Both channels write into `data/hsniff.db`.

## Features

- Windows Mobile Hotspot + iPhone system HTTP proxy, no jailbreak.
- One SQLite record per app service/submenu, with `app_name`, `parent_service`, `service_name`, `run_no`, `focus_domains`.
- `focus_domains` isolates target domains from phone background traffic in reports and MCP responses.
- Markdown report per record plus a JSON summary (`session_summaries`).
- MCP tools, resources and prompts for agent-driven capture and review.
- The CLI and the MCP server share the same storage and analysis code.
- Request bodies, cookies, passwords and photo content are **not** stored.

## Architecture

```text
iPhone ──Wi-Fi──> Windows Mobile Hotspot (192.168.137.1)
                     │
                     ├─ dumpcap on the Wi-Fi Direct adapter ──> tshark ──> SQLite
                     │       DNS / SNI / QUIC / CONNECT
                     │
                     └─ mitmproxy :8080 ──> SQLite (full URLs)
                             │
                             └─ CA page :8081 ──> iPhone installs/trusts CA

Agent / MCP client ──stdio──> hotspot_sniffer_mcp.server
                                 │
                                 └─ hsniff_lib ──> SQLite + reports + CLI
```

## Requirements

- **Windows 11** (the hotspot, Npcap and PowerShell orchestration are Windows-only).
- A Wi-Fi adapter that supports Windows Mobile Hotspot (most Intel/Qualcomm laptop cards).
- [Wireshark](https://www.wireshark.org/) 4.x with **Npcap**. The free Npcap installer requires its GUI wizard; silent install is an Npcap OEM feature.
- Python **3.12+**.
- iPhone with the HotspotSniffer CA installed and fully trusted.
- Administrator approval once for starting the hotspot and adding the firewall rule.

## Install from source

```powershell
git clone https://github.com/haohaoo3o/HotspotSniffer.git
cd HotspotSniffer
py -3.12 -m venv .venv
.venv\Scripts\Activate.ps1
pip install -e ".[dev]"
copy config.example.json config.json
notepad config.json      # set a strong hotspot passphrase
python hsniff.py init
```

`pip install -e .` installs the MCP SDK (`mcp[cli]`) and mitmproxy. Wireshark and
Npcap are external Windows applications and must be installed separately.

> Replace the sample passphrase. Do not commit `config.json`, `data/`,
> `captures/`, `reports/`, `proxy_cert/` or date-prefixed capture reports.

## One-time host setup

```powershell
python hsniff.py up
```

- Requests UAC once for the hotspot/firewall and starts `dumpcap`.
- Starts mitmproxy on `0.0.0.0:8080` and the CA download page on `0.0.0.0:8081`.
- Prints the hotspot SSID and proxy/cert URLs.
- The hotspot passphrase is read from `config.json`.

If you only need to restart the capture after a reboot, `python hsniff.py up`
again (one UAC). `python hsniff.py down` stops capture/proxy/hotspot.

## iPhone setup

1. Connect to the hotspot SSID from `config.json`.
2. Wi-Fi → current network → Configure Proxy → **Manual**:
   - Server `192.168.137.1`
   - Port `8080`
   - Authentication off
3. Safari → `http://192.168.137.1:8081/` → install the profile.
4. Settings → General → VPN & Device Management → install **HotspotSniffer CA**.
5. Settings → General → About → **Certificate Trust Settings** → enable full trust.
6. For cleaner measurements, turn off **Limit IP Address Tracking** and
   **iCloud Private Relay** for this network.

Verify with `python hsniff.py status`: hotspot `On`, capture running, proxy and
cert page listening. A test HTTPS site should now produce `http_request` events.

## CLI workflow

```powershell
# 1. Remember the app
python hsniff.py app set --name "MyApp"

# 2. Start one service / submenu
python hsniff.py service start --parent "Dashboard" --name "Orders" --focus "example.edu.cn"

# 3. Operate the service on the iPhone and wait until it finishes

# 4. Stop, parse, report, summarize (waits 10–20s for pcap rotation)
python hsniff.py service stop

# 5. Review
python hsniff.py service list
python hsniff.py analyze --session last
python hsniff.py export --session last --out reports\orders.csv
```

- `--parent` creates a `Parent > Submenu` hierarchy.
- `--focus` is a comma-separated list of domain suffixes; the report gets a
  "Target domains" section that excludes phone background traffic.
- Repeating the same app/service increments `run_no` (1st, 2nd, …).
- A record is stored in SQLite even if the report generation is interrupted;
  call `python hsniff.py analyze --session <id>` to regenerate.

## MCP server

The MCP server uses the official Python SDK v2 (`MCPServer`) over stdio.

```powershell
# Development / inspector
.venv\Scripts\mcp.exe dev hotspot_sniffer_mcp/server.py

# Or run stdio directly
.venv\Scripts\python.exe -m hotspot_sniffer_mcp.server
```

Client configuration (Claude Desktop, Cursor, Qoder or any MCP client):

```json
{
  "mcpServers": {
    "hotspot-sniffer": {
      "command": "C:\\path\\to\\HotspotSniffer\\.venv\\Scripts\\python.exe",
      "args": ["-m", "hotspot_sniffer_mcp.server"],
      "env": {
        "HSNIFF_ROOT": "C:\\path\\to\\HotspotSniffer"
      }
    }
  }
}
```

`HSNIFF_ROOT` tells the server where `schema.sql`, `scripts/` and `config.json`
live when it is not started from the checkout. The MCP server does not start the
hotspot; start the host environment once with `hsniff up`.

### MCP tools

| Tool | Purpose |
|---|---|
| `get_status` | Hotspot, capture, proxy, current app, open record |
| `set_app` | Confirm and remember the target app |
| `start_service` | Start a service/submenu record (`parent`, `focus`, `note`) |
| `stop_service` | Stop, parse, report and summarize the open record |
| `list_services` | List service records |
| `get_service_summary` | Read the stored summary JSON |
| `analyze_service` | Regenerate a report by session id or time window |
| `get_events` | Read event metadata with query strings stripped |
| `parse_capture` | Incrementally parse new pcap files |
| `start_proxy` / `stop_proxy` / `get_proxy_status` | Manage mitmproxy and the CA page |
| `list_apps` | List apps with records |

Resources: `hsniff://status`, `hsniff://services`,
`hsniff://service/{id}/summary`, `hsniff://service/{id}/report`,
`hsniff://schema`.

Prompts: `capture_service_workflow`, `analyze_capture`.

### Agent skill

`skills/hotspot-sniffer/SKILL.md` packages the same workflow for MCP-capable
agents. Copy the folder into your agent's skills directory; it uses the
`hotspot-sniffer` MCP server and does not require any extra code.

See [docs/MCP.md](docs/MCP.md) for the full client setup, agent workflow and safety
notes.

## Data model

| Table / view | Contents |
|---|---|
| `sessions` | One row per service/submenu; app, parent, service, run number, focus, times, status |
| `events` | DNS, TLS ClientHello, TCP connects, QUIC Initial, CONNECT, HTTP requests/responses, proxy/TLS errors |
| `session_summaries` | Counts, top/focus data, report path, full summary JSON |
| `capture_files` | Per-pcap parse state |
| `v_service_runs` | Joined view for review |
| `v_hosts`, `v_http_endpoints`, `v_direct_ips` | Convenience views |

Example:

```sql
SELECT session_id, app_name, parent_service, service_name, run_no,
       duration_s, hosts_count, endpoints_count, mitm_http, report_path
FROM v_service_runs ORDER BY started_at DESC;
```

## Security and privacy

- Authorized devices/accounts only. Installing a CA on someone else's phone is
  not acceptable without explicit consent.
- The CA private key (`proxy_cert/.mitm/mitmproxy-ca.pem`) can impersonate any
  site to a trusting device. Never commit or share it.
- Request bodies, cookies, passwords, tokens and photo bytes are not stored.
  MCP `get_events` strips URL query strings.
- Reports and SQLite still contain hostnames and internal paths. Clean runtime
  data before sharing a checkout.
- Use a strong hotspot passphrase and stop the hotspot after capture.
- Use GitHub Security Advisories for vulnerability reports.

## Limitations

- IPv4 only: Windows ICS does not provide IPv6 to hotspot clients by default.
- Pinned Apple/system services reject the user CA; passive SNI/IP is still
  recorded, but HTTPS content is not decrypted.
- HTTP/3/QUIC is not proxied by mitmproxy; passive Initial/SNI only.
- A page opening is not the same as an action submission. A "page shell" record
  may not contain the final submit API (e.g., loss report, password change,
  photo upload); the report labels what was actually observed.
- Phone background traffic (health, wearable, push, OS services) can appear in a
  record. Use `focus` to isolate the target and read the full report for evidence.
- The free Npcap installer is interactive; automation cannot fully silently
  install the driver.

## Development

```powershell
ruff check .
pytest -q
```

Python tests cover the SQLite session/summary layer and do not need Wireshark,
Npcap or an iPhone. Live integration testing is manual on Windows; include what
you tested in the pull request. See [CONTRIBUTING.md](CONTRIBUTING.md).

## License

MIT. See [LICENSE](LICENSE).