Skip to main content
Glama

transit-mcp-server

Servidor MCP para la API de tránsito 511.org SF Bay Open Data. Proporciona a un LLM datos de tránsito en vivo del Área de la Bahía: agencias, rutas, paradas, salidas en tiempo real, posiciones de vehículos y alertas de servicio, en BART, Muni, AC Transit, Caltrain, VTA y cualquier otro operador que reporte a 511.

6 herramientas, todas de solo lectura.

Requisitos

Related MCP server: Bay Wheels MCP Server

Instalación

npm install
npm run build

Configuración

{
  "mcpServers": {
    "transit": {
      "command": "node",
      "args": ["/absolute/path/to/transit-mcp-server/dist/index.js"],
      "env": { "TRANSIT_511_API_KEY": "your-token-here" }
    }
  }
}

Variable

¿Requerida?

Valor predeterminado

Propósito

TRANSIT_511_API_KEY

Token de https://511.org/open-data/token

TRANSIT_511_BASE_URL

no

https://api.511.org

Sobrescribir el host de la API

TRANSIT_511_REQUEST_TIMEOUT_MS

no

30000

Tiempo de espera por solicitud

TRANSPORT

no

stdio

stdio o http

PORT / HOST

no

3000 / 127.0.0.1

Dirección de enlace del transporte HTTP

MCP_PATH_SECRET

cuando se aloja

Sirve el endpoint en /mcp/<secreto>. Requerida cuando HOST no es loopback

ALLOWED_ORIGINS

no

localhost + claude.ai

Lista de orígenes permitidos separados por comas

La cuota es la principal limitación

511 permite 60 solicitudes por hora por clave, compartidas entre todos los endpoints. Eso es lo suficientemente bajo como para dar forma a cómo se deben usar estas herramientas:

  • Resuelve los códigos de operador y de parada una vez, y luego reutilízalos. No cambian.

  • Prefiere transit_list_service_alerts sin operator_id: una sola llamada cubre todas las agencias.

  • Nunca hagas polling de transit_next_departures en un bucle. Diez comprobaciones durante un viaje al trabajo son una sexta parte del presupuesto por hora.

transit_list_operators informa cuánto presupuesto queda, leído del encabezado RateLimit-Remaining que 511 devuelve en cada respuesta. Superar la cuota devuelve 429; solicita un aumento a transitdata@511.org.

Despliegue (para conectores de Claude mobile / claude.ai)

Misma forma que cualquier servidor MCP alojado: genera un secreto de ruta con openssl rand -hex 32, establece TRANSIT_511_API_KEY y MCP_PATH_SECRET en el panel de la plataforma, y el Dockerfile y railway.json incluidos funcionan tal cual en Railway, Render o Fly. El servidor se niega a iniciarse en una interfaz pública sin un secreto. /healthz es una sonda de actividad sin autenticación.

Luego, en claude.ai en un navegador: Personalizar → Conectores → Añadir conector personalizado, URL https://tu-app.up.railway.app/mcp/<secreto>.

Herramientas

Redtransit_list_operators, transit_list_lines, transit_find_stops

Tiempo realtransit_next_departures, transit_list_vehicles

Alertastransit_list_service_alerts

Cada herramienta acepta response_format: "markdown" | "json". Markdown es el valor predeterminado y está optimizado para que un LLM lo lea; JSON es la carga útil estructurada completa. structuredContent siempre se completa independientemente del formato.

Ejemplos

"¿Cuándo es el próximo N Judah?"transit_find_stops con operator_id="SF", query="judah" para obtener el código de parada, luego transit_next_departures con ese código y line="N".

"¿Está BART funcionando con normalidad?"transit_list_service_alerts con operator_id="BA".

"¿Algo mal en mi viaje al trabajo?"transit_list_service_alerts sin operador: una llamada cubre todas las agencias del Área de la Bahía.

"¿Dónde están los trenes ahora mismo?"transit_list_vehicles con operator_id="BA".

Notas de diseño

Solo lectura por construcción. 511 no publica endpoints de escritura, y cada herramienta lleva readOnlyHint: true. Una prueba lo verifica.

Un operator_id, mapeado por endpoint. 511 llama a este parámetro operator_id en sus endpoints estáticos y agency en los de tiempo real, para el mismo valor. Cada herramienta aquí acepta operator_id y el cliente lo mapea. Esa división es problema de 511, no del llamador.

Los dos endpoints de tiempo real tienen envolturas genuinamente diferentes. StopMonitoring no tiene envoltura raíz Siri; VehicleMonitoring la tiene. La especificación publicada muestra una para ambos: la especificación está equivocada, y analizar la forma documentada no devolvería nada en absoluto para las salidas. Ambos se analizan tal como la API en vivo realmente los emite, con una prueba que fija cada uno.

Las llegadas llevan la cuenta regresiva, no las salidas. ExpectedDepartureTime es nulo en prácticamente todas las filas reales, por lo que basar una cuenta regresiva en él mostraría una parada sin servicio. ExpectedArrivalTime es el campo confiable.

Se elimina una marca de orden de bytes UTF-8 antes del análisis. 511 antepone U+FEFF a los cuerpos JSON, lo que hace que un JSON.parse ingenuo falle con una carga útil perfectamente válida. Los fallos de autenticación son texto plano sin BOM, por lo que la eliminación ocurre después de la verificación de estado.

Los valores que parecen números y booleanos a menudo no lo son. Las coordenadas y los rumbos llegan como cadenas JSON, VehicleAtStop es la cadena "false", y "" se usa en todo donde se quiere decir nulo. Coercionar a ciegas convertiría una posición faltante en un 0,0 de apariencia válida frente a la costa de África, por lo que las cadenas vacías se tratan como ausentes en lugar de cero.

El centinela de época cero no es una marca de tiempo. Un viaje que está programado pero no tiene vehículo asignado reporta RecordedAtTime de 1970-01-01T00:00:00Z. Se muestra como "aún no se ha asignado vehículo" en lugar de "registrado hace 56 años".

Los enums de GTFS-Realtime se decodifican. La representación JSON de alertas de 511 emite "effect": 3 donde la representación XML dice SignificantDelays. Tanto la causa como el efecto se mapean de vuelta a palabras.

Las pseudo-agencias internas de 511 se filtran. 5E, 5F, 5O y 5S son 511 Emergency, Flap Sign, Operations y Staff: aparecen en la lista de operadores sin datos de servicio.

Todo es Pacífico. Las marcas de tiempo llegan como UTC y se muestran en America/Los_Angeles, por lo que el cambio de horario de verano se maneja aquí una vez en lugar de que el modelo lo haga dos veces al año. Ten en cuenta que el propio campo TimeZone de 511 reporta America/Vancouver para cada agencia del Área de la Bahía: un error conocido de datos ascendente, ignorado deliberadamente.

La truncación siempre se indica. 511 no pagina; devuelve colecciones completas, y una agencia grande tiene miles de paradas. Las herramientas aceptan un limit del lado del cliente y cada resultado recortado indica cuánto se retuvo, porque una lista acortada silenciosamente se lee como "eso es todo".

Advertencias

  • La cuota por hora es de 60 solicitudes en todos los endpoints. Esta es la restricción vinculante para cualquier flujo de trabajo.

  • Los códigos de operador son fáciles de adivinar mal: VTA es SC (no VT), Capitol Corridor es AM (no CC), Tri Delta es 3D. transit_list_operators imprime estas trampas en su salida.

  • Los códigos de parada pertenecen a un operador y no son intercambiables entre agencias.

  • transit_find_stops filtra en este servidor, por lo que una consulta estrecha no ahorra cuota: la lista completa de paradas se obtiene de todos modos.

  • Las predicciones en tiempo real se extienden aproximadamente 90 minutos hacia adelante, y 511 omite la parada final de solo llegada de una ruta del feed de salidas.

  • tripupdates y vehiclepositions son solo protobuf sin opción JSON, por lo que deliberadamente no se exponen: soportarlos significaría asumir una dependencia de protobuf para datos que los endpoints SIRI ya cubren.

Estructura del proyecto

src/
├── index.ts               # entry point, transport selection
├── constants.ts           # enums, limits, operator-code traps
├── types.ts               # interfaces for every 511 entity
├── services/
│   └── transit-client.ts  # fetch wrapper, auth, BOM stripping, quota tracking, errors
├── schemas/
│   ├── inputs.ts          # Zod input schemas
│   └── outputs.ts         # structuredContent schemas
├── formatters/
│   ├── response.ts        # limiting, truncation, Pacific-time rendering
│   └── entities.ts        # per-entity markdown rendering
└── tools/
    ├── network.ts         # operators, lines, stops
    ├── departures.ts      # real-time arrivals and vehicles
    └── alerts.ts          # service alerts

Pruebas

npm run build
npm test            # 42 checks: handshake, BOM, envelopes, quirks, errors (mocked API)
npm run test:http   # 17 checks: config validation, path-secret gating, method handling, origins

Ambas suites se ejecutan contra un mock local que reproduce deliberadamente las peculiaridades reales de 511: el BOM, la envoltura Siri faltante, booleanos y coordenadas como cadenas, el centinela de época y cuerpos de error en texto plano, porque eso es exactamente lo que un cliente ingenuo hace mal.

Install Server
F
license - not found
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Gateway between LLM agents and world data through eight tools and a bundled endpoint catalog.

  • Read and update your Everway trips and itineraries from any MCP-compatible AI assistant.

  • US weather & geo for AI agents: forecasts, alerts, earthquakes, elevation, geocoding. No keys.

View all MCP Connectors

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/RyK57/transit-mcp-server'

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