Metadata-Version: 2.4
Name: flight-recon-mcp
Version: 0.1.1
Summary: Flight reconnaissance MCP server: search, price calendar, layover scoring, carbon emissions, weighted optimal-path ranking. Pluggable providers (SerpApi + RapidAPI Sky-Scrapper) with automatic monthly-quota fallback.
Project-URL: Homepage, https://pypi.org/project/flight-recon-mcp/
Project-URL: Issues, https://pypi.org/project/flight-recon-mcp/
Author: flight-recon-mcp
License: MIT
License-File: LICENSE
Keywords: claude,flights,mcp,model-context-protocol,rapidapi,skyscanner,travel
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp>=1.2.0
Requires-Dist: pydantic>=2.6.0
Requires-Dist: python-dotenv>=1.0.1
Requires-Dist: tenacity>=8.2.3
Provides-Extra: dev
Requires-Dist: build>=1.2.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Requires-Dist: twine>=5.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# flights-mcp

A **flight-reconnaissance MCP server** with one provider, one key, no KYC.

- Search flights with full pricing, every segment, every carrier, every layover
- Per-day price calendar (cheapest dates)
- Layover-quality scoring (connection-time risk, terminal change, overnight, airport reputation)
- Weighted multi-criteria ranking → "find the optimal flight path"
- Airport autocomplete

## The one API you need

| Provider              | Free tier             | Signup                                           |
| --------------------- | --------------------- | ------------------------------------------------ |
| RapidAPI Sky-Scrapper | 100 requests / month  | https://rapidapi.com/apiheya/api/sky-scrapper    |

Steps:
1. Sign up at https://rapidapi.com/auth/sign-up (just email).
2. Visit https://rapidapi.com/apiheya/api/sky-scrapper and click **Subscribe to Test**.
3. Pick the **Basic (Free)** plan — no card required.
4. Copy `X-RapidAPI-Key` from the code-snippets panel.

## Quick start

```powershell
git clone <repo> flights-mcp
cd flights-mcp
python -m venv .venv
.venv\Scripts\activate
pip install -e .
copy .env.example .env
# open .env and paste your RAPIDAPI_KEY
python -m flights_mcp                       # stdio MCP server
```

## Wire it into your MCP client

### Claude Desktop
Edit `claude_desktop_config.json` (macOS: `~/Library/Application Support/Claude/`;
Windows: `%APPDATA%\Claude\`):

```json
{
  "mcpServers": {
    "flights": {
      "command": "python",
      "args": ["-m", "flights_mcp"],
      "env": {
        "PYTHONPATH": "C:/path/to/flights-mcp/src",
        "RAPIDAPI_KEY": "your_rapidapi_key_here"
      }
    }
  }
}
```

Full example: [`examples/claude_desktop_config.json`](examples/claude_desktop_config.json).

### Cursor / Continue / Cline / generic MCP clients
Most clients accept the [`mcp.json`](mcp.json) form. The `${RAPIDAPI_KEY}`
placeholder there is **not a real key** — the client substitutes it from your
shell env or its secret store at launch. Real keys live in `.env` (gitignored)
or your client's secret store.

## Tools

| Tool                | Purpose                                                              |
| ------------------- | -------------------------------------------------------------------- |
| `search_airports`   | City/airport → IATA, name, country                                   |
| `search_flights`    | Search w/ full segments, carriers, durations, layovers, prices       |
| `cheapest_dates`    | Per-day price calendar across upcoming dates                         |
| `analyze_layovers`  | Score each layover: MCT, terminal change, overnight, airport quality |
| `rank_options`      | Multi-criteria weighted scoring on a set of offer IDs                |
| `find_optimal_path` | One-shot: search + rank + return top N with rationale                |
| `compare_offers`    | Side-by-side comparison table                                        |

## Ranking model

Each criterion is normalised to [0, 1] across the candidate set (1 = best),
then combined with caller-tunable weights:

| Criterion         | Default | Meaning |
| ----------------- | ------- | ------- |
| `price`           | 0.40    | Lower total → higher score |
| `duration`        | 0.25    | Shorter total travel time → higher |
| `stops`           | 0.15    | Non-stop > 1 stop > 2 stops |
| `layover_quality` | 0.15    | Connection time, terminal change, overnight, airport reputation |
| `seat_quality`    | 0.05    | Best-effort: cabin class signal from search results |

Override per call:

```text
find_optimal_path(
  origin="SFO", destination="SIN", departure_date="2026-07-04",
  weight_price=0.10, weight_layover_quality=0.40, weight_duration=0.30
)
```

Weights are auto-normalised, so any positive numbers work.

## Layover heuristics

`analyze_layovers` and the `layover_quality` criterion penalise:

| Connection length | Penalty |
| ----------------- | ------- |
| < 45 min          | heavy — below most carriers' Minimum Connection Time |
| 45–60 min         | moderate (tight) |
| 60–180 min        | none (sweet spot) |
| 180–360 min       | small (long wait) |
| > 360 min         | moderate (very long) |

Plus penalty for **overnight** and **terminal-change** layovers. Small bonus
for premium hubs (SIN, HKG, ICN, DOH, DXB, ZRH, AMS, CPH, HEL, MUC, FRA, ATL…);
small penalty for delay-prone hubs (EWR, LGA, ORD, PHL, MIA, FCO, MAD).

## Project layout

```
flights-mcp/
├── README.md
├── mcp.json                       # MCP manifest — env-var placeholders only
├── pyproject.toml
├── .env.example                   # one signup URL, one key
├── src/flights_mcp/
│   ├── __main__.py                # python -m flights_mcp
│   ├── server.py                  # FastMCP server, 7 tools
│   ├── config.py
│   ├── models.py                  # Airport / FlightOffer / Itinerary / Segment / Layover
│   ├── ranking.py                 # weighted multi-criteria scoring
│   ├── cache.py
│   └── providers/
│       ├── base.py
│       └── rapidapi.py            # Sky-Scrapper client + normaliser
├── examples/
│   ├── claude_desktop_config.json
│   └── sample_queries.md
└── tests/test_ranking.py
```

## Development

```powershell
pip install -e ".[dev]"
$env:PYTHONPATH = "src"
pytest                                       # Windows PowerShell
# PYTHONPATH=src pytest                      # macOS / Linux
python tests\_live_smoke.py                  # live RapidAPI call (uses one quota credit)
```

## Security note

API keys live in `.env` (gitignored) or your MCP client's secret store. The
`mcp.json` in this repo contains only `${VAR_NAME}` placeholders — never
literal keys.

## License

MIT.
