Click on "Install 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., "@ns-bridgePlan a trip from Amsterdam Centraal to Utrecht Centraal for this afternoon"
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.
MCP Server for Netherlands NS Trains
mcp-name: ns-bridge
A Model Context Protocol (MCP) server that enables AI assistants to interact with the Netherlands Railways (NS) API for route planning, pricing, and real-time departure information.
Compatible with any MCP client, including Claude Desktop, custom implementations, and AI agent frameworks.
Features
MCP Tools
search_stations - Find train stations by name or country
Search by station name
Filter by country code
Returns station codes needed for trip planning
search_trips - Plan routes between stations
Get multiple trip options with connections
View detailed leg-by-leg journey information
See pricing with discount options
Choose travel class (1st or 2nd)
Search by departure or arrival time
get_departures - View real-time departure boards
See upcoming departures from any station
Track delays and cancellations
Monitor platform changes
MCP Resources
station://{code}- Get detailed information about a specific station
Installation
Prerequisites
NS API key from NS API Portal
Choose one installation method:
Docker (easiest - no Python installation needed)
uv (recommended for development)
pip (traditional Python workflow)
Option 1: Docker (Easiest)
Prerequisites: Docker Desktop or Docker Engine
# Pull the pre-built image from Docker Hub
docker pull ezegodoy26/mcp-server-ns-bridge:latestThen configure your MCP client (see Usage section below for configuration examples).
For detailed Docker usage, troubleshooting, and advanced options, see DOCKER.md.
Option 2: Setup with uv (Recommended for Development)
# Clone the repository
cd mcp-server-ns-bridge
# Install dependencies
uv sync --all-extras
# Set up pre-commit hooks (recommended for development)
uv run pre-commit install
# Copy environment template
cp .env.example .env
# Edit .env and add your NS API key
# NS_API_KEY=your_actual_api_key_hereOption 3: Setup with pip
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install dependencies
pip install -e ".[dev]"
# Set up environment
cp .env.example .env
# Edit .env and add your NS API keyGetting an NS API Key
Go to NS API Portal
Create an account
Subscribe to the following APIs:
Reisinformatie API (Travel Information)
NS-APP Stations API
Copy your subscription key
Add it to your
.envfile asNS_API_KEY
Usage
Running the MCP Server
Development Mode (with Inspector)
export PATH="$HOME/.local/bin:$PATH"
uv run mcp dev src/ns_bridge/server.pyThis opens the MCP Inspector for interactive testing.
Configuring MCP Clients
This server works with any MCP-compatible client. Below are configuration examples for popular clients.
Claude Desktop
Automatic Installation:
uv run mcp install src/ns_bridge/server.pyThis will automatically configure Claude Desktop to use your MCP server.
Manual Configuration:
Add to your Claude Desktop config file (location varies by OS):
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json
For Docker installation:
{
"mcpServers": {
"ns-bridge": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"--init",
"-e",
"NS_API_KEY",
"ezegodoy26/mcp-server-ns-bridge:latest"
],
"env": {
"NS_API_KEY": "your_api_key_here"
}
}
}
}Note: The
-e NS_API_KEYin theargsarray tells Docker to pass the environment variable from the host (set by theenvsection) into the container. Without this, the API key won't be available inside Docker.
For uv installation:
{
"mcpServers": {
"ns-bridge": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/mcp-server-ns-bridge",
"run",
"src/ns_bridge/server.py"
],
"env": {
"NS_API_KEY": "your_api_key_here"
}
}
}
}After updating the configuration, restart your MCP client to load the server.
Other MCP Clients
For other MCP-compatible clients (custom implementations, AI agent frameworks, etc.), refer to your client's documentation for stdio server configuration. The server accepts standard MCP protocol messages via stdin/stdout.
Example Queries
Once configured, you can ask your AI assistant:
"What trains are departing from Utrecht Centraal in the next hour?"
"Find me a train from Amsterdam to Rotterdam tomorrow at 9 AM"
"What's the fastest route from Den Haag to Groningen?"
"How much does a first-class ticket from Eindhoven to Maastricht cost?"
"Show me stations near the German border"
Development
Project Structure
mcp-server-ns-bridge/
├── src/
│ └── ns_bridge/
│ ├── __init__.py # Package initialization
│ ├── server.py # MCP server implementation
│ ├── ns_api_client.py # NS API wrapper
│ ├── models.py # Data models (Pydantic)
│ └── config.py # Configuration management
├── tests/ # Test suite
├── pyproject.toml # Project configuration & dependencies
├── .env.example # Environment template
└── README.md # This fileDeveloper Tools
This project uses modern Python development tools for code quality:
Pre-commit Hooks
Pre-commit hooks automatically check your code before each commit:
General checks: Trailing whitespace, EOF fixes, YAML/TOML validation
Ruff: Fast linting and code formatting
MyPy: Static type checking
Bandit: Security vulnerability scanning
# Install pre-commit hooks (one-time setup)
uv run pre-commit install
# Run manually on all files
uv run pre-commit run --all-files
# Hooks will automatically run on git commitCode Formatting & Linting
You can also run tools manually:
# Format code with Ruff
uv run ruff format src/ tests/
# Lint and auto-fix
uv run ruff check --fix src/ tests/
# Type checking
uv run mypy src/
# Security scanning
uv run bandit -r src/See DEVELOPER_TOOLS.md for detailed documentation on each tool and why we use them.
Testing
pytest: Test framework
pytest-asyncio: Async test support
pytest-cov: Code coverage
pytest-httpx: HTTP mocking for API tests
Run tests:
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov
# Run specific test file
uv run pytest tests/test_models.py
# Run with verbose output
uv run pytest -vVirtual Environment Note
Yes, uv is compatible with virtual environments! uv automatically creates and manages a .venv directory in your project. You can activate it manually if needed:
source .venv/bin/activate # macOS/Linux
.venv\Scripts\activate # WindowsHowever, uv run automatically uses the virtual environment, so activation is optional for most tasks.
API Documentation
NS API Endpoints Used
Stations API (
/nsapp-stations/v2)Search and list train stations
Filter by country
Trips API (
/reisinformatie-api/api/v3/trips)Route planning with connections
Pricing information
Support for via stations
Departures API (
/reisinformatie-api/api/v2/departures)Real-time departure information
Delay and cancellation tracking
Station Codes
Common station codes:
ut- Utrecht Centraalasd- Amsterdam Centraalrtd- Rotterdam Centraalgvc- Den Haag Centraalehv- Eindhoven Centraalnm- Nijmegengn- Groningen
Use the search_stations tool to find more station codes.
Contributing
Suggestions and improvements are welcome!
Development Workflow
Create a feature branch
Make your changes
Run the test suite:
uv run pytestPre-commit hooks will automatically run on commit (or run manually:
uv run pre-commit run)Submit a pull request
Note: Pre-commit hooks automatically handle formatting, linting, type checking, and security scanning.
License
MIT License - see LICENSE file for details
Acknowledgments
Model Context Protocol - Anthropic's MCP specification
NS API - Netherlands Railways API
FastMCP - Python MCP SDK
Roadmap
Future enhancements planned:
Add support for disruptions API
Include station facilities information
Add journey details (crowdedness predictions)
Support for international routes
Caching for frequently accessed data
Rate limiting to respect API quotas