# wirecrab
Agent-first CLI network analysis platform.
## Build
```bash
cargo build
```
## Key Commands
Create/list/delete sessions:
```bash
wirecrab sessions create
wirecrab sessions list
wirecrab sessions delete --id <session-id>
```
Start/stop live capture:
```bash
wirecrab capture start --iface en0 --session <session-id>
wirecrab capture stop --session <session-id>
```
Run SQL queries:
```bash
wirecrab query --session <session-id> --sql "SELECT ts_sec, src_ip, dst_ip, l4_proto FROM packets LIMIT 25" --format json
```
Save and run parameterized saved queries (`{{param_name}}` placeholders):
```bash
wirecrab query-save --session <session-id> --name top_tcp --sql "SELECT COUNT(*) AS n FROM packets WHERE l4_proto = {{proto}}"
wirecrab query-run-saved --session <session-id> --name top_tcp --param proto=tcp --format json
```
Export filtered packets to PCAP:
```bash
wirecrab export pcap --session <session-id> --out /tmp/out.pcap --where "l4_proto = 'tcp'"
wirecrab export pcap --session <session-id> --out /tmp/out.pcap --filter "l4_proto = 'tcp' AND dst_port IN (80,443)"
```
Inject packets from spec:
```bash
wirecrab inject --session <session-id> --iface en0 --spec inject.yaml
```
Run probe script:
```bash
wirecrab probe run --session <session-id> --script probe.yaml
```
Ingest/replay PCAP:
```bash
wirecrab ingest pcap --session <session-id> --in /tmp/input.pcap --iface-label pcap0
wirecrab replay pcap --session <session-id> --in /tmp/input.pcap --iface en0 --speed max --loop 1
```
Tail normalized event stream:
```bash
wirecrab events tail --session <session-id> --cursor latest --kind packet,dns,http,ops --batch 500 --wait-ms 1000 --format jsonl
```
Retention and maintenance:
```bash
wirecrab retention set --session <session-id> --max-packets 200000 --ttl-sec 86400
wirecrab retention run --session <session-id>
wirecrab db vacuum --session <session-id>
```
Start MCP compatibility endpoint:
```bash
wirecrab mcp serve --host 127.0.0.1 --port 8787
```
The MCP endpoint speaks newline-delimited JSON-RPC 2.0 over TCP and supports:
`initialize`, `ping`, `tools/list`, `tools/call`.
Inspect schema and environment:
```bash
wirecrab schema --session <session-id>
wirecrab doctor
```
## SQL Contract v1
Wirecrab is decision-neutral: it exposes facts for agents via SQL.
Canonical entities:
- `v1_sessions`
- `v1_packets`
- `v1_flows`
- `v1_dns_queries`
- `v1_http_requests`
- `v1_service_discovery`
- `v1_stun_events`
- `v1_endpoint_ownership`
- `v1_snapshots`
- `v1_snapshot_protocol_mix`
- `v1_snapshot_top_endpoints`
- `v1_snapshot_top_flows`
- `v1_snapshot_discovery`
- `v1_snapshot_dns_top_qnames`
- `v1_snapshot_protocol_diff`
- `v1_snapshot_endpoint_diff`
- `v1_snapshot_flow_diff`
- `v1_events`
- `v1_events_enriched`
- `v1_tls_handshakes`
- `v1_quic_handshakes`
- `v1_protocol_fingerprints`
- `v1_saved_queries`
- `v1_retention_policy`
- `v1_streams`
- `v1_stream_http_requests`
- `v1_plugins_registry`
- `v1_stream_buffers`
- `v1_ipv4_fragments`
SQL functions:
- `v1_snapshot_create(label)` -> `snapshot_id`
- `v1_snapshot_create(label, start_sec, end_sec)` -> `snapshot_id`
- `v1_snapshot_delete(snapshot_id)` -> `rows_deleted`
- `v1_enrich_ip(ip)` -> `1` if updated/inserted, `0` if cache still fresh
Examples:
```bash
wirecrab query --session <session-id> --sql \
"SELECT * FROM v1_flows ORDER BY byte_count DESC LIMIT 20" --format json
wirecrab query --session <session-id> --sql \
"SELECT v1_snapshot_create('baseline', NULL, NULL) AS snapshot_id" --format json
wirecrab query --session <session-id> --sql \
"SELECT v1_enrich_ip('2607:6bc0::10')" --format json
```
## Inject Spec (YAML)
```yaml
iface: en0
payload_hex: "ffffffffffff0011223344550800450000280001000040060000c0a80101c0a8010204d2005000000000000000005002200000000000"
count: 1
interval_ms: 100
```
You can use `payload_base64` instead of `payload_hex`.
## Probe Script (YAML)
```yaml
iface: en0
steps:
- type: inject
payload_hex: "ffffffffffff0011223344550800450000280001000040060000c0a80101c0a8010204d2005000000000000000005002200000000000"
count: 1
- type: sleep
ms: 500
- type: query
sql: "SELECT count(*) AS n FROM packets"
```
## Notes
- Live capture and packet injection require OS-level capture permissions.
- Session data is stored in `~/.wirecrab/sessions/<session-id>/session.db`.
- Query output formats: `json`, `jsonl`, `csv`, `human`.
- `events tail` streams normalized facts for agents with cursor-based resume.
- Plugin manifests can be placed in `~/.wirecrab/plugins/*.json` and matching packets emit `kind='plugin'` events.