---
name: google-flights
description: Search for flights on Google Flights using camoufox (anti-detection browser) and the residential proxy. Returns structured results with airline, times, duration, stops, and price. Use this skill whenever the user wants to find, compare, or research flights — one-way or return, any route, any date.
---

# Google Flights Skill

Searches Google Flights using **camoufox** (anti-fingerprint Firefox) and the
tenant's **residential proxy**. Fills the search form programmatically and
extracts structured flight results.

---

## Quick reference

```bash
# One-way flight
python3 /home/node/.claude/skills/google-flights/scripts/search.py \
  --origin LGW --destination PMI --date 2026-04-24

# Return flight
python3 /home/node/.claude/skills/google-flights/scripts/search.py \
  --origin LHR --destination JFK --date 2026-05-10 \
  --trip-type return --return-date 2026-05-20

# With passengers and cabin class
python3 /home/node/.claude/skills/google-flights/scripts/search.py \
  --origin LHR --destination DXB --date 2026-06-01 \
  --adults 2 --cabin business

# Return with children and infant
python3 /home/node/.claude/skills/google-flights/scripts/search.py \
  --origin LGW --destination TRD --date 2026-05-25 \
  --trip-type return --return-date 2026-05-28 \
  --adults 2 --children 1 --infants-on-lap 1
```

---

## Parameters

| Flag | Required | Default | Description |
|------|----------|---------|-------------|
| `--origin` | Yes | — | Origin airport IATA code (e.g. `LGW`, `LHR`, `JFK`) |
| `--destination` | Yes | — | Destination IATA code (e.g. `PMI`, `CDG`, `DXB`) |
| `--date` | Yes | — | Departure date in `YYYY-MM-DD` format |
| `--trip-type` | No | `one-way` | `one-way` or `return` |
| `--return-date` | No | — | Return date `YYYY-MM-DD` (required when `--trip-type return`) |
| `--adults` | No | `1` | Number of adult passengers |
| `--children` | No | `0` | Children age 2–11 (own seat) |
| `--infants-in-seat` | No | `0` | Infants with their own seat |
| `--infants-on-lap` | No | `0` | Lap infants age 0–1 |
| `--passengers` | No | — | Legacy alias for `--adults` |
| `--cabin` | No | `economy` | `economy`, `premium_economy`, `business`, or `first` |

---

## Output

Results are printed as a JSON array to stdout. Each entry contains whatever
fields Google Flights surfaces for that card:

```json
[
  {
    "airline": "easyJet",
    "times": "06:30 – 10:05",
    "duration": "2 hr 35 min",
    "stops": "Nonstop",
    "price": "£89",
    "raw": "..."
  },
  ...
]
```

The `raw` field always contains the full text of the card, useful when
structured parsing misses a field.

---

## Debugging

Screenshots are saved at each step:

| File | Content |
|------|---------|
| `/tmp/google-flights-1-load.png` | Page after initial load |
| `/tmp/google-flights-2-airports.png` | After filling origin/destination |
| `/tmp/google-flights-3-dates.png` | After filling dates |
| `/tmp/google-flights-4-results.png` | Full results page |

If results are empty or wrong, read the screenshots to diagnose what went wrong.

---

## Prerequisites

- **Residential proxy** must be active: run `tc proxy` — should return a `socks5://` URL
- **camoufox** is pre-installed in the container image at `/opt/camoufox` — no setup needed

---

## Usage in a script

```python
import subprocess, json, sys

result = subprocess.run([
    "python3",
    "/home/node/.claude/skills/google-flights/scripts/search.py",
    "--origin", "LGW",
    "--destination", "PMI",
    "--date", "2026-04-24",
], capture_output=True, text=True)

flights = json.loads(result.stdout)
for f in flights:
    print(f.get("airline"), f.get("times"), f.get("price"))
```

---

## Notes

- Results are displayed in GBP by default (`curr=GBP`, `gl=GB`). Adjust the URL
  in the script if a different currency/locale is needed.
- Google Flights form selectors can change — if results stop working, check the
  screenshots and update the CSS selectors in `search.py`.
- For the same route searched repeatedly, you can also try the direct `tfs=`
  URL encoding approach (like in `flights_search.py`) which bypasses form filling
  entirely and is more reliable for fixed routes.
