Skip to main content
Glama
blevinstein

Aviation Model Context Protocol

by blevinstein

get_notams

Retrieve NOTAMs using ICAO, domestic locations, types, classifications, or other filters in formats like geoJson, aixm, or aidap. Supports aviation pre-flight and in-flight planning within the Aviation Model Context Protocol.

Instructions

Retrieves NOTAMs based on specified filters

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
classificationNoThe NOTAM classification
domesticLocationNoThe domestic location criteria (e.g., 'IAD' for Dulles International Airport)
effectiveEndDateNoThe effective end date
effectiveStartDateNoThe effective start date
featureTypeNoThe feature type filter
icaoLocationNoThe ICAO location criteria (e.g., 'KIAD' for Dulles International Airport)
lastUpdatedDateNoThe last update date
locationLatitudeNoThe location latitude (e.g., 60.57)
locationLongitudeNoThe location longitude (e.g., -151.24)
locationRadiusNoThe location radius in nautical miles (max: 100)
notamNumberNoThe NOTAM number (e.g., 'CK0000/01')
notamTypeNoThe NOTAM type: 'N' for New, 'R' for Replaced, 'C' for Canceled
pageNumNoThe page number
pageSizeNoThe page size (max: 1000)
responseFormatNoResponse format for NOTAM datageoJson
sortByNoThe field to sort results by
sortOrderNoThe sort order

Implementation Reference

  • The core handler function that constructs the FAA NOTAM API request URL with filters, authenticates using env vars, fetches the data, and returns it as text content.
    async function handleNotams(
      responseFormat?: string,
      icaoLocation?: string,
      domesticLocation?: string,
      notamType?: string,
      classification?: string,
      notamNumber?: string,
      effectiveStartDate?: string,
      effectiveEndDate?: string,
      featureType?: string,
      locationLongitude?: number,
      locationLatitude?: number,
      locationRadius?: number,
      lastUpdatedDate?: number,
      sortBy?: string,
      sortOrder?: string,
      pageSize?: number,
      pageNum?: number,
    ) {
      // Set default format if not provided
      responseFormat = responseFormat || 'geoJson';
      
      // Construct the URL with query parameters
      const baseUrl = 'https://external-api.faa.gov/notamapi/v1/notams';
      const urlParams = new URLSearchParams();
      
      // Add parameters to URL if they exist
      if (responseFormat) urlParams.append('responseFormat', responseFormat);
      if (icaoLocation) urlParams.append('icaoLocation', icaoLocation);
      if (domesticLocation) urlParams.append('domesticLocation', domesticLocation);
      if (notamType) urlParams.append('notamType', notamType);
      if (classification) urlParams.append('classification', classification);
      if (notamNumber) urlParams.append('notamNumber', notamNumber);
      if (effectiveStartDate) urlParams.append('effectiveStartDate', effectiveStartDate);
      if (effectiveEndDate) urlParams.append('effectiveEndDate', effectiveEndDate);
      if (featureType) urlParams.append('featureType', featureType);
      if (locationLongitude !== undefined) urlParams.append('locationLongitude', locationLongitude.toString());
      if (locationLatitude !== undefined) urlParams.append('locationLatitude', locationLatitude.toString());
      if (locationRadius !== undefined) urlParams.append('locationRadius', locationRadius.toString());
      if (lastUpdatedDate !== undefined) urlParams.append('lastUpdatedDate', lastUpdatedDate.toString());
      if (sortBy) urlParams.append('sortBy', sortBy);
      if (sortOrder) urlParams.append('sortOrder', sortOrder);
      if (pageSize !== undefined) urlParams.append('pageSize', pageSize.toString());
      if (pageNum !== undefined) urlParams.append('pageNum', pageNum.toString());
      
      const url = `${baseUrl}?${urlParams.toString()}`;
      
      // Check if required auth credentials are provided
      if (!process.env.FAA_CLIENT_ID || !process.env.FAA_CLIENT_SECRET) {
        throw new Error('Client ID and Client Secret are required for NOTAM API authentication');
      }
      
      // Make the request with authentication headers
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Accept': 'application/json',
          'client_id': process.env.FAA_CLIENT_ID,
          'client_secret': process.env.FAA_CLIENT_SECRET
        }
      });
      
      if (!response.ok) {
        const errorText = await response.text();
        return {
          content: [
            {
              type: "text",
              text: `NOTAM API Error (${response.status}): ${errorText}`
            }
          ],
          isError: true
        }
      }
      
      const data = await response.text();
      return {
        content: [
          {
            type: "text",
            text: data
          }
        ],
        isError: false
      };
    }
  • Registers the 'get_notams' tool with name, description, and detailed input schema for MCP tool system.
    export const TOOLS: Tool[] = [
      {
        name: "get_notams",
        description: "Retrieves NOTAMs based on specified filters",
        inputSchema: {
          type: "object",
          properties: {
            responseFormat: {
              type: "string",
              enum: ["aixm", "geoJson", "aidap"],
              default: "geoJson",
              description: "Response format for NOTAM data"
            },
            icaoLocation: {
              type: "string",
              description: "The ICAO location criteria (e.g., 'KIAD' for Dulles International Airport)"
            },
            domesticLocation: {
              type: "string",
              description: "The domestic location criteria (e.g., 'IAD' for Dulles International Airport)"
            },
            notamType: {
              type: "string",
              enum: ["N", "R", "C"],
              description: "The NOTAM type: 'N' for New, 'R' for Replaced, 'C' for Canceled"
            },
            classification: {
              type: "string",
              enum: ["INTL", "MIL", "DOM", "LMIL", "FDC"],
              description: "The NOTAM classification"
            },
            notamNumber: {
              type: "string",
              description: "The NOTAM number (e.g., 'CK0000/01')"
            },
            effectiveStartDate: {
              type: "string",
              description: "The effective start date"
            },
            effectiveEndDate: {
              type: "string",
              description: "The effective end date"
            },
            featureType: {
              type: "string",
              enum: [
                "RWY", "TWY", "APRON", "AD", "OBST", "NAV", "COM", "SVC", "AIRSPACE",
                "ODP", "SID", "STAR", "CHART", "DATA", "DVA", "IAP", "VFP", "ROUTE",
                "SPECIAL", "SECURITY", "MILITARY", "INTERNATIONAL"
              ],
              description: "The feature type filter"
            },
            locationLongitude: {
              type: "number",
              description: "The location longitude (e.g., -151.24)"
            },
            locationLatitude: {
              type: "number",
              description: "The location latitude (e.g., 60.57)"
            },
            locationRadius: {
              type: "number",
              description: "The location radius in nautical miles (max: 100)"
            },
            lastUpdatedDate: {
              type: "number",
              description: "The last update date"
            },
            sortBy: {
              type: "string",
              enum: [
                "icaoLocation", "domesticLocation", "notamType", "notamNumber",
                "effectiveStartDate", "effectiveEndDate", "featureType"
              ],
              description: "The field to sort results by"
            },
            sortOrder: {
              type: "string",
              enum: ["Asc", "Desc"],
              description: "The sort order"
            },
            pageSize: {
              type: "number",
              default: 50,
              description: "The page size (max: 1000)"
            },
            pageNum: {
              type: "number",
              default: 1,
              description: "The page number"
            },
          },
        }
      }
    ];
  • Defines the input schema for the get_notams tool, including all filter parameters, types, enums, and descriptions.
    inputSchema: {
      type: "object",
      properties: {
        responseFormat: {
          type: "string",
          enum: ["aixm", "geoJson", "aidap"],
          default: "geoJson",
          description: "Response format for NOTAM data"
        },
        icaoLocation: {
          type: "string",
          description: "The ICAO location criteria (e.g., 'KIAD' for Dulles International Airport)"
        },
        domesticLocation: {
          type: "string",
          description: "The domestic location criteria (e.g., 'IAD' for Dulles International Airport)"
        },
        notamType: {
          type: "string",
          enum: ["N", "R", "C"],
          description: "The NOTAM type: 'N' for New, 'R' for Replaced, 'C' for Canceled"
        },
        classification: {
          type: "string",
          enum: ["INTL", "MIL", "DOM", "LMIL", "FDC"],
          description: "The NOTAM classification"
        },
        notamNumber: {
          type: "string",
          description: "The NOTAM number (e.g., 'CK0000/01')"
        },
        effectiveStartDate: {
          type: "string",
          description: "The effective start date"
        },
        effectiveEndDate: {
          type: "string",
          description: "The effective end date"
        },
        featureType: {
          type: "string",
          enum: [
            "RWY", "TWY", "APRON", "AD", "OBST", "NAV", "COM", "SVC", "AIRSPACE",
            "ODP", "SID", "STAR", "CHART", "DATA", "DVA", "IAP", "VFP", "ROUTE",
            "SPECIAL", "SECURITY", "MILITARY", "INTERNATIONAL"
          ],
          description: "The feature type filter"
        },
        locationLongitude: {
          type: "number",
          description: "The location longitude (e.g., -151.24)"
        },
        locationLatitude: {
          type: "number",
          description: "The location latitude (e.g., 60.57)"
        },
        locationRadius: {
          type: "number",
          description: "The location radius in nautical miles (max: 100)"
        },
        lastUpdatedDate: {
          type: "number",
          description: "The last update date"
        },
        sortBy: {
          type: "string",
          enum: [
            "icaoLocation", "domesticLocation", "notamType", "notamNumber",
            "effectiveStartDate", "effectiveEndDate", "featureType"
          ],
          description: "The field to sort results by"
        },
        sortOrder: {
          type: "string",
          enum: ["Asc", "Desc"],
          description: "The sort order"
        },
        pageSize: {
          type: "number",
          default: 50,
          description: "The page size (max: 1000)"
        },
        pageNum: {
          type: "number",
          default: 1,
          description: "The page number"
        },
      },
    }
  • The switch case in handleToolCall that extracts arguments from tool call and invokes the handleNotams function for 'get_notams' tool.
    case "get_notams": {
      const {
        responseFormat,
        icaoLocation,
        domesticLocation,
        notamType,
        classification,
        notamNumber,
        effectiveStartDate,
        effectiveEndDate,
        featureType,
        locationLongitude,
        locationLatitude,
        locationRadius,
        lastUpdatedDate,
        sortBy,
        sortOrder,
        pageSize,
        pageNum,
      } = args;
      
      return await handleNotams(
        responseFormat,
        icaoLocation,
        domesticLocation,
        notamType,
        classification,
        notamNumber,
        effectiveStartDate,
        effectiveEndDate,
        featureType,
        locationLongitude,
        locationLatitude,
        locationRadius,
        lastUpdatedDate,
        sortBy,
        sortOrder,
        pageSize,
        pageNum,
      );
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden but only states retrieval with filters. It lacks behavioral details like pagination handling (implied by pageNum/pageSize but not explained), rate limits, authentication needs, or response format implications (e.g., geoJson output). This leaves significant gaps in understanding tool behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the core action and scope without unnecessary words. It's appropriately sized for its purpose, with zero waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with 17 parameters, no annotations, and no output schema, the description is inadequate. It doesn't address behavioral aspects like pagination, response formats, or error handling, leaving the agent with insufficient context to use the tool effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so parameters are well-documented in the schema. The description adds no extra meaning beyond implying filters exist, which the schema already details. Baseline 3 is appropriate as the schema handles parameter semantics effectively.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Retrieves') and resource ('NOTAMs'), with scope ('based on specified filters'). It's specific about the action and subject matter, though without sibling tools to differentiate from, it can't achieve the highest score for sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool, such as scenarios or prerequisites. The description mentions filters but doesn't explain their application or alternatives, leaving usage context unclear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/blevinstein/aviation-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server