BusTime MCP

BusTime MCP

Wraps the CTA Bus Tracker API to provide live access to bus routes, stops, predictions, vehicle locations, patterns, and detours via MCP clients.

Category
Visit Server

README

BusTime MCP

An MCP server that wraps the CTA (Chicago Transit Authority) Bus Tracker API, giving MCP clients live access to CTA bus routes, stops, predictions, vehicle locations, patterns, and detours. Built with FastMCP and deployed via Prefect Horizon.

Features

  • Full coverage of the CTA Bus Tracker v3 API (routes, directions, stops, patterns, predictions, vehicles, locales, detours, enhanced detours, system time)
  • Async HTTP via httpx, with clean error handling for missing config, bad status codes, and network failures
  • In-memory TTL caching on slow-changing endpoints (routes, directions, stops, patterns, locales, detours) — real-time endpoints (predictions, vehicles, time) always hit the live API
  • Server-level instructions and per-tool descriptions designed to help MCP clients chain calls correctly (e.g. routes → directions → stops → predictions)
  • Test suite covering the HTTP layer, caching behavior, and tool parameter validation

Prerequisites

  • A CTA Bus Tracker developer API key
  • A GitHub account, with this repo pushed to it (Horizon deploys from a GitHub repo)
  • A Horizon account (free personal tier)

Getting a CTA API key

  1. Sign up for and activate a Bus Tracker account
  2. Sign in, then go to My Account (upper right)
  3. Follow the Developer API link to apply for a key

Full details: CTA Developer Center — Bus Tracker APIs

Deploying to Horizon

  1. Push this repo to GitHub (public or private both work).

  2. Sign in to horizon.prefect.io with GitHub and connect the repo.

  3. On the configure screen, set:

    • Entrypoint: main.py:mcp
    • Authentication: enable this if you want to restrict access to your org rather than leaving the endpoint open — see Rate limits below for why that matters here.
    • Dependencies are auto-detected from pyproject.toml — nothing to configure manually.
  4. Set CTA_URL and CTA_API_KEY as environment variables/secrets for the deployment. Horizon's configuration screen should have a place for this; check the current UI when you get there, since the exact field wasn't fully documented at the time this was written.

  5. Click Deploy. You'll get a live URL, typically in under 60 seconds:

    https://<your-server-name>.fastmcp.app/mcp
    

Horizon rebuilds and redeploys automatically on every push to main, and builds preview deployments for PRs.

Verifying before you deploy

uv run fastmcp inspect main.py:mcp

This shows what Horizon will see when it runs the server — tools, resources, and prompts — so you can catch config problems locally before pushing.

Connecting a client once deployed

Once live, MCP clients connect by URL rather than by spawning a local process:

{
  "mcpServers": {
    "BusTime": {
      "url": "https://<your-server-name>.fastmcp.app/mcp"
    }
  }
}

Horizon also provides its own Inspector and ChatMCP for testing the deployed server directly in the browser before wiring up any client.

Available tools

Tool Endpoint Cached?
get_routes() /getroutes 24h
get_directions(rt) /getdirections 24h
get_stops_for_route(rt, direction) /getstops 30 min
get_patterns(pid=, rt=) /getpatterns 1h
get_predictions_for_stop(stpid, rt, top) /getpredictions never (real-time)
get_vehicle(vid) /getvehicles never (real-time)
get_time(unix_time=) /gettime never (real-time)
get_locale_list(locale=, in_locale_language=) /getlocalelist 24h
get_detours(rt=, direction=) /getdetours 2 min
get_enhanced_detours() /getenhanceddetours 2 min

Typical call sequence: get_routesget_directions(rt)get_stops_for_route(rt, direction)get_predictions_for_stop(stpid, rt, top). See the server's instructions string in main.py for the full call graph, including how patterns, vehicles, and detours fit in.

Known limitation: get_enhanced_detours may return an "Unsupported function" error depending on your API key — this endpoint is GTFS-RT-oriented and appears to require CTA to enable it per-account. This is a CTA-side limitation, not a bug in this server.

Caching

Cacheable endpoints use a simple in-memory TTL cache (see _cached_get in main.py) keyed by endpoint path + parameters. TTLs are set per-endpoint based on how often the underlying data actually changes.

The cache is in-memory and per-instance. It resets on restart/redeploy, and if Horizon ever runs multiple replicas of this server, each replica has its own independent cache rather than a shared one — still correct, just less effective at cutting duplicate calls than a single-instance setup.

Testing

uv sync
uv run pytest -v

Tests use pytest-asyncio (auto mode) and respx to mock HTTP calls — no real network access or live API key is needed to run them. Run this before every push, since Horizon redeploys automatically on main.

Project structure

.
├── main.py            # server entrypoint + all tool definitions
├── pyproject.toml      # dependencies (uv-managed; also read by Horizon for auto dependency detection)
├── tests/
│   ├── conftest.py     # makes main.py importable from tests/
│   └── test_main.py
└── README.md

Rate limits

CTA's Bus Tracker API defaults to a 100,000 request/day limit per key. This server's caching helps reduce call volume for slow-changing data, but there's currently no built-in tracking or backoff as you approach that limit. This matters more once deployed publicly: a hosted URL can be called by anyone who finds it, unlike a local stdio server only you can spawn — enabling Horizon's authentication option (above) is the simplest way to keep usage scoped to people you trust.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured