---
summary: "Adds `ourairports_search_runways` — cross-airport runway-attribute search over the bundled corpus by airport facets (country/region/type) and runway facets (surface, min length/width, lighting), one flat airport-plus-runway row per match (#8)."
breaking: false
security: false
---

# 0.2.0 — 2026-07-18

## Added

- **`ourairports_search_runways`** — cross-airport runway search, the counterpart to `ourairports_get_airport`'s per-airport runway list. Narrows airports by `country` / `region` / `type`, then filters their runways by `surface`, `min_length_ft`, `min_width_ft`, and `lighted`, returning one flat `{ airport, runway }` row per matching runway with total-match and truncation disclosure. ([#8](https://github.com/cyanheads/ourairports-mcp-server/issues/8))
- **`surface` substring match** — case-insensitive substring against the raw upstream surface string (no controlled vocabulary: `asp` matches ASP / ASPH / Asphalt), not an exact code.
- **Sparse threshold exclusion** — a runway with an unknown length or width is dropped when the matching `min_*_ft` filter is set, never assumed to meet a threshold the data can't confirm.
- **Closed excluded by default** — closed airports and closed runways are both omitted unless `include_closed_airports` / `include_closed_runways` is set.
- **`AirportDataService.searchRunways()`** accessor plus the `RunwaySearchFilters` / `RunwayMatch` / `RunwaySearchResult` types. Tool count 5 → 6.

## Fixed

- **Test fixtures tracked** — the hand-curated CSVs under `tests/fixtures/data/` are now committed; the broad `data/` ignore is root-anchored to `/data/` so it no longer catches them, and the suite runs from a clean clone.
