Navitia MCP Server
Navitia MCP Server
An MCP server exposing the Navitia public-transport API: journey planning, place search, realtime departures and timetables, usable from Claude Desktop, Claude Code, or any MCP client.
→ Full usage guide — install, client setup, worked examples, tool reference, response shapes and troubleshooting.
Tools
Tool | What it does |
| Geocode / autocomplete stations, addresses, POIs, cities — returns the object ids the other tools need |
| Find networks, lines, routes and stops by name (e.g. "metro 14" → a |
| Stops and POIs within a radius of a coordinate |
| Door-to-door multi-modal itineraries (with disruptions), with optional per-line preferences |
| Realtime departure/arrival boards for a stop |
| Timetable at a stop, grouped by line and direction |
| Station-display board for one line at a stop, grouped by destination (needs a |
| Full timetable grid for a line or route |
The server is scoped to a single coverage region (default Île-de-France, fr-idf) set via the NAVITIA_REGION env var — tools take no region parameter. Set NAVITIA_REGION=fr-se for the southeast (Lyon), sncf for national rail, etc.
Configuration
Env var | Required | Default | Purpose |
| yes | — | Your Navitia token |
| no |
| Coverage region id the server is scoped to |
| no |
| API root (override for a self-hosted Navitia) |
Setup
You need a Navitia API token (request one via navitia.io / Hove). The server reads it from NAVITIA_API_KEY only — never commit it. For local runs, copy .env.example to .env (gitignored) or export the variable in your shell.
npm install
npm run buildClaude Code
claude mcp add navitia --env NAVITIA_API_KEY=your-token --env NAVITIA_REGION=fr-idf -- node /absolute/path/to/dist/index.jsClaude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"navitia": {
"command": "node",
"args": ["/absolute/path/to/dist/index.js"],
"env": {
"NAVITIA_API_KEY": "your-token",
"NAVITIA_REGION": "fr-idf"
}
}
}
}Line preferences (experimental)
plan_journey can express a taste for or against a line instead of a hard rule:
Parameter | Effect | Typical phrasing |
| Favours the line — itineraries using it rank higher | "I'd rather take metro 14" |
| Proposes the line less, without removing it | "I'd like to avoid metro 14, but not rule it out" |
| Excludes the line outright | "never put me on metro 14" |
All three take ids from search_pt_objects; prefer_lines / avoid_lines reject anything that is not a line: id rather than sending it on.
Preferences map to Navitia's experimental flag, one per line:
_features_flags[]=boost_line({line_id},{boost_factor})with boost_factor = 3 for a preferred line and 0.4 for an avoided one.
Because boosting changes what the default ordering means, a response that used line preferences is re-ordered by the reliability rank in each journey's criteria_ranker — rank 1 first — and carries ordered_by: "reliability" so the client can explain the order it is showing. Without preferences, the API's own order is left untouched and ordered_by is absent.
The flag is experimental and depends on server-side support: an instance that does not implement it may ignore it or return an error, which the tool relays unchanged.
Usage notes
Datetimes are ISO 8601 in the region's local time (e.g.
2026-06-11T17:30); responses use the same format.Ids: find stops/addresses with
search_places(stop_area:…), and lines/networks withsearch_pt_objects(line:…), then feed them to the journey/departure/schedule tools.terminus_schedulesrequires aline_id— resolve it withsearch_pt_objectsfirst (e.g. "metro 14").plan_journeycalls always carry the technical parameter_frontend=gormun, which identifies this caller to Navitia. It is a constant, not a tool input.Line preferences (
prefer_lines/avoid_linesonplan_journey) nudge the ranking;forbidden_urisremoves a line entirely. See Line preferences.All tools are scoped to the
NAVITIA_REGIONcoverage; no per-callregionparameter. To serve several regions, run one instance per region.Responses are deliberately slimmed (no geojson/links) to stay LLM-friendly; large results are truncated at 50 kB.
Output format
Tools return slimmed JSON — Navitia's HATEOAS links, geojson geometries and deep fare/co2 trees are dropped so the payload stays inside a model's context. Presentation is the client's job, not the server's.
Time-sensitive responses (plan_journey, next_departures, next_arrivals, stop_schedules, terminus_schedules, route_schedules) carry a top-level now — the API's own context.current_datetime, in the region's local timezone. Compute countdowns ("dans 3 min") against that field, never against the reader's clock, which may sit in another timezone.
Each journey also carries Navitia's criteria_ranker when the API supplies it — that journey's 1-based rank for asap, less_transfers, less_walking and reliability, 1 being the best on that criterion. It is what the line-preference re-ordering sorts on, and a client can reuse it to tag itineraries.
prompts/agent-system-prompt.md is a ready-to-use strict system prompt for an agent driving this server: it specifies the board layouts (departure boards, journey chains, timetables), the anti-fabrication rules, and the id-resolution protocol.
Development
NAVITIA_API_KEY=your-token npm run dev # run from source
npx @modelcontextprotocol/inspector node dist/index.js # interactive testingSee docs/USAGE.md for the full guide, and docs/USAGE.md#12-troubleshooting when something returns nothing.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/wassimbenaissa/Navitia-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server