Skip to main content
Glama
JanProvaznik

Czech Railways (České dráhy) MCP Server

by JanProvaznik

cd-mcp

MCP (Model Context Protocol) server for Czech Railways (České dráhy) API.

This server provides AI assistants with tools to search for train connections, stations, and prices on the Czech railway network.

Features

  • Search Locations: Find train stations and cities in the Czech Railways network

  • Search Connections: Search for train connections between two stations

  • Get Connection Details: Get detailed information about a specific connection

  • Get Passenger Types: List available passenger types and discount categories

  • Get Price Offers: Get pricing information for connections

Related MCP server: NS Travel MCP Server

Installation

npm install
npm run build

Usage

With Claude Desktop

Add to your Claude Desktop configuration (claude_desktop_config.json):

{
  "mcpServers": {
    "cd-mcp": {
      "command": "node",
      "args": ["/path/to/cd-mcp/dist/index.js"]
    }
  }
}

With MCP Inspector

npx @modelcontextprotocol/inspector node dist/index.js

Development

npm run dev

Available Tools

search_locations

Search for train stations and cities by name.

Parameters:

  • query (string, required): Search query (e.g., "Praha", "Brno")

  • type (string, optional): Location type filter (e.g., "station", "city")

search_connections

Search for train connections between two stations.

Parameters:

  • from (string, required): Departure station

  • to (string, required): Arrival station

  • departure (string, required): Departure date/time in ISO 8601 format

  • passengers (number, optional): Number of passengers (1-9, default: 1)

get_connection_details

Get detailed information about a specific connection.

Parameters:

  • handle (string, required): Connection search handle from previous search

  • connectionId (string, required): Connection identifier

get_passenger_types

Get available passenger types and discount categories.

Parameters: None

get_price_offer

Get a price offer for a connection (read-only, does not book tickets).

Parameters:

  • connectionId (string, required): Connection identifier

  • passengers (array, required): Array of passenger types and counts

Design Decisions

As a Principal Architect, the following design decisions were made:

  1. Read-only operations only: The server only exposes read operations (search, get details, pricing). Booking, payment, and refund operations are intentionally excluded for security reasons - these should require explicit user action through official channels.

  2. Stdio transport: Uses stdio transport for simple integration with MCP clients like Claude Desktop. HTTP transport can be added if needed.

  3. Error handling: All tools include proper error handling and return user-friendly error messages.

  4. Type safety: Full TypeScript implementation with proper type definitions for API responses.

  5. Formatting: Results are formatted for readability with emojis and structured text output.

API Reference

This server interfaces with the Czech Railways Ticket API:

License

MIT

Available Tools

5 tools
get_connection_detailsGet Connection DetailsA

Get detailed information about a specific train connection. Note: This endpoint is not available with the mobile API - all connection details are included in search results.

ParametersJSON Schema
NameRequiredDescriptionDefault
handleYesConnection search handle from a previous search
connectionIdYesConnection identifier from the search results

TDQS

A3.9/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It discloses the mobile API limitation but does not mention auth, rate limits, or non-destructive nature. The 'get' verb implies read-only, which is adequate but not explicit.

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

Conciseness5/5

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

Two sentences: first states the purpose, second adds a crucial usage note. No wasted words, front-loaded, and to the point.

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

Completeness3/5

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

The description covers the tool's purpose and a key limitation, but lacks details on what 'detailed information' includes (e.g., stops, prices). With no output schema, more context on return content would be helpful, though not critical for a simple tool.

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

Parameters3/5

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

Schema coverage is 100% and both parameters (handle, connectionId) are well-described in the schema. The description adds no extra parameter meaning, which is acceptable given the schema covers it.

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 gets detailed information about a specific train connection, distinguishing it from sibling search_connections which lists connections. The note about mobile API adds specificity.

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 says to get details of a specific connection and notes it is not available with the mobile API, implying use search_connections instead. This provides clear context but lacks an explicit alternative mention.

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

get_passenger_typesGet Passenger TypesA

Get a list of available passenger types and discount categories (e.g., adult, child, senior, student discounts).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior3/5

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

No annotations provided, so the description carries full burden for behavioral disclosure. It correctly implies a read operation but does not explicitly state safety, authentication needs, or latency. For a simple list tool, this is adequate but not thorough.

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 a single sentence that efficiently communicates the tool's purpose and includes specific examples. No superfluous information; every word earns its place.

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?

For a tool with no parameters and a simple output, the description adequately covers what it returns. However, it lacks details on output structure (e.g., array format) since no output schema is provided. Still, it is sufficient for an AI to understand the tool's role.

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. The description adds value by listing examples of passenger types (adult, child, senior, student discounts), providing context beyond the empty schema. Baseline for 0 params is 4.

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

Purpose5/5

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

The description clearly states the tool retrieves a list of passenger types and discount categories, with specific examples. The verb 'Get' and resource 'list of available passenger types' are precise. It distinguishes from sibling tools that deal with connections, prices, and locations.

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

Usage Guidelines2/5

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. While the purpose is clear, the description lacks information on prerequisites or typical usage context, such as calling this before searching connections.

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

get_price_offerGet Price OfferB

Get a price offer for a specific connection. Note: Prices are already included in connection search results, so this separate endpoint is not available with the mobile API.

ParametersJSON Schema
NameRequiredDescriptionDefault
passengersYesArray of passenger types and counts
connectionIdYesConnection identifier from search results

TDQS

B3.2/5.0
Behavior2/5

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

No annotations are provided, and the description only notes that prices are included in search results. It does not disclose behavioral traits such as idempotency, error states, or requirements (e.g., valid connectionId).

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 concise with two sentences. The first sentence delivers the primary purpose, and the second provides relevant context. No superfluous information.

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

Completeness3/5

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

For a simple tool with no output schema, the description covers the basic purpose and a usage caveat. However, it lacks details on expected return values or error conditions, leaving some gaps.

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

Parameters3/5

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

Schema coverage is 100%, meaning both parameters are described in the input schema. The description adds no extra meaning beyond what the schema already provides, meeting the baseline expectation.

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

Purpose4/5

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

The description clearly states the action ('Get a price offer') and the target ('for a specific connection'). It is specific and unambiguous, but does not explicitly distinguish from sibling tools like get_connection_details or search_connections.

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 mentions that prices are already in search results and that the endpoint is not available in the mobile API, implying when not to use it. However, it lacks explicit guidance on when to prefer this tool over alternatives.

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

search_connectionsSearch ConnectionsB

Search for train connections between two stations. Returns available trains with departure times, duration, and transfers.

ParametersJSON Schema
NameRequiredDescriptionDefault
toYesArrival station key or name (e.g., "Brno hl.n.")
fromYesDeparture station key or name (e.g., "Praha hl.n.")
departureYesDeparture date and time in ISO 8601 format (e.g., "2024-03-15T08:00:00")
passengersNoNumber of passengers (1-9, default: 1)

TDQS

B3.2/5.0
Behavior2/5

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

With no annotations provided, the description carries the full burden of disclosing behavioral traits. It does not state that the operation is read-only, nor does it mention authentication, rate limits, or what happens when no results are found. The description only describes the output format, leaving safety and behavioral assumptions unstated. This is insufficient for a tool with no annotation support.

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

Conciseness3/5

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

The description is a single sentence, very concise, but at the cost of missing essential behavioral and usage guidance. Every word earns its place in describing the function and output, but the minimal length neglects important context. It is not overly verbose, but the lack of structural elements (e.g., separate sections or bullet points) reduces clarity for an agent.

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

Completeness2/5

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

Given the complexity of 4 parameters, no output schema, and missing annotations, the description is incomplete. It does not explain the exact structure of the return value (e.g., pagination, fields beyond those listed) or how to handle errors. The presence of siblings suggests a workflow, but no guidance is provided. For a tool that likely feeds into get_connection_details or get_price_offer, the description should be more comprehensive.

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

Parameters3/5

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

The input schema has 100% description coverage, so parameters are already documented. The description adds no extra meaning beyond what the schema provides (e.g., it mentions 'two stations' but that is already covered by from/to fields). The description does not clarify constraints like station name format or ISO 8601 precision beyond the schema. Baseline score of 3 is appropriate since schema does the heavy lifting.

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 verb 'search' and the resource 'train connections between two stations'. It explicitly mentions the return type: available trains with departure times, duration, and transfers. This distinguishes it from siblings like get_connection_details, which would focus on a specific connection, and search_locations for stations. The purpose is unambiguous and specific.

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

Usage Guidelines3/5

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

The description implies usage for finding connections but provides no explicit guidance on when to use this tool versus alternatives like get_connection_details or search_locations. No exclusions or prerequisites are mentioned. The usage context is implied through the action and parameters, but without clear differentiation from siblings, the agent may not know when to choose this over other tools.

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

search_locationsSearch LocationsA

Search for train stations and cities in the Czech Railways network. Use this to find station codes for connection searches.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoOptional location type filter (e.g., "station", "city")
queryYesSearch query (station or city name, e.g., "Praha", "Brno")

TDQS

A4/5.0
Behavior3/5

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

With no annotations provided, the description must carry the burden of behavioral disclosure. It reveals the scope (Czech Railways network) and purpose (find station codes) but lacks details on authentication, rate limits, or response behavior (e.g., fuzzy matching, sorting). The description is adequate but not exhaustive.

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

Conciseness5/5

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

The description is two sentences, front-loaded with the purpose, and contains no unnecessary words. Every sentence adds value, making it highly efficient for an AI agent to parse.

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 simple tool (2 params, no output schema), the description provides enough context for a basic use case. However, it could be more complete by mentioning response format (e.g., list of stations with codes) or behavior on partial matches. Still, it meets the minimum needs.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents both parameters (query and type). The description adds extra context (e.g., 'Czech Railways network', examples) but does not significantly enhance understanding beyond the schema's own descriptions. Baseline 3 is appropriate.

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

Purpose5/5

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

The description clearly specifies the action ('Search for') and the resources ('train stations and cities') within the Czech Railways network. It distinguishes itself from sibling tools by explicitly stating it finds station codes for connection searches, which is a specific use case different from tools like search_connections.

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 states to use this tool to find station codes for connection searches, giving clear context. However, it does not explicitly mention when not to use it or provide alternatives, leaving some ambiguity about handling cases where the location is not found.

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.

  1. 5 tool updatesv1.0.0
    • First observedget_connection_details
    • First observedget_passenger_types
    • First observedget_price_offer
    • First observedsearch_connections
    • First observedsearch_locations

TDQS

A3.6/5.0

Scored across 5 tools

Disambiguation4/5

Tools have distinct purposes, but get_connection_details and get_price_offer are noted as redundant with search results, which could cause agent confusion if they attempt to use them and fail.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern using snake_case: get_* and search_*. No naming anomalies.

Tool Count4/5

5 tools is a reasonable size for a railway information server, but two tools are marked as unavailable with the mobile API, suggesting they could be removed.

Completeness3/5

Covers basic query operations (search stations, connections, passenger types), but lacks booking, real-time info, or station details, and duplicate tools reduce practical completeness.

Maintenance

ActivityInactive
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers