Skip to main content
Glama
PythonicMind2

flight-search-mcp

✈️ flight-search-mcp

A Model Context Protocol server for live flight tracking — built with the official MCP Python SDK, powered by a genuinely free API.

Python 3.10+ MCP

Give Claude (or any MCP client) the ability to look up live flights, check real-time status, and resolve airport/airline codes — no paid API, no credit card.


What this does

Ask your MCP client things like:

"Is flight BA100 delayed?" "What flights are currently in the air from JFK to LHR?" "What's the IATA code for Heathrow?"

...and it answers with real, live data pulled straight from AviationStack.

Related MCP server: Aviationstack MCP Server

Why AviationStack

AviationStack is the one that's still genuinely free for indie developers: ~100 requests/month, no credit card, API key in seconds.

The trade-off: the free plan covers current & near-term live flights only — no future-dated trip search, no historical data, no fares. This is a flight tracker, not a trip planner. If you outgrow that, see Scope & limitations below.

✨ Features

  • 🔍 search_flights — live flights by route, airline, or status

  • 📡 get_flight_status — real-time status, gate, delay, live position for one flight

  • 🛫 resolve_airport — city/airport name → IATA code

  • 🏢 resolve_airline — airline name → IATA code

  • ⚡ Smart caching — protects your monthly quota automatically

  • 🛡️ Input validation with actionable error messages, not raw API errors

  • ✅ Tested, typed, and small enough to actually read

🚀 Quickstart

git clone https://github.com/PythonicMind2/flight-search-mcp.git
cd flight-search-mcp
pip install -e .

cp .env.example .env
# paste your free AviationStack key into .env — get one at
# https://aviationstack.com/signup/free (instant, no card)

python -m flight_search_mcp.server

Connect to Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "flight-search": {
      "command": "python",
      "args": ["-m", "flight_search_mcp.server"],
      "cwd": "/absolute/path/to/flight-search-mcp",
      "env": {
        "AVIATIONSTACK_API_KEY": "your_api_key"
      }
    }
  }
}

Restart Claude Desktop and ask it about a flight.

🧰 Tools

Tool

Args

Returns

search_flights

origin?, destination?, airline_name?, flight_status?, max_results?

Live flights matching at least one filter

get_flight_status

flight_iata (e.g. "BA100")

Status, gate, delay, live position

resolve_airport

keyword (city or airport name)

Matching IATA codes

resolve_airline

keyword (airline name)

Matching IATA codes

search_flights requires at least one of origin, destination, or airline_name — an unfiltered call would burn quota on an arbitrary global sample.

🏗️ Project structure

flight-search-mcp/
├── src/flight_search_mcp/
│   ├── server.py               # FastMCP server + tool definitions
│   ├── aviationstack_client.py # Async API client, caching, error handling
│   ├── models.py                # Pydantic response models
│   ├── cache.py                 # Minimal in-memory TTL cache
│   └── config.py                # Env-based settings
├── tests/test_server.py         # Parsing + validation tests (no network)
├── .github/workflows/tests.yml  # CI
├── .env.example
└── pyproject.toml

Design choices worth knowing about:

  • Auth is a plain access_key query param — no OAuth token juggling.

  • Caching is tiered: reference data (airports/airlines) is cached for an hour since it barely changes; live flight data for 30 seconds, mainly to absorb accidental duplicate calls in the same turn. Every cache hit is a request you don't spend against your ~100/month quota.

  • Errors: AviationStack often returns HTTP 200 with an "error" object in the body instead of a 4xx. The client catches this and raises a real exception with a useful hint (quota exhausted, wrong key, paid-only feature) instead of silently returning nothing.

🧪 Testing

pip install pytest pytest-asyncio
pytest tests/ -v

All tests run against sample payloads — no API key or network access needed.

⚠️ Scope & limitations

AviationStack's free plan does not include:

  • Future-dated trip search (/flightsFuture is paid-only)

  • Historical flights beyond the current window

  • /routes (date-independent schedule lookups — paid-only)

  • Any pricing/fare data (AviationStack doesn't do fares on any plan)

  • The search autocomplete param on /airports//airlines (this repo works around it by filtering one reference page client-side)

If you need real future-dated search with prices, look at FlightAPI.io (small free trial, then paid) or Duffel (free sandbox data forever, real data is pay-per-use). PRs adding either as an optional second backend are welcome.

🤝 Contributing

Issues and PRs welcome. Keep it small, keep it tested.

Available Tools

4 tools
get_flight_statusA

Get the real-time status of a specific flight by its IATA flight code.

Args: flight_iata: IATA flight code, e.g. "AA100" (airline code + flight number).

Returns current status (scheduled/active/landed/cancelled/etc.), gate, terminal, delay, and live position if airborne.

ParametersJSON Schema
NameRequiredDescriptionDefault
flight_iataYes

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It discloses that the tool returns current status (scheduled/active/landed/cancelled/etc.) and optional live position, which is helpful. However, it does not explicitly state that the operation is read-only (though implied by 'get'), nor does it cover rate limits, authentication needs, data freshness, or error handling. Adequate for a simple tool but could be more transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise: one sentence for purpose, a short args section, and a return summary. Every sentence adds value, and the structure is front-loaded with the main action. No redundant phrases.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no output schema), the description covers the purpose, parameter meaning, and return values clearly. It does not mention edge cases (e.g., invalid flight code) or data freshness guarantees, but it is largely complete for a straightforward retrieval tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 0% description coverage, but the description explains the single parameter flight_iata with an example ('AA100') and clarifies the format ('airline code + flight number'). This adds significant meaning beyond the raw schema definition and fully compensates for the lack of schema-level descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence clearly states the tool's purpose: 'Get the real-time status of a specific flight by its IATA flight code.' This uses a specific verb ('Get') and a well-defined resource ('real-time status of a specific flight'). The tool is distinct from siblings like search_flights (which searches by criteria) and resolve_airport/airline (which resolve codes).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: when you have an IATA flight code and want real-time status. However, there is no explicit guidance on when to use this tool versus alternatives (e.g., search_flights if code is unknown). No when-not conditions are stated, so it barely meets 'implied usage'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolve_airlineA

Look up airline IATA codes by airline name.

Args: keyword: Airline name or partial name (e.g. "American", "Emirates"), or exact IATA code (e.g. "AA"). Minimum 2 characters. max_results: Max number of matches to return (1-20, default 10).

ParametersJSON Schema
NameRequiredDescriptionDefault
keywordYes
max_resultsNo

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral transparency. It discloses that the tool accepts partial names or exact codes and returns matches, implying a lookup operation. However, it doesn't mention whether the tool is read-only, if there are rate limits, or what happens on no match, which are gaps for a resolution tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with two sentences and parameter details. It front-loads the main purpose before listing args. The arg descriptions are clear and efficient, though the full description is about 90 words, which is reasonable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 2 params, 0% coverage, no output schema, and moderate complexity, the description covers purpose and parameter constraints. However, missing output details, error behavior, and use cases limits completeness. It's adequate but not thorough.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does explain keyword as 'Airline name or partial name... or exact IATA code' and max_results with range and default. This adds meaning beyond the schema's types, but doesn't describe return format or error handling, and max_results semantics could be clearer (e.g., what happens if fewer matches exist). Baseline with 0% coverage is 3, and description meets that minimum.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: to look up airline IATA codes by airline name or exact IATA code. It specifies the resource (airline codes) and the action (look up by name or code), and differentiates from siblings like search_flights and get_flight_status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use the tool (resolving airline names/codes) and usage tips like minimum 2 characters. However, it does not explicitly state when not to use it or compare to siblings like resolve_airport, though sibling names imply they handle different domains.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolve_airportA

Look up IATA airport codes by city or airport name.

Args: keyword: City or airport name, or exact IATA code (e.g. "London", "Heathrow", "JFK"). Minimum 2 characters. max_results: Max number of matches to return (1-20, default 10).

Use this before search_flights if you only have a city/airport name rather than a 3-letter IATA code.

ParametersJSON Schema
NameRequiredDescriptionDefault
keywordYes
max_resultsNo

TDQS

A4.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses input constraints (minimum 2 characters, max_results range) and core behavior, but does not explicitly state that it is read-only, what happens on no match, or the output format. The description is adequate but lacks deeper behavioral details that an agent might need.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is succinct with two clear paragraphs. The first sentence front-loads the purpose, followed by precise argument definitions in a standard format. No redundant or unnecessary sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema and no annotations, the description covers the tool's purpose, usage context, and parameter semantics well. The only minor gap is the lack of explicit output structure (e.g., 'returns a list of IATA code strings'), but the verb 'look up' and typical use case imply the result. For a simple lookup tool, it is largely complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must add meaning. It provides rich details for both parameters: keyword examples ('London', 'Heathrow', 'JFK'), minimum length (2 chars), and max_results range (1-20, default 10). This fully compensates for the empty schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('look up') and resource ('IATA airport codes') and specifies the input as 'city or airport name'. It distinguishes itself from siblings (search_flights, resolve_airline) by its specific purpose and the explicit guidance to use it before search_flights.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells when to use the tool: 'Use this before search_flights if you only have a city/airport name rather than a 3-letter IATA code.' This provides clear context and an alternative (direct IATA code usage) without needing additional exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_flightsA

Search current/live flights, optionally filtered by route, airline, or status.

IMPORTANT: this returns CURRENT and near-term real-time flights only — it cannot search a future travel date (e.g. "flights on Sept 20th") or historical flights, and it does not include prices. For a specific flight's status, use get_flight_status instead.

Args: origin: Optional 3-letter IATA departure airport code (e.g. "JFK"). destination: Optional 3-letter IATA arrival airport code (e.g. "LHR"). airline_name: Optional airline name to filter by (e.g. "American Airlines"). flight_status: Optional status filter: scheduled, active, landed, cancelled, incident, or diverted. max_results: Max number of results to return (1-100, default 10).

Provide at least one filter (origin, destination, or airline_name) — an unfiltered call returns an arbitrary global sample and burns quota fast.

ParametersJSON Schema
NameRequiredDescriptionDefault
originNo
destinationNo
max_resultsNo
airline_nameNo
flight_statusNo

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description fully bears the transparency burden. It declares that only current/near-term real-time flights are returned, excludes future/historical flights and prices, and warns about unfiltered calls. This sufficiently discloses the tool's behavioral constraints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose, followed by key caveats in a clear 'IMPORTANT' block, then a structured 'Args' list. Every sentence adds value, with no unnecessary words. The organization aids quick comprehension.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 5 parameters, no output schema, and no annotations, the description covers scope, limitations, parameter details, usage best practices, and sibling alternatives. It leaves no critical gaps for an agent to misuse the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must and does compensate by explaining each parameter: origin/destination as 3-letter IATA codes, max_results range/default, airline_name as optional name, and flight_status with enumerated allowed values. The filter requirement is also clarified.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Search current/live flights' and specifies filtering by route, airline, or status. It explicitly differentiates from sibling 'get_flight_status' by noting the scope and directing specific status queries to that tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use (current/near-term real-time flights), when-not-to-use (future dates, historical, prices), and recommends the alternative 'get_flight_status' for specific flight status. It also advises providing at least one filter to avoid quota waste.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 4 tool updatesv0.1.0
    • First observedget_flight_status
    • First observedresolve_airline
    • First observedresolve_airport
    • First observedsearch_flights

TDQS

A4.4/5.0
Disambiguation5/5

Each tool has a distinct purpose: get_flight_status for a specific flight, search_flights for multi-flight search, resolve_airport for IATA code lookup by city/airport name, and resolve_airline for airline code lookup. No overlap or ambiguity.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern: get_flight_status, search_flights, resolve_airport, resolve_airline. No mixing of styles or conventions.

Tool Count5/5

With 4 tools, the server is well-scoped for a flight search MCP: two lookups (airport/airline codes) and two flight operations (search and specific status). Each tool earns its place without being too few or too many.

Completeness5/5

The tool surface covers the core domain: resolving identifiers, searching live flights, and retrieving detailed status. Gaps like historical or future scheduled flights are explicitly out of scope, so no missing functionality for its stated real-time purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/PythonicMind2/flight-search-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server