Skip to main content
Glama
esteveavi
by esteveavi
README.md
# TMB Bus Arrival Times MCP Server

A Model Context Protocol (MCP) server that provides real-time bus arrival information for TMB (Transports Metropolitans de Barcelona) bus stops.

## πŸš€ Features

- **Real-time bus arrivals**: Get up-to-date information about when buses will arrive
- **Multiple lines support**: See all bus lines serving a stop
- **Time in minutes**: Arrival times shown in minutes for easy understanding
- **Detailed information**: Line numbers, destinations, directions, and bus IDs
- **MCP compliant**: Works with any MCP client including Claude Desktop

## πŸ“‹ Prerequisites

- Node.js 18+ 
- npm or yarn
- TMB API credentials (get them at https://developer.tmb.cat/)

## πŸ”§ Installation

1. **Clone or create the project:**
```bash
mkdir tmb-bus-mcp
cd tmb-bus-mcp
```

2. **Install dependencies:**
```bash
npm install
```

3. **Set up your TMB API credentials:**
```bash
# Copy the example environment file
cp .env.example .env

# Edit .env and add your credentials
# TMB_APP_ID=your_app_id
# TMB_APP_KEY=your_app_key
```

4. **Build the project:**
```bash
npm run build
```

## 🎯 Usage

### Option 1: Using the Client (Testing)

The client is perfect for testing and development:

```bash
# Set environment variables
export TMB_APP_ID=your_app_id
export TMB_APP_KEY=your_app_key

# Query a specific bus stop
npm run client 2775

# List available tools
npm run client -- list
```

**Example output:**
```
🚌 Bus Stop: Pl Espanya - FGC (108)
πŸ“… Query Time: 11/6/2025, 10:30:00 AM

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🚍 Line H12 (212) β†’ Gornal
   Direction: return

   Next arrivals:
   β€’ ⏱️  2 min (at 10:32:00) - Bus #3673
   β€’ ⏱️  16 min (at 10:46:00) - Bus #8531
```

### Option 2: Using with Claude Desktop

Add the server to your Claude Desktop configuration:

**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`  
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "tmb-bus": {
      "command": "node",
      "args": ["/absolute/path/to/tmb-bus-mcp/dist/server.js"],
      "env": {
        "TMB_APP_ID": "your_app_id",
        "TMB_APP_KEY": "your_app_key"
      }
    }
  }
}
```

Then restart Claude Desktop. You can now ask Claude things like:
- "What buses are coming to stop 2775?"
- "When is the next bus at Pl Espanya?"
- "Show me all bus arrivals for stop 108"

### Option 3: Using the Host (Standalone)

Run the server independently:

```bash
export TMB_APP_ID=your_app_id
export TMB_APP_KEY=your_app_key
npm run host
```

## πŸ› οΈ Architecture Explained

### MCP Server (`src/server.ts`)
The core component that:
- Exposes the `get_bus_arrivals` tool via MCP protocol
- Handles communication with TMB's iBus API
- Transforms raw API responses into user-friendly formats
- Runs on stdio transport for easy integration

**Key responsibilities:**
- Tool registration and discovery
- Request validation
- API communication with error handling
- Data transformation and formatting

### Host Application (`src/host.ts`)
A simple wrapper that:
- Starts the MCP server as a child process
- Manages environment variables
- Handles graceful shutdown

**When to use:** For standalone deployment or testing without an MCP client.

### Client Application (`src/client.ts`)
A demonstration client that:
- Connects to the MCP server via stdio
- Lists available tools
- Calls tools with parameters
- Displays formatted results

**When to use:** For testing, development, or as a reference implementation.

## πŸ”Œ API Integration Details

The server connects to TMB's iBus API:

**Endpoint:** `https://api.tmb.cat/v1/itransit/bus/parades/{stopCode}`

**Parameters:**
- `app_id`: Your TMB application ID
- `app_key`: Your TMB application key

**Response structure:**
```javascript
{
  timestamp: number,              // Query timestamp
  parades: [{
    codi_parada: string,         // Stop code
    nom_parada: string,          // Stop name
    linies_trajectes: [{         // Lines serving this stop
      codi_linia: string,        // Line code
      nom_linia: string,         // Line name
      desti_trajecte: string,    // Destination
      id_sentit: number,         // 1=Outbound, 2=Return
      propers_busos: [{          // Upcoming buses
        temps_arribada: number,  // Arrival timestamp
        id_bus: number          // Bus identifier
      }]
    }]
  }]
}
```

## πŸ“ Type Safety

The project uses TypeScript with strict type checking. All API responses are properly typed in `src/types.ts`:

- `TMBApiResponse`: Raw API response structure
- `BusStopInfo`: Transformed, user-friendly format
- `FormattedBusArrival`: Individual line information

## πŸ§ͺ Testing Different Bus Stops

Try these Barcelona bus stops:

- `2775`: Random stop
- `108`: Pl Espanya - FGC
- `1`: Pl Catalunya
- `2554`: Sagrada FamΓ­lia

## πŸ” How It Works

1. **Client Request**: An MCP client (like Claude) calls the `get_bus_arrivals` tool with a stop code
2. **Server Processing**: The MCP server receives the request via stdio transport
3. **API Query**: Server makes an authenticated request to TMB's iBus API
4. **Data Transformation**: Raw API response is transformed into a readable format
5. **Time Calculation**: Arrival timestamps are converted to "minutes until arrival"
6. **Response**: Formatted text is returned to the client

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Client │────────▢│   MCP    │────────▢│   TMB   β”‚
β”‚ (Claude)β”‚         β”‚  Server  β”‚         β”‚   API   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β–²                    β”‚                    β”‚
     β”‚                    β–Ό                    β”‚
     β”‚              Transform Data             β”‚
     β”‚                    β”‚                    β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

## 🚦 Error Handling

The server handles various error scenarios:

- **Missing credentials**: Exits with clear error message
- **Invalid stop code**: Returns user-friendly error
- **API errors**: Catches and formats API error responses
- **Network issues**: Handles timeout and connection errors

## πŸ” Security Notes

- Never commit your `.env` file or API credentials
- The `.env.example` file shows the format without real credentials
- Credentials are passed via environment variables, not hardcoded
- Use MCP's built-in transport security for production deployments

## πŸ“š MCP Protocol Details

This server implements MCP (Model Context Protocol):

- **Transport**: stdio (standard input/output)
- **Capabilities**: Tools
- **Tool Name**: `get_bus_arrivals`
- **Input**: `{ stopCode: string }`
- **Output**: Formatted text with bus arrival information

## 🀝 Contributing

To extend this server:

1. Add new tools in `server.ts` `getTools()` method
2. Implement handlers in `handleToolCall()`
3. Update types in `types.ts` as needed
4. Test with the client application

## πŸ“„ License

MIT

## πŸ™ Credits

- TMB API: https://developer.tmb.cat/
- MCP SDK: https://github.com/anthropics/modelcontextprotocol

---

**Questions?** Check the MCP documentation at https://modelcontextprotocol.io/