Skip to main content
Glama

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

Публичный размещённый сервер: https://ourairports.caseyjhand.com/mcp


Обзор

ourairports-mcp-server — это статический справочный слой авиационных данных для разрешения идентификаторов аэропортов и привязки координат. Он отвечает на вопрос что существует — каталог аэропортов, их коды, ВПП, радионавигационные средства и радиочастоты, — дополняя живые авиационные сервисы, которые отвечают на вопрос что происходит (погода, местоположения).

Весь набор данных OurAirports передан в общественное достояние и опубликован в виде плоских CSV-файлов. Эти шесть CSV-файлов — аэропорты, ВПП, радионавигационные средства, частоты аэропортов, страны и регионы (~178 тыс. строк, ~20 МБ) — входят в состав пакета и встраиваются в Docker-образ на этапе сборки. При запуске сервер разбирает их в индексы в памяти; после этого каждый инструмент — это локальный запрос. В результате нет ни API-ключа, ни ограничения частоты запросов, ни вышестоящей зависимости, от которой можно унаследовать сбой.

Как устроена рабочая модель:

  • Разрешение кодов в пяти пространствах идентификаторов. Аэропорты имеют коды IATA, ICAO, GPS, local и ident из OurAirports. Один параметр code разрешается через единый индекс (приоритет: ident → ICAO → IATA → GPS → local), а ответ повторяет полный набор кодов, так что неоднозначный национальный код сам себя корректирует. Отсутствующий код (нет IATA у небольшого аэродрома) сообщается как null, а не как 404.

  • Ближайший сосед по расстоянию большого круга. Координатные запросы выполняют гаверсинусное сканирование по плоскому Float64Array позиций всех аэропортов (или радионавигационных средств) и возвращают ближайшие результаты, отсортированные по расстоянию, каждый с азимутом — на таком масштабе это занимает доли миллисекунды, пространственный индекс не нужен.

  • Честная разрежённость. Отсутствующие поля из исходных данных (нет высоты, нулевые размеры ВПП) отображаются как неизвестные. Усечённые списки результатов явно сообщают об ограничении.

OurAirports редактируется сообществом. Данные предоставляются как есть и не являются авторитетными для реальных полётов — относитесь к ним так же, как к любому краудсорсинговому справочнику.

Related MCP server: mcp-metar

Инструменты

Шесть инструментов только для чтения, все — локальные запросы к встроенному индексу: разрешение кодов и детализация, поиск аэропортов и ВПП, привязка по координатам, радионавигационные средства и справочная таблица стран/регионов:

Инструмент

Описание

ourairports_search_airports

Полнотекстовый и фасетный поиск по корпусу аэропортов по названию, населённому пункту, стране, региону или типу. Ранжированные сводки, закрытые аэропорты по умолчанию исключены.

ourairports_search_runways

Поиск ВПП по всем аэропортам по покрытию, длине, ширине и освещению с обратным соединением с их аэропортами и фильтрацией по стране, региону или типу аэропорта. Одна плоская строка { airport, runway } на каждую подходящую ВПП.

ourairports_get_airport

Полная запись одного аэропорта, разрешённого по любому коду (IATA/ICAO/GPS/local/ident), с его ВПП и радиочастотами прямо в ответе.

ourairports_find_airports

Аэропорты в радиусе от координаты, отсортированные по расстоянию большого круга от ближайшего к дальнему, с расстоянием и азимутом.

ourairports_find_navaids

Радионавигационные средства (VOR, VOR-DME, DME, NDB, NDB-DME, TACAN, VORTAC) рядом с координатой или обслуживающие конкретный аэропорт.

ourairports_list_countries

Страны, присутствующие в наборе данных, с кодами ISO и количеством аэропортов; опциональный фильтр по континенту и вложенные регионы. Справочная таблица допустимых значений фильтров country/region.

ourairports_search_airports

Общая точка входа — поиск по свободному тексту, фасетам или тому и другому.

  • Полнотекстовый поиск по названию, населённому пункту и ключевым словам; токены сопоставляются по принципу И (учитываются порядок слов и частичные совпадения)

  • Фасетные фильтры: country (ISO 3166-1 alpha-2), region (ISO 3166-2) и type — country/region сопоставляются точно, без учёта регистра, окружающие пробелы игнорируются

  • Закрытые аэропорты по умолчанию исключены; включить можно с помощью include_closed

  • Результаты ранжированы: сначала действующие/более крупные аэропорты, каждый с полным набором кодов и координатами для передачи в ourairports_get_airport

  • Раскрытие усечения — общее количество совпадений, применённый лимит и подсказка, как расширить или сузить поиск


ourairports_search_runways

Поиск ВПП по всем аэропортам — аналог ourairports_get_airport, который перечисляет ВПП для одного уже известного аэропорта.

  • Фасеты аэропорта (country, region, type) сначала сужают множество аэропортов; фасеты ВПП (surface, min_length_ft, min_width_ft, lighted) затем фильтруют их ВПП

  • surface — это сопоставление подстроки без учёта регистра с исходной строкой покрытия из данных (без контролируемого словаря — более короткий фрагмент, например asp, соответствует ASP, ASPH и Asphalt), а не точный код

  • Возвращает одну плоскую строку { airport, runway } на каждую подходящую ВПП — аэропорт с тремя подходящими ВПП даёт три строки

  • ВПП, длина или ширина которой неизвестна, исключается, когда задан соответствующий фильтр min_*_ft — она никогда не считается удовлетворяющей порогу, который данные не могут подтвердить

  • Закрытые аэропорты и закрытые ВПП исключаются, если не заданы include_closed_airports / include_closed_runways

  • Раскрытие усечения — общее количество совпадений, применённый лимит и подсказка, как расширить или сузить поиск


ourairports_get_airport

Инструмент детализации — один вызов возвращает всё, что нужно в типовом случае.

  • Разрешает один code без учёта регистра во всех пяти пространствах идентификаторов (приоритет: ident → ICAO → IATA → GPS → local); окружающие пробелы игнорируются

  • ВПП и радиочастоты прямо в ответе; include сокращает ответ до подмножества, а поле included в выводе отличает связь, пропущенную из-за include, от связи, у которой действительно нет записей

  • Повторяет полный набор кодов аэропорта плюс resolvedVia / resolutionNote, с предупреждением о неоднозначности для общих национальных кодов, чтобы неверное разрешение само себя корректировало

  • Отсутствующие коды сообщаются как null; закрытые аэропорты разрешаются всегда

  • Ошибка unknown_code с подсказкой по восстановлению, когда не совпадает ни одно пространство идентификаторов


ourairports_find_airports

Инструмент привязки — превращает широту/долготу в ближайший(ие) аэропорт(ы).

  • Ранжирование по большому кругу (гаверсинус), от ближайшего к дальнему, каждый результат с distanceKm и bearingDeg (истинный азимут в градусах) от точки запроса

  • radius_km (1–500, по умолчанию 100), опциональный фильтр type, включение через include_closed

  • На входе координата, на выходе ранжированные аэропорты — без геокодирования; сначала преобразуйте названия мест в широту/долготу выше по потоку

  • Подсказка при пустом радиусе, предлагающая увеличить radius_km


ourairports_find_navaids

Радионавигационные средства двумя способами — пространственно или по аэропорту.

  • Режим координат: latitude + longitude (+ опциональный radius_km) ранжирует средства от ближайшего к дальнему с расстоянием и азимутом

  • Режим аэропорта: airport_code возвращает средства, обслуживающие этот аэропорт

  • Требуется ровно один режим — передача обоих или ни одного является ошибкой валидации

  • Частоты отображаются и в кГц (хранимое значение — VOR на 114,5 МГц читается как frequencyKhz 114500), и в МГц

  • Режим аэропорта отличает «аэропорт не найден» (ошибка unknown_code) от «аэропорт найден, но связанных радионавигационных средств нет» (пустой список с примечанием)


Ресурс и промпт

Тип

Имя

Описание

Ресурс

airport://{code}

Одна запись аэропорта по любому коду (IATA/ICAO/GPS/local/ident), с ВПП и частотами прямо в ответе.

Ресурс airport://{code} — это стабильный URI-двойник ourairports_get_airport для клиентов, которые внедряют контекст ресурсов. Все данные доступны и через одни инструменты — клиенты, работающие только с инструментами, ничего не теряют. Корпус не предоставляется в виде списка ресурсов (перечисление 85 000 аэропортов — это выгрузка, а не средство обнаружения); обнаружение выполняется через ourairports_search_airports.

Возможности

Построен на @cyanheads/mcp-ts-core:

  • Декларативные определения инструментов и ресурсов — один файл на примитив, регистрацию и валидацию берёт на себя фреймворк

  • Единая обработка ошибок — обработчики выбрасывают исключения, фреймворк перехватывает, классифицирует и форматирует их

  • Подключаемая аутентификация: none, jwt, oauth

  • Сменяемые хранилища: in-memory, filesystem, Supabase, Cloudflare KV/R2/D1

  • Структурированное логирование с опциональной трассировкой OpenTelemetry

  • Запускается локально (stdio/HTTP) или на Cloudflare Workers из одной и той же кодовой базы

Специфичное для OurAirports:

  • Встроенный набор данных в общественном достоянии, включённый в пакет и Docker-образ — без обращения к API в рантайме, без ключа, без ограничения частоты запросов, без сбоев вышестоящего сервиса

  • Индексы в памяти, создаваемые один раз при запуске: карты идентификаторов, приоритетно упорядоченный единый индекс кодов, соединения по ссылкам на аэропорты для ВПП и частот, соединение навигационных средств по идентификатору, плоский Float64Array координат, карты стран/регионов и токенизированный индекс текстового поиска

  • Полный перебор по формуле гаверсинуса для поиска ближайшего соседа по массиву координат — менее миллисекунды на 85 000 аэропортов, без зависимости от пространственного индекса

  • CSV-файлы разбираются по имени заголовка, а не по позиции столбца, поэтому перестановка столбцов в вышестоящем источнике не может незаметно нарушить соответствие полей

Вывод, удобный для агентов:

  • Честная разрежённость — отсутствующие поля вышестоящего источника (нет IATA, нет высоты, размеры ВПП равны null) отображаются как null, а не выдумываются

  • Самокорректирующееся разрешение — каждая запись аэропорта повторяет полный набор кодов и resolvedVia / resolutionNote, с предупреждением о неоднозначности для общих национальных кодов

  • Раскрытие информации об усечении и пустых результатах — общее количество, применённые ограничения и рекомендации по восстановлению, чтобы вызывающие стороны могли расширить, сузить или повторить запрос, не разбирая текст

Начало работы

Публичный инстанс

Публичный инстанс доступен по адресу https://ourairports.caseyjhand.com/mcp — установка не требуется. Подключите любой MCP-клиент к нему через Streamable HTTP, используя следующую конфигурацию клиента:

{
  "mcpServers": {
    "ourairports-mcp-server": {
      "type": "streamable-http",
      "url": "https://ourairports.caseyjhand.com/mcp"
    }
  }
}

Локальный / на собственном сервере

Добавьте следующее в файл конфигурации вашего MCP-клиента.

{
  "mcpServers": {
    "ourairports-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/ourairports-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

Или с помощью npx (Bun не требуется):

{
  "mcpServers": {
    "ourairports-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/ourairports-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

Или с помощью Docker:

{
  "mcpServers": {
    "ourairports-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "MCP_TRANSPORT_TYPE=stdio",
        "ghcr.io/cyanheads/ourairports-mcp-server:latest"
      ]
    }
  }
}

API-ключ не требуется — набор данных поставляется вместе с пакетом и образом.

Для Streamable HTTP укажите транспорт и запустите сервер:

MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp

Предварительные требования

  • Bun v1.3.0 или выше (или Node.js v24+).

  • Не требуется API-ключ, учётная запись или внешний сервис — все данные входят в комплект.

Установка

  1. Клонируйте репозиторий:

git clone https://github.com/cyanheads/ourairports-mcp-server.git
  1. Перейдите в каталог:

cd ourairports-mcp-server
  1. Установите зависимости:

bun install
  1. Загрузите и соберите набор данных (записывает шесть CSV-файлов в data/):

bun run build:data

Обновление данных

Встроенный снимок данных актуален на момент последнего запуска build:data (или, для Docker-образа, последней сборки). Чтобы получить последнюю ежедневную выгрузку из зеркала OurAirports, повторно выполните bun run build:data и пересоберите. Чтобы указать на существующую локальную выгрузку данных без пересборки, задайте переменную OURAIRPORTS_DATA_DIR.

Конфигурация

Переменная

Описание

По умолчанию

OURAIRPORTS_DATA_DIR

Каталог, содержащий шесть CSV-файлов OurAirports. Можно переопределить, чтобы указать на более свежую локальную выгрузку данных.

Встроенный data/

OURAIRPORTS_DEFAULT_SEARCH_LIMIT

Максимальное количество результатов по умолчанию для инструментов поиска, если вызывающая сторона не указала limit (1–100).

20

MCP_TRANSPORT_TYPE

Транспорт: stdio или http.

stdio

MCP_HTTP_PORT

Порт HTTP-сервера.

3010

MCP_HTTP_ENDPOINT_PATH

Путь HTTP-эндпоинта, по которому смонтирован сервер.

/mcp

MCP_AUTH_MODE

Режим аутентификации: none, jwt или oauth.

none

MCP_SESSION_MODE

Режим HTTP-сессии: stateful, stateless или auto. Этот сервер использует режим stateless, поскольку ни один инструмент не запрашивает последующий ввод.

stateless

MCP_LOG_LEVEL

Уровень журналирования (RFC 5424).

info

LOGS_DIR

Каталог для файлов журналов (только Node.js).

<project-root>/logs

STORAGE_PROVIDER_TYPE

Серверная часть хранилища (не используется на пути данных — индекс находится в памяти).

in-memory

OTEL_ENABLED

Включить инструментирование OpenTelemetry.

false

Полный список дополнительных переопределений см. в .env.example.

Запуск сервера

Локальная разработка

  • Сборка и запуск:

    # One-time data fetch + build
    bun run build:data
    bun run rebuild
    
    # Run the built server
    bun run start:stdio
    # or
    bun run start:http
  • Запуск проверок и тестов:

    bun run devcheck   # Lint, format, typecheck, security
    bun run test       # Vitest test suite
    bun run lint:mcp   # Validate MCP definitions against spec

Docker

docker build -t ourairports-mcp-server .
docker run --rm -e MCP_TRANSPORT_TYPE=stdio ourairports-mcp-server

На этапе сборки выполняется bun run build:data, поэтому набор данных загружается и включается в образ — итоговый контейнер полностью автономен и не выполняет сетевых вызовов во время работы. В Dockerfile по умолчанию используются HTTP-транспорт, режим сессии stateless и журналирование в /var/log/ourairports-mcp-server. Пиринговые зависимости OpenTelemetry устанавливаются по умолчанию — соберите с --build-arg OTEL_ENABLED=false, чтобы исключить их.

Структура проекта

Каталог

Назначение

src/index.ts

Точка входа createApp() — регистрирует инструменты/ресурсы и загружает встроенный индекс в setup().

src/config

Разбор и проверка переменных окружения, специфичных для сервера, с помощью Zod.

src/mcp-server/tools

Определения инструментов (*.tool.ts). Шесть инструментов только для чтения: аэропорты, ВПП, навигационные средства.

src/mcp-server/resources

Определения ресурсов. Запись airport://{code}.

src/services/airport-data

Сервис встроенных данных — разбор CSV, индексы в памяти, разрешение кодов, поиск и геосканирование по формуле гаверсинуса.

scripts/build-data.ts

Загрузчик на этапе сборки, который включает шесть CSV-файлов OurAirports в data/.

tests/

Модульные и интеграционные тесты, повторяющие структуру src/.

Руководство по разработке

Рекомендации по разработке и архитектурные правила см. в CLAUDE.md/AGENTS.md. Краткая версия:

  • Обработчики выбрасывают исключения, фреймворк перехватывает — никаких try/catch в логике инструментов

  • Используйте ctx.log для журналирования в рамках запроса и ctx.state для хранилища в рамках тенанта

  • Регистрируйте новые инструменты и ресурсы через barrel-файлы в src/mcp-server/*/definitions/index.ts

  • Предоставляйте данные вышестоящего источника как есть: отсутствующие поля указывайте как null, никогда не выдумывайте недостающие значения

Атрибуция

Данные об аэропортах, ВПП, навигационных средствах и частотах предоставлены OurAirports и переданы в общественное достояние. Атрибуция — это жест вежливости, а не требование. Исходные CSV-файлы публикуются ежедневно на davidmegginson.github.io/ourairports-data.

Участие в разработке

Приветствуются issue и pull request. Перед отправкой запустите проверки и тесты:

bun run devcheck
bun run test

Лицензия

Apache-2.0 — подробности см. в LICENSE.

Related MCP Connectors

Related MCP Servers