Skip to main content
Glama
README.md
# MBTA MCP

Model Context Protocol (MCP) server that exposes live **MBTA V3** transit data over **Streamable HTTP**.

Public production endpoint (after Cloud Run deploy):

`https://mbta.metaverseprofessional.tech/mcp`

For more info, I wrote a Medium post about this project here: [Link](https://jegamboafuentes.medium.com/i-built-and-deployed-my-first-mcp-server-for-bostons-mbta-and-cursor-changed-the-game-ba0b37034074)

## Architecture

```
MCP Client
  → Streamable HTTP (/mcp)
  → Python MCP server (MCP Python SDK v2)
  → MBTA V3 API (https://api-v3.mbta.com)
```

## Tools

| Tool | When to use |
|------|-------------|
| `get_routes` | List routes; optional `route_type` filter (0–4) |
| `get_stops_for_route` | Stops for a known `route_id` (e.g. `Red`, `Green-B`, `1`) |
| `find_stop` | Resolve a station/stop name to stop IDs (client-side name match) |
| `get_next_arrivals` | Predicted arrivals at a `stop_id` |
| `get_alerts` | Service alerts; optional route/stop filters |
| `get_vehicles` | Live vehicle positions; optional `route_id` |

Also exposes `GET /health` for load balancers and Cloud Run probes.

## Requirements

- Python 3.12+
- MBTA API key from [api-v3.mbta.com](https://api-v3.mbta.com/)

## Quick start (local)

```powershell
cd MBTA-MCP
py -3.12 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install -e ".[dev]"

copy .env.example .env
# Edit .env and set MBTA_API_KEY=...

python -m mbta_mcp
```

Server listens on:

- MCP: `http://127.0.0.1:8080/mcp`
- Health: `http://127.0.0.1:8080/health`

Or with uvicorn:

```powershell
uvicorn mbta_mcp.server:create_app --factory --host 0.0.0.0 --port 8080
```

## Configuration

All secrets come from the environment (never hardcode keys).

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `MBTA_API_KEY` | recommended | — | MBTA V3 API key (optional for light anonymous testing) |
| `HOST` | no | `0.0.0.0` | Bind address |
| `PORT` | no | `8080` | Bind port (Cloud Run sets this) |
| `MBTA_BASE_URL` | no | `https://api-v3.mbta.com` | API base URL |
| `LOG_LEVEL` | no | `INFO` | Logging level |
| `MCP_ALLOWED_HOSTS` | no | localhost + production host | Streamable HTTP Host allowlist |

See `.env.example`.

## Tests

```powershell
pytest
pytest -m integration   # live MBTA calls when MBTA_API_KEY is set
```

Smoke-test tools against a running server:

```powershell
python scripts/smoke_tools.py --url http://127.0.0.1:8080/mcp
```

## Docker

```powershell
docker build -t mbta-mcp .
docker run --rm -p 8080:8080 -e MBTA_API_KEY=your_key mbta-mcp
```

Then:

```powershell
curl http://127.0.0.1:8080/health
python scripts/smoke_tools.py --url http://127.0.0.1:8080/mcp
```

## Connect an MCP client

Point a Streamable HTTP MCP client at:

- Local: `http://127.0.0.1:8080/mcp`
- Production: `https://mbta.metaverseprofessional.tech/mcp`

## Cloud Run (later — do not deploy until local + Docker work)

1. Store the key in **Secret Manager** as `MBTA_API_KEY`.
2. Build/push the image to Artifact Registry.
3. Deploy to Cloud Run with:
   - secret mapped to env var `MBTA_API_KEY`
   - container port `8080`
   - health check path `/health`
4. Map custom domain `mbta.metaverseprofessional.tech`.
5. Ensure `MCP_ALLOWED_HOSTS` includes `mbta.metaverseprofessional.tech` and `mbta.metaverseprofessional.tech:*`.

App code only reads `MBTA_API_KEY` from the environment; Secret Manager wiring is a Cloud Run concern.

## Project layout

```
src/mbta_mcp/
  server.py          # MCPServer, tools, /health
  config.py          # env settings
  mbta/client.py     # MBTA V3 httpx client
  tools/             # tool handlers
tests/
Dockerfile
```

## License

Use at your own risk. MBTA data is subject to MBTA API terms of use.