azair-eu-mcp
MCP server for azair.eu that enables flexible-date cheap flight searches across European low-cost airlines, with multi-airport, metro-area, and advanced filter support.
README
✈️ azair-eu-mcp
MCP server for azair.eu — cheap flight search across European low-cost airlines with flexible dates. Give your AI assistant the power to hunt for bargain flights the way humans do on azair: loose date ranges, multiple airports, metro areas, and every advanced filter from the azair search form.
Features
- 🔎 Flexible-date search — the core azair superpower: pick a date range, get the cheapest day combinations within it
- 🛫 Multi-airport search — search from several airports at once (e.g.
PRG+BRQ+NUE) - 🏙️ Metro-area search — cover all airports of a city via metro codes (e.g.
MIL_ALL→ MXP, BGY, LIN) - 🌍 Anywhere mode — destination
XXXsearches the whole continent - ⚙️ All advanced filters — weekdays, time windows, stopover length, transfers, Schengen-only, clubs, and more
- 💱 Multi-currency — EUR, USD, GBP, PLN, CZK, and all azair currencies
- ✍️ Structured results — clean JSON with prices, dates, per-segment flight details, and booking links
Quick start
Ask your assistant (Claude, Cursor, Windsurf, …):
Find cheap return flights from Prague to anywhere in Italy between August and January, min 5 nights, max 8 nights, any Milan or Rome airport.
or directly:
search_flights(src_airport="PRG", src_airports=["BRQ", "NUE"],
dst_airport="MXP", dst_airports=["LIN", "BGY"], dst_metro_code="MIL_ALL",
dep_date="2026-08-01", arr_date="2027-01-31",
min_days_stay=5, max_days_stay=8)
Example response:
{
"total_price": 33.33,
"currency": "EUR",
"length_of_stay_days": 6,
"outbound_date": "Thu 20/08/26",
"return_date": "Wed 26/08/26",
"outbound_segments": [
{
"airline": "Ryanair",
"airline_iata": "FR",
"flight_number": "FR3601",
"departure_airport": "Prague",
"departure_airport_code": "PRG",
"departure_time": "09:00",
"arrival_airport": "Bologna",
"arrival_airport_code": "BLQ",
"arrival_time": "10:30",
"duration": "12:10 h / 1 change",
"price": 33.33,
"currency": "EUR"
}
],
"return_segments": [],
"booking_url": "book/b.php?b=RlJQUkdCTFEyNjA4MjUzNjAxMTAwMjAyNi0wOC0wMSswMjoxM2Vud3d3LmF6YWlyLmV1"
}
Returns up to 180 results, each with total price, dates, outbound/return segments (airline, flight number, times, duration, leg price), and a direct booking URL.
Tools
search_flights
Full-featured flight search mirroring the azair search form, including advanced parameters.
| Parameter | Type | Default | Description |
|---|---|---|---|
src_airport |
string | — | Source airport IATA code (e.g. WMI, STN) |
dst_airport |
string | — | Destination IATA code or XXX for anywhere |
src_airports |
string[] | — | Additional source airports, e.g. BRQ, NUE together with PRG |
dst_airports |
string[] | — | Additional destination airports, e.g. LIN, BGY together with MXP |
src_metro_code |
string | — | Source metro code covering all its airports, e.g. MIL_ALL |
dst_metro_code |
string | — | Destination metro code covering all its airports, e.g. MIL_ALL |
dep_date |
string | — | Earliest departure, DD.MM.YYYY or YYYY-MM-DD |
arr_date |
string | — | Latest return, DD.MM.YYYY or YYYY-MM-DD |
min_days_stay |
int | 2 |
Minimum trip length in days |
max_days_stay |
int | 7 |
Maximum trip length in days |
adults |
int | 1 |
Adults (1-9) |
children |
int | 0 |
Children (0-8) |
infants |
int | 0 |
Infants (0-8) |
currency |
string | EUR |
EUR, USD, GBP, PLN, CZK, … |
max_changes |
int | 1 |
Max stopovers per leg (0-3, 0 = direct flights only) |
is_oneway |
bool | false |
One-way instead of return |
schengen_only |
bool | false |
Only transfers inside the Schengen area |
allow_transfer |
bool | false |
Allow ground transfer between airports |
departure_weekdays |
int[] | all | Departure weekdays, 0=Mon..6=Sun |
return_weekdays |
int[] | all | Return weekdays |
min_hour_outbound |
string | 0:00 |
Earliest outbound time |
max_hour_outbound |
string | 24:00 |
Latest outbound time |
min_hour_inbound |
string | 0:00 |
Earliest inbound time |
max_hour_inbound |
string | 24:00 |
Latest inbound time |
min_hour_stay |
string | 0:45 |
Minimum stopover time |
max_hour_stay |
string | 23:20 |
Maximum stopover time |
next_day |
int | 0 |
Allow overnight stopovers |
same_dep |
bool | true |
Return to the same departure airport |
same_arr |
bool | true |
Return from the same arrival airport |
search_airports
Resolve IATA codes and airport names before searching — useful for finding the right code for a city.
| Parameter | Type | Description |
|---|---|---|
query |
string | IATA code or partial name (e.g. WMI, London, Barcelona) |
Returns up to 50 matching airports with code and name.
Installation
git clone <repo-url> azair-eu-mcp
cd azair-eu-mcp
uv sync
Usage
Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"azair-eu-mcp": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/azair-eu-mcp", "python", "main.py"]
}
}
}
Cursor / Windsurf
Add the same command in the MCP servers settings.
Any MCP client
Run the server directly — it speaks MCP over stdio:
uv run python main.py
Development
uv sync
uv run python main.py
Sanity-check a search without spinning up the server:
uv run python -c "
import asyncio
from azair.models import SearchParams
from azair.client import fetch_search_results
from azair.parser import parse_results
async def main():
html = await fetch_search_results(SearchParams(
src_airport='PRG', dst_airport='STN',
dep_date='2026-08-01', arr_date='2026-08-31',
))
print(len(parse_results(html)), 'results')
asyncio.run(main())
"
How it works
- Azair exposes no public JSON API — results are scraped from the HTML search results page (
azfin.php) - The airport database is fetched once from azair's static JS asset and cached in memory
- Multi-airport and metro codes are sent exactly as the azair web app does (bracket notation +
srcapN/dstapNparams)
Notes
- Azair uses an expired SSL certificate — the server bypasses SSL verification
- Search times vary (10-60s) depending on the query scope
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
E2B
Using MCP to run code via e2b.