Skip to main content
Glama
Bellaposa
by Bellaposa
README.md
# āœˆļø Airplane Tracker MCP Server

![Python](https://img.shields.io/badge/python-3.8+-blue.svg)
![MCP](https://img.shields.io/badge/MCP-v1.17.0-orange.svg)
![License](https://img.shields.io/badge/license-MIT-green.svg)
![API](https://img.shields.io/badge/API-airplanes.live-red.svg)

![Airplane Tracker Banner](./images/airplane-banner.png)

## šŸŽÆ Overview

This MCP server integrates with the **airplanes.live API** to provide real-time aircraft tracking capabilities to Claude Desktop. Track flights, find aircraft by callsign, registration, or position - all directly from Claude!

## āš ļø Important Notice - Terms of Use

> **šŸ“– Educational and Non-Commercial Use Only**
> 
> This project uses the [airplanes.live API](https://airplanes.live/api-guide/) which is provided for **educational and non-commercial purposes only**. Please respect their terms of service.
>
> ### šŸ“‹ Usage Guidelines:
> - āœ… **Educational projects** - Learning and research
> - āœ… **Personal use** - Non-commercial tracking
> - āœ… **Open source contributions** - Community development
> - āŒ **Commercial applications** - Business/profit purposes
> - āŒ **High-volume requests** - Respect rate limits
>
> ### šŸ›”ļø Disclaimer:
> **The author of this MCP server does not assume any responsibility for the use of this software.** This is a community contribution intended for educational purposes and to demonstrate MCP server development. Users are responsible for complying with airplanes.live API terms and any applicable regulations.
>
> ### 🌐 Respect for Existing Services:
> **This project does NOT intend to replace or compete with the official [airplanes.live globe viewer](https://globe.airplanes.live).** The official globe is the primary and recommended way to visualize flight data. This MCP server is designed as a complementary educational tool for Claude Desktop integration and MCP development learning.
>
> šŸ“– **Full API Terms**: https://airplanes.live/api-guide/  
> šŸŒ **Official Globe Viewer**: https://globe.airplanes.live

## šŸ“ø Screenshots

<div align="center">

![Claude Desktop with Airplane Tracker](./images/claude-screenshot.png)
*Real-time airplane tracking in Claude Desktop*

</div>

### šŸš€ Features

- šŸ” **Search by Callsign** - Find specific flights (e.g., UAL123)
- šŸ“‹ **Registration Lookup** - Track by tail number (e.g., N12345)
- šŸŽÆ **Position-based Search** - Aircraft near coordinates
- šŸ·ļø **Hex ID Search** - Mode S transponder codes
- šŸ›”ļø **Military Aircraft** - Tracked military flights
- 🚁 **LADD Aircraft** - Law enforcement tracking
- ⭐ **PIA Aircraft** - Private/Interesting aircraft
- šŸ“” **Squawk Codes** - Emergency and special codes


*Various API search examples*

## šŸ—ļø Architecture

### šŸ”§ Components

- šŸ **Python MCP Server** - Async server implementation
- 🌐 **MCP Framework** - Modern server architecture  
- ⚔ **httpx Client** - High-performance HTTP requests
- šŸ“Š **Data Formatter** - Clean, readable aircraft information
- šŸ”Œ **Claude Integration** - Direct MCP protocol support

### šŸ“Š Data Flow

```mermaid
graph TD
    A[Claude Desktop] --> B[MCP Protocol]
    B --> C[airplane_server.py]
    C --> D[API Functions]
    D --> E[airplanes.live API]
    E --> F[Aircraft Data]
    F --> G[Formatted Response]
    G --> A
```

*System architecture and data flow*

## šŸš€ Quick Start

### šŸ“‹ Prerequisites

- šŸ Python 3.8+
- šŸ’» Claude Desktop
- 🌐 Internet connection

### ⚔ Installation

```bash
# 1. Clone the repository
git clone https://github.com/Bellaposa/airplanes-live-mcp.git
cd airplanes-live-mcp

# 2. Create virtual environment (REQUIRED!)
python -m venv .venv

# 3. Activate virtual environment
# macOS/Linux:
source .venv/bin/activate
# Windows:
.venv\Scripts\activate

# 4. Install dependencies
pip install -r requirements.txt

# 5. Test the server
python airplane_server.py
```

#### āš ļø **Common Issues & Solutions**

**šŸ”„ Virtual Environment is MANDATORY!**
- If you skip step 2-3, you'll get `ModuleNotFoundError: No module named 'httpx'`
- Claude Desktop needs the **full path** to the venv Python, not system Python
- Without venv, dependencies aren't isolated and things break

**🪟 Windows Users:**
- Virtual env creates `.venv\Scripts\` folder (not `.venv\bin\`)
- Use `Scripts\python.exe` in Claude config, not `bin/python`
- Always use double backslashes `\\` in JSON paths

**šŸ Python Path Issues:**
- Make sure Python 3.8+ is installed: `python --version`
- If `python` doesn't work, try `python3` or `py`
- Virtual environment MUST exist before configuring Claude Desktop

## 🐳 Docker Installation (Alternative)

**Skip Python setup headaches - use Docker instead!**

### šŸ“‹ Prerequisites

- 🐳 Docker Desktop installed and running
- šŸ’» Claude Desktop

### ⚔ Docker Setup

```bash
# 1. Clone the repository
git clone https://github.com/Bellaposa/airplanes-live-mcp.git
cd airplanes-live-mcp

# 2. Build Docker image
docker build -t airplane-mcp-server .

# 3. Test the container
docker run --rm -it airplane-mcp-server python airplane_server.py
```

### āš™ļø Claude Desktop Configuration for Docker

#### šŸŽ **macOS/Linux with Docker**

Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "airplanes-live": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i", 
        "airplane-mcp-server", 
        "python", "airplane_server.py"
      ]
    }
  }
}
```

#### 🪟 **Windows with Docker**

Add to `%APPDATA%\Claude\claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "airplanes-live": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i", 
        "airplane-mcp-server", 
        "python", "airplane_server.py"
      ]
    }
  }
}
```

### šŸ”„ Docker Commands Reference

```bash
# Build the image
docker build -t airplane-mcp-server .

# Run interactively for testing
docker run --rm -it airplane-mcp-server bash

# Check if image exists
docker images | grep airplane-mcp-server

# Remove image if needed
docker rmi airplane-mcp-server

# View container logs (if running detached)
docker logs <container_id>
```

### āœ… **Docker Advantages**

- šŸš€ **No Python setup required** - Everything pre-configured
- šŸ”’ **Isolated environment** - No dependency conflicts
- šŸŒ **Works everywhere** - Same setup on Windows/Mac/Linux  
- šŸ“¦ **Easy updates** - Just rebuild the image
- šŸ›”ļø **Consistent behavior** - Eliminates "works on my machine"

### āš ļø **Docker Troubleshooting**

**Problem: "docker: command not found"**
```bash
# Install Docker Desktop first
# macOS: https://docs.docker.com/desktop/install/mac-install/
# Windows: https://docs.docker.com/desktop/install/windows-install/
# Linux: https://docs.docker.com/desktop/install/linux-install/
```

**Problem: "Cannot connect to Docker daemon"**
```bash
# Start Docker Desktop application
# Wait for Docker to fully start (green icon)
```

**Problem: "Permission denied" (Linux)**
```bash
# Add user to docker group
sudo usermod -aG docker $USER
# Log out and back in, or:
newgrp docker
```

**Problem: Image build fails**
```bash
# Clean Docker cache
docker system prune -a
# Try building again
docker build --no-cache -t airplane-mcp-server .
```

### šŸŽÆ **Even Easier: Docker Compose**

For the simplest setup, use Docker Compose:

```bash
# 1. Clone and enter directory
git clone https://github.com/Bellaposa/airplanes-live-mcp.git
cd airplanes-live-mcp

# 2. Build and run with one command
docker-compose up --build

# 3. In another terminal, test the server
docker-compose exec airplane-mcp-server python airplane_server.py
```

**Docker Compose Claude Configuration:**

```json
{
  "mcpServers": {
    "airplanes-live": {
      "command": "docker-compose", 
      "args": [
        "-f", "/path/to/airplanes-live-mcp/docker-compose.yml",
        "exec", "-T", "airplane-mcp-server", 
        "python", "airplane_server.py"
      ],
      "cwd": "/path/to/airplanes-live-mcp"
    }
  }
}
```

### 🐳 **How to Use with Claude Desktop**

#### **Method 1: Simple Docker Run**

**Configuration for all platforms:**

```json
{
  "mcpServers": {
    "airplanes-live": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i", 
        "airplane-mcp-server", 
        "python", "airplane_server.py"
      ]
    }
  }
}
```

#### **Method 2: Docker Compose (Advanced)**

**Configuration with full paths:**

```json
{
  "mcpServers": {
    "airplanes-live": {
      "command": "docker-compose",
      "args": [
        "-f", "/full/path/to/your/airplanes-live-mcp/docker-compose.yml",
        "exec", "-T", "airplane-mcp-server", 
        "python", "airplane_server.py"
      ],
      "cwd": "/full/path/to/your/airplanes-live-mcp"
    }
  }
}
```

#### **Complete Docker Setup Steps:**

```bash
# 1. Clone and build
git clone https://github.com/Bellaposa/airplanes-live-mcp.git
cd airplanes-live-mcp
docker build -t airplane-mcp-server .

# 2. Configure Claude Desktop with Method 1 (above)

# 3. Restart Claude Desktop completely

# 4. Test with: "Show me aircraft near New York"
```

#### **šŸŽÆ Docker vs Python Comparison:**

| Method | Pros | Cons | Best For |
|--------|------|------|----------|
| **Docker** | āœ… No Python setup<br>āœ… Works everywhere<br>āœ… Isolated | āŒ Requires Docker<br>āŒ Slight overhead | Beginners, Windows users |
| **Python** | āœ… Direct execution<br>āœ… Easy debugging<br>āœ… No Docker needed | āŒ Manual Python setup<br>āŒ OS-specific issues | Developers, experienced users |

**Docker Compose Commands:**

```bash
# Start services in background
docker-compose up -d

# View logs
docker-compose logs airplane-mcp-server

# Stop services
docker-compose down

# Rebuild and restart
docker-compose up --build
```

```

### āš™ļø Claude Desktop Configuration

#### šŸŽ **macOS/Linux Configuration**

Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `~/.config/claude-desktop/config.json` (Linux):

```json
{
  "mcpServers": {
    "airplanes-live": {
      "command": "/path/to/airplanes-live-mcp/.venv/bin/python",
      "args": ["/path/to/airplanes-live-mcp/airplane_server.py"],
      "env": {
        "PYTHONPATH": "/path/to/airplanes-live-mcp"
      }
    }
  }
}
```

#### 🪟 **Windows Configuration**

Add to `%APPDATA%\Claude\claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "airplanes-live": {
      "command": "C:\\Users\\YourUsername\\airplanes-live-mcp\\.venv\\Scripts\\python.exe",
      "args": ["C:\\Users\\YourUsername\\airplanes-live-mcp\\airplane_server.py"],
      "env": {
        "PYTHONPATH": "C:\\Users\\YourUsername\\airplanes-live-mcp"
      }
    }
  }
}
```

**āš ļø Important Windows Notes:**
- Use `Scripts\\python.exe` (not `bin/python`)
- Replace `YourUsername` with your actual Windows username
- Use double backslashes `\\` in paths
- Make sure the virtual environment is created with `python -m venv .venv`


*Claude Desktop configuration*

## šŸŽ® Usage Examples

### Search by Callsign
```
šŸ” Find flight UAL123
```

### Near Position Search  
```
šŸ“ Show aircraft near 40.7128, -74.0060 within 50nm
```

### Military Aircraft
```
šŸ›”ļø Show all military aircraft
```

## šŸ”§ Key Design Decisions

### 1. Async Implementation

All tools use `async` to handle multiple requests efficiently:

```python
@mcp.tool()
async def aircraft_near_position(latitude: str = "", longitude: str = "", radius: str = "250") -> str:
```

This allows the server to handle concurrent requests without blocking.

### 2. String-Based Parameters

All parameters are strings because MCP protocols work best with simple types:

```python
# Correct
def tool(param: str = "") -> str:

# Avoid
def tool(param: Optional[int] = None) -> str:
```

### 3. Error Handling

Every tool includes comprehensive error handling:

```python
try:
    # Main logic
except ValueError:
    return f"āŒ Error: Invalid input"
except Exception as e:
    return f"āŒ Error: {str(e)}"
```

### 4. Data Formatting

The `format_aircraft_data()` function provides consistent, readable output:

```python
def format_aircraft_data(aircraft_data):
    # Handles both single aircraft and lists
    # Formats all available fields with emoji indicators
    # Returns human-readable strings
```

### 5. API Wrapper

The `make_api_request()` function centralizes HTTP logic:

```python
async def make_api_request(endpoint):
    async with httpx.AsyncClient(timeout=15) as client:
        url = f"{API_BASE_URL}{endpoint}"
        response = await client.get(url)
        response.raise_for_status()
        return response.json()
```

This approach:
- Centralizes error handling
- Manages timeouts
- Logs all requests
- Makes it easy to add authentication later

## Tool Reference

### aircraft_by_hex(hex_id: str = "")

**Purpose**: Search for aircraft by Mode S hex identifier

**Input**: Comma-separated hex IDs (e.g., "45211e,45212f")

**Returns**: List of matching aircraft with full details

**Example**: 
```
User: "Show me aircraft with hex 45211e"
Tool: "šŸ” Found 1 aircraft: āœˆļø Callsign: RYR123 ..."
```

### aircraft_by_callsign(callsign: str = "")

**Purpose**: Search for aircraft by flight callsign

**Input**: Comma-separated callsigns (e.g., "BA387,AA123")

**Returns**: Aircraft matching the callsign

**Example**:
```
User: "Find flight BA387"
Tool: "šŸ” Found 1 aircraft: āœˆļø Callsign: BA387 ..."
```

### aircraft_by_registration(reg: str = "")

**Purpose**: Search for aircraft by tail number/registration

**Input**: Comma-separated registrations (e.g., "N123AB,G-EUPA")

**Returns**: Aircraft matching the registration

**Example**:
```
User: "Show aircraft with tail N123AB"
Tool: "šŸ” Found 1 aircraft: šŸ“‹ Registration: N123AB ..."
```

### aircraft_by_type(icao_type: str = "")

**Purpose**: Search for aircraft by ICAO type code

**Input**: Type codes (A321, B738, C172, E190, etc.)

**Returns**: All aircraft of that type currently flying

**Example**:
```
User: "Show all Boeing 737s"
Tool: "šŸ” Found 247 aircraft of type B738: ..."
```

### aircraft_by_squawk(squawk_code: str = "")

**Purpose**: Search for aircraft by squawk code

**Input**: 4-digit squawk code (e.g., "7500", "7600", "7700")

**Returns**: Aircraft squawking that code

**Note**: 7700 = Emergency, 7600 = Communications failure, 7500 = Hijacking

**Example**:
```
User: "Find aircraft squawking 7700"
Tool: "šŸ” Found aircraft in emergency: ..."
```

### aircraft_near_position(latitude: str = "", longitude: str = "", radius: str = "250")

**Purpose**: Find all aircraft within a radius of coordinates

**Input**: 
- latitude (decimal degrees, -90 to 90)
- longitude (decimal degrees, -180 to 180)
- radius (nautical miles, max 250)

**Returns**: All aircraft within the radius

**Example**:
```
User: "Show aircraft within 50 nm of Madrid (40.4168, -3.7038)"
Tool: "šŸ“ Found 23 aircraft within 50 nm of 40.4168, -3.7038: ..."
```

### military_aircraft()

**Purpose**: List all military aircraft

**Input**: None

**Returns**: All aircraft tagged as military

**Example**:
```
User: "What military aircraft are flying?"
Tool: "šŸŽ–ļø Found 12 military aircraft: ..."
```

### ladd_aircraft()

**Purpose**: List law enforcement and security aircraft

**Input**: None

**Returns**: All LADD (Law Enforcement/Security) aircraft

**Example**:
```
User: "Show law enforcement aircraft"
Tool: "🚁 Found 8 LADD aircraft: ..."
```

### pia_aircraft()

**Purpose**: List interesting/special aircraft

**Input**: None

**Returns**: All PIA (special interest) aircraft

**Example**:
```
User: "Show special/private aircraft"
Tool: "šŸ›”ļø Found 156 PIA aircraft: ..."
```

## Output Format

All tools return formatted strings with emoji indicators:

```
āœˆļø Callsign: BA387
šŸ“‹ Registration: G-EUPA
šŸ›©ļø Type: A350
šŸ“ Position: 51.4769, -0.4589
šŸ“ Altitude: 35000 ft
⚔ Ground Speed: 485 knots
🧭 Track: 089°
šŸ”– Mode S Hex: 406ee9
šŸ‘ļø Last Seen: 3 seconds ago
```

This provides:
- Visual clarity with emojis
- Easy scanning of information
- Consistent formatting
- Professional appearance

## Adding New Tools

To add a new tool to this server:

### Step 1: Create the Tool Function

```python
@mcp.tool()
async def new_tool(param1: str = "", param2: str = "") -> str:
    """Single-line description of what this tool does."""
    if not param1.strip():
        return "āŒ Error: param1 is required"
    
    try:
        # Your implementation
        result = await make_api_request("/endpoint")
        formatted = format_aircraft_data(result.get('ac', []))
        return f"āœ… Success:\n\n{formatted}"
    except Exception as e:
        return f"āŒ Error: {str(e)}"
```

### Step 2: Add to Catalog

Update the `tools:` section in custom.yaml:

```yaml
tools:
  - name: new_tool
```

### Step 3: Rebuild Docker Image

```bash
docker build -t airplane-mcp-server .
```

### Step 4: Restart Claude Desktop

The new tool will automatically appear.

## Testing

### Unit Test Pattern

```python
import asyncio

async def test_aircraft_by_callsign():
    result = await aircraft_by_callsign("BA387")
    assert "āœˆļø" in result
    assert "Found" in result
    print(result)

# Run with: asyncio.run(test_aircraft_by_callsign())
```

### Integration Test

```bash
# Start server
python airplane_server.py

# In another terminal, test via stdin:
echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | python airplane_server.py
```

## Performance Considerations

### API Response Times

- Typical: 500ms - 1s
- Complex queries: 1s - 2s
- Timeout: 15 seconds

### Data Limits

- Max 1000 aircraft per query (API limit)
- Radius search: max 250 nautical miles
- Callsign/registration: comma-separated up to 8000 chars

### Optimization Tips

1. **Use specific searches** - Narrow searches are faster
2. **Avoid hammering the API** - Reasonable request frequency
3. **Cache results locally** - Consider storing recent queries
4. **Monitor timeouts** - API may be slow during peak traffic

## Troubleshooting Guide

### Problem: Tools Don't Appear

**Solution**:
1. Verify image built: `docker images | grep airplane`
2. Check catalog: `cat ~/.docker/mcp/catalogs/custom.yaml`
3. Verify registry: `cat ~/.docker/mcp/registry.yaml`
4. Restart Claude: Quit completely, then reopen

### Problem: "No Aircraft Found"

**Causes**:
- Wrong coordinates (verify lat/lon format)
- Radius too small
- No traffic in that area
- Wrong type code (try uppercase)

**Solution**: Try a broader search or different parameters

### Problem: API Timeout

**Cause**: API is slow or rate-limited

**Solution**:
- Wait 30 seconds
- Try a simpler query
- Check internet connection

### Problem: Docker Permission Denied

**Solution**:
```bash
# Add user to docker group
sudo usermod -aG docker $USER
# Log out and back in
newgrp docker
```

## šŸ—ŗļø Future Enhancements

> **āš ļø Important Note**: This planned dashboard is intended as an **educational complement** to the excellent official [airplanes.live globe viewer](https://globe.airplanes.live), not a replacement. The goal is to demonstrate web development integration with MCP servers for learning purposes.

- [ ] **Caching System** - Redis cache to reduce API calls
- [ ] **Rate Limiting** - Smart request throttling
- [ ] **Export Features** - Save results as JSON/CSV/KML
- [ ] **Enhanced Formatting** - Better data visualization in Claude
- [ ] **Flight Alerts** - Notify when specific aircraft appear
- [ ] **Historical Tracking** - Store and track aircraft movements
- [ ] **Statistics Dashboard** - Aggregate data and analytics
- [ ] **API Extensions** - Additional airplanes.live endpoints

#### šŸ¤– **AI-Powered Features**
- 🧠 **Flight Prediction** - ML-based flight path estimation
- šŸ“ˆ **Pattern Analysis** - Identify unusual flight patterns  
- 🚨 **Anomaly Detection** - Automated alerts for interesting events
- šŸ“Š **Trend Analysis** - Historical data insights

## Security

### Current Approach

- No authentication required (public API data)
- Consider applying for an API key for production use
- No sensitive credentials stored
- Runs as non-root user
- Input validation on all parameters

### Future Considerations

- Add rate limiting if needed
- Implement query logging for monitoring
- Consider caching to reduce API calls
- Add input sanitization for custom endpoints

## šŸ“š Resources

- **API Documentation**: https://airplanes.live/
- **API Terms of Use**: https://airplanes.live/api-guide/
- **MCP Specification**: https://docs.anthropic.com/mcp
- **FastMCP Documentation**: https://github.com/jlowin/fastmcp
- **httpx Documentation**: https://www.python-httpx.org/

## šŸ¤ Contributing

This is an open-source educational project! Contributions are welcome:

- šŸ› **Bug Reports** - Open an issue
- šŸ’” **Feature Requests** - Suggest improvements  
- šŸ”§ **Pull Requests** - Submit code changes
- šŸ“– **Documentation** - Improve guides and examples

## šŸ“„ License & Disclaimer

**MIT License** - Feel free to use, modify, and distribute for educational purposes.

### āš–ļø Legal Notice:
- This software is provided "AS IS" without warranty
- Author assumes no responsibility for usage or compliance
- Users must respect airplanes.live API terms
- Educational and non-commercial use only
- Not affiliated with airplanes.live

### šŸŽÆ Project Intent:
This project is a **community contribution** for educational purposes, demonstrating MCP server development and API integration. The goal is to help developers learn and contribute to the MCP ecosystem, not for commercial gain.

---

**Made with ā¤ļø for the MCP community** āœˆļø

*Remember: Always respect API terms and use responsibly!*