flighty-mcp
README.md
# flighty-mcp
A read-only MCP server that exposes your personal Flighty app flight data as geo-ready legs with departure and arrival coordinates. Query your flight history by date, year, or flight number; browse aggregate stats (distance, unique airports/airlines, top routes).
Credit: inspired by [LukasHaas/flighty-mcp](https://github.com/LukasHaas/flighty-mcp) for the original idea.
## Tools
### `list_my_flights`
List your own flights as geo-ready legs (departure/arrival airports with coordinates).
**Arguments:**
- `year` (optional): Filter to a calendar year (e.g. 2025).
- `after` (optional): Only flights departing on/after this ISO date (YYYY-MM-DD).
- `before` (optional): Only flights departing before this ISO date (YYYY-MM-DD).
- `upcoming_only` (optional): Return non-archived flights, soonest first. Full history is newest first.
- `limit` (optional): Maximum number of legs to return (default 200).
**Returns:** List of leg objects with this structure:
```json
{
"date": "2025-06-23",
"flight_no": "UA194",
"airline": {
"iata": "UA",
"name": "United Airlines"
},
"from": {
"iata": "SFO",
"city": "San Francisco",
"country": "United States",
"lat": 37.6213,
"lon": -122.379
},
"to": {
"iata": "JFK",
"city": "New York",
"country": "United States",
"lat": 40.6413,
"lon": -73.7781
},
"departure": "2025-06-23T10:30:00",
"arrival": "2025-06-24T01:15:00Z"
}
```
### `get_flight`
Get your most recent flight leg matching a flight number (e.g. "UA194").
**Arguments:**
- `flight_no`: The flight number (case- and space-insensitive).
**Returns:** A single leg object (or null if no match found).
### `flight_stats`
Aggregate stats over your flights: counts, distance, unique airports/airlines, and top routes.
**Arguments:**
- `year` (optional): Filter stats to a calendar year. Omit for all-time.
**Returns:** Stats object with this structure:
```json
{
"flights": 42,
"distance_km": 18500.5,
"unique_airports": 15,
"unique_airlines": 5,
"top_routes": [
{ "route": "SFO -> JFK", "count": 8 },
{ "route": "JFK -> SFO", "count": 7 }
],
"top_airlines": [
{ "iata": "UA", "name": "United Airlines", "count": 12 }
],
"year": "all_time"
}
```
### `animate_trip`
Build a flight-animator route link for your trip to a place.
Resolves the connected flights from your home (or `origin`) to `destination` and returns shareable links: `url` (one-way trip) and `round_trip_url` (there and back). May instead return a resolution prompt with status `ambiguous_destination`, `confirm_home`, or `no_match`.
**Arguments:**
- `destination`: Where the trip goes — IATA code, city, or country (e.g. "Japan", "NRT").
- `origin` (optional): Starting location — IATA code, city, or country. Defaults to your inferred home (most common departure airport).
- `after` (optional): ISO date (YYYY-MM-DD); only trips departing on/after it.
- `before` (optional): ISO date (YYYY-MM-DD); only trips departing before it.
**Example:** "animate my flight to Japan"
**Returns:** If successful, a dict with keys `status` (always "ok"), `url`, `round_trip_url` (if a return is found), `home`, `destination`, `stops` (summary), `start_date`, `end_date`, `leg_count`, and `home_confidence`. On ambiguity or mismatch, returns `status` with one of: `no_match` (no flights match criteria), `ambiguous_destination` (multiple cities match the destination), or `confirm_home` (inferred home confidence is low—returns top alternatives for confirmation).
**Route link format:** the `?d=` value is `base64url` of `{"v":1,"stops":[…]}` (the versioned envelope shared with flight-animator's decoder). Each stop carries `code`, `lat`, `lon`, `label`, and optional `arrive`/`depart` (ISO 8601). We always embed `lat`/`lon` so the animator needs no airport-table lookup and so points outside its bundled dataset still render — consumers should prefer the embedded coordinates over resolving the `code`.
## Installation
Install [`uv`](https://docs.astral.sh/uv/getting-started/installation/), clone this repository,
and replace `/absolute/path/to/flighty-mcp` below with the clone's absolute path.
### Codex
```bash
codex mcp add flighty -- uv --directory /absolute/path/to/flighty-mcp run flighty-mcp
```
Restart Codex after adding the server. The ChatGPT desktop app, Codex CLI, and Codex IDE
extension share this configuration.
### Claude Code
```bash
claude mcp add --scope user flighty -- uv --directory /absolute/path/to/flighty-mcp run flighty-mcp
```
### Claude Desktop and Cursor
Add this entry to Claude Desktop's `claude_desktop_config.json` or Cursor's
`~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"flighty": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/flighty-mcp", "run", "flighty-mcp"]
}
}
}
```
Restart the client after saving the file.
### VS Code / GitHub Copilot
Add this to your user or workspace `mcp.json`:
```json
{
"servers": {
"flighty": {
"type": "stdio",
"command": "uv",
"args": ["--directory", "/absolute/path/to/flighty-mcp", "run", "flighty-mcp"]
}
}
}
```
You can open the user file with **MCP: Open User Configuration** from the Command Palette.
### Other stdio MCP clients
Use the `mcpServers` JSON example above, or adapt its `command` and `args` values to your
client's configuration format. This server uses standard MCP over stdio and has no
client-specific runtime behavior.
## Configuration
| Variable | Default | Description |
|----------|---------|-------------|
| `FLIGHTY_DB_PATH` | `$HOME/Library/Containers/com.flightyapp.flighty/Data/Documents/MainFlightyDatabase.db` | Path to the Flighty app's SQLite database. |
| `FLIGHTY_USER_ID` | Auto-detected from `UserProfile` table | The Flighty user ID to query (normally auto-detected; set only if overriding). |
| `FLIGHT_ANIMATOR_BASE_URL` | `https://flights.sailingnaturali.com` | Base URL for `animate_trip` route links (consumed by the companion flight-animator app). |
## Full Disk Access Requirement
**Important:** The MCP server needs macOS Full Disk Access to read the Flighty database.
**Symptom:** If the server fails to connect or reads hang indefinitely, it's likely because Full Disk Access is missing.
**Solution:**
1. Open **System Preferences** → **Privacy & Security** → **Full Disk Access**.
2. Add the app that will launch this server:
- For Codex, Claude Desktop, Cursor, or VS Code, add that application.
- For Claude Code or another terminal-launched client, add Terminal (or your terminal app).
3. Restart the app (or kill and relaunch it).
4. Try again.
The database lives at `~/Library/Containers/com.flightyapp.flighty/Data/Documents/`, which is in your user's private container — Full Disk Access is required for any application to read it.
TDQS
A4/5.0
Scored across 3 tools
Disambiguation5/5
Each tool has a clear, distinct purpose: aggregate stats, get a specific flight by number, and list flights with filters. No overlap or ambiguity.
Naming Consistency5/5
All tool names follow a consistent verb_noun pattern in snake_case (flight_stats, get_flight, list_my_flights), making them predictable and readable.
Tool Count4/5
With only 3 tools, the server feels slightly undersized for a flight tracking domain, but each tool serves a core read operation. The count is reasonable for a minimal API.
Completeness2/5
The server is read-only, missing any create, update, or delete operations for flights. Users cannot add or modify flight data, which is a significant gap for a personal flight tracker.
Maintenance
ActivityMaintained
ResponsivenessNo issues