stl-transit
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@stl-transitrun the assertion suite and check for feed drift"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
stl-transit
Developer tooling for the Light Phone 3 St. Louis transit tool: GTFS and GTFS-Realtime inspection, golden-fixture generation for the Kotlin test gate, and feed surveillance.
Never ships in the APK. This is build-time tooling and Light never vets it. The shipped tool is a separate Kotlin repo, and unlike this one it cannot use Metro's trademarks.
Ships as one thing usable two ways:
CLI —
stl ..., 64 commands, for interactive work and cron/CI.MCP server —
stl-mcpon stdio, 45 tools, for Claude Cowork / Desktop / Code.
Both are thin shells over stl_transit.core.service. See SPEC.md for the full
design and the CLI-to-MCP contract; tests/test_wiring.py enforces it.
Install
git clone https://github.com/tyleryancey/stl-transit
cd stl-transit
python3 -m venv .venv
.venv/bin/pip install -e .
.venv/bin/stl doctor # sanity checkRequires Python 3.12+. No API keys — every source is public and unauthenticated, which is what keeps MCP configuration trivial.
Related MCP server: db-mcp
First run
.venv/bin/stl snapshot fetch metro_gtfs # ~3.5 MB zip, expands to ~29 MB
.venv/bin/stl gtfs import # build the SQLite index
.venv/bin/stl report brief # is anything wrong right now?
.venv/bin/stl gtfs stop-resolve # answers the stop_code vs stop_id question
.venv/bin/stl rt fetch --entity trip_updates
.venv/bin/stl assert run # the assumptions the app depends onSnapshots land in ~/.local/share/stl-transit (override with $STL_HOME).
Attaching to Claude Cowork / Desktop
Add to your MCP config (Cowork: Settings → Connectors → Add local server;
Desktop: claude_desktop_config.json). Use absolute paths:
{
"mcpServers": {
"stl-transit": {
"command": "/absolute/path/to/stl-transit/.venv/bin/stl-mcp",
"env": {
"STL_HOME": "/absolute/path/to/stl-transit"
}
}
}
}Verify before wiring it up:
.venv/bin/stl-mcp # should sit silently waiting on stdio; Ctrl-C to exitPointing STL_HOME at a directory inside the repo (gitignored) keeps every
snapshot the agent touches next to the code, which makes a Cowork session
reproducible after the fact.
What the 45 tools cover
Group | Tools |
Orientation |
|
Feed shape |
|
Entities |
|
Schedule |
|
Realtime |
|
Assumptions |
|
Drift |
|
Web sources |
|
Ship artifacts |
|
Digests |
|
Oracle |
|
Support |
|
Escape hatch |
|
stl_gtfs_query is why the surface stays at 45 rather than 64: anything the
named tools do not cover is expressible as read-only SQL. It is also the only
tool with real blast radius, so it is constrained at the SQLite driver —
mode=ro, an authorizer denying ATTACH/PRAGMA/every write, a wall-clock
timeout, and row/byte caps. DROP TABLE routes comes back as a structured
UNSAFE_QUERY error with a remedy, not a stack trace.
A note on surface size.
SPEC.md§10 targets 20–25 MCP tools, arguing from context-window economics. This server exposes 45, which is a deliberate departure: every group added since answers a question no other tool can, and the ones that would genuinely flood a context (bundle stops-indexat 646 KB,bundle compact,support bundle) are CLI-only for exactly that reason. The mitigation for a larger surface is the question-to-tool index at the top of the server instructions, so a cold-start model does not have to read 45 descriptions to find its entry point.
The parts that carry the most weight
core/gtfs/calendar.py + departures.py — the reference implementation the
Kotlin engine is graded against. GTFS measures times from noon-minus-twelve-hours,
not local midnight; a 00:12 departure is usually encoded 24:12:00 on the
previous service date; pickup_type=1 means a rider cannot board. Every
result carries service_date and gtfs_time beside the resolved local time, so
an implementation that gets the instant right by luck and the service date wrong
fails visibly instead of quietly.
The time arithmetic is done in UTC throughout, and that is not stylistic.
Subtracting or adding a timedelta on a zone-aware datetime is wall-clock
arithmetic in Python — and in java.time.LocalDateTime — so noon - 12h
collapses back to local midnight and every departure on the two DST transition
days each year shifts by an hour. Port the UTC conversion, not just the formula.
core/rt/wire.py + schema.py — a hand-rolled protobuf reader, deliberately
not gtfs-realtime-bindings. The LP3 has no protobuf runtime on the Light SDK
dependency allow-list, so the on-device decoder is either
kotlinx-serialization-protobuf or hand-written. schema.py is the porting
table and it marks signedness explicitly: delay is int32, and a decoder that
reads it unsigned turns "three minutes early" into 18446744073709551436. About
31% of the delay values in Metro's feed are negative, so this is the common case,
not the edge case.
core/assertions/ — 16 things the app depends on that Metro never promised:
that stop_code is populated and unique, that no trip runs past 28:00, that the
agency timezone does not move, that ≥95% of realtime trip ids resolve into the
static feed. Every result reports the observed value beside the threshold,
because "coverage 0.982, threshold 0.99" is actionable and "FAIL" is not. Three
outcomes, not two: skip means the measurement could not be taken, and a
stability check with no baseline has not been performed.
core/oracle.py — 19 golden-fixture cases, each present because it can break
independently: DST spring-forward and fall-back, 24:xx rollover queried from both
sides of midnight, Labor Day (MetroBus → Sunday, MetroLink → Weekend — different
concepts), an ordinary Monday that is not a holiday, expired feed as a distinct
state, realtime absent. A case that legitimately raises is a first-class
expectation compared on error type, so it does not read as permanent drift.
Coverage
metro_gtfs covers MetroBus in both Missouri and Illinois — St. Clair County
service is operated by Metro under contract and lives in this feed — plus
MetroLink. Two Illinois-side sources are configured but blocked on unresolved
URLs; stl snapshot sources reports them with discovery notes:
mct_gtfs— Madison County Transit, own buses, not in Metro's feed. Resolve via Transitland (f-madison~county~transit~il~us) or Mobility Database.loop_trolley— seasonal streetcar. Check whether its trips are already insidemetro_gtfsbefore adding it separately.
Resolving either is a one-line edit to src/stl_transit/data/sources.toml.
Exit codes
0 ok · 1 error · 2 usage · 3 assertion violated · 4 drift detected ·
5 network unavailable · 6 feed expired. Codes 3, 4 and 6 exist so
stl assert run, stl web check, stl oracle verify and stl report brief
drop into cron or a GitHub Action without anyone parsing output.
Tests
.venv/bin/pip install -e '.[dev]'
.venv/bin/pytest -q # 431 tests, no networkEverything runs against miniature synthetic feeds in tests/fixtures.py — three
stops, two routes, a calendar exception, a 24:12 rollover trip — small enough to
reason about completely, which is the only way to be sure the calendar math is
right rather than merely self-consistent. Protobuf tests run against
hand-encoded bytes with known field numbers.
Two suites go further than unit coverage:
tests/test_wiring.pyenforces the CLI-to-MCP contract itself: tool naming, the four annotations on every tool, thatcore/never importscli/ormcp/and never prints, and that no MCP tool exists without a CLI equivalent to debug it from.scripts/verify_fixes.pyre-runs the 2026-08-03 audit's failures against a real snapshot. The synthetic feeds have no negative RT delays and no 489k-row table to time out on, so these checks cannot be unit tests.scripts/smoke_mcp.pyspeaks real JSON-RPC tostl-mcpover stdio. Importing the tool functions proves the wiring but not that the server starts, negotiates a protocol version, or serializes its schemas — and those failures all happen before any of this code runs.
tests/test_review_fixes.py is worth reading on its own: it pins a class of bug
that appeared six separate times in this codebase. Adding a timedelta to a
zone-aware datetime, or subtracting or comparing two datetimes that share a
tzinfo object, is wall-clock arithmetic in Python. It is correct on 363 days
a year. On the fall-back night it made a bus 45 minutes away report as
−15 minutes and disappear from the board entirely; a fixed 1440-minute probe
missed the 25th hour and told a developer a stop had no service when it did.
If you touch time arithmetic here, do it in UTC, and add a test dated in March
or November — the shipped feed only covers about a month, so no real snapshot
can exercise a transition.
The second recurring theme is reporting success on a measurement never taken:
a survival rate of null beside meets_assumption: true, a drift check that
returned ok having verified zero fixtures, an assumption that failed every
morning because it measured how long since you last fetched rather than what it
claimed to. That failure mode does not announce itself — it looks exactly like
good news. skip is a first-class outcome here for that reason.
Evaluations
evaluations/ holds 10 question/answer pairs pinned to a specific snapshot,
each requiring several tool calls to answer. evaluations/verify_answers.py
recomputes all ten by two independent routes and tells you which have moved when
the pinned snapshot is eventually replaced.
Not yet built
Per SPEC.md: job handles for long operations (snapshot fetch, rt poll,
history pull, gtfs validate still block rather than returning a job id), the
history group over Mobility Database archives, and rt record / rt replay.
rt replay is a file emitter when built; the local HTTP server that mimics
Metro's endpoints for on-device testing is backlogged.
Terms
Metro's data is licensed non-exclusively, limited, and revocably, with no
trademark use permitted. Full terms:
https://www.metrostlouis.org/developer-resources/. Be a good guest — the HTTP
layer sends an identifying User-Agent, uses conditional requests, rate-limits
per host, and caps web-page fetches at one per day. stl assert run watches the
terms page for changes, because the redistribution right this project rests on
is one Metro can withdraw.
Available Tools
45 toolsstl_assert_explainARead-onlyIdempotent
One assumption in full: why it matters, which code path depends on it, and how to remediate a failure. Call this on anything stl_assert_run reports as failing, before deciding what to do about it.
Args: assumption_id: an id from stl_assert_list, e.g. 'stop_code_unique' or 'rt_join_rate'.
| Name | Required | Description | Default |
|---|---|---|---|
| assumption_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide the read-only, idempotent, non-destructive safety profile, lowering the burden on the description. The description adds value by explaining what the output captures (why it matters, code path, remediation), but it does not disclose error-handling behavior, prerequisites beyond the ID provenance, or limits. This is adequate given the annotation coverage, but not exceptional.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the core purpose is stated first, then usage, then parameter details. The phrasing 'One assumption in full' is slightly telegraphic but economical. No extra words or unnecessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with a single parameter, a presence of output schema, and rich safety annotations, the description covers the essential context. It explains the source and examples for the parameter, states the primary use case (failed assertions), and is sufficient for an agent to invoke correctly. It doesn't discuss invalid IDs or empty results, but those are minor and often left to the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter assumption_id receives meaningful guidance: it must be 'an id from stl_assert_list' and concrete examples are given ('stop_code_unique', 'rt_join_rate'). This compensates for the 0% schema description coverage and clarifies both the provenance and format of the expected value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description conveys the tool's purpose by framing it as 'One assumption in full: why it matters, which code path depends on it, and how to remediate a failure.' This clearly identifies that the tool explains a single assumption, and the relationship to stl_assert_run distinguishes it from the related siblings stl_assert_list and stl_assert_run, though the verb 'explain' is implicit rather than stated upfront.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs when to use the tool: 'Call this on anything stl_assert_run reports as failing, before deciding what to do about it.' This gives a clear triggering condition and rationale. It does not explicitly mention alternative tools, but the context against stl_assert_run and stl_assert_list is sufficient for an agent to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_assert_listARead-onlyIdempotent
The assumptions this app makes about the feed that Metro never promised.
Each one names what it checks and, more usefully, what breaks in the app if it stops holding. Read this before adding a feature that depends on feed behaviour, so the dependency gets encoded rather than discovered later by a user.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is consistent with the readOnlyHint and destructiveHint annotations, adding context about what the tool lists without contradicting the read-only nature. It does not introduce any side effects or caveats beyond what annotations already cover.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core purpose, then adding detail about the content and usage context. It is concise without being terse, and every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides enough context for a user to understand what the tool does and when to use it. Since there is no output schema provided, the description does not need to explain return values. It is complete for a listing tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has no parameters, so the schema coverage is 100%. The description does not need to explain any parameters, and the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: listing assumptions the app makes about the feed that Metro never promised. It also explains what each assumption names (what it checks and what breaks). This distinguishes it from sibling tools like stl_assert_run and stl_assert_explain.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance on when to use the tool: 'Read this before adding a feature that depends on feed behaviour.' It implies the tool is for understanding existing assumptions, though it does not explicitly mention alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_assert_runARead-onlyIdempotent
Evaluate the assumption suite against the current feed.
Every result carries the OBSERVED value beside the threshold, so a failure is actionable without a second call: "stop_code coverage 0.982, threshold 0.99" tells you how bad it is, "FAIL" does not.
Three outcomes, not two. skip means the measurement could not be taken --
a stability check with no baseline to compare against has not been
performed, and reporting that as a pass would be a lie.
Args: only: assumption ids to run. Omit for all. baseline: snapshot id or pin name for the stability assumptions (stop_ids_stable, rail_route_ids_stable). Without it those skip.
| Name | Required | Description | Default |
|---|---|---|---|
| only | No | ||
| baseline | No | ||
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive behavior, and the description adds meaningful behavioral detail: failures include observed values, and skip is used when a measurement cannot be taken. This is consistent with the annotations and gives the caller a clear model of outcomes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The text is compact and well structured: a one-sentence purpose, two brief outcome clarifications, and a labeled Args block. The example ('stop_code coverage 0.982, threshold 0.99') is valuable and the prose does not feel padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With three optional parameters and no schema-level descriptions, the description covers the main invocation details for 'only' and 'baseline', but the undocumented 'snapshot' parameter leaves a caller without enough information to know when or why to pass it. Output semantics are well described, so the primary gap is parameter completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description explains 'only' and 'baseline' well, including defaults and skip behavior, but it completely omits the 'snapshot' parameter that appears in the schema. Since there are no per-parameter descriptions in the schema, this is a significant gap in parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence clearly states the action: 'Evaluate the assumption suite against the current feed.' It also clarifies non-obvious output semantics (observed values and skip), which makes the tool's purpose unambiguous and distinguishable from sibling assert list/explain tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The Args section provides concrete usage guidance: omit 'only' to run all assumptions, and provide 'baseline' for stability assumptions or those checks will skip. It does not explicitly contrast with stl_assert_list or stl_assert_explain, but the operational conditions are clear enough for invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_bundle_faresARead-onlyIdempotent
The fare table the app ships, with its as_of date and source URL baked in.
Fares are NOT in the GTFS feed -- this reads the latest capture of Metro's fares page, so run stl_web_capture first if it reports nothing. Prices are integer cents; a fare table carrying 2.4999999 is a bug that reaches riders.
Args: fmt: 'json', or 'kotlin' to emit compilable Kotlin source. Hand-copying a fare table into Kotlin is how a stale fare reaches a rider.
| Name | Required | Description | Default |
|---|---|---|---|
| fmt | No | json |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark it read-only and idempotent; the description adds that it reads the latest web capture, includes as_of date/source URL, and requires integer-cent prices. It also hints at failure mode if capture is absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The text is compact and front-loaded with the core purpose, then adds caveats and parameter details. The 'bug that reaches riders' phrasing is colorful but not redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with one optional parameter, the description provides enough context: source, relationship to web capture, output formats, and data integrity expectation. It does not fully specify return schema or invalid-fmt behavior, but those gaps are minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter fmt is described as accepting 'json' or 'kotlin', with the Kotlin option emitting compilable source, which goes beyond the bare schema type and default. It could be slightly more explicit about the JSON output shape, but it compensates for low schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description identifies the resource as the app-shipped fare table and clarifies it is not from the GTFS feed, backed by Metro's captured fares page. It lacks an explicit action verb but the tool name and 'reads' make the retrieval purpose clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description gives practical guidance by directing users to run stl_web_capture first if no data is reported and warns against hand-copying fares into Kotlin to avoid stale values. It distinguishes from GTFS but does not enumerate all alternative tools for fare data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_bundle_holidaysARead-onlyIdempotent
Holiday to service-type mapping, bus and rail kept distinct.
On a holiday MetroBus runs SUNDAY service while MetroLink runs WEEKEND service. Those are different concepts that happen to coincide most of the time, and merging them produces a wrong answer on exactly the days a rider is most likely to check.
Args: year: the calendar year to resolve holiday dates against. Defaults to the current year, which is usually but not always what you want near a year boundary.
| Name | Required | Description | Default |
|---|---|---|---|
| year | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description makes clear that the tool returns a mapping and is read-only/idempotent via annotations. It explains the semantic distinction between MetroBus SUNDAY service and MetroLink WEEKEND service, giving transparency about the data model, though it does not spell out the exact output fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is succinct and well-structured, with a brief purpose statement, a critical caveat, and parameter documentation. No unnecessary wording or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's purpose and parameter semantics thoroughly, and the existence of an output schema fills in return-structure details. It is complete for the agent to call the tool correctly, though a bit more detail about the exact output mapping would be slightly richer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single year parameter is fully explained: what it represents, that it defaults to the current year, and the edge case near a year boundary. This gives the agent complete guidance for setting the parameter correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as a holiday-to-service-type mapping and stresses the bus/rail distinction, which is the core purpose. It is specific enough to differentiate from related GTFS calendar/service-day tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides practical usage guidance by warning against merging bus and rail service types and explaining why that matters. It also covers the year parameter's default and the year-boundary caveat, helping the agent decide when to pass an explicit year.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_bundle_size_reportBRead-onlyIdempotent
On-device size budget: bytes per table, with index cost isolated.
The raw feed is ~29 MB expanded and the LP3 is a minimalist device, so this is what decides which pruning strategy the shipped app uses.
Args:
compact_path: a database built by stl bundle compact, to compare
against the full feed.
| Name | Required | Description | Default |
|---|---|---|---|
| snapshot | No | ||
| compact_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, non-destructive behavior. The description adds output details (bytes per table, index cost isolated) but does not disclose potential errors or edge cases. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: a purpose statement, context, then a parameter description. It avoids unnecessary detail, though the second paragraph could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While the purpose and one parameter are described, the missing `snapshot` parameter and lack of output format details leave gaps. The description is not complete enough for a user to fully understand the tool's behavior without additional context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema provides no parameter descriptions (0% coverage). The description explains only `compact_path` (a database built by `stl bundle compact`), but leaves `snapshot` entirely unexplained. This is insufficient for correct invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: reporting on-device size budget (bytes per table, with index cost isolated) to decide pruning strategy. It distinguishes from sibling bundle tools (e.g., fares, holidays) by focusing on size metrics.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides context about when to use it (when deciding pruning strategy for the LP3 device) but does not explicitly mention alternatives or when not to use it. Usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_diff_stop_idsARead-onlyIdempotent
Survival rate of stop_id and stop_code across a service change.
The single most consequential number in this whole tool. The app's saved- stops feature lives or dies on it: every code that does not survive a pick is a user whose saved stop silently stops working, with no error and no way for them to tell what happened.
Args: a: the earlier snapshot id or pin name. b: the later one. Run stl_snapshot_list to see what is stored.
| Name | Required | Description | Default |
|---|---|---|---|
| a | Yes | ||
| b | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive behavior, so the description adds little on side effects. It mentions the real-world impact of the result but not what the tool actually returns or how it behaves on error.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core functional description is compact, but the motivational paragraph about the app's saved-stops feature and user impact is redundant for tool invocation. It adds emotional emphasis rather than operational guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and the parameter semantics explained, the description provides enough context for typical use. It does not detail the result format beyond 'survival rate', but the output schema likely covers that gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description gives meaningful context for both parameters: 'a' is the earlier snapshot and 'b' is the later one, with a pointer to stl_snapshot_list. This goes beyond the bare schema, though it leaves details like pin-name syntax unspecified.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool's purpose: computing the survival rate of stop_id and stop_code across a service change. It is distinct from sibling diff/summary tools by focusing specifically on stop identifier persistence.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains the input roles and points to stl_snapshot_list for retrieving snapshot IDs, which is useful. However, it does not explicitly state when to choose this tool over alternatives like stl_diff_summary or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_diff_summaryARead-onlyIdempotent
Everything that changed between two GTFS snapshots, in one screen.
Findings are graded, because a pick that renames three headsigns is routine and one that retires four hundred stop codes is not, and an ungraded list of deltas makes the reader do that triage themselves.
Args: a: the earlier snapshot id or pin name. b: the later one. Direction matters and is never normalized.
| Name | Required | Description | Default |
|---|---|---|---|
| a | Yes | ||
| b | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, and non-destructive behavior, and the description does not contradict them. It adds useful behavioral context by explaining that findings are graded and that direction matters, giving the user a clearer expectation of the tool's output and sensitivity to argument order.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise but includes a slightly stylistic explanatory sentence about why findings are graded. That sentence is informative rather than redundant, and the overall structure is clean: purpose, rationale, and parameter guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists, the description adequately covers the tool's purpose and parameters. It explains the input semantics and directionality, and it sets expectations for the summary output. It could mention error conditions or snapshot existence expectations, but these are not critical for basic usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema has 0% description coverage, the text provides meaningful parameter descriptions: 'a' is the earlier snapshot id or pin name, 'b' is the later one, and direction matters. This compensates for the missing schema annotations, though it could be more explicit about allowable formats for snapshot IDs or pins.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Everything that changed between two GTFS snapshots, in one screen.' This is specific and distinguishes it from narrower siblings like stl_diff_stop_ids, which focuses only on stop ID changes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for getting a broad, graded summary of changes between two snapshots, but it does not explicitly mention when to prefer this over alternative diff or snapshot tools. It does provide practical guidance that direction matters and is not normalized, which helps avoid misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_doctorARead-onlyIdempotent
Health of the local environment: store location, snapshot count, disk use, which configured sources are usable and which are blocked on an unresolved URL. Call this first if you do not know what data is available locally.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, so the safety profile is fully covered. The description adds no additional behavioral detail beyond describing the diagnostic output, which is appropriate but does not go beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, direct, and free of irrelevant detail. It front-loads the purpose and immediately provides the when-to-use guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter diagnostic tool, the description gives a sufficient list of what the health report includes and when to invoke it. Since an output schema is indicated, the description does not need to enumerate return fields.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has no parameters, and the empty input schema is fully covered. Baseline for zero parameters is 4; the description does not need to explain parameters that do not exist.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as a diagnostic for the local environment, listing concrete information it provides: store location, snapshot count, disk use, and source usability. It also distinguishes its role from sibling tools by positioning it as the first call when local data availability is unknown.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool: 'Call this first if you do not know what data is available locally.' It does not explicitly mention alternatives or when not to use it, but the primary usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_calendarBRead-onlyIdempotent
service_ids active on a date, showing the calendar.txt weekly pattern and each calendar_dates.txt exception SEPARATELY rather than pre-merged, so you can see whether a date's behaviour came from the weekly pattern or from an exception.
Args: on: ISO date (YYYY-MM-DD). Defaults to today.
| Name | Required | Description | Default |
|---|---|---|---|
| on | No | ||
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the annotations by explaining the behavioral nuance of separating weekly patterns from exceptions, which is not covered by the readOnly/idempotent flags. It clearly indicates what the tool does without hiding side effects (there are none).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is relatively concise and well-structured: it starts with the core functionality, then adds the distinguishing detail, and ends with parameter info. It avoids redundancy and is easy to parse, though slightly verbose in the second sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the main query purpose and one parameter but lacks an explanation of the output structure (despite the output schema) and the meaning of 'snapshot'. Given the existence of many sibling tools, the description is adequate for basic usage but not fully self-contained for complex scenarios.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only the 'on' parameter is explained in the description (ISO date, defaults to today), while 'snapshot' is entirely undefined. With two optional parameters and zero schema descriptions, the agent cannot fully understand how to use 'snapshot' or interact with snapshot-related siblings, leaving significant ambiguity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly conveys that the tool returns service_ids active on a given date, and it explains the distinguishing feature of showing weekly patterns and exceptions separately. It is specific enough to understand the tool's purpose, though it could more explicitly state that it returns query results.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not name any alternative tools or provide guidance on when to use this tool instead of siblings like stl_gtfs_service_day or stl_gtfs_query. The contrast with 'pre-merged' is implicit but not tied to specific alternatives, leaving the agent without explicit selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_coverageARead-onlyIdempotent
Service date range and days remaining before the feed expires.
Metro publishes a feed whose service data ends at the next quarterly pick. Check this before trusting any departure result: an empty departures list is frequently an expired feed rather than an absent bus.
| Name | Required | Description | Default |
|---|---|---|---|
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only and idempotent. The description adds functional behavior (returns coverage range and days remaining) and the reason for expiration (quarterly feed), which is helpful context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: first sentence states the core function, second sentence provides contextual advice. No unnecessary fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While the tool's purpose and usage context are clear, the description lacks any explanation of the 'snapshot' parameter. This is a significant gap that could lead to incorrect invocation, especially since the parameter is optional and its default behavior is unknown.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides no description for the 'snapshot' parameter, and the tool description does not explain it at all. With 0% schema coverage, the agent receives no guidance on what this parameter represents or whether it is required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: to provide the service date range and days remaining before the feed expires. It is distinct from sibling tools like stl_gtfs_schema and stl_gtfs_stats.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly advises when to use this tool: 'Check this before trusting any departure result.' It also explains the context (empty departures may be due to expired feed) and indirectly differentiates from stl_gtfs_departures and stl_support_explain_empty.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_departuresARead-onlyIdempotent
Scheduled departures at a stop for a time window. Schedule only, no realtime.
Correctly attributes departures encoded past 24:00:00 to the previous service date, and resolves service_ids through both calendar.txt and calendar_dates.txt. Each result carries its service_date and raw gtfs_time alongside the resolved local time, so a wrong service-date attribution is visible rather than hidden.
Args: stop: stop_code (number on the sign) or stop_id. at: ISO-8601 instant. Naive values are read as America/Chicago local time. Defaults to now. window_minutes: how far ahead to look. route: optional route_id or route_short_name filter.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | ||
| stop | Yes | ||
| limit | No | ||
| route | No | ||
| snapshot | No | ||
| window_minutes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations provide readOnlyHint, idempotentHint, and destructiveHint=false, which already cover safety. The description adds valuable context about how times are attributed across service days and how calendar files are resolved, increasing transparency about behavior beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured, with a clear opening sentence and additional detail in a second paragraph. It avoids unnecessary words and reads efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the core behavior and most parameters, but omits explanation of limit and snapshot, which could be important for advanced usage (e.g., limiting results or querying historical snapshots). Given the output schema is present, return values are not explained, but the missing parameter context limits completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description explains stop (code or id), at (ISO-8601 with timezone handling), window_minutes (lookahead), and route (filter), providing useful semantics. However, it does not mention limit or snapshot parameters that are present in the schema, leaving some parameter meanings undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool returns scheduled departures at a stop for a time window, and explicitly distinguishes it from realtime data. This is a specific and unambiguous purpose that differentiates it from likely sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says 'Schedule only, no realtime' which hints at when to use this tool versus realtime alternatives like stl_rt_stop_arrivals, but it does not explicitly name alternatives or provide explicit conditionals. The guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_featuresBRead-onlyIdempotent
Which GTFS features this feed provides, phrased to line up with the badges on the Mobility Database feed page (route colors, shapes, headsigns, wheelchair accessibility, fares, pathways, transfers, frequencies).
| Name | Required | Description | Default |
|---|---|---|---|
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations clearly indicate read-only, idempotent, non-destructive behavior, and the description is consistent with those annotations. No hidden side effects or state changes are described, and none are implied.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and free of extraneous content, listing relevant feature examples in a compact way. It is slightly awkward as a noun phrase rather than a clear imperative sentence, but overall it is efficient and readable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description gives the core purpose and useful examples, but it omits any explanation of the snapshot parameter and does not describe the output format. An output schema is indicated as present, which mitigates some incompleteness, but the textual description alone is only moderately complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, 'snapshot', is completely undocumented in both the schema and the description. The parameter name is suggestive but not explanatory, and no guidance is provided about accepted values, format, or how it affects the returned feature list.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool's purpose: reporting which GTFS features a feed provides, with concrete examples of feature badges such as route colors, shapes, and fares. It is reasonably distinct from sibling GTFS tools, though it is phrased as a noun phrase rather than an explicit verb-oriented statement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not state when to use this tool versus alternatives, nor does it provide conditions or examples of appropriate usage. It relies on the reader to infer when feature-level GTFS capabilities are needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_filesBRead-onlyIdempotent
Inventory of files in the GTFS zip with row counts and columns, plus a list of optional GTFS files that are ABSENT and why each absence matters (transfers, fares, frequencies, pathways...).
| Name | Required | Description | Default |
|---|---|---|---|
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, and non-destructive behavior, and the description is consistent with these. It adds no additional behavioral context such as potential performance implications, data size limits, or side effects, but since annotations are present and adequate, the bar is lower. The description does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, compact sentence that conveys all core functionality without redundancy or extraneous details. It is well-structured and front-loads the primary purpose, making it easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While the description explains what the tool does, it lacks critical context about the 'snapshot' parameter and does not clarify how this tool relates to similar ones (e.g., stl_gtfs_schema or stl_gtfs_stats). The presence of an output schema mitigates the need to describe return values, but the missing parameter explanation leaves an important gap for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema includes a 'snapshot' parameter with no description, and the tool description does not mention it at all. Since schema coverage is 0% (below 50%), the description was expected to explain what 'snapshot' refers to (e.g., a GTFS snapshot identifier), but it fails to do so, leaving the agent without guidance on how to populate the parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: it inventories files in a GTFS zip, including row counts and columns, and lists missing optional files with reasons. This is a specific and distinct resource compared to sibling tools like stl_gtfs_schema or stl_gtfs_stats, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when a high-level file inventory of a GTFS snapshot is needed, but it does not explicitly state when to prefer this over other tools (e.g., stl_gtfs_schema for schema details or stl_gtfs_stats for statistics). No direct comparison or conditions are provided, so guidance is only implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_late_nightBRead-onlyIdempotent
Trips whose stop times cross the service-day boundary, plus the maximum departure_time anywhere in the feed. Use it to find edge-case test material.
Args: threshold: GTFS time string; departures at or after it are returned.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| snapshot | No | ||
| threshold | No | 24:00:00 |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description states the query behavior (returning trips with cross-boundary stop times and the maximum departure time) and aligns with the readOnlyHint and idempotentHint annotations. No contradiction is present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and follows a clear two-part structure: first defining the resource, then a brief Args section. No unnecessary words or redundancy are present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description omits semantics for limit and snapshot, and while it mentions an output (trips plus max departure_time), it does not describe the return structure. More detail is needed for a caller to invoke the tool confidently without prior knowledge.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only the threshold parameter is explained in the description; limit and snapshot are present in the schema but have no description, and schema coverage is 0%. Since most parameters are undocumented, the description does not compensate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the resource (trips whose stop times cross the service-day boundary) and the distinct output (maximum departure_time in the feed), which helps separate it from the many stl_gtfs_* siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides a use case ('Use it to find edge-case test material') and explains the threshold filter, but it does not explicitly contrast with related tools like stl_gtfs_departures or stl_gtfs_query, leaving some when-to-use ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_queryARead-onlyIdempotent
Run one read-only SQL query against the imported GTFS feed.
Tables are the GTFS filenames without .txt: agency, stops, routes, trips, stop_times, calendar, calendar_dates, shapes, feed_info. All columns are TEXT, including numeric-looking ids -- leading zeros are meaningful in GTFS.
Writes, ATTACH and PRAGMA are denied at the database driver; a wall-clock timeout and row/byte caps are enforced. Only a single statement is accepted.
This is the general-purpose escape hatch: anything the named tools do not cover can be expressed here.
Args: sql: a single SELECT or WITH statement. limit: max rows (hard cap 1000).
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | ||
| limit | No | ||
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description reinforces the read-only annotation and adds concrete denied operations and limits, making the tool's behavior highly transparent. There is no contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and information-dense, covering purpose, constraints, data model, and fallback role without unnecessary elaboration. Each sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is largely complete for a general-purpose query tool, including constraints and the escape-hatch role. It does not explain the snapshot parameter or output format, but these are less critical given the SQL-query nature and the provided schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The sql and limit parameters are well explained, including the required SELECT/WITH form and the hard cap. However, the snapshot parameter is not described, leaving its purpose and format unclear.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool runs one read-only SQL query against the GTFS feed and explicitly identifies itself as the general-purpose escape hatch. This distinguishes it from the many specialized sibling tools by indicating it covers anything they do not.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly tells when to use this tool: for anything the named tools do not cover. It also provides critical usage constraints, such as only one statement, no writes, no ATTACH/PRAGMA, and row/byte caps.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_routeBRead-onlyIdempotent
One route in detail: directions, headsigns, per-service trip counts, and the first and last departure time in each direction.
Args: route_id: the GTFS route_id, NOT the number on the front of the bus. Metro's route_ids look like '19731B'; run stl_gtfs_routes with a search term to map a rider-facing number onto one.
| Name | Required | Description | Default |
|---|---|---|---|
| route_id | Yes | ||
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive. The description adds no additional behavioral context beyond these hints, so a neutral score is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Very concise and well-structured. The purpose is stated in one sentence, and the parameter tip is directly embedded without unnecessary wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Sufficient for a basic single-route lookup. Output details are not described but an output schema exists, and the description covers the essential purpose and key parameter. Missing snapshot semantics is the main gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The route_id parameter is well explained (GTFS ID, not bus number, with lookup tip), but snapshot remains undescribed. Schema provides no descriptions, so partial compensation only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool retrieves details for a single route, including directions, headsigns, trip counts, and departure times. The singular focus distinguishes it from stl_gtfs_routes (plural) though not explicitly named.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides guidance on how to obtain the route_id (run stl_gtfs_routes) but no explicit when-to-use vs. alternatives. The description implies single-route detail use, but lacks direct comparison or preconditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_routesBRead-onlyIdempotent
List routes with ids, short and long names, type and trip counts.
Args: route_type: GTFS route_type as a string. '3' is bus, '0' tram/streetcar, '1' subway, '2' rail. search: case-insensitive substring match across all route fields.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| search | No | ||
| snapshot | No | ||
| route_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare read-only, idempotent, non-destructive. Description adds no further behavioral detail (e.g., result size, pagination behavior). Given annotations present, it's minimally transparent but no contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is concise, with a clear main sentence and an argument list. No irrelevant details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Description includes output fields but omits details about snapshot meaning, search behavior, or pagination. Given the presence of sibling tools, some context is available, but not fully self-contained. Output schema is said to exist but not shown.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Description does not explain any of the five parameters (limit, offset, search, snapshot, route_type). Schema coverage is 0% - parameters are only listed with types and defaults, no semantic meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('routes'), and specifies output fields (ids, names, type, trip counts). Siblings include singular 'route', so this is clearly the plural list operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Does not provide explicit guidance on when to use this tool versus alternatives, nor conditions for filtering or pagination. No comparison to stl_gtfs_route or other query tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_schemaBRead-onlyIdempotent
Columns, null rates, distinct counts and sample values for one GTFS file.
Args: table: GTFS file name with or without .txt, e.g. 'stops' or 'stop_times.txt'.
| Name | Required | Description | Default |
|---|---|---|---|
| table | Yes | ||
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description does not contradict the readOnlyHint/idempotentHint annotations, and it correctly implies a read-only inspection. However, it adds no extra behavioral context beyond the annotations, such as potential cost of retrieving sample values for large tables or any side effects (though none exist).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, using a single sentence to convey the tool's purpose and a brief parameter explanation. No superfluous words or redundant phrasing, making it easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although the description lists the kinds of output (columns, null rates, etc.), it does not explain the output schema structure or how the snapshot parameter affects results. For a tool with an output schema, this lack of detail leaves the agent uncertain about the exact return format and the role of snapshot.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description explains the 'table' parameter with examples but leaves the 'snapshot' parameter entirely undocumented. With schema coverage at 0% and only one of two parameters described, the description fails to compensate for the missing snapshot semantics, which is a significant gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly indicates the tool provides schema information (columns, null rates, distinct counts, sample values) for a single GTFS file/table. It distinguishes itself from sibling tools like stl_gtfs_files or stl_gtfs_stats by focusing on schema details, though the verb is implicit rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives like stl_gtfs_query or stl_gtfs_stats. It does not mention typical use cases, such as inspecting a table's structure before querying, or scenarios where the snapshot parameter would be needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_service_dayARead-onlyIdempotent
Which GTFS service date(s) a wall-clock instant could belong to, with the corresponding gtfs_time for each.
Use this whenever a departure time looks off by a day. GTFS measures times from noon-minus-twelve-hours, not local midnight -- on DST transition days those differ by an hour.
Args: timestamp: ISO-8601 instant. Naive values read as America/Chicago.
| Name | Required | Description | Default |
|---|---|---|---|
| timestamp | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description states that it returns service date(s) and corresponding gtfs_time values, which is helpful. Annotations already indicate read-only, idempotent behavior, so the description adds meaningful behavioral detail without needing to restate 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is brief and to the point, with no redundant wording. Every sentence adds value: the purpose, the usage condition, the GTFS convention, and the parameter definition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given this is a simple single-parameter tool with read-only annotations and a clear domain explanation, the description is complete enough for an agent to decide when to use it and what to expect. The DST note addresses the key subtlety relevant to this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only specifies timestamp as an optional string/null, but the description adds crucial semantics: ISO-8601 instant format, naive values interpreted as America/Chicago, and the timezone-related DST explanation. This fully compensates for the 0% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: determining which GTFS service date(s) a wall-clock instant could belong to and providing the corresponding gtfs_time. This is specific and distinct from sibling tools focused on routes, stops, departures, or other GTFS aspects.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'Use this whenever a departure time looks off by a day,' giving a concrete condition for when to invoke the tool. It also explains the GTFS time convention and DST nuance, providing important context for correct use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_statsARead-onlyIdempotent
Headline counts: agencies, routes broken down by route type, stops, trips, stop_times rows, shape points, service_ids.
| Name | Required | Description | Default |
|---|---|---|---|
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description indicates a read-only counting operation, and annotations reinforce readOnlyHint=true and destructiveHint=false. No side effects are implied or hidden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that lists the exact count categories with no redundant words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple stats tool, the description gives enough context about the returned count categories and the optional snapshot parameter, though the return format/type is not explicitly detailed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter 'snapshot' is mentioned with a default but not explained; schema coverage is 0%, yet the name and default are self-explanatory in the GTFS snapshot context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool provides headline counts for key GTFS entities (agencies, routes, stops, trips, stop_times, shapes, service_ids), identifying it as a summary/stats tool distinct from query or feature tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this vs. alternatives like stl_gtfs_query or stl_gtfs_coverage, but the count-oriented description makes the use case reasonably inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_stopARead-onlyIdempotent
One stop resolved by rider-facing code or internal id, with both identifiers, parent station, accessibility flags, coordinates, and the routes serving it.
Args: stop: a stop_code (the number on the sign) or a stop_id.
| Name | Required | Description | Default |
|---|---|---|---|
| stop | Yes | ||
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description clarifies that the input can be either a stop_code or stop_id and that the output includes both identifiers, going beyond the annotations. However, it does not describe error handling or behavior when the stop is not found. Annotations already cover read-only and idempotent behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, with two sentences that front-load the purpose and then list arguments. No fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description includes what the tool returns, which is helpful. It omits the snapshot parameter, but that is optional. Given the simplicity of the tool, the description is mostly adequate, though the missing parameter explanation is a gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description explains the 'stop' parameter (stop_code or stop_id) but does not explain the 'snapshot' parameter at all. Schema coverage is 0%, so this is the only source. It covers 1 of 2 parameters (50% coverage), adding meaningful info for the main parameter but leaving the optional one unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns a single stop's details including both identifiers, parent station, accessibility flags, coordinates, and routes. It differentiates from sibling tools like stl_gtfs_stops (plural) and stl_gtfs_stop_resolve (which likely resolves an ID).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives. It does not mention when to use stl_gtfs_stops for multiple stops or stl_gtfs_stop_resolve for ID resolution. The description only implies single-stop usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_stop_resolveARead-onlyIdempotent
Determine which GTFS field holds the number printed on a bus stop sign.
Reports coverage, uniqueness and observed format for both stop_code and stop_id, checks Metro's own published example (15111), and returns a verdict.
This matters more than it looks: the Light SDK exposes no usable location API, so 'stops near me' is not buildable and the app's entire input UX is stop-number entry. Run this once and rely on the verdict.
| Name | Required | Description | Default |
|---|---|---|---|
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the tool as readOnly, non-destructive, and idempotent. The description adds context by stating it is a one-time analysis and that its verdict can be relied upon, which aligns with the annotations and provides additional behavioral clarity without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and starts with the core purpose, followed by details and context. It is slightly verbose with the 'This matters more than it looks' section, but this adds useful rationale without being excessively long.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides sufficient context for the tool's overall goal and its importance, but it omits an explanation of the 'snapshot' parameter and does not specify the output format or how the 'verdict' is represented. This incomplete parameter understanding and output specification make it only partially complete for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema parameter 'snapshot' is not described at all in the tool description. With 0% schema description coverage, the description fails to compensate by explaining the parameter's meaning, type, or usage, leaving the agent unable to correctly provide input.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose with a specific verb ('Determine') and resource ('which GTFS field holds the number printed on a bus stop sign'). It also lists the actions (reports coverage, uniqueness, format, checks example, returns verdict) that make it distinct from sibling tools like stl_gtfs_stops or stl_gtfs_stop.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool by explaining why this analysis matters (no location API, so stop-number entry is the UX) and suggests a one-time invocation ('Run this once and rely on the verdict'). However, it does not explicitly contrast with alternative tools or state conditions that would make this tool preferable over others.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_gtfs_stopsARead-onlyIdempotent
Search stops by name substring, rider-facing stop code, or serving route.
Args: search: substring of stop_name, case-insensitive. code: exact stop_code match. route_id: return every stop served by this route.
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | ||
| limit | No | ||
| offset | No | ||
| search | No | ||
| route_id | No | ||
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the safety profile is clear. The description adds search criteria but does not explain return format (e.g., returns a list) or pagination behavior via limit/offset, though this is less critical given the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, tightly worded sentence that conveys the core purpose without redundancy. It is well-structured and easily parsed by an agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is adequate for a simple search tool but lacks explanation of the 'snapshot' parameter (likely to select a data version) and does not describe the output schema. Given the tool's straightforward nature and presence of annotations, this is acceptable but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description explains three of six parameters: search (as case-insensitive substring), code (as exact match), and route_id (as serving route). It omits limit, offset, and snapshot, which are likely used for pagination and data versioning. This covers about 50% of parameters, providing basic but incomplete semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Search' and the resource 'stops', and enumerates specific search criteria (name substring, stop code, route). It distinguishes itself from sibling tools like stl_gtfs_stop (exact stop retrieval) and stl_gtfs_stop_resolve (ID resolution) by focusing on search functionality.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus the many sibling tools. It does not mention that stl_gtfs_stop is for single-stop lookup or that stl_gtfs_stop_resolve handles fuzzy matching, leaving the agent to infer the appropriate context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_oracle_casesBRead-onlyIdempotent
The golden-fixture case list for the Kotlin test gate, each with the specific failure mode it pins down (DST transitions, 24:xx rollover, holiday service mapping, expired feed, realtime absent, and so on).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, and non-destructive behavior. The description adds minimal extra context about the static golden-fixture nature, but does not elaborate on return format or side effects, so a baseline score is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that directly states the tool's purpose and gives concrete examples. It is concise and well-structured without unnecessary padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description conveys the basic nature of the return value (a list of cases with failure modes) but does not specify the structure or fields of each case, nor how the output might be consumed. This is adequate for a simple list tool, but leaves some ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has no input parameters, and the schema coverage for properties is complete (empty). Since there are no parameters to explain, the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly indicates it provides a list of golden-fixture cases for Kotlin test gates, with examples of failure modes. It distinguishes from sibling list tools by focusing on oracle cases, though it does not explicitly use a verb like 'list' or 'fetch'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool compared to the many sibling tools. It does not mention alternatives or specific conditions that would make this the appropriate choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_oracle_generateAIdempotent
Compute expected departure outputs and write committed fixture JSON files.
Output is byte-stable for a given snapshot (sorted keys, fixed indent) so that a later verify run is a meaningful drift check.
Args: spec_path: JSON file binding each case id to concrete inputs, e.g. {"weekday_midday": {"stop": "15111", "at": "2026-08-05T12:00:00"}}. out_dir: directory to write fixtures into. case: generate only this case id.
| Name | Required | Description | Default |
|---|---|---|---|
| case | No | ||
| out_dir | No | fixtures | |
| snapshot | No | ||
| spec_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide idempotentHint and destructiveHint, and the description adds that it writes committed fixture files with byte-stable output. It does not mention details like overwriting or side effects beyond writing files, but the annotation coverage lowers the bar and the description supplies relevant context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, well-structured, and free of fluff. It clearly separates the main purpose from parameter details and includes a relevant example for spec_path.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description explains the tool's side effect (writing fixtures) and its role in verify runs, which is helpful. However, it omits any explanation of the snapshot parameter and does not describe the output schema or return value, leaving some gaps for a tool with four parameters and an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description covers spec_path with an example, out_dir as the output directory, and case as an optional filter, but does not explain the snapshot parameter at all. With 3 of 4 parameters described, coverage is near but not above the high threshold, and the missing snapshot is a notable gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool computes expected departure outputs and writes committed fixture JSON files. It specifies the resource (fixture files) and the action (generate/write), and distinguishes itself from verification and case-listing tools by focusing on generation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage before a verify run ('so that a later verify run is a meaningful drift check') but does not explicitly name alternatives like stl_oracle_cases or stl_oracle_verify or state when not to use this tool. More direct guidance would improve clarity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_oracle_verifyARead-onlyIdempotent
Recompute every committed fixture against the current feed and report which ones no longer match. Drift means either the feed changed or the fixtures are stale -- both are things you want to learn from a scheduled run, not a user.
A case that legitimately raises (unknown stop code, expired feed) is a first-class expectation, compared on error type rather than message, so it does not read as permanent drift.
Args: fixtures_dir: directory of committed fixture JSON, normally the tool repo's test resources rather than anywhere in this store.
| Name | Required | Description | Default |
|---|---|---|---|
| snapshot | No | ||
| fixtures_dir | No | fixtures |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnly, idempotent, and non-destructive behavior. The description adds no additional behavioral details beyond the core 'recompute and report', so it meets the baseline without enriching beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences long and mostly relevant, but the second sentence about 'scheduled run' could be more concise. It does not waste words, yet the phrasing is slightly convoluted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool's main purpose is clear, but the undocumented 'snapshot' parameter and lack of output description (though an output schema exists) leave gaps for an agent attempting to call it correctly. The scheduled-run context helps but does not fully compensate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only 'fixtures_dir' is described in the args section; 'snapshot' is left entirely undocumented. With 50% coverage, the description provides partial meaning but lacks full parameter clarity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: recompute committed fixtures against the current feed and report mismatches. It distinguishes this verification tool from sibling tools like 'stl_oracle_generate' by focusing on checking rather than creating fixtures.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides context on when to use: scheduled runs to detect drift, and notes that user-driven calls are not the primary scenario. However, it does not explicitly contrast with alternative tools, leaving some inference to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_report_briefARead-onlyIdempotent
The state of the feed right now, in one call, with the next command to run.
Composes coverage, the assumption suite, realtime health and web drift. Every input is optional and absences are reported rather than silently passed, so this still works on a machine that has only ever fetched the static feed. Start here if you do not know what is wrong.
| Name | Required | Description | Default |
|---|---|---|---|
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnly, idempotent, non-destructive), the description adds behavioral details: it reports absences rather than silently passing them, and mentions that all inputs are optional. This gives users a clear idea of how the tool behaves at runtime.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, consisting of two well-organized sentences. The first sentence states the core purpose, and the second provides supplementary details about composition, optionality, and behavior. No wasted words or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides sufficient context for a composite report tool, mentioning what it aggregates and its role as a first diagnostic step. However, it omits any explanation of the 'snapshot' parameter, which could be a meaningful gap for users deciding whether to provide it. Overall, it is mostly complete for the tool's intended use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has one parameter 'snapshot' with no description, and the tool description does not explain its meaning or usage. Since schema coverage is 0%, the description should compensate, but it only says 'every input is optional' without clarifying what snapshot does. This leaves the parameter semantics entirely unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: to provide the current state of the feed in one call and recommend the next command. It also explicitly mentions it composes coverage, assumption suite, realtime health, and web drift, and positions it as a starting point for diagnosing issues, distinguishing it from specialized sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance on when to use it: 'Start here if you do not know what is wrong.' It also notes that every input is optional and that it works even on a machine that has only fetched the static feed, helping users understand its applicability in minimal setups.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_report_handoffARead-onlyIdempotent
Verified facts about the feed as a markdown block, with citations.
Written for pasting into a CLAUDE.md handoff document. Every claim carries the snapshot id and date it was verified against, so a later reader can re-verify rather than trust -- the feed moves, and an uncited fact in a handoff doc silently becomes a lie. Includes the sharp edges that bite a Kotlin port: 24:xx encoding, DST arithmetic, stop_code vs stop_id, the absent protobuf runtime, fares living off-feed.
| Name | Required | Description | Default |
|---|---|---|---|
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations already providing readOnlyHint, openWorldHint=false, idempotentHint, and destructiveHint=false, the description adds substantial behavior: every claim carries the snapshot id and date it was verified against, the warning about uncited facts silently becoming lies in a handoff doc, and the explicit list of sharp edges (24:xx encoding, DST arithmetic, stop_code vs stop_id, absent protobuf runtime, fares living off-feed). No annotation is contradicted. This is exactly the kind of context the annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is front-loaded: first sentence states the deliverable, second states the artifact, third explains citations/re-verification, and the last enumerates concrete fallible areas. Each sentence earns its place with useful detail, though the final list of edge filters is a little heavy on the lowercase ('24:xx', 'stop_code vs stop_id') and could be trimmed without meaning change.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists (so the return value needs no description), low parameter count, and safe/idempotent annotations, the description is nearly complete: it covers purpose, output nature, verification semantics, and the specific sharp edges that a consumer needs. Remaining gaps are the snapshot parameter semantics and an implicit alternative (stl_report_brief) which would firm up the boundary, both minor at this volume of single optional parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single optional parameter, `snapshot`, and schema description coverage is 0%, so the description must compensate. It references 'the snapshot id... it was verified against', which hints at what the parameter concerns, but it never explains what value to pass, what omitting it means (e.g., latest snapshot), or any format constraints. The meaningful mentions keep it above a 2, but the parameter is realistically guesswork for an agent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the output ('a markdown block... with citations' of 'verified facts about the feed') and the intended artifact ('Written for pasting into a CLAUDE.md handoff document'). It is easy to distinguish from the data-query siblings (stl_gtfs_*) and the brief (stl_report_brief seems the natural confusable), but it never explicitly names that sibling or defines how it differs, so it misses the fifth point.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Pending in a CLAUDE.md handoff document' gives a concrete, materially useful usage context that tells an agent exactly when this tool's output is needed, and the re-verification rationale implies the situation. It stops short of saying when not to use it, does not name alternatives such as stl_report_brief, and gives no conditional guidance, so it misses full when/when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_rt_decodeBRead-onlyIdempotent
Decode a stored GTFS-Realtime snapshot into normalized JSON.
Fields present in the bytes but absent from the schema map are preserved under '_unknown' rather than dropped, because silently discarding fields is how you ship a decoder that is wrong in ways nobody notices.
Args: entity: 'trip_updates', 'vehicle_positions', or 'alerts'.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| entity | No | trip_updates | |
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already indicate read-only, idempotent, and non-destructive behavior, and the description aligns with those hints. It adds useful detail that unknown fields are preserved under '_unknown', but it does not describe output structure or error behavior, though an output schema exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is reasonably concise and front-loads the main purpose. The explanatory clause about silently discarding fields is slightly verbose but supports the stated behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is not complete enough given the three optional parameters and a schema with no descriptions. It omits explanations for 'limit' and 'snapshot', and does not address how the output normalizes data beyond the '_unknown' note, leaving an agent to guess at important inputs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description mentions only the 'entity' parameter and its allowed values; 'limit' and 'snapshot' are not explained. Since the input schema has no parameter descriptions, the description fails to compensate for the missing semantics of two of the three parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool decodes a stored GTFS-Realtime snapshot into normalized JSON, with a specific verb, resource, and output format. It also calls out the entity types accepted, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the appropriate use case—when a stored GTFS-Realtime snapshot needs to be decoded to normalized JSON—but it does not explicitly compare this tool with sibling tools such as stl_rt_wire or stl_rt_reference. There is no 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.
stl_rt_healthARead-onlyIdempotent
Staleness and entity counts for the locally stored realtime feeds, and whether the three feeds agree on their header timestamp.
Args: entity: 'trip_updates', 'vehicle_positions', or 'alerts'. Omit for all.
| Name | Required | Description | Default |
|---|---|---|---|
| entity | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnly and idempotent behavior. The description adds that it operates on 'locally stored realtime feeds,' giving further context on data locality. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, two sentences, with the main purpose first and parameter details second. No fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides sufficient context for what the tool returns (staleness, counts, agreement) and the optional parameter. Since an output schema exists separately, it does not need to detail return structure.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter 'entity' is clearly explained with allowed values ('trip_updates', 'vehicle_positions', 'alerts') and the behavior when omitted. This fully covers the schema's lack of description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly specifies the tool's purpose: providing staleness, entity counts, and header timestamp agreement for realtime feeds. It distinguishes itself from other realtime tools by focusing on health metrics rather than decoding or wire data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies its use as a health check for realtime feeds, but it does not explicitly contrast with sibling tools like stl_rt_schema_census or stl_rt_reference. However, the purpose is straightforward enough that an agent can infer when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_rt_referenceARead-onlyIdempotent
The full GTFS-Realtime field map as a flat table (message, field number, name, kind, repeated) plus all enum value mappings.
This is the porting reference for the on-device decoder. The Light SDK dependency allow-list contains no protobuf runtime, so the Kotlin decoder is either kotlinx-serialization-protobuf or hand-written from this table.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare the tool as read-only and idempotent, so the description does not need to repeat those. The description adds content details but no additional behavioral traits beyond what annotations cover, making a 3 appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, immediately stating the tool's output and its purpose. It is tightly written with no unnecessary words, making it highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless static reference, the description fully explains what the tool returns and why it exists. The mention of a 'flat table' and 'enum value mappings' gives a sufficient picture of the output, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is nothing for the description to add beyond the schema. Per the baseline for 0 params, a score of 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool provides a flat table of GTFS-Realtime field mappings and enum values. This distinguishes it from sibling tools like stl_rt_decode or stl_rt_health, which serve different runtime or diagnostic purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description identifies this as the porting reference for the on-device decoder, giving a concrete use case. It does not explicitly contrast with alternatives, but the context of being a static reference for porting is clear enough for a developer to know when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_rt_schema_censusARead-onlyIdempotent
Which protobuf fields this feed actually populates, and at what rate, across N stored snapshots.
Decides what to model in Kotlin: low-rate fields can be skipped in v1, and any path reported as unmodelled is present in the bytes but missing from the schema map, which needs investigating before porting.
Args: samples: how many recent snapshots to census.
| Name | Required | Description | Default |
|---|---|---|---|
| entity | No | trip_updates | |
| samples | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the read-only annotation, the description discloses key behavioral nuances, such as reporting population rates and distinguishing unmodelled paths that are present in bytes but missing from the schema map. It does not describe the output shape, but an output schema is present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well structured, with the purpose stated first followed by the practical decision context and parameter explanation. No unnecessary fluff is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the core purpose, decision context, and one of two parameters. However, it omits the 'entity' parameter and does not clarify how the output should be interpreted beyond the unmodelled-path note.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only 'samples' is explained in the description, as 'how many recent snapshots to census.' The 'entity' parameter is left undocumented, despite having a default value of 'trip_updates' and likely controlling which feed entity is analysed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool's purpose: determining which protobuf fields a feed actually populates and at what rate across stored snapshots. This is distinct from the sibling RT tools (decode, wire, reference, stop_arrivals), which focus on other aspects of real-time data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use the tool by framing it around Kotlin modeling decisions: low-rate fields can be skipped and unmodelled paths need investigation. It does not explicitly compare against alternatives, but the intended workflow use is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_rt_stop_arrivalsARead-onlyIdempotent
Scheduled departures with realtime predictions merged in -- exactly what the app should render.
When no realtime snapshot is available it degrades to scheduled-only and says so explicitly, which is the behaviour the app must also have.
Args: stop: stop_code or stop_id. at: ISO-8601 instant, America/Chicago if naive. Defaults to now.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | ||
| stop | Yes | ||
| limit | No | ||
| snapshot | No | ||
| window_minutes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses that realtime data is merged when available and that the tool explicitly signals when it falls back to scheduled-only. This gives useful behavioral insight for callers.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is brief and forward-loaded with the core purpose, but includes some redundant phrasing around app behavior ('exactly what the app should render' and 'behaviour the app must also have') that could be trimmed without loss.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While the output schema exists and the description covers the main purpose and an important fallback behavior, it omits context for several input parameters and does not relate the tool to the surrounding workflow (e.g., how it fits with snapshot selection or GTFS departures). This leaves room for user uncertainty.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description only explains stop and at. Parameters limit, snapshot, and window_minutes are left completely unexplained, leaving significant ambiguity in how to correctly invoke the tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns scheduled departures merged with realtime predictions, which is a specific and unambiguous purpose. It distinguishes this tool from the broader set of GTFS/RT tools by focusing on the app-rendering departure view.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description mentions a degradation behavior (falls back to scheduled-only) but does not explicitly state when to use this tool versus alternatives like stl_gtfs_departures or stl_rt_decode. It lacks direct 'use this when...' or 'prefer this over...' guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_rt_wireARead-onlyIdempotent
Raw protobuf wire-format dump of a realtime snapshot: field number, wire type, length, bytes and nesting, with the named path for each numeric path.
This is the ground-truth artifact for validating a hand-written decoder. Point the Kotlin implementation at the same snapshot and compare trees.
Args: depth: how deep to recurse into submessages. max_entities: how many feed entities to dump (keeps output bounded).
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | ||
| entity | No | trip_updates | |
| snapshot | No | ||
| max_entities | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description's reference to a 'dump' and 'validate' aligns with these hints, and no contradictory side effects are mentioned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loads the primary purpose. However, the 'Args' section is incomplete, which slightly detracts from the structural clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value details are not needed. The description provides a use case but omits explanations for 'entity' and 'snapshot', and does not mention how a snapshot is sourced, leaving some contextual gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, and the description only explains two of the four parameters ('depth' and 'max_entities'). The meaning of 'entity' and 'snapshot' is left unspecified, leaving a significant gap in parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool dumps raw protobuf wire-format data, including field numbers, wire types, lengths, bytes, and nesting. It distinguishes itself from siblings like stl_rt_decode by emphasizing the raw, ground-truth nature and its use for validating a decoder.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a concrete use case: 'Point the Kotlin implementation at the same snapshot and compare trees.' It does not explicitly differentiate from all sibling tools, but the stated validation purpose makes when to use it clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_snapshot_fetchA
Download a feed from the network into the local snapshot store.
Uses conditional requests, so an unchanged feed returns unchanged=true and costs a 304 rather than re-downloading. The GTFS zip is ~3.5 MB and expands to ~29 MB, so this can take a few seconds.
Args: source: 'metro_gtfs', 'metro_rt_trips', 'metro_rt_vehicles', 'metro_rt_alerts'. force: bypass the conditional-request cache.
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | ||
| source | No | metro_gtfs |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses important side effects and behavior: it performs network downloads, uses conditional requests with 304 responses, and can take a few seconds due to file sizes. This goes beyond the annotations, which already indicate readOnly=false and idempotent=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: a clear first sentence, then additional relevant details about conditional requests and expected size/time, followed by the argument explanations. No unnecessary wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description gives enough context for invocation, including source and force semantics and performance characteristics. It mentions the return field 'unchanged=true' but leaves other return details to the output schema, which is acceptable given the tool's simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has no parameter descriptions, but the description fully compensates by listing the valid source values ('metro_gtfs', 'metro_rt_trips', 'metro_rt_vehicles', 'metro_rt_alerts') and explaining that force bypasses the conditional-request cache.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Download a feed from the network into the local snapshot store') and clearly distinguishes this from sibling tools like stl_snapshot_list and stl_snapshot_sources by focusing on the fetch/refresh action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: to download a feed into the snapshot store. It explains the source options and the force flag, though it does not explicitly name alternative sibling tools or state when not to use them.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_snapshot_listARead-onlyIdempotent
List stored snapshots newest-first, with pins.
Args: kind: 'gtfs' or 'rt'. Omit for all. source: source name, e.g. 'metro_gtfs'. Omit for all.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | ||
| limit | No | ||
| offset | No | ||
| source | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, idempotentHint, and destructiveHint, covering behavioral aspects. The description does not contradict these and adds no misleading side-effect info, so the lower bar for annotation-covered cases is comfortably met.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The content is extremely concise, with only two sentences and no fluff. Every word contributes to understanding the tool's purpose and parameters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema is present, so return details need not be described. The description covers ordering (newest-first) and filtering, making it complete enough for usage. Minor ambiguity about 'pins' does not reduce usability.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the input schema has no descriptions, the tool description text explicitly explains both parameters: kind is 'gtfs' or 'rt', and source is a name like 'metro_gtfs'. This adds meaning beyond the bare types and defaults in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists stored snapshots newest-first with pins, using specific verbs and a distinct resource. This differentiates it from siblings like stl_snapshot_sources, which likely lists sources, and stl_snapshot_fetch, which likely fetches a snapshot.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains how to filter using kind and source, including examples and the instruction to omit for all. It does not explicitly compare with alternatives, but the usage pattern is straightforward and well-implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_snapshot_sourcesARead-onlyIdempotent
List every configured feed and page: agency, region, URL, whether it is usable, how many snapshots exist locally, and when the latest was fetched.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is consistent with the annotations (readOnly, idempotent, non-destructive) and adds useful detail about the output fields, including whether each source is usable and snapshot counts. It does not mention error cases or rate limits, but given the simple read-only nature and strong annotations, the behavioral contract is clear and complete enough.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that packs all essential information without redundancy. It front-loads the action and resource, then lists the returned fields in a readable order.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple and read-only, has no parameters, and the description states exactly what will be listed. Since an output schema is present and annotations already cover safety and idempotency, the description provides sufficient context for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there are no parameter descriptions to evaluate. According to the rubric, zero parameters earns a baseline of 4, and the schema coverage is effectively complete since no inputs need explanation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and clearly identifies the resource ('every configured feed and page'). It enumerates the exact fields returned (agency, region, URL, usability, snapshot count, latest fetch), which makes the purpose unmistakable and distinct from sibling tools like stl_snapshot_list or stl_gtfs_routes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no explicit guidance about when to use this tool instead of alternatives such as stl_snapshot_list or stl_web_list. There is no mention of appropriate use cases, filtering conditions, or related tools, so an agent must infer when to invoke it from the name and general wording alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_support_diff_deviceARead-onlyIdempotent
Diff what a device actually rendered against what it should have.
Deliberately forgiving about the shape of actual_json: it accepts a bare
list, several wrapper shapes, and differing key names, and reports what it
assumed. The realistic input is something pasted out of a bug report, and a
support tool that rejects the user's paste over a key name has failed at
its one job.
Args: expected_json: a file path or inline JSON -- typically the output of stl_support_repro. actual_json: a file path or inline JSON captured from the device.
| Name | Required | Description | Default |
|---|---|---|---|
| actual_json | Yes | ||
| expected_json | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, and non-destructive behavior. The description adds important behavioral details: it is 'deliberately forgiving' about input shapes and 'reports what it assumed,' which goes beyond the annotations by explaining how it handles unexpected input.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is mostly succinct but includes a slightly tangential statement, 'a support tool that rejects the user's paste over a key name has failed at its one job,' which adds flavor but not essential information. Two paragraphs are structured well.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's purpose, parameter semantics, and some behavior. It does not mention the output format or return value, but given the output schema exists (though not shown) and the tool's straightforward nature, the missing detail is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides no descriptions (0% coverage), but the tool description fully compensates by explaining both parameters: expected_json is 'a file path or inline JSON -- typically the output of stl_support_repro' and actual_json is 'a file path or inline JSON captured from the device.' This is clear and complete.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action: 'Diff what a device actually rendered against what it should have.' It specifies the resource (device rendering vs. expected) and even references stl_support_repro as the source of expected_json, fully distinguishing its role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives contextual hints (e.g., 'pasted out of a bug report' and expected from stl_support_repro) but does not explicitly differentiate from sibling diff tools like stl_diff_summary or stl_diff_stop_ids. When to use this tool over alternatives is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_support_explain_emptyARead-onlyIdempotent
Diagnose why a stop shows no departures, by walking the decision tree and naming the branch: unknown stop code, expired feed, no service that date, stop present but never served, or simply too narrow a window.
Use this whenever stl_gtfs_departures returns an empty list, instead of guessing at the cause.
Args: stop: stop_code or stop_id. at: ISO-8601 instant, America/Chicago if naive.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | ||
| stop | Yes | ||
| snapshot | No | ||
| window_minutes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description indicates a read-only diagnostic behavior, consistent with the readOnlyHint, idempotentHint, and destructiveHint annotations. Walking a decision tree and naming a branch is clearly non-mutating.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well structured, with the purpose, trigger, and argument notes clearly separated. No redundant or extraneous content is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is mostly complete for the intended use case: it names the diagnostic branches and links to stl_gtfs_departures. Since an output schema exists, return details are not required, but the omitted snapshot and window_minutes semantics leave minor contextual gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The Args section explains stop and at with format details, but snapshot and window_minutes are not described. Schema defaults provide some inference for window_minutes, yet snapshot's role in the diagnosis is left unclear.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool's purpose: diagnosing why a stop has no departures. It names the exact decision branches and explicitly connects it to stl_gtfs_departures returning an empty list, distinguishing it from the related departure-query tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a direct usage trigger: use whenever stl_gtfs_departures returns an empty list. It does not explicitly say when not to use the tool, but the trigger and 'instead of guessing at the cause' provide enough guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_support_reproARead-onlyIdempotent
Reconstruct exactly what the app should have shown at a stop and instant.
This is how "stop 15111 showed nothing at 11:47 last Tuesday" gets answered without a device and without waiting for Tuesday. When the answer is empty it also returns WHY it is empty, rather than leaving you to guess.
Args: stop: stop_code (the number on the sign) or stop_id. at: ISO-8601 instant; naive values read as America/Chicago. rt_snapshot: a stored realtime snapshot id to merge in, for reproducing a complaint about a wrong prediction.
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | ||
| stop | Yes | ||
| snapshot | No | ||
| rt_snapshot | No | ||
| window_minutes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, so the safety profile is covered. The description adds useful behavioral detail by saying that when the answer is empty it also returns why, which goes beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is succinct, using only two sentences plus the parameter list. It avoids fluff and gets directly to the tool's purpose and the empty-result behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is too thin for a tool with five parameters and an output schema. It does not document the parameters, the output shape, or how the historical reconstruction actually works. The support use case is clear, but the missing parameter and output information leaves significant gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides zero parameter descriptions and the description does not explain the five parameters. In particular, the difference between 'snapshot' and 'rt_snapshot', the meaning of 'window_minutes', and the expected format for 'at' are all left undefined. With only parameter names and defaults, an agent cannot reliably choose and fill the arguments.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: reconstruct what the app should have shown at a stop and instant. The opening sentence is specific about the verb, resource, and temporal scope, and the example scenario makes it easy to understand without needing the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a concrete scenario ('stop 15111 showed nothing at 11:47 last Tuesday') and notes it works without a device or waiting for the time to pass. However, it does not explicitly mention when to prefer this tool over sibling tools or when not to use it, relying on the reader to infer the niche.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_web_captureA
Fetch, normalize, extract and store a Metro web page.
Hashes the EXTRACTED content, never the raw HTML: raw HTML changes on every request (analytics ids, nonces, rotating images), so hashing it would make every later drift check a false positive.
Rate-limited to one fetch per page per day by default. Metro is a public agency whose infrastructure this tool is an unpaid guest on.
Args: page: 'fares', 'holidays', 'purchase', 'schedule_changes', 'developer_terms', 'rider_alerts'. Omit to capture all. force: bypass the interval gate and the conditional-request cache.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| force | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses rate limiting, the conditional-request cache, the hashing strategy, and the fact that the tool fetches and stores data. It also notes the external dependency ('unpaid guest on Metro infrastructure'), which is relevant context. It does not detail all side effects of 'force', but overall behavior is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is slightly verbose but well-organized. It leads with the core purpose, then explains the hashing rationale, rate limit, and parameter details. The extra context about being an 'unpaid guest' is mildly tangential but supports appropriate usage.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's purpose, key behaviors, rate limits, and both parameters. An output schema is indicated as present, so not detailing return values is acceptable. The only minor omission is a more explicit statement of what the stored result is or how it can be retrieved later.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides only names, types, and defaults, but the description compensates by enumerating valid page values and explaining the 'force' parameter. The meaning of omitting 'page' ('capture all') is also clarified. This is sufficient despite the schema itself having no descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Fetch, normalize, extract and store a Metro web page.' It uses specific verbs and a concrete resource, and it is distinguishable from sibling tools like stl_web_list, stl_web_extract, and stl_web_check.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains the rate-limiting policy ('one fetch per page per day'), how to bypass it with 'force', and the rationale for hashing extracted content. It does not explicitly contrast with sibling web tools, but the provided page values and capture-all behavior give enough practical guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_web_checkARead-onlyIdempotent
Has any watched page changed since its last capture?
This is the surveillance job. A changed fares page means the app's bundled fare table is now lying to riders; a changed developer-terms page means the redistribution rights this whole project rests on may have moved.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint and idempotentHint annotations already communicate safety, and the description adds contextual consequences but does not describe internal behavior or output details beyond the core question.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, with two sentences that carry the purpose, the domain role, and the real-world impact without any wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
It provides enough domain context to understand why change detection matters (fares and developer-terms), and the output schema exists to define return values, so the missing return detail is acceptable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has no parameters, so there is nothing for the description to clarify; the absence of parameters is consistent and needs no additional explanation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a clear, specific verb ('check') and resource ('watched page') and immediately distinguishes its change-detection role from sibling tools such as stl_web_list, stl_web_capture, and stl_web_extract.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies usage through the phrase 'This is the surveillance job' and explains consequences, but it does not explicitly state when to use this tool versus alternatives or provide a direct decision rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_web_extractARead-onlyIdempotent
Structured data pulled out of a stored page capture.
fares -> fare rows with prices in integer cents; holidays -> holiday rows with BUS and RAIL service kept separate; schedule_changes -> the pick id; others -> normalized text.
Args: page: the page key. Run stl_web_list for valid values.
| Name | Required | Description | Default |
|---|---|---|---|
| page | Yes | ||
| snapshot | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds behavioral value by explaining the structure of the extracted data (e.g., prices in integer cents, BUS/RAIL separation), which is not in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, front-loads the main purpose, uses bullet-like output categories, and includes only necessary info. No wasted sentences; each element earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description need not detail return types. It covers the main extraction categories and the page parameter. The only missing piece is the snapshot parameter's semantics, but overall the tool is straightforward and the description is sufficient for basic use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must explain parameters. It does explain 'page' with a pointer to stl_web_list, but completely omits the 'snapshot' parameter (optional, default null). This leaves the agent to guess its purpose, a notable gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('extract') and resource ('stored page capture') and details the output categories (fares, holidays, schedule_changes, others). It implicitly distinguishes itself from siblings like stl_web_list (listing pages) and stl_web_capture (capturing pages) by focusing on extraction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear context on how to obtain valid inputs ('Run stl_web_list for valid values'), implying the workflow of first listing then extracting. However, it does not explicitly state when not to use this tool or compare to alternatives like stl_web_check.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stl_web_listARead-onlyIdempotent
Metro web pages configured for capture, with their last capture and content hash. Fares, holiday schedules, the developer terms, and the upcoming-schedule-changes page -- everything the app needs that is not in the GTFS feed.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds what data is returned (last capture, content hash) but does not disclose potential errors or edge cases, which are not covered by annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is reasonably concise and structured as a single sentence. The enumeration of example content (fares, holiday schedules, etc.) adds specificity but could be trimmed without losing meaning; still, it earns a high score for clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the absence of parameters and output schema, the description provides sufficient context about what the tool returns and its purpose. It does not specify output format, but this is not required since no output schema is provided.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so schema coverage is trivially complete. The baseline for no parameters is 4; the description does not need to explain parameter semantics because there are none.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly indicates the tool returns configured Metro web pages with their last capture and content hash, and distinguishes these from GTFS feed data. The verb 'list' is implied by the tool name and the description's enumerative nature, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description hints at when to use the tool ('everything the app needs that is not in the GTFS feed') but does not explicitly contrast it with sibling tools like stl_web_capture or stl_web_check. Usage guidance is implied rather than stated.
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.
45 tool updates
v0.1.0- First observed
stl_assert_explain - First observed
stl_assert_list - First observed
stl_assert_run - First observed
stl_bundle_fares - First observed
stl_bundle_holidays - First observed
stl_bundle_size_report - First observed
stl_diff_stop_ids - First observed
stl_diff_summary - First observed
stl_doctor - First observed
stl_gtfs_calendar - First observed
stl_gtfs_coverage - First observed
stl_gtfs_departures - First observed
stl_gtfs_features - First observed
stl_gtfs_files - First observed
stl_gtfs_late_night - First observed
stl_gtfs_query - First observed
stl_gtfs_route - First observed
stl_gtfs_routes - First observed
stl_gtfs_schema - First observed
stl_gtfs_service_day - First observed
stl_gtfs_stats - First observed
stl_gtfs_stop - First observed
stl_gtfs_stop_resolve - First observed
stl_gtfs_stops - First observed
stl_oracle_cases - First observed
stl_oracle_generate - First observed
stl_oracle_verify - First observed
stl_report_brief - First observed
stl_report_handoff - First observed
stl_rt_decode - First observed
stl_rt_health - First observed
stl_rt_reference - First observed
stl_rt_schema_census - First observed
stl_rt_stop_arrivals - First observed
stl_rt_wire - First observed
stl_snapshot_fetch - First observed
stl_snapshot_list - First observed
stl_snapshot_sources - First observed
stl_support_diff_device - First observed
stl_support_explain_empty - First observed
stl_support_repro - First observed
stl_web_capture - First observed
stl_web_check - First observed
stl_web_extract - First observed
stl_web_list
TDQS
Scored across 45 tools
Each tool has a clearly distinct purpose: static GTFS inspection, realtime decoding, oracle fixtures, web capture, diffing, and support reconstruction are cleanly separated even where they touch similar data. Potentially adjacent tools like stl_gtfs_departures, stl_rt_stop_arrivals, and stl_support_repro are explicitly differentiated by schedule-only vs realtime-merged vs device-reproduction intent.
Names follow a highly consistent stl_<domain>_<topic> snake_case pattern, with domain prefixes like gtfs, rt, oracle, web, diff, assert, bundle, report, and support. Plural/singular distinctions and verb choices are uniform and predictable across the set.
45 tools is far beyond the 3-15 well-scoped range and well above the 25+ 'too many' threshold. The breadth is justified by the domain's complexity, but the raw count still makes the surface heavy and harder for an agent to scan efficiently.
The tool surface covers the full lifecycle: fetching static and realtime feeds, inspecting GTFS schema and data, querying departures and calendars, decoding realtime protobuf, generating/verifying oracle fixtures, diffing snapshots, capturing web pages, bundling fares/holidays, running assumptions, and producing reports and support reconstructions. No obvious dead-end workflow remains.
Maintenance
Related MCP Connectors
Transitland MCP — global GTFS aggregator
MCP server for progressive tool usage at any scale (see https://klavis.ai)
MCP server for Modern Treasury — payment orders, transactions, counterparties and ledgers.
MBTA MCP — Boston real-time transit via the MBTA v3 API (api-v3.mbta.com)
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server that provides tools for querying live transit data (stops, departures, routes, vehicles, alerts) from any WP GTFS Pro site, enabling AI assistants to answer rider questions.11 npmGPL 2.0
- AlicenseAqualityDmaintenanceAn MCP server that exposes the Deutsche Bahn public transport API to any MCP-compatible client (Claude Desktop, Cursor, Cline, Continue, etc.). Five tools cover station search, departures, journey planning, trip details, and nearby stations.6MIT
- AlicenseBqualityDmaintenanceMCP server exposing Pittsburgh Regional Transit (PRT) TrueTime operations as typed tools for agent clients.7MIT
- AlicenseBqualityBmaintenanceLocal MCP server aggregating Métropole de Lyon open data services (transit, bike-sharing, parking, traffic, facilities, waste) behind 10 read-only tools for use with any stdio MCP client.10MIT