Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/issue.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
You are a helpful assistant responding to a GitHub Issue created by user @${{ github.actor }}
in the repository ${{ github.server_url }}/${{ github.repository }}
Provide initial triage and troubleshooting steps, then gather any additional information needed to proceed.
Respond using your general knowledge and the following knowledge files:
Respond using your general knowledge of MCP Servers and the following knowledge files:
file: |
README.md
tail: |
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ jobs:
with:
shellcheck_opts: -e SC2012

- name: "Build"
if: ${{ !cancelled() }}
run: |
uv run hatch build

#- name: "pytest"
# if: ${{ !cancelled() }}
# id: coverage
Expand Down
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ classifiers = [
"Typing :: Typed",
]
dependencies = [
"hishel[httpx]>=1.2.1",
"hishel[httpx]>=1.0.0",
"httpx>=0.28.0",
"mcp[cli]>=1.27.1",
"mcp[cli]>=1.27.0",
"pydantic>=2.0.0",
"uvicorn>=0.47.0",
"watchfiles>=1.0.0",
"uvicorn>=0.31.1",
]
dynamic = ["version"]

Expand Down Expand Up @@ -47,6 +46,7 @@ dev = [
"toml-run>=0.0.2",
"ty>=0.0.39",
"validate-pyproject[all]>=0.25",
"watchfiles>=1.2.0",
"yamllint>=1.38.0",
]

Expand Down
23 changes: 22 additions & 1 deletion src/flightaware_mcp/server.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import logging
import os
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from dataclasses import dataclass
Expand All @@ -13,6 +14,7 @@

from ._version import __version__
from .fa import FlightAware
from .utils import str_to_bool

logger = logging.getLogger(__name__)

Expand All @@ -38,7 +40,7 @@ async def app_lifespan(server: FastMCP) -> AsyncIterator[AppContext]:
"flightaware",
lifespan=app_lifespan,
json_response=True,
stateless_http=True,
stateless_http=str_to_bool(os.environ.get("STATELESS_HTTP", "true")),
transport_security=TransportSecuritySettings(enable_dns_rebinding_protection=False),
)

Expand Down Expand Up @@ -80,6 +82,25 @@ async def iata_to_icao(
return CallToolResult(content=[TextContent(type="text", text=text)], isError=not result)


@mcp.tool()
async def aircraft_data_links(
registration_number: Annotated[str, Field(description="Aircraft Registration Number, ex: N1234, C-ABCD")],
) -> CallToolResult:
"""Return useful links for a given Aircraft Registration"""
logger.info("aircraft_data_links: %s", registration_number)
reg = registration_number.strip().upper()
links = {
"FlightAware Registration": f"https://flightaware.com/resources/registration/{reg}",
"FlightRadar24 Aircraft": f"https://www.flightradar24.com/data/aircraft/{reg}",
"Airfleets Search": f"https://www.airfleets.net/recherche/?key={reg}",
"JetPhotos": f"https://www.jetphotos.com/registration/{reg}",
"Aviation Herald Search": f"https://avherald.com/h?dosearch=1&search_term={reg}",
}
text = json.dumps(links)
logger.info("text: %s", text)
return CallToolResult(content=[TextContent(type="text", text=text)])


def main():
mcp.run(transport="stdio")

Expand Down
7 changes: 7 additions & 0 deletions src/flightaware_mcp/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from typing import Any


def str_to_bool(value: Any) -> bool:
if str(value).strip().lower() in ["1", "on", "t", "true", "y", "yes"]:
return True
return False
Loading