Skip to main content
Glama
malkreide

swiss-transport-mcp

by malkreide

πŸ‡¨πŸ‡­ Part of the Swiss Public Data MCP Portfolio

πŸš† swiss-transport-mcp

Version License: MIT Python 3.11+ MCP Data Source CI

MCP server connecting AI models to the Swiss public transport system – journey planning, real-time departures, disruptions, occupancy, ticket prices, train formations and open data from opentransportdata.swiss.

πŸ‡©πŸ‡ͺ Deutsche Version

Demo

Demo: Claude queries disruptions and departures


Overview

swiss-transport-mcp gives AI assistants like Claude a complete Swiss travel information system – not just timetables, but also real-time disruption alerts, occupancy forecasts, ticket prices, and a full train formation view. All accessible through a single, standardised MCP interface.

The various APIs at opentransportdata.swiss speak different protocols – OJP 2.0 (XML/SOAP), SIRI-SX (XML), REST/JSON. This server translates everything into clean JSON for the AI model, acting as a multilingual protocol interpreter.

Anchor demo query: "Plan a school trip for 25 students from Zurich to the Technorama in Winterthur – check for disruptions and find the best departure." β†’ More use cases by audience β†’


Related MCP server: swiss-public-transport-mcp

Features

  • πŸ—ΊοΈ Journey planning (A β†’ B with transfers, duration, transport mode) via OJP 2.0

  • πŸ• Real-time departures with delays and platform information

  • πŸ” Stop search by name or coordinates

  • 🚨 Live disruption alerts (cancellations, closures) via SIRI-SX

  • πŸ“Š Occupancy forecasts for trains (SBB, BLS, Thurbo, SOB)

  • πŸ’° Ticket prices including class selection

  • πŸšƒ Train formation – coaches, classes, amenities, accessibility

  • πŸ“¦ Open data catalogue – ~90 transport datasets via CKAN

  • πŸ”‘ Graceful degradation – server starts with core tools even without optional API keys

  • ☁️ Dual transport – stdio for Claude Desktop, Streamable HTTP/SSE for cloud deployment


Prerequisites


Installation

# Clone the repository
git clone https://github.com/malkreide/swiss-transport-mcp.git
cd swiss-transport-mcp

# Install
pip install -e .

Or with uvx (no permanent installation):

uvx swiss-transport-mcp

Quickstart

# Set the minimum required key (OJP core tools)
export TRANSPORT_API_KEY=your_key_here

# Start the server (stdio mode for Claude Desktop)
swiss-transport-mcp

Try it immediately in Claude Desktop:

"What are the next departures from Zurich Stadelhofen?" "How do I get from WΓ€denswil to Bern by train?"


Configuration

Environment Variables

Variable

API

Required

TRANSPORT_API_KEY

Unified key for OJP + CKAN

βœ… (or individual keys)

TRANSPORT_OJP_API_KEY

OJP 2.0 Journey Planner

Optional (override)

TRANSPORT_CKAN_API_KEY

CKAN data catalogue

Optional (separate subscription)

SIRI_SX_API_KEY

Disruption alerts (SIRI-SX)

Optional

OCCUPANCY_API_KEY

Occupancy forecast

Optional

FORMATION_API_KEY

Train formation

Optional

OJP_FARE_API_KEY

Ticket prices (OJP Fare)

Optional

APIs without a key are silently disabled – the server starts fine with just the 6 core tools.

Operational / security variables:

Variable

Effect

Default

MCP_ENV / ENV

Process environment. Must be dev/development/local/test to allow disabling TLS verification.

(unset β†’ production)

TRANSPORT_SSL_VERIFY

Set to false to disable TLS certificate verification. Honoured only when MCP_ENV marks a dev environment – otherwise the request is ignored and verification stays on.

true

TRANSPORT_CKAN_URL

Override the CKAN base URL. Must stay on the egress allow-list (*.opentransportdata.swiss); off-site overrides are refused.

https://api.opentransportdata.swiss/ckan-api

MCP_CORS_ORIGINS

Comma-separated list of browser origins allowed to call the HTTP transport. Use * to allow any origin (not recommended). The Mcp-Session-Id header is exposed to these origins.

https://claude.ai

LOG_FORMAT

json for structured logs (RFC 5424 severity); anything else for human-readable text. Always written to stderr.

text

OTEL_TRACES_ENABLED

1 to enable OpenTelemetry tracing (requires the otel extra: pip install 'swiss-transport-mcp[otel]'). No-op otherwise.

(off)

MCP_STATELESS

1 to run the Streamable HTTP transport statelessly β€” no server-side session state, so instances need no sticky load balancing. Recommended for horizontal scale-out.

(off β†’ stateful)

MCP_ALLOWED_HOSTS

Comma-separated list of the names this server is reachable under, port included where it matters (e.g. fahrplan.example.ch:8080). Requests arriving under any other Host are rejected with 421; loopback stays allowed so container health checks keep working. Unset on a non-loopback bind, the check is off and a warning is logged.

(unset β†’ off)

πŸ”’ Egress allow-list: all outbound requests are restricted to https:// on opentransportdata.swiss hosts. Any other host is refused before a request is sent (SSRF / egress hardening).

Claude Desktop Configuration

Minimal (core tools only):

{
  "mcpServers": {
    "swiss-transport": {
      "command": "swiss-transport-mcp",
      "env": {
        "TRANSPORT_API_KEY": "your_key_here"
      }
    }
  }
}

Full (all 11 tools):

{
  "mcpServers": {
    "swiss-transport": {
      "command": "swiss-transport-mcp",
      "env": {
        "TRANSPORT_API_KEY": "your_ojp_key_here",
        "SIRI_SX_API_KEY": "your_siri_key_here",
        "OCCUPANCY_API_KEY": "your_occupancy_key_here",
        "FORMATION_API_KEY": "your_formation_key_here",
        "OJP_FARE_API_KEY": "your_fare_key_here"
      }
    }
  }
}

Config file locations:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Cloud Deployment (Streamable HTTP)

For use via claude.ai in the browser (e.g. on managed workstations without local software). The cloud transport is Streamable HTTP (MCP_TRANSPORT=streamable-http, endpoint /mcp). SSE (/sse) is still supported but deprecated.

MCP_TRANSPORT

Use

Endpoint

stdio (default)

Local Claude Desktop subprocess

–

streamable-http (or http)

Cloud / container (recommended)

/mcp

sse

Legacy browser transport (deprecated)

/sse

Docker (recommended):

# Build + run with explicit resource limits (see docker-compose.yml)
TRANSPORT_API_KEY=xxx docker compose up --build
# β†’ http://127.0.0.1:8000/mcp

The image is a multi-stage build running as a non-root user; docker-compose.yml adds read_only, no-new-privileges and memory/CPU/PID limits.

Render.com:

  1. Push/fork the repository to GitHub

  2. On render.com: New Web Service β†’ connect GitHub repo (Docker runtime)

  3. Set env MCP_TRANSPORT=streamable-http and MCP_HOST=0.0.0.0

  4. In claude.ai under Settings β†’ MCP Servers, add: https://your-app.onrender.com/mcp

πŸ’‘ "stdio for the developer laptop, Streamable HTTP for the cloud."

Scaling horizontally: run with MCP_STATELESS=1. In stateless mode the server keeps no per-session state, so any instance can serve any request and a plain round-robin load balancer suffices β€” no sticky sessions / Mcp-Session-Id affinity required. If you need stateful streaming instead, route by Mcp-Session-Id at the edge LB (e.g. HAProxy stick-tables) so each session stays pinned to one instance.

⚠️ Binding: In a network transport the server binds to 127.0.0.1 by default so a locally started server is not exposed to your whole network (e.g. public Wi-Fi). Set MCP_HOST=0.0.0.0 only in a container/cloud environment where binding to all interfaces is intended (the Docker image does this for you).


Available Tools

Core Tools (OJP 2.0 / CKAN)

Tool

Description

Data Source

transport_search_stop

Search stops/stations by name

OJP 2.0

transport_nearby_stops

Find nearby stops by coordinates

OJP 2.0

transport_departures

Real-time departure board with delays & platforms

OJP 2.0

transport_trip_plan

Plan journey A β†’ B with transfers, duration, mode

OJP 2.0

transport_search_datasets

Search open data catalogue (~90 datasets)

CKANΒΉ

transport_get_dataset

Get full details of a specific dataset

CKANΒΉ

ΒΉ CKAN tools require a separate subscription in the API Manager.

Extension Tools (optional API keys)

Tool

Description

Data Source

get_transport_disruptions

🚨 Live disruptions, cancellations, line closures

SIRI-SX

get_train_occupancy

πŸ“Š Occupancy forecast for specific trains

Occupancy JSON

get_ticket_price

πŸ’° Ticket prices for connections

OJP Fare

get_train_composition

πŸšƒ Train formation, classes, accessibility

Formation REST

check_transport_api_status

πŸ” Health check for all configured APIs

All

Example Use Cases

Query

Tool

"Next trains from Zurich Stadelhofen?"

transport_departures

"Plan a trip for 25 students from Zurich to Winterthur Technorama"

transport_trip_plan

"Any disruptions between Zurich and Bern?"

get_transport_disruptions

"How full is IC 1009 today?"

get_train_occupancy

"What does a ticket from WΓ€denswil to Bern cost?"

get_ticket_price

"Does IC 708 have a dining car?"

get_train_composition

"Which stops are near Langstrasse 100?"

transport_nearby_stops


Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Claude / AI   │────▢│   Swiss Transport MCP     │────▢│  opentransportdata.swiss  β”‚
β”‚   (MCP Host)    │◀────│   (MCP Server)            │◀────│                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚                           β”‚     β”‚  OJP 2.0  (XML/SOAP)     β”‚
                        β”‚  11 Tools Β· 2 Resources   β”‚     β”‚  SIRI-SX  (XML)          β”‚
                        β”‚  Stdio | SSE              β”‚     β”‚  CKAN     (REST/JSON)    β”‚
                        β”‚                           β”‚     β”‚  Occupancy(REST/JSON)    β”‚
                        β”‚  Core:                    β”‚     β”‚  Formation(REST/JSON)    β”‚
                        β”‚   api_client + ojp_client β”‚     β”‚  OJP Fare (XML/SOAP)     β”‚
                        β”‚  Extensions:              β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚   siri_sx, occupancy,     β”‚
                        β”‚   ojp_fare, formation     β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Infrastructure Components

Component

Metaphor

Function

RateLimiter

Bouncer

Limits API calls per time window

SimpleCache

Whiteboard

Caches responses for repeated queries

APIClient

Switchboard

Handles auth, redirects, errors centrally

APIConfig

Business card

Key, URL, limits per API

Caching Strategy

API

Cache TTL

Rationale

SIRI-SX

120s

Disruptions don't change every second

Occupancy

300s

Forecasts are day-based

Formation

600s

Train composition is stable for the day

OJP Fare

1800s

Prices rarely change intraday


Project Structure

swiss-transport-mcp/
β”œβ”€β”€ src/swiss_transport_mcp/        # Main package
β”‚   β”œβ”€β”€ server.py                   # FastMCP server, tool definitions
β”‚   β”œβ”€β”€ api_client.py               # Core OJP + CKAN client
β”‚   β”œβ”€β”€ ojp_client.py               # OJP 2.0 XML/SOAP parser
β”‚   β”œβ”€β”€ api_infrastructure.py       # RateLimiter, SimpleCache, APIClient
β”‚   β”œβ”€β”€ siri_sx.py                  # Disruption alerts
β”‚   β”œβ”€β”€ occupancy.py                # Occupancy forecasts
β”‚   β”œβ”€β”€ ojp_fare.py                 # Ticket prices
β”‚   └── formation.py                # Train formation
β”œβ”€β”€ tests/
β”‚   └── test_server.py              # Unit + integration tests
β”œβ”€β”€ .github/workflows/ci.yml        # GitHub Actions (Python 3.11/3.12/3.13)
β”œβ”€β”€ claude_desktop_config.json       # Example Claude Desktop config
β”œβ”€β”€ pyproject.toml
β”œβ”€β”€ CHANGELOG.md
β”œβ”€β”€ CONTRIBUTING.md
β”œβ”€β”€ LICENSE
β”œβ”€β”€ README.md                        # This file (English)
└── README.de.md                     # German version

Safety & Limits

  • Read-only: All tools perform read-only requests (HTTP GET / OJP XML POST for queries only) β€” no data is written, modified, or deleted on any upstream system.

  • No personal data: Journey queries are transient and not stored by this server. The APIs return scheduled timetable and real-time operational data. No personally identifiable information (PII) is processed or retained.

  • Rate limits: opentransportdata.swiss enforces per-key rate limits (documented in the API Manager). The server's built-in RateLimiter (SIRI-SX: 2 req/min, Formation/OJP Fare: 5 req/min) stays within these bounds automatically. Use the limit parameters conservatively for bulk queries.

  • API key required: A free key from api-manager.opentransportdata.swiss is mandatory. Keys are bound to your account's subscription β€” only subscribe to APIs you intend to use.

  • Data freshness: Real-time tools (departures, disruptions, occupancy) reflect the upstream source at query time. The server caches responses for short TTLs (120s–1800s) to reduce API load β€” see the Caching Strategy table above.

  • Terms of service: Data is subject to the ToS of opentransportdata.swiss. OJP, SIRI-SX, and the CKAN catalogue are published under open licences (ODbL / CC BY 4.0) for non-commercial and research use.

  • No guarantees: This server is a community project, not affiliated with the Federal Office of Transport (BAV/OFT) or SBB. Availability depends on upstream APIs.

Adding this server to your MCP client lets the connected AI model issue Swiss public-transport queries on your behalf, using your opentransportdata.swiss API key, and make outbound HTTPS requests to opentransportdata.swiss. Nothing is written upstream and no PII is stored, but you should review the tool list above and confirm you are comfortable granting that access before configuring the server.

Running the HTTP transport safely (no built-in auth)

The server has no authentication of its own. When you run the Streamable HTTP transport (MCP_TRANSPORT=streamable-http), the MCP SDK issues a cryptographically random Mcp-Session-Id per session, but there is no user identity bound to it. Therefore:

  • Do not expose a no-auth instance directly to the public internet. Put it behind an authenticating reverse proxy (OAuth2 proxy, mTLS, or your platform's access control), or restrict it to a trusted network.

  • Keep the default MCP_HOST=127.0.0.1 for local use; only bind 0.0.0.0 inside a controlled container/cloud environment (see Deployment).

  • Scope MCP_CORS_ORIGINS to the origins you actually trust.

  • Set MCP_ALLOWED_HOSTS whenever you bind beyond loopback. It guards against DNS rebinding: a page on your network resolves its own hostname to this server's address and then talks to it from the browser. CORS does not stop that β€” from the browser's point of view the request is same-origin β€” and neither would a token, since the attacking page runs in a context that holds one. Only the Host check does. Left unset the check stays off, which is the right default only when something in front of the server validates Host.

See SECURITY.md for the full security posture and the accepted-risk decisions (gateway-level controls).


Known Limitations

  • OJP Fare: Discounts (Halbtax, GA, regional passes) are not always reflected

  • Formation: Stop-based data is only available for TODAY (real-time dependency)

  • Occupancy: SBB, BLS, Thurbo and SOB only – no private railways

  • SIRI-SX: Returns ALL Swiss disruptions β†’ use the filter_text parameter

  • CKAN: Requires a separate subscription in the API Manager


MCP Protocol Version

This server speaks two protocol eras over the same endpoint. The client's first request on a connection decides which one applies; a later claim from the other era is refused.

Era

Revision

Who reaches it

initialize handshake

2024-11-05 … 2025-11-25

What today's clients speak. The server answers with the revision asked for, or with the 2025-11-25 ceiling when the request asks for something newer.

Per-request envelope

2026-07-28

A request carrying the 2026-07-28 _meta envelope opens a modern connection.

Both revisions are pinned in tests/test_protocol_version.py and asserted against the installed SDK, so a Dependabot bump of mcp cannot move either one silently. This server builds no ASGI app to send an initialize through, so the gate asserts the SDK constants rather than a measured response β€” the weaker form, named rather than left unsaid.

Note that the SDK's LATEST_PROTOCOL_VERSION is an alias for the modern era, not for the handshake era β€” pinning against it alone would leave the era that current clients actually negotiate free to drift.

Update policy. When the gate fails, do not edit the constant blindly: read the spec changelog between the two revisions, verify the server still behaves, then move the constant, this section, README.de.md and CHANGELOG.md together.


Testing

# Unit tests (no API key required)
PYTHONPATH=src pytest tests/ -m "not live"

# Integration tests (API key required)
TRANSPORT_API_KEY=xxx pytest tests/ -m "live"

Where the test data comes from

All four upstream APIs need a Bearer token from the opentransportdata.swiss API-Manager, so CI cannot record a real response β€” measured and kept in tests/fixtures/upstream_auth_probe.json. The XML payloads in the test modules are therefore hand-written, not recorded, and cannot refute the production code: both come from the same reading of the docs, and where both are wrong they are wrong together.

What can be recorded is the contract. OJP 2.0 is a CEN standard (CEN/TS 17118) with a public XML schema, and tests/fixtures/ojp_2_0_contract.json is a dated index derived from it β€” element names, the structures this server builds on, the enumerations it sends as values, plus the SHA-256 of every schema file read. tests/test_ojp_contract.py holds the requests and parsers against it. The schema itself is deliberately not vendored: the source repository carries no licence file.

python scripts/record_fixtures.py          # re-record
python scripts/record_fixtures.py --check  # recompute against the pinned tag

Source, date, selection rule and hashes: tests/fixtures/PROVENANCE.md.


Changelog

See CHANGELOG.md


Contributing

See CONTRIBUTING.md


Security

See SECURITY.md (Deutsch) for the security posture and how to report a vulnerability.


License

MIT License β€” see LICENSE


Author

Hayal Oezkan Β· github.com/malkreide


Installation

Run via uv's uvx β€” no clone or manual install needed. Add to your MCP client config (mcpServers for Claude Desktop, Cursor and Windsurf; use a top-level servers key for VS Code in .vscode/mcp.json):

{
  "mcpServers": {
    "swiss-transport-mcp": {
      "command": "uvx",
      "args": [
        "swiss-transport-mcp"
      ]
    }
  }
}

Available Tools

11 tools
check_transport_api_statusA
Read-only

PrΓΌft den Verbindungsstatus aller konfigurierten Transport-APIs.

Zeigt an, welche APIs verfΓΌgbar sind, ob die API-Keys gΓΌltig sind und ob die Dienste erreichbar sind.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint true and destructiveHint false. The description adds value by detailing what the check includes (availability, key validity, reachability). It does not contradict annotations and provides useful behavioral context.

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

Conciseness5/5

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

The description is concise with two sentences, front-loading the action and purpose. Every sentence adds meaningful information without redundancy.

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

Completeness4/5

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

Given no parameters and an output schema exists, the description is fairly complete. It explains what is checked and shown. Could slightly expand on scope ('all configured APIs'), but sufficient for a simple status tool.

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

Parameters4/5

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

There are no parameters, so schema coverage is 100% trivially. Per guidelines, baseline is 4. The description appropriately does not need to detail parameters.

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

Purpose5/5

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

The description clearly states the tool checks the connection status of all configured transport APIs, specifying what it shows: availability, API key validity, and service reachability. This distinguishes it from sibling tools which query specific transport data.

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

Usage Guidelines3/5

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

The description does not explicitly state when to use this tool or when to avoid it, nor does it mention alternatives. Usage is implied from context (checking health before using other transport tools), but lacks explicit guidance.

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

get_ticket_priceA
Read-onlyIdempotent

Ticketpreise fΓΌr eine Γ–V-Verbindung in der Schweiz abfragen.

Berechnet den Fahrpreis fΓΌr eine Verbindung inklusive Routeninformation. Zeigt regulΓ€re Tarife an. Rabatte (Halbtax, GA) sind mΓΆglicherweise nicht vollstΓ€ndig berΓΌcksichtigt.

Args: origin: Abfahrtsort (z.B. "ZΓΌrich HB", "WΓ€denswil", "Bern") destination: Ankunftsort (z.B. "Bern", "Luzern", "Basel SBB") departure_time: Abfahrtszeit im Format YYYY-MM-DDTHH:MM (z.B. "2026-03-01T08:00"). Standard: jetzt. travel_class: Reiseklasse. "first" = 1. Klasse, "second" = 2. Klasse.

Beispiele: - Einfache Preisabfrage: get_ticket_price(origin="ZΓΌrich HB", destination="Bern") - Mit Zeitangabe: get_ticket_price(origin="WΓ€denswil", destination="Luzern", departure_time="2026-03-01T08:00") - 1. Klasse: get_ticket_price(origin="Basel SBB", destination="Genf", travel_class="first")

Hinweis: FΓΌr verbindliche Preise immer sbb.ch oder den Schalter konsultieren.

ParametersJSON Schema
NameRequiredDescriptionDefault
originYes
destinationYes
travel_classNosecond
departure_timeNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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

Annotations declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. Description adds valuable caveat that discounts may not be fully considered and that route info is included. 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.

Conciseness4/5

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

Well-structured with Args, examples, and a note. Each sentence adds value, though slightly verbose. Front-loaded with main purpose.

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

Completeness4/5

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

Covers purpose, parameters, usage notes, and caveats. Output schema exists, so return values need not be described. Missing explicit when-to-use compared to siblings, but overall sufficient.

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

Parameters5/5

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

Input schema has no property descriptions (0% coverage). Description fully explains each parameter with format, examples, and defaults, compensating completely for the schema gap.

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

Purpose5/5

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

Description clearly states purpose: query ticket prices for Swiss public transport connections, including fare calculation and route info. Specific verb 'abfragen' and resource 'Ticketpreise' distinguish it from sibling tools like transport_trip_plan.

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

Usage Guidelines4/5

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

Provides examples and a note about consulting sbb.ch for binding prices. Implies usage for price queries via examples, but does not explicitly contrast with sibling tools or state when not to use.

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

get_train_compositionA
Read-onlyIdempotent

Zugzusammensetzung und Wagenreihung fΓΌr einen Schweizer Zug abrufen.

Zeigt die Wagenreihung, Klassen, Sektoren, Ausstattung (Rollstuhlplatz, Velohaken, Speisewagen, Familienzone) und Gleisbelegung an.

Args: train_number: Zugnummer (z.B. "2806", "1009", "708"). Nur die Nummer, ohne Zugtyp-PrΓ€fix. railway_company: Eisenbahnunternehmen (EVU). Erlaubt: SBBP (SBB), BLSP (BLS), RhB (RhΓ€tische Bahn), SOB (SΓΌdostbahn), THURBO, TPF, TRN, MBC, OeBB, VDBB, ZB. operation_date: Betriebstag YYYY-MM-DD. Standard: heute. Wichtig: Stop-based nur fΓΌr HEUTE verfΓΌgbar. show_details: Detailgrad. "stop_based" = kompakt (empfohlen), "vehicle_based" = pro Fahrzeug, "full" = alles.

Beispiele: - SBB-Zug: get_train_composition(train_number="1009") - BLS-Zug: get_train_composition(train_number="2806", railway_company="BLSP") - Detailliert: get_train_composition(train_number="708", show_details="vehicle_based")

Typische Fragen, die damit beantwortet werden kΓΆnnen: - "Hat der IC nach Bern einen Speisewagen?" - "Wo kann ich mit dem Rollstuhl einsteigen?" - "In welchem Sektor hΓ€lt die 1. Klasse?" - "Gibt es VeloplΓ€tze im Zug?"

ParametersJSON Schema
NameRequiredDescriptionDefault
show_detailsNostop_based
train_numberYes
operation_dateNo
railway_companyNoSBBP

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

The description adds context about the returned information (carriage order, equipment, track assignment) beyond the annotations which already indicate read-only, idempotent, and non-destructive behavior. 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.

Conciseness4/5

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

The description is well-structured with clear sections (purpose, args, examples, typical questions) and front-loaded with the main purpose. While somewhat lengthy, every sentence adds value; minor redundancy could be trimmed.

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

Completeness5/5

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

Given the tool's complexity and the presence of an output schema, the description covers all necessary aspects: purpose, parameter details, usage examples, and typical queries. It is comprehensive for an AI agent to select and invoke correctly.

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

Parameters5/5

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

Despite 0% schema description coverage, the description thoroughly explains each parameter: train_number with examples, railway_company with allowed values, operation_date with default and usage note, show_details with three options. This fully compensates for the schema's lack of descriptions.

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

Purpose5/5

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

The description clearly states the tool retrieves train composition and carriage order for Swiss trains, listing specific details like classes, sectors, equipment, and track assignment. It distinguishes from sibling tool `get_train_occupancy` by focusing on composition rather than occupancy.

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

Usage Guidelines4/5

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

The description explains when to use the tool with parameter defaults and examples, and lists typical questions it can answer. However, it does not explicitly state when not to use it or mention alternative tools, though the context of sibling tools makes this implicit.

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

get_train_occupancyA
Read-only

Auslastungsprognose fΓΌr Schweizer ZΓΌge abrufen.

Zeigt, wie voll ein bestimmter Zug voraussichtlich sein wird, aufgeteilt nach 1. und 2. Klasse pro Streckenabschnitt. Auslastungsstufen: wenig belegt, mΓ€ssig belegt, nur StehplΓ€tze.

Zwei Abfragemodi:

  1. Nach Zugnummer: train_number + operator angeben

  2. Nach Strecke: departure_station + arrival_station angeben

Args: train_number: Zugnummer (z.B. "1009", "IC 708"). Zugtyp-PrΓ€fixe werden automatisch entfernt. departure_station: Abfahrtsort fΓΌr Streckensuche (z.B. "ZΓΌrich HB") arrival_station: Ankunftsort fΓΌr Streckensuche (z.B. "Bern") operation_date: Betriebstag YYYY-MM-DD (Standard: heute). Prognosen sind bis 3 Monate voraus verfΓΌgbar. operator: Betreiber-Code. "11"=SBB, "33"=BLS, "65"=Thurbo, "82"=SOB.

Beispiele: - Bestimmter Zug: get_train_occupancy(train_number="1009") - BLS-Zug: get_train_occupancy(train_number="2806", operator="33") - Strecke: get_train_occupancy(departure_station="ZΓΌrich HB", arrival_station="Bern")

ParametersJSON Schema
NameRequiredDescriptionDefault
operatorNo11
train_numberNo
operation_dateNo
arrival_stationNo
departure_stationNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already indicate readOnlyHint=true (safe read), and the description adds valuable behavioral details: automatic removal of train type prefixes, default date range up to 3 months ahead, and operator code mappings. 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.

Conciseness5/5

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

The description is well-structured with a brief intro, bulleted args, and examples. It is comprehensive without being verbose; every sentence adds value.

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

Completeness5/5

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

Given the tool's complexity (two query modes, multiple parameters) and the existence of an output schema, the description covers all necessary context: parameter semantics, usage patterns, and examples. It is complete.

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

Parameters5/5

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

Schema coverage is 0%, so the description fully compensates by explaining each parameter with examples, default values, and allowed values (operator codes). It clarifies the two modes and which parameters are needed for each.

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

Purpose5/5

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

The description clearly states it retrieves occupancy forecasts for Swiss trains, specifies the output format (per class and segment), and distinguishes itself from sibling tools like transport_departures or get_train_composition by focusing on occupancy.

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

Usage Guidelines4/5

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

The description explicitly explains two usage modes (by train number or by route) and gives examples, guiding the agent on when to use each. However, it does not explicitly contrast with alternatives or state when not to use the tool.

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

get_transport_disruptionsA
Read-only

Aktuelle StΓΆrungsmeldungen im Schweizer ΓΆffentlichen Verkehr abrufen.

Liefert Informationen zu ZugausfΓ€llen, VerspΓ€tungen, GleisΓ€nderungen, Streckensperrungen und anderen BetriebsstΓΆrungen.

Args: filter_text: Suchbegriff zum Filtern (z.B. "ZΓΌrich", "S-Bahn", "IC 1", "Bern-Thun"). Leer = alle StΓΆrungen. language: Sprache der Meldungen. DE (Deutsch), FR (FranzΓΆsisch), IT (Italienisch), EN (Englisch). max_results: Maximale Anzahl Ergebnisse (1-50). Standard: 15.

Beispiele: - Alle aktuellen StΓΆrungen: get_transport_disruptions() - StΓΆrungen in ZΓΌrich: get_transport_disruptions(filter_text="ZΓΌrich") - S-Bahn StΓΆrungen: get_transport_disruptions(filter_text="S-Bahn") - Strecke prΓΌfen: get_transport_disruptions(filter_text="Bern")

ParametersJSON Schema
NameRequiredDescriptionDefault
languageNoDE
filter_textNo
max_resultsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, so the agent knows this is a safe read operation. The description adds context about the types of data returned (ZugausfΓ€lle, VerspΓ€tungen, etc.), which supplements the annotations without contradiction.

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

Conciseness4/5

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

The description is well-structured with a clear headline, bullet-like list of disruption types, parameter documentation, and examples. It is a bit lengthy but every part adds value, especially the examples. A slightly more concise phrasing might improve it.

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

Completeness4/5

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

Given the tool has 3 optional parameters and no required ones, the description covers the main functionality and parameters. With an output schema existing, return values need not be explained. However, it could mention that the data is specific to Swiss public transport, which is already clear from the description.

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

Parameters5/5

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

The input schema has 3 parameters with 0% schema description coverage, so the description carries full burden. It provides explicit meanings for each parameter, including filter text examples, language codes, and max results range, adding significant value beyond the bare schema.

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

Purpose5/5

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

The description clearly states that the tool retrieves current disruption reports in Swiss public transport, listing specific types of disruptions (train cancellations, delays, track changes, line closures). This distinguishes it from siblings like transport_departures or transport_trip_plan, which serve different purposes.

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

Usage Guidelines4/5

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

The description provides examples and explains parameters (filter_text, language, max_results) with default values. It implies use cases (e.g., 'Alle aktuellen StΓΆrungen' with no arguments, filtering by city or line). However, it does not explicitly state when not to use or compare to sibling tools.

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

transport_departuresA
Read-only

Get upcoming departures or arrivals at a Swiss public transport stop.

Shows real-time information including delays when available. Like a digital departure board at a train station.

Use transport_search_stop first to get the stop_id.

Returns: Departures with line, destination, scheduled time, real-time time, delay, and platform.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
hintNo
typeNo
countNo
messageNo
stop_idNo
stop_nameNo
departuresNo

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already indicate readOnlyHint=true and destructiveHint=false, so the description's job is lighter. The description adds value by noting real-time information including delays, and analogizing to a digital departure board, which helps set expectations beyond 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.

Conciseness5/5

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

The description is concise: three sentences plus a bullet list. It front-loads the primary function and uses efficient language with no redundancy.

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

Completeness4/5

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

Given the tool's moderate complexity (real-time data, multiple parameters), the description covers the main purpose, prerequisite, and return fields. It does not explain all edge cases, but an output schema likely handles that. The description is sufficient for an agent to select and invoke the tool correctly.

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

Parameters3/5

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

Despite schema description coverage reported as 0%, the input schema itself contains detailed descriptions for each property (e.g., stop_id, time, limit). The tool description adds little new parameter-specific meaning beyond what is already in the schema, though it does reiterate the prerequisite for stop_id.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'Get upcoming departures or arrivals at a Swiss public transport stop.' It uses a specific verb+resource pattern and distinguishes itself from sibling tools by explicitly referencing transport_search_stop as a prerequisite.

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

Usage Guidelines4/5

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

The description instructs users to 'Use transport_search_stop first to get the stop_id,' providing clear usage guidance. It also implies the tool is for real-time departure boards. However, it does not explicitly state when not to use it or compare it to alternatives like transport_nearby_stops.

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

transport_get_datasetA
Read-onlyIdempotent

Get full details of a specific transport dataset.

Returns metadata, description, all available resources (files/APIs) with download URLs and formats.

Use transport_search_datasets first to find the dataset ID.

Returns: Full dataset metadata, resources with URLs, and format info.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
idNo
urlNo
tagsNo
titleNo
licenseNo
messageNo
resourcesNo
descriptionNo
organizationNo
last_modifiedNo

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds value by detailing the return format (metadata, resources with URLs and formats) and confirming no destructive side effects, aligning 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.

Conciseness5/5

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

The description is concise (three sentences) and front-loaded with the main purpose. Every sentence adds value: purpose, return details, and usage hint. No redundant information.

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

Completeness5/5

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

Given the low complexity (single parameter, read-only operation) and the presence of annotations and output schema, the description covers all necessary aspects: what it does, what it returns, and how to use it with a sibling tool.

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

Parameters4/5

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

Although context signals schema coverage as 0%, the input schema actually provides a descriptive example for dataset_id. The description reinforces the parameter's role and references the sibling tool for finding valid IDs, adding semantics beyond the schema.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'Get full details of a specific transport dataset.' It specifies the resource type (dataset) and distinguishes from sibling tool transport_search_datasets by explaining the first step to find the dataset ID.

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

Usage Guidelines4/5

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

Explicitly instructs to use transport_search_datasets first to find the dataset ID. Provides clear context but does not include when-not-to-use or alternatives beyond this.

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

transport_nearby_stopsA
Read-onlyIdempotent

Find public transport stops near a geographic location.

Useful for finding stops near a school, address, or point of interest. Swiss coordinates only (lat 45–48.5, lon 5.5–10.8).

Returns: Nearby stops with id, name, coordinates, and distance info.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
hintNo
countNo
messageNo
latitudeNo
longitudeNo
nearby_stopsNo

TDQS

A4.2/5.0
Behavior4/5

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

Description adds that it returns id, name, coordinates, distance info, and Swiss coordinate bounds. Annotations already cover safety (readOnly, idempotent, non-destructive), so no contradiction.

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

Conciseness5/5

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

Very concise: four short sentences, each adding distinct value. No redundant or filler content.

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

Completeness4/5

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

With output schema present, description mentions return fields. Lacks mention of authentication or prerequisites, but for a simple read-only tool this is acceptable.

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

Parameters3/5

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

Input schema already provides detailed descriptions for all parameters. Description only repeats the coordinate bounds already in schema, adding no new semantic value beyond a baseline for high schema coverage.

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

Purpose5/5

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

The description clearly states the tool finds public transport stops near a geographic location, distinguishes from siblings like transport_search_stop by specifying coordinates, and mentions Swiss coordinate bounds.

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

Usage Guidelines4/5

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

Provides usage context (near schools, addresses, POIs) and geographic constraints. Lacks explicit when-not-to-use or alternative tool mention, but implied by coordinate focus.

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

transport_search_datasetsA
Read-onlyIdempotent

Search the Swiss transport open data catalog (~90 datasets).

Find datasets about timetables, real-time data, GTFS feeds, accessibility info, traffic counters, and more from opentransportdata.swiss.

Returns: Matching datasets with name, description, formats, and download URLs.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
hintNo
queryNo
messageNo
showingNo
datasetsNo
total_foundNo

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, making behavior clear. The description adds concrete return structure (name, description, formats, download URLs) and catalog size (~90 datasets), enriching understanding 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.

Conciseness5/5

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

The description is very concise: three sentences front-loading the purpose (search catalog), listing content categories, and specifying return fields. No unnecessary words, every sentence adds value.

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

Completeness4/5

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

Given annotations (readOnly, idempotent) and existence of an output schema, the description provides adequate context: catalog scope, example dataset types, and return structure. It could mention pagination or result count, but it's sufficient for a straightforward search tool.

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

Parameters4/5

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

The schema already describes both parameters (query required, limit optional with constraints). The description adds value by providing concrete search term examples ('gtfs', 'fahrplan', 'realtime') and clarifying that results are datasets from opentransportdata.swiss, which aids parameter interpretation.

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

Purpose5/5

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

The description clearly states the tool searches the Swiss transport open data catalog (~90 datasets), enumerating example dataset types (timetables, GTFS, etc.) and return fields. It distinguishes from sibling tools like transport_search_stop or transport_departures by focusing on dataset metadata.

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

Usage Guidelines4/5

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

The description implies usage for finding transport datasets and gives search examples ('gtfs', 'fahrplan'), providing clear context. However, it does not explicitly state when to use this vs. alternatives like transport_search_stop or transport_get_dataset, though sibling differentiation is achievable from context.

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

transport_search_stopA
Read-onlyIdempotent

Search for Swiss public transport stops and stations by name.

Searches across all Swiss public transport stops (train stations, tram/bus stops, boat stations). Returns stop IDs needed for transport_departures and transport_trip_plan.

Returns: Matching stops with id, name, coordinates, and transport modes.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
hintNo
countNo
queryNo
stopsNo
messageNo

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already provide readOnly, idempotent, and non-destructive hints. Description adds that the tool searches across all Swiss public transport stops and returns specific fields (id, name, coordinates, transport modes), clarifying the scope and output.

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

Conciseness5/5

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

Three sentences, front-loaded with action, each sentence adds value: purpose, scope, and output. No filler or redundancy.

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

Completeness5/5

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

Given the presence of an output schema and low parameter complexity, the description covers what the tool does, when to use it, and what it returns (including the critical role of stop IDs). Complete for an agent to use correctly.

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

Parameters3/5

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

Schema already includes descriptions for both parameters (query and limit), so the description does not need to add parameter details. It adds no extra semantic value beyond the schema.

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

Purpose5/5

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

Description clearly states the verb 'Search' and the resource 'Swiss public transport stops and stations by name'. It distinguishes from sibling transport_nearby_stops which searches by location. Also explains the output's role for other tools.

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

Usage Guidelines4/5

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

Description indicates when to use (before transport_departures and transport_trip_plan) and implies use by name rather than location, contrasting with sibling transport_nearby_stops. No explicit exclusions but clear context.

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

transport_trip_planA
Read-only

Plan a journey between two locations in Switzerland.

Works like the SBB app: enter origin and destination (stop IDs or place names), get multiple trip options with transfers, durations, and transport modes.

For best results, use stop IDs from transport_search_stop. Place names (addresses) also work but may be slower.

Returns: Trip options, each with legs (individual journey segments), total duration, number of transfers, and transport modes used.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
hintNo
countNo
tripsNo
originNo
messageNo
destinationNo

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, so the description's claim of returning trips without modification aligns. It adds useful context such as operating like the SBB app and specifying return structure, but does not disclose performance characteristics or edge cases beyond the annotation.

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

Conciseness5/5

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

The description is concise, with three well-structured paragraphs that front-load the core purpose, followed by usage tips and return overview. No unnecessary sentences or redundancy.

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

Completeness4/5

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

The description covers primary use, input advice, and return structure, but lacks details on optional parameters (time, limit) and their defaults. Given an existing output schema, the description is mostly complete, but minor omissions prevent a perfect score.

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

Parameters3/5

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

Schema description coverage is 0% according to context, but the description mentions origin and destination parameters and their preferred inputs. However, it omits the time and limit parameters, which are described in the schema. The description adds value by suggesting stop IDs, but incomplete coverage reduces the score.

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

Purpose5/5

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

The description clearly defines the tool as planning a journey between two locations in Switzerland, explicitly stating it returns multiple trip options with transfers, durations, and transport modes, distinguishing it from sibling tools like transport_search_stop.

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

Usage Guidelines5/5

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

The description provides explicit guidance on when to use stop IDs from transport_search_stop for best results and notes that place names work but may be slower, effectively differentiating between this tool and its sibling for stop search.

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

Tool Schema Changelog

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

  1. 11 tool updatesv0.3.3
    • First observedcheck_transport_api_status
    • First observedget_ticket_price
    • First observedget_train_composition
    • First observedget_train_occupancy
    • First observedget_transport_disruptions
    • First observedtransport_departures
    • First observedtransport_get_dataset
    • First observedtransport_nearby_stops
    • First observedtransport_search_datasets
    • First observedtransport_search_stop
    • First observedtransport_trip_plan

TDQS

A4.4/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose. Even closely related tools like transport_search_stop and transport_nearby_stops are differentiated by search method (by name vs. by location). No overlapping or ambiguous tools.

Naming Consistency3/5

Naming is inconsistent: six tools use the 'transport_' prefix, four use 'get_', and one uses 'check_'. The verb-noun pattern is not consistently applied, mixing prefixes and different verb styles.

Tool Count5/5

11 tools is well-scoped for a Swiss transport server. Each tool serves a clear need without being redundant or excessive, covering stops, departures, trips, disruptions, occupancy, prices, composition, and data catalog access.

Completeness5/5

The tool surface covers all major use cases for Swiss public transport: stop search, nearby stops, departures, trip planning, disruptions, occupancy forecasts, ticket pricing, train composition, and even access to the open data catalog. No obvious gaps for an assistant helping with transport queries.

Maintenance

ActivityActive
ResponsivenessUnresponsive

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    A zero-authentication MCP server for Swiss public transport, enabling users to query train connections, disruptions, station facilities, and plan journeys using natural language.
    12
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides real-time Swiss railway information including departures, connections, train composition, occupancy forecasts, disruptions, and pricing, accessible via natural language in over 100 languages.
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/malkreide/swiss-transport-mcp'

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