aviationstack-mcp-server 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. aviationstack_mcp_server/__init__.py +0 -0
  2. aviationstack_mcp_server/__main__.py +15 -0
  3. aviationstack_mcp_server/client/__init__.py +9 -0
  4. aviationstack_mcp_server/client/aviationstack.py +138 -0
  5. aviationstack_mcp_server/client/factory.py +30 -0
  6. aviationstack_mcp_server/client/http.py +292 -0
  7. aviationstack_mcp_server/config/__init__.py +3 -0
  8. aviationstack_mcp_server/config/settings.py +162 -0
  9. aviationstack_mcp_server/errors/__init__.py +25 -0
  10. aviationstack_mcp_server/errors/exceptions.py +56 -0
  11. aviationstack_mcp_server/logging_config.py +52 -0
  12. aviationstack_mcp_server/mcp/__init__.py +3 -0
  13. aviationstack_mcp_server/mcp/dependencies.py +64 -0
  14. aviationstack_mcp_server/mcp/errors.py +118 -0
  15. aviationstack_mcp_server/mcp/prompts/__init__.py +0 -0
  16. aviationstack_mcp_server/mcp/prompts/aviation.py +98 -0
  17. aviationstack_mcp_server/mcp/resources/__init__.py +0 -0
  18. aviationstack_mcp_server/mcp/resources/documentation.py +165 -0
  19. aviationstack_mcp_server/mcp/resources/metadata.py +46 -0
  20. aviationstack_mcp_server/mcp/server.py +164 -0
  21. aviationstack_mcp_server/mcp/tools/__init__.py +0 -0
  22. aviationstack_mcp_server/mcp/tools/aircraft.py +64 -0
  23. aviationstack_mcp_server/mcp/tools/airlines.py +43 -0
  24. aviationstack_mcp_server/mcp/tools/airports.py +43 -0
  25. aviationstack_mcp_server/mcp/tools/flights.py +125 -0
  26. aviationstack_mcp_server/mcp/tools/reference.py +129 -0
  27. aviationstack_mcp_server/models/__init__.py +81 -0
  28. aviationstack_mcp_server/models/aircraft.py +43 -0
  29. aviationstack_mcp_server/models/airline.py +29 -0
  30. aviationstack_mcp_server/models/airport.py +33 -0
  31. aviationstack_mcp_server/models/common.py +20 -0
  32. aviationstack_mcp_server/models/flight.py +125 -0
  33. aviationstack_mcp_server/models/location.py +50 -0
  34. aviationstack_mcp_server/models/queries.py +284 -0
  35. aviationstack_mcp_server/models/route.py +24 -0
  36. aviationstack_mcp_server/models/tax.py +20 -0
  37. aviationstack_mcp_server/observability.py +27 -0
  38. aviationstack_mcp_server/security.py +62 -0
  39. aviationstack_mcp_server/services/__init__.py +13 -0
  40. aviationstack_mcp_server/services/aircraft_service.py +156 -0
  41. aviationstack_mcp_server/services/airline_service.py +89 -0
  42. aviationstack_mcp_server/services/airport_service.py +116 -0
  43. aviationstack_mcp_server/services/flight_service.py +366 -0
  44. aviationstack_mcp_server/services/reference_service.py +315 -0
  45. aviationstack_mcp_server/utils/__init__.py +0 -0
  46. aviationstack_mcp_server-0.1.0.dist-info/METADATA +57 -0
  47. aviationstack_mcp_server-0.1.0.dist-info/RECORD +50 -0
  48. aviationstack_mcp_server-0.1.0.dist-info/WHEEL +4 -0
  49. aviationstack_mcp_server-0.1.0.dist-info/entry_points.txt +3 -0
  50. aviationstack_mcp_server-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,164 @@
1
+ import logging
2
+ from collections.abc import AsyncIterator, Callable
3
+ from contextlib import asynccontextmanager
4
+
5
+ from mcp.server import MCPServer
6
+
7
+ from aviationstack_mcp_server.client.aviationstack import AviationstackClient
8
+ from aviationstack_mcp_server.client.factory import create_aviationstack_client
9
+ from aviationstack_mcp_server.config import get_settings
10
+ from aviationstack_mcp_server.mcp.dependencies import (
11
+ AppContext,
12
+ build_app_context,
13
+ )
14
+ from aviationstack_mcp_server.mcp.prompts.aviation import (
15
+ register_aviation_prompts,
16
+ )
17
+ from aviationstack_mcp_server.mcp.resources.documentation import (
18
+ register_documentation_resources,
19
+ )
20
+ from aviationstack_mcp_server.mcp.resources.metadata import (
21
+ register_metadata_resources,
22
+ )
23
+ from aviationstack_mcp_server.mcp.tools.aircraft import register_aircraft_tools
24
+ from aviationstack_mcp_server.mcp.tools.airlines import register_airline_tools
25
+ from aviationstack_mcp_server.mcp.tools.airports import register_airport_tools
26
+ from aviationstack_mcp_server.mcp.tools.flights import register_flight_tools
27
+ from aviationstack_mcp_server.mcp.tools.reference import register_reference_tools
28
+
29
+ logger = logging.getLogger(__name__)
30
+
31
+ ClientFactory = Callable[[], AviationstackClient]
32
+
33
+
34
+ def default_client_factory() -> AviationstackClient:
35
+ """Create the production Aviationstack client from application settings."""
36
+
37
+ settings = get_settings()
38
+ return create_aviationstack_client(settings)
39
+
40
+
41
+ def create_lifespan(
42
+ client_factory: ClientFactory = default_client_factory,
43
+ ):
44
+ """Create the application lifespan with an injectable client factory."""
45
+
46
+ @asynccontextmanager
47
+ async def lifespan(
48
+ server: MCPServer[AppContext],
49
+ ) -> AsyncIterator[AppContext]:
50
+ logger.info("Starting Aviationstack MCP application lifespan")
51
+ client = client_factory()
52
+
53
+ try:
54
+ logger.info("Aviationstack API client initialized")
55
+
56
+ app_context = build_app_context(client)
57
+ logger.info("Aviationstack application context ready")
58
+
59
+ yield app_context
60
+ finally:
61
+ logger.info("Shutting down Aviationstack MCP application lifespan")
62
+ try:
63
+ await client.close()
64
+ except Exception:
65
+ logger.exception("Failed to close Aviationstack API client")
66
+ raise
67
+ else:
68
+ logger.info("Aviationstack API client closed")
69
+
70
+ return lifespan
71
+
72
+
73
+ def create_server(
74
+ client_factory: ClientFactory = default_client_factory,
75
+ ) -> MCPServer[AppContext]:
76
+ """Create and configure the Aviationstack MCP server."""
77
+
78
+ logger.debug("Creating Aviationstack MCP server")
79
+ server = MCPServer(
80
+ "aviationstack-mcp",
81
+ lifespan=create_lifespan(client_factory),
82
+ )
83
+
84
+ # Tools
85
+ register_flight_tools(server)
86
+ register_airport_tools(server)
87
+ register_airline_tools(server)
88
+ register_aircraft_tools(server)
89
+ register_reference_tools(server)
90
+
91
+ # Prompts
92
+ register_aviation_prompts(server)
93
+
94
+ # Resources
95
+ register_metadata_resources(server)
96
+ register_documentation_resources(server)
97
+
98
+ logger.info("Aviationstack MCP server configured")
99
+ return server
100
+
101
+
102
+ # from collections.abc import AsyncIterator
103
+ # from contextlib import asynccontextmanager
104
+
105
+ # from mcp.server import MCPServer
106
+
107
+ # from aviationstack_mcp_server.client.factory import create_aviationstack_client
108
+ # from aviationstack_mcp_server.config import get_settings
109
+ # from aviationstack_mcp_server.mcp.dependencies import AppContext, build_app_context
110
+ # from aviationstack_mcp_server.mcp.prompts.aviation import (
111
+ # register_aviation_prompts,
112
+ # )
113
+ # from aviationstack_mcp_server.mcp.resources.documentation import (
114
+ # register_documentation_resources,
115
+ # )
116
+ # from aviationstack_mcp_server.mcp.resources.metadata import (
117
+ # register_metadata_resources,
118
+ # )
119
+ # from aviationstack_mcp_server.mcp.tools.aircraft import register_aircraft_tools
120
+ # from aviationstack_mcp_server.mcp.tools.airlines import register_airline_tools
121
+ # from aviationstack_mcp_server.mcp.tools.airports import register_airport_tools
122
+ # from aviationstack_mcp_server.mcp.tools.flights import register_flight_tools
123
+ # from aviationstack_mcp_server.mcp.tools.reference import register_reference_tools
124
+
125
+
126
+ # @asynccontextmanager
127
+ # async def app_lifespan(
128
+ # server: MCPServer[AppContext],
129
+ # ) -> AsyncIterator[AppContext]:
130
+ # """Initialize and clean up application-wide dependencies."""
131
+
132
+ # settings = get_settings()
133
+ # client = create_aviationstack_client(settings)
134
+
135
+ # try:
136
+ # app_context = build_app_context(client)
137
+
138
+ # yield app_context
139
+
140
+ # finally:
141
+ # await client.close()
142
+
143
+
144
+ # def create_server() -> MCPServer[AppContext]:
145
+ # """Create and configure the Aviationstack MCP server."""
146
+
147
+ # server = MCPServer(
148
+ # "aviationstack-mcp",
149
+ # lifespan=app_lifespan,
150
+ # )
151
+
152
+ # register_flight_tools(server)
153
+ # register_airport_tools(server)
154
+ # register_airline_tools(server)
155
+ # register_aircraft_tools(server)
156
+ # register_reference_tools(server)
157
+
158
+ # register_aviation_prompts(server)
159
+
160
+ # # Resources
161
+ # register_metadata_resources(server)
162
+ # register_documentation_resources(server)
163
+
164
+ # return server
File without changes
@@ -0,0 +1,64 @@
1
+ import logging
2
+
3
+ from mcp.server.mcpserver import Context
4
+
5
+ from aviationstack_mcp_server.mcp.dependencies import AppContext
6
+ from aviationstack_mcp_server.mcp.errors import mcp_error_boundary
7
+ from aviationstack_mcp_server.models.queries import RecordLimitQuery
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ def register_aircraft_tools(server) -> None:
13
+ """Register aircraft-related MCP tools."""
14
+
15
+ @server.tool(
16
+ name="list_aircraft_types",
17
+ title="List Aircraft Types",
18
+ description=(
19
+ "List aircraft type records available from Aviationstack. "
20
+ "Use the limit parameter to control the number of records."
21
+ ),
22
+ )
23
+ @mcp_error_boundary
24
+ async def list_aircraft_types(
25
+ query: RecordLimitQuery,
26
+ ctx: Context[AppContext],
27
+ ):
28
+ """List aircraft type records."""
29
+
30
+ app = ctx.request_context.lifespan_context
31
+ logger.info("MCP tool called: list_aircraft_types limit=%s", query.limit)
32
+ records = await app.services.aircraft.list_aircraft_types(query)
33
+ logger.debug(
34
+ "MCP tool completed: list_aircraft_types returned=%s",
35
+ len(records),
36
+ )
37
+
38
+ return records
39
+
40
+ @server.tool(
41
+ name="list_airplanes",
42
+ title="List Airplanes",
43
+ description=(
44
+ "List individual airplane records available from "
45
+ "Aviationstack. Use the limit parameter to control "
46
+ "the number of records."
47
+ ),
48
+ )
49
+ @mcp_error_boundary
50
+ async def list_airplanes(
51
+ query: RecordLimitQuery,
52
+ ctx: Context[AppContext],
53
+ ):
54
+ """List individual airplane records."""
55
+
56
+ app = ctx.request_context.lifespan_context
57
+ logger.info("MCP tool called: list_airplanes limit=%s", query.limit)
58
+ records = await app.services.aircraft.list_airplanes(query)
59
+ logger.debug(
60
+ "MCP tool completed: list_airplanes returned=%s",
61
+ len(records),
62
+ )
63
+
64
+ return records
@@ -0,0 +1,43 @@
1
+ import logging
2
+
3
+ from mcp.server.mcpserver import Context
4
+
5
+ from aviationstack_mcp_server.mcp.dependencies import AppContext
6
+ from aviationstack_mcp_server.mcp.errors import mcp_error_boundary
7
+ from aviationstack_mcp_server.models.queries import AirlineSearchQuery
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ def register_airline_tools(server) -> None:
13
+ """Register airline-related MCP tools."""
14
+
15
+ @server.tool(
16
+ name="search_airlines",
17
+ title="Search Airlines",
18
+ description=(
19
+ "Search airline records using airline name, IATA code, "
20
+ "ICAO code, or other supported airline search criteria."
21
+ ),
22
+ )
23
+ @mcp_error_boundary
24
+ async def search_airlines(
25
+ query: AirlineSearchQuery,
26
+ ctx: Context[AppContext],
27
+ ):
28
+ """Search airline records."""
29
+
30
+ app = ctx.request_context.lifespan_context
31
+ logger.info(
32
+ "MCP tool called: search_airlines limit=%s offset=%s search_provided=%s",
33
+ query.limit,
34
+ query.offset,
35
+ query.search is not None,
36
+ )
37
+ records = await app.services.airline.search_airlines(query)
38
+ logger.debug(
39
+ "MCP tool completed: search_airlines returned=%s",
40
+ len(records),
41
+ )
42
+
43
+ return records
@@ -0,0 +1,43 @@
1
+ import logging
2
+
3
+ from mcp.server.mcpserver import Context
4
+
5
+ from aviationstack_mcp_server.mcp.dependencies import AppContext
6
+ from aviationstack_mcp_server.mcp.errors import mcp_error_boundary
7
+ from aviationstack_mcp_server.models.queries import AirportSearchQuery
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ def register_airport_tools(server) -> None:
13
+ """Register airport-related MCP tools."""
14
+
15
+ @server.tool(
16
+ name="search_airports",
17
+ title="Search Airports",
18
+ description=(
19
+ "Search airports by airport name, IATA code, ICAO code, "
20
+ "city, or other supported airport search criteria."
21
+ ),
22
+ )
23
+ @mcp_error_boundary
24
+ async def search_airports(
25
+ query: AirportSearchQuery,
26
+ ctx: Context[AppContext],
27
+ ):
28
+ """Search airport records."""
29
+
30
+ app = ctx.request_context.lifespan_context
31
+ logger.info(
32
+ "MCP tool called: search_airports limit=%s offset=%s search_provided=%s",
33
+ query.limit,
34
+ query.offset,
35
+ query.search is not None,
36
+ )
37
+ records = await app.services.airport.search_airports(query)
38
+ logger.debug(
39
+ "MCP tool completed: search_airports returned=%s",
40
+ len(records),
41
+ )
42
+
43
+ return records
@@ -0,0 +1,125 @@
1
+ import logging
2
+
3
+ from mcp.server.mcpserver import Context
4
+
5
+ from aviationstack_mcp_server.mcp.dependencies import AppContext
6
+ from aviationstack_mcp_server.mcp.errors import mcp_error_boundary
7
+ from aviationstack_mcp_server.models.queries import (
8
+ AirportScheduleQuery,
9
+ FlightSearchQuery,
10
+ HistoricalFlightQuery,
11
+ )
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ def register_flight_tools(
17
+ server,
18
+ ) -> None:
19
+ """Register flight-related MCP tools."""
20
+
21
+ @server.tool(
22
+ name="search_flights",
23
+ title="Search Flights",
24
+ description=(
25
+ "Search flights using airline, flight number, departure, "
26
+ "arrival, date, and pagination filters."
27
+ ),
28
+ )
29
+ @mcp_error_boundary
30
+ async def search_flights(
31
+ query: FlightSearchQuery,
32
+ ctx: Context[AppContext],
33
+ ):
34
+ """Search scheduled flight records."""
35
+
36
+ app = ctx.request_context.lifespan_context
37
+ logger.info(
38
+ "MCP tool called: search_flights limit=%s filters=%s",
39
+ query.limit,
40
+ [
41
+ field
42
+ for field in (
43
+ "airline_name",
44
+ "airline_iata",
45
+ "flight_iata",
46
+ "flight_icao",
47
+ "departure_iata",
48
+ "arrival_iata",
49
+ )
50
+ if getattr(query, field) is not None
51
+ ],
52
+ )
53
+ records = await app.services.flight.search_flights(query)
54
+ logger.debug(
55
+ "MCP tool completed: search_flights returned=%s",
56
+ len(records),
57
+ )
58
+
59
+ return records
60
+
61
+ @server.tool(
62
+ name="search_historical_flights",
63
+ title="Search Historical Flights",
64
+ description=(
65
+ "Search historical flight records for a specific date "
66
+ "using optional airline, flight number, departure, "
67
+ "arrival, and pagination filters."
68
+ ),
69
+ )
70
+ @mcp_error_boundary
71
+ async def search_historical_flights(
72
+ query: HistoricalFlightQuery,
73
+ ctx: Context[AppContext],
74
+ ):
75
+ """Search historical flight records."""
76
+
77
+ app = ctx.request_context.lifespan_context
78
+ logger.info(
79
+ "MCP tool called: search_historical_flights date=%s limit=%s filters=%s",
80
+ query.flight_date,
81
+ query.limit,
82
+ [
83
+ field
84
+ for field in ("airline_iata", "departure_iata", "arrival_iata")
85
+ if getattr(query, field) is not None
86
+ ],
87
+ )
88
+ records = await app.services.flight.get_historical_flights(query)
89
+ logger.debug(
90
+ "MCP tool completed: search_historical_flights returned=%s",
91
+ len(records),
92
+ )
93
+
94
+ return records
95
+
96
+ @server.tool(
97
+ name="get_flight_schedule",
98
+ title="Get Flight Schedule",
99
+ description=(
100
+ "Retrieve airport arrival or departure schedules using "
101
+ "an airport IATA code and schedule filters."
102
+ ),
103
+ )
104
+ @mcp_error_boundary
105
+ async def get_flight_schedule(
106
+ query: AirportScheduleQuery,
107
+ ctx: Context[AppContext],
108
+ ):
109
+ """Retrieve airport flight schedules."""
110
+
111
+ app = ctx.request_context.lifespan_context
112
+ logger.info(
113
+ "MCP tool called: get_flight_schedule airport=%s type=%s airline_filter=%s limit=%s",
114
+ query.airport_iata,
115
+ query.schedule_type.value,
116
+ query.airline_name is not None,
117
+ query.limit,
118
+ )
119
+ records = await app.services.flight.get_airport_schedule(query)
120
+ logger.debug(
121
+ "MCP tool completed: get_flight_schedule returned=%s",
122
+ len(records),
123
+ )
124
+
125
+ return records
@@ -0,0 +1,129 @@
1
+ import logging
2
+
3
+ from mcp.server.mcpserver import Context
4
+
5
+ from aviationstack_mcp_server.mcp.dependencies import AppContext
6
+ from aviationstack_mcp_server.mcp.errors import mcp_error_boundary
7
+ from aviationstack_mcp_server.models.queries import (
8
+ RecordLimitQuery,
9
+ RouteSearchQuery,
10
+ TaxSearchQuery,
11
+ )
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ def register_reference_tools(server) -> None:
17
+ """Register reference-data MCP tools."""
18
+
19
+ @server.tool(
20
+ name="list_countries",
21
+ title="List Countries",
22
+ description=(
23
+ "List country records available from Aviationstack. "
24
+ "Use the limit parameter to control the number of records."
25
+ ),
26
+ )
27
+ @mcp_error_boundary
28
+ async def list_countries(
29
+ query: RecordLimitQuery,
30
+ ctx: Context[AppContext],
31
+ ):
32
+ """List country reference records."""
33
+
34
+ app = ctx.request_context.lifespan_context
35
+ logger.info("MCP tool called: list_countries limit=%s", query.limit)
36
+ records = await app.services.reference.list_countries(query)
37
+ logger.debug(
38
+ "MCP tool completed: list_countries returned=%s",
39
+ len(records),
40
+ )
41
+
42
+ return records
43
+
44
+ @server.tool(
45
+ name="list_cities",
46
+ title="List Cities",
47
+ description=(
48
+ "List city records available from Aviationstack. "
49
+ "Use the limit parameter to control the number of records."
50
+ ),
51
+ )
52
+ @mcp_error_boundary
53
+ async def list_cities(
54
+ query: RecordLimitQuery,
55
+ ctx: Context[AppContext],
56
+ ):
57
+ """List city reference records."""
58
+
59
+ app = ctx.request_context.lifespan_context
60
+ logger.info("MCP tool called: list_cities limit=%s", query.limit)
61
+ records = await app.services.reference.list_cities(query)
62
+ logger.debug(
63
+ "MCP tool completed: list_cities returned=%s",
64
+ len(records),
65
+ )
66
+
67
+ return records
68
+
69
+ @server.tool(
70
+ name="search_routes",
71
+ title="Search Routes",
72
+ description=(
73
+ "Search airline route records using supported route "
74
+ "filters such as airline, departure airport, arrival "
75
+ "airport, and pagination."
76
+ ),
77
+ )
78
+ @mcp_error_boundary
79
+ async def search_routes(
80
+ query: RouteSearchQuery,
81
+ ctx: Context[AppContext],
82
+ ):
83
+ """Search route records."""
84
+
85
+ app = ctx.request_context.lifespan_context
86
+ logger.info(
87
+ "MCP tool called: search_routes limit=%s offset=%s filters=%s",
88
+ query.limit,
89
+ query.offset,
90
+ [
91
+ field
92
+ for field in ("airline_iata", "departure_iata", "arrival_iata")
93
+ if getattr(query, field) is not None
94
+ ],
95
+ )
96
+ records = await app.services.reference.search_routes(query)
97
+ logger.debug(
98
+ "MCP tool completed: search_routes returned=%s",
99
+ len(records),
100
+ )
101
+
102
+ return records
103
+
104
+ @server.tool(
105
+ name="search_taxes",
106
+ title="Search Taxes",
107
+ description=("Search aviation tax records using supported tax filters and pagination."),
108
+ )
109
+ @mcp_error_boundary
110
+ async def search_taxes(
111
+ query: TaxSearchQuery,
112
+ ctx: Context[AppContext],
113
+ ):
114
+ """Search tax records."""
115
+
116
+ app = ctx.request_context.lifespan_context
117
+ logger.info(
118
+ "MCP tool called: search_taxes limit=%s offset=%s search_provided=%s",
119
+ query.limit,
120
+ query.offset,
121
+ query.search is not None,
122
+ )
123
+ records = await app.services.reference.search_taxes(query)
124
+ logger.debug(
125
+ "MCP tool completed: search_taxes returned=%s",
126
+ len(records),
127
+ )
128
+
129
+ return records
@@ -0,0 +1,81 @@
1
+ from .aircraft import (
2
+ AircraftType,
3
+ AircraftTypeResponse,
4
+ Airplane,
5
+ AirplaneResponse,
6
+ )
7
+ from .airline import Airline, AirlineResponse
8
+ from .airport import Airport, AirportResponse
9
+ from .common import AviationstackModel, AviationstackResponse
10
+ from .flight import (
11
+ AirlineReference,
12
+ AirportReference,
13
+ Flight,
14
+ FlightAircraftReference,
15
+ FlightIdentifier,
16
+ FlightResponse,
17
+ ScheduleFlight,
18
+ ScheduleFlightIdentifier,
19
+ ScheduleResponse,
20
+ ScheduleTimeReference,
21
+ )
22
+ from .location import City, CityResponse, Country, CountryResponse
23
+ from .queries import (
24
+ AirlineSearchQuery,
25
+ AirportScheduleQuery,
26
+ AirportSearchQuery,
27
+ FlightSearchQuery,
28
+ FutureScheduleQuery,
29
+ HistoricalFlightQuery,
30
+ PaginationQuery,
31
+ QueryModel,
32
+ RecordLimitQuery,
33
+ RouteSearchQuery,
34
+ ScheduleType,
35
+ TaxSearchQuery,
36
+ )
37
+ from .route import Route, RouteResponse
38
+ from .tax import Tax, TaxResponse
39
+
40
+ __all__ = [
41
+ "AircraftType",
42
+ "AircraftTypeResponse",
43
+ "Airline",
44
+ "AirlineReference",
45
+ "AirlineResponse",
46
+ "Airport",
47
+ "AirportReference",
48
+ "AirportResponse",
49
+ "AviationstackModel",
50
+ "AviationstackResponse",
51
+ "Airplane",
52
+ "AirplaneResponse",
53
+ "City",
54
+ "CityResponse",
55
+ "Country",
56
+ "CountryResponse",
57
+ "Flight",
58
+ "FlightAircraftReference",
59
+ "FlightIdentifier",
60
+ "FlightResponse",
61
+ "Route",
62
+ "RouteResponse",
63
+ "ScheduleFlight",
64
+ "ScheduleFlightIdentifier",
65
+ "ScheduleResponse",
66
+ "ScheduleTimeReference",
67
+ "Tax",
68
+ "TaxResponse",
69
+ "AirlineSearchQuery",
70
+ "AirportScheduleQuery",
71
+ "AirportSearchQuery",
72
+ "FlightSearchQuery",
73
+ "FutureScheduleQuery",
74
+ "HistoricalFlightQuery",
75
+ "PaginationQuery",
76
+ "QueryModel",
77
+ "RecordLimitQuery",
78
+ "RouteSearchQuery",
79
+ "ScheduleType",
80
+ "TaxSearchQuery",
81
+ ]
@@ -0,0 +1,43 @@
1
+ from __future__ import annotations
2
+
3
+ from pydantic import Field
4
+
5
+ from aviationstack_mcp_server.models.common import AviationstackModel
6
+
7
+
8
+ class AircraftType(AviationstackModel):
9
+ """Aircraft type reference data."""
10
+
11
+ aircraft_name: str | None = None
12
+ iata_code: str | None = None
13
+ icao_code: str | None = None
14
+
15
+
16
+ class AircraftTypeResponse(AviationstackModel):
17
+ """Response containing aircraft types."""
18
+
19
+ pagination: dict | None = None
20
+ data: list[AircraftType] = Field(default_factory=list)
21
+
22
+
23
+ class Airplane(AviationstackModel):
24
+ """Detailed airplane information."""
25
+
26
+ production_line: str | None = None
27
+ plane_owner: str | None = None
28
+ plane_age: int | float | None = None
29
+ model_name: str | None = None
30
+ model_code: str | None = None
31
+ plane_series: str | None = None
32
+ registration_number: str | None = None
33
+ engines_type: str | None = None
34
+ engines_count: int | None = None
35
+ delivery_date: str | None = None
36
+ first_flight_date: str | None = None
37
+
38
+
39
+ class AirplaneResponse(AviationstackModel):
40
+ """Response containing airplane records."""
41
+
42
+ pagination: dict | None = None
43
+ data: list[Airplane] = Field(default_factory=list)