Skip to main content
Glama
countaight

BusTime MCP

by countaight

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

Related MCP server: openbusdata

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.

Available Tools

11 tools
addA

Add two numbers

ParametersJSON Schema
NameRequiredDescriptionDefault
aYes
bYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavior. It only states the operation; it does not mention any edge cases, return type, or side effects. However, for a simple addition, the implied behavior is clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Extremely concise at three words, with no unnecessary information. Every word earns its place for such a simple tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity and the presence of an output schema, the description is nearly complete. It could mention that the output is the sum, but it is implicitly understood.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so parameters have no descriptions. The description adds the context that a and b are the numbers to be added, which compensates partially. Baseline for 2 params with low coverage is 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the operation (add) and the resource (two numbers). It is a specific verb+resource that distinguishes well from sibling tools which are all transit-related.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit when-to-use or alternatives, but the context of sibling tools makes usage obvious. This tool is the only arithmetic one among transit data retrieval tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_detoursA

Fetch active detours in the system. Optionally filter by route (rt) and, if rt is given, by direction. Check this before trusting a get_stops_for_route or get_patterns result is current, since detours can add/remove stops or shift pattern geometry.

ParametersJSON Schema
NameRequiredDescriptionDefault
rtNoRoute designator to filter detours by, e.g. the 'rt' field from a get_routes() result.
directionNoDirection id to filter by (requires rt). Use the 'id' field from a get_directions(rt) result.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description bears full burden. It discloses that detours can add/remove stops or shift pattern geometry, which is valuable. However, it does not mention auth needs, rate limits, or other behavioral aspects. The output schema exists but is not described.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no wasted words. The main purpose is front-loaded, and the second sentence adds critical usage context. Very concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists, the description doesn't need to explain returns. It adds important context about when to use the tool (before relying on other tools). However, it could mention any limitations or side effects.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds dependency between direction and rt, but the schema already states 'requires rt'. No additional parameter semantics beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool fetches active detours and optionally filters by route and direction. However, it does not explicitly differentiate from the sibling tool 'get_enhanced_detours', but the purpose is distinct enough.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance to check detours before trusting results from get_stops_for_route or get_patterns, highlighting why this tool is important. It does not mention when to use get_enhanced_detours instead, but the given guidance is strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_directionsA

Fetch the set of directions serviced by the specified route. Use the 'id' field (not the human-readable 'name') from a result as the 'direction' parameter for get_stops_for_route.

ParametersJSON Schema
NameRequiredDescriptionDefault
rtYesRoute designator, e.g. the 'rt' field from a get_routes() result.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries burden. It discloses the output includes 'id' and 'name' fields, hinting at data structure. However, no mention of side effects, rate limits, or error conditions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, efficient, front-loaded with purpose. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Low complexity tool with one parameter and an output schema. Description provides essential usage hint about id/name fields. Could mention it returns a list of directions, but output schema likely covers that.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 100% coverage for the single parameter 'rt'. Description adds value by explaining the parameter comes from get_routes() result, beyond the schema description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool fetches directions for a specified route, using the verb 'fetch' and resource 'directions'. It distinguishes from siblings like get_routes and get_stops_for_route.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells when to use the tool (to get directions for a route) and how to use its output (id field for get_stops_for_route). It implies prerequisite use of get_routes, but lacks explicit when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_enhanced_detoursA

Fetch enhanced detour data (used by GTFS-RT systems), including affected patterns, trips, and stops. Only returns data when detour support is enabled in BusTime for this API key; may return an 'Unsupported function' error otherwise (this is a CTA-side account limitation, not a bug in this tool).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses beyond the schema that it may return an 'Unsupported function' error due to a CTA-side limitation, explaining that this is not a tool bug. This is valuable behavioral context not covered by annotations (which are absent).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is very concise: two sentences with no wasted words. It front-loads the main purpose and then adds a critical behavioral note.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no parameters and an existing output schema, the description covers the tool's purpose, output contents, and a potential error case. It is complete for its simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters exist in the input schema, so the description is not required to elaborate on parameters. The baseline score of 4 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it fetches enhanced detour data including affected patterns, trips, and stops. It doesn't explicitly differentiate from the sibling tool 'get_detours', but the term 'enhanced' implies a distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides context for when to use (GTFS-RT systems needing detour data) and warns about a potential error scenario. However, it does not explicitly state when not to use it or mention alternatives like 'get_detours'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_locale_listA

Fetch the list of locales (languages) supported by the API. Not currently consumed by other tools here, but useful to validate a 'locale' value before it's added elsewhere.

ParametersJSON Schema
NameRequiredDescriptionDefault
localeNoAn ISO 639 locale code (e.g. 'es') to show display names in that language. Omit for English.
in_locale_languageNoIf true, show each locale's display name in its own language instead of the requested locale. Takes precedence over 'locale' if set.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. Only notes that tool isn't consumed by others, but lacks disclosure on safety, side effects, rate limits, or idempotency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences, front-loaded with main purpose. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Simple tool with output schema present. Description covers purpose, validation use case, and current usage context. Lacks behavioral details but adequate for this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and description mostly restates schema info (locale display language, locale language override). Adds minimal new meaning beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states verb 'Fetch' and resource 'list of locales' with additional validation context. Distinguishes from all sibling tools which concern transit data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says it's useful to validate a locale before adding elsewhere, but does not explicitly list when not to use or provide alternatives, though none exist among siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_patternsA

Fetch pattern points for a comma-delimited list of pattern ids (pid, max 10), or all active patterns for a single route (rt). Provide exactly one of pid or rt, not both. Useful for drawing a route or vehicle's path on a map.

ParametersJSON Schema
NameRequiredDescriptionDefault
rtNoRoute designator to fetch all active patterns for. Mutually exclusive with pid.
pidNoComma-delimited pattern ids (max 10), e.g. the 'pid' field from a get_vehicle or get_predictions_for_stop result. Mutually exclusive with rt.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. It discloses the constraints (max 10 pids, mutually exclusive parameters, 'active patterns') but does not detail behavior on invalid inputs or other edge cases. Adequate for a simple read tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no wasted words. Front-loaded with the core action and constraints, followed by use case. Every sentence adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 2 optional mutually exclusive parameters and no required fields, the description fully covers the two modes of operation and the intended use case. Since an output schema exists, return values need not be described.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, baseline 3. The description adds value by explaining pid is comma-delimited, max 10, and where pid values come from (get_vehicle, get_predictions_for_stop), which is helpful context beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool fetches pattern points for either a list of pattern IDs (pid) or all active patterns for a single route (rt). It distinguishes from sibling tools by focusing on pattern points for map drawing, not routes or stops.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states to provide exactly one of pid or rt, not both. Mentions a use case (drawing a path on a map) but does not explicitly list alternatives or when not to use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_predictions_for_stopA

Fetch the top number of predictions or just the latest one if not specified for buses on a specific stop. This is real-time data and is always live, never cached.

ParametersJSON Schema
NameRequiredDescriptionDefault
rtYesRoute designator, e.g. the 'rt' field from a get_routes() result.
topYesMaximum number of predictions to return.
stpidYesStop id, e.g. the 'stpid' field from a get_stops_for_route result.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description mentions that data is real-time and never cached, which is a useful behavioral trait. However, it does not disclose other aspects like error handling or performance implications. With no annotations, the description carries the full burden but only partially satisfies it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loading the core function and adding a key detail about real-time nature. No unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the main purpose and data freshness, but it lacks details on edge cases (e.g., empty result) and contains a contradiction about parameter optionality. With an output schema present, some missing details are compensated, but the contradiction hurts completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description says 'or just the latest one if not specified' for the top parameter, but the input schema marks top as required. This contradiction misleads about parameter optionality. Schema coverage is 100%, but the description adds confusion instead of clarity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool fetches predictions for a specific stop, and the name itself indicates the function. It distinguishes from siblings like get_routes and get_vehicle by focusing on predictions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The context of use is clear from the description and name, but there is no explicit mention of when not to use this tool versus alternatives. The implied usage is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_routesA

Fetch all CTA routes. This is usually the first call in a session: use the 'rt' field from each returned route as the route designator for get_directions, get_stops_for_route, get_predictions_for_stop, get_patterns, and get_detours.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description fully carries the burden of behavioral disclosure. It accurately describes a no-parameter read operation that fetches all routes, with no hidden side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with two sentences: the first states the core function, the second provides essential usage context. No extraneous words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple fetch-all tool with an output schema, the description is complete. It explains the purpose, the key output field 'rt', and how it connects to other tools, providing sufficient context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters and is fully covered by the schema. The description adds no parameter information, which is appropriate. Baseline score of 4 for zero-parameter tools.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Fetch all CTA routes,' specifying the verb and resource. It also explains the tool's role as the first call in a session, distinguishing it from sibling tools that depend on its output.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'This is usually the first call in a session' and lists tools that use the 'rt' field from its output, providing clear context for when and how to use this tool versus alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_stops_for_routeA

Fetch all stops for a route heading in a specified direction. Use the 'stpid' field from a result as input to get_predictions_for_stop. Call get_directions(rt) first if you don't already have a valid direction id.

ParametersJSON Schema
NameRequiredDescriptionDefault
rtYesRoute designator, e.g. the 'rt' field from a get_routes() result.
directionYesDirection id for the route. Use the 'id' field (not 'name') from a get_directions(rt) result.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must cover behavioral traits. It mentions the output field 'stpid' but does not disclose potential edge cases (e.g., empty result, error conditions) or any other behavioral aspects like auth or rate limits. The description is adequate but lacks depth.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences long with no wasted words. The first sentence states the primary purpose; the second provides critical chaining instructions. It is front-loaded and efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that an output schema exists (context signal 'has output schema: true'), the description does not need to explain return values. It already provides chaining context (prerequisite and follow-up), making the tool self-contained and well-integrated into the workflow.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema covers 100% of parameters, but the description adds valuable clarifications: for 'rt', it specifies the source field from get_routes(); for 'direction', it explicitly states to use the 'id' field (not 'name') from get_directions(). This goes beyond the schema descriptions and reduces ambiguity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the verb 'Fetch' and clearly specifies the resource: 'all stops for a route heading in a specified direction'. It distinguishes from sibling tools like get_directions and get_routes by focusing on stops for a specific route and direction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage guidance: it tells the agent to call get_directions first if a valid direction id is not available, and to use the 'stpid' field output as input to get_predictions_for_stop. This clearly states when to use this tool and its relation to siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_timeA

Fetch the current BusTime system date and time. Useful for reconciling against prediction timestamps ('prdtm') from get_predictions_for_stop. Always live, never cached.

ParametersJSON Schema
NameRequiredDescriptionDefault
unix_timeNoIf true, return Unix epoch milliseconds instead of a local YYYYMMDD HH:MM string.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Since no annotations are provided, the description carries the full burden. It adds 'Always live, never cached', which informs the agent of the data freshness policy. No side effects are mentioned, but for a time fetch this is sufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description consists of three concise sentences. The first sentence states the core purpose, the second provides a usage example, and the third offers behavioral context. No redundant or irrelevant information is present.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity of the tool (one optional parameter), the description covers all necessary aspects: purpose, usage context, behavioral transparency, and the parameter semantics are covered by the schema. The presence of an output schema further reduces the need to describe return values.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the description for the 'unix_time' parameter matches the schema's own description. The description adds no new information beyond what is in the schema, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'Fetch the current BusTime system date and time', which clearly identifies the verb and resource. It also mentions a specific use case (reconciling against prediction timestamps from get_predictions_for_stop), distinguishing it from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear context: 'Useful for reconciling against prediction timestamps...' indicating when to use the tool. However, it does not explicitly exclude any scenarios or mention alternatives, which prevents a top score.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_vehicleA

Fetch a vehicle's live location based on its id. This is real-time data and is always live, never cached. The returned 'pid' field can be passed to get_patterns to draw the vehicle's route shape.

ParametersJSON Schema
NameRequiredDescriptionDefault
vidYesVehicle id, e.g. the 'vid' field from a get_predictions_for_stop result.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description discloses key behavioral traits: data is real-time, never cached, and returns a 'pid' field. Additional details like authentication or error handling are missing but are minor for this simple fetch tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose. Every sentence adds value, with no redundant or extra content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists, the description adequately covers purpose, live data nature, and chaining. Missing details like prerequisites are not critical for this simple tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides 100% coverage with a clear description of the vid parameter. The description adds no further parameter meaning beyond the schema, maintaining the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool fetches a vehicle's live location by ID, using specific verb 'Fetch' and resource 'vehicle's live location'. It distinguishes from siblings by mentioning the output 'pid' field can be used with get_patterns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for real-time location retrieval and hints at chaining with get_patterns, but lacks explicit when-to-use or when-not-to-use guidance compared to siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 11 tool updatesv0.1.0
    • First observedadd
    • First observedget_detours
    • First observedget_directions
    • First observedget_enhanced_detours
    • First observedget_locale_list
    • First observedget_patterns
    • First observedget_predictions_for_stop
    • First observedget_routes
    • First observedget_stops_for_route
    • First observedget_time
    • First observedget_vehicle

TDQS

A3.8/5.0
Disambiguation2/5

Most tools target distinct aspects of CTA bus data, but the inclusion of 'add' (add two numbers) is completely unrelated to bus time, creating confusion about the server's purpose and when to use it.

Naming Consistency3/5

All bus-related tools follow a consistent 'get_<noun>' pattern, but the 'add' tool breaks this pattern entirely, resulting in moderate inconsistency.

Tool Count4/5

With 11 tools, the count is reasonable for a bus transit API. The 'add' tool is unnecessary but does not make the set too large or too small.

Completeness4/5

The bus tools cover core functionality: routes, directions, stops, predictions, vehicles, time, patterns, detours, and locale. Minor gaps exist (e.g., no route search), but the surface is largely complete for the domain.

Maintenance

ActivitySlowing
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Connectors

Related MCP Servers

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/countaight/bustime-mcp'

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