# 🗺️ OpenRoute MCP

[![PyPI - Version](https://img.shields.io/pypi/v/openroute-mcp.svg?logo=pypi&label=PyPI&logoColor=silver)](https://pypi.org/project/openroute-mcp/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/openroute-mcp.svg?logo=python&label=Python&logoColor=silver)](https://pypi.org/project/openroute-mcp/)
[![Tests](https://github.com/vemonet/openroute-mcp/actions/workflows/test.yml/badge.svg)](https://github.com/vemonet/openroute-mcp/actions/workflows/test.yml)
[![MCP registry](https://img.shields.io/badge/MCP-Registry-green?logo=modelcontextprotocol)](https://vemonet.github.io/mcp-registry/?search=io.github.vemonet%2Fopenroute-mcp)

</div>

[Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server to plan routes using the **[OpenRouteService API](https://api.openrouteservice.org/)**, for activities such as hiking or mountain biking.

> [!CAUTION]
>
> **DISCLAIMER:** The routes generated by this service are provided for informational purposes only and are **not guaranteed to be safe, legal, or suitable** for your intended use. **Always verify routes independently** using official maps, local authorities, and current conditions before attempting any journey. Users assume all risks and responsibilities for their safety and compliance with local laws and regulations.

> [!TIP]
>
> Copy the whole GPX file returned as part of the tool call results, and use a service such as [gpx.studio](https://gpx.studio) to load the generated GPX file on a map.

## 🛠️ Available tools

- **📍 Find possible coordinates** for a location
  - Arguments:
    - `location` (string): location to get coordinates for
  - Returns: list of 10 coordinates with available description to enable the agent figure out the right one
- **🏠 Find possible locations** (addresses) for given coordinates.
  - Arguments:
    - `lon` (float): Longitude of the location
    - `lat` (float): Latitude of the location
  - Returns: list of objects close to the given coordinates
- **🗺️ Create a route** from a starting location to a destination, optionally with waypoints
  - Arguments:
    - `route_type` (string): Type of route, e.g. "cycling-mountain", "cycling-regular", "foot-hiking", "driving-car"
    - `from_coordinates` (list[float]): Starting location as [longitude, latitude]
    - `from_coordinates` (list[float]): Destination location as [longitude, latitude]
    - `waypoints` (list[list[float]]): optional list of waypoints coordinates as [[lon, lat], ...]
  - Returns:
    - a resource file containing the **route GPX** (e.g. `route://foot-hiking-98.gpx`)
    - a resource file containing a **PNG image** visualization of the route (e.g. `route://foot-hiking-98.png`)
    - a resource file containing a **HTML** interactive visualization of the route (e.g. `ui://foot-hiking-98.html`) that can be directly opened with your browser
- **📌 Search for Points of Interest** (POIs) in an area
  - Arguments:
    - `bounding_box_coordinates` (list[list[float]]): coordinates defining a bounding box as [[min_lon, min_lat], [max_lon, max_lat]]
    - `filters_name` (list[string]): optional list of names to filter POIs, e.g. ["Gas station", "Restaurant"]
  - Returns: found POIs information
- **🔎 Search for known routes** close to a given start and end coordinates, this enables to suggest waypoints to go through known trails when creating a route. It is only working in Switzerland for now thanks to the Swiss Confederation **[api3.geo.admin.ch 🇨🇭](https://api3.geo.admin.ch)**
  - Arguments:
    - `route_type` (string): Type of route, e.g. "cycling-mountain", "cycling-regular", "foot-hiking", "driving-car"
    - `from_coordinates` (list[float]): Starting location as [longitude, latitude]
    - `from_coordinates` (list[float]): Destination location as [longitude, latitude]
  - Returns: known trails trace and description when available to help the agent build a nice route
- **⏱️ Computes the area that can be reached within a given time** or distance from one or more starting points.
  - Arguments:
    - `coordinates_list`: 1 or more coordinates to compute reachable area from as [[lon, lat], ...]
    - `route_type`: Type of route, e.g. "cycling-mountain", "cycling-regular", "foot-hiking", "driving-car"
    - `range_type`: Type of range, either `time` (in seconds) or `distance` (in metres)
    - `area_range`: maximum range value of the analysis in seconds for time and metres for distance. Or a comma separated list of specific range values

  - Returns: Reachable area information in GeoJSON format

## 🗃️ Available Resources

- **🚏 Route files**
  - URL pattern: `route://{filename}`
  - Type: GPX (`.gpx`), HTML (`.html`), or PNG (`.png`)
  - Description: Returns a previously generated route file by filename.
  - Produced by: `create_route_from_to` tool


## 🔌 Connect client to MCP server

Follow the instructions of your client, and use the `/mcp` URL of your deployed server (e.g. http://localhost:8888/mcp)

For example, for [GitHub Copilot in VSCode](https://code.visualstudio.com/docs/copilot/overview), to add a new MCP server through the VSCode UI:

- [x] Open side panel chat (`ctrl+shift+i` or `cmd+shift+i`), and make sure the mode is set to `Agent` in the bottom right
- [x] Open command palette (`ctrl+shift+p` or `cmd+shift+p`), and search for `MCP: Open User Configuration`, this will open a `mcp.json` file

### ⌨️ Use stdio transport

> [!IMPORTANT]
>
> Login with GitHub to [openrouteservice.org](https://openrouteservice.org/) and get an API key that you can provide through the `OPENROUTESERVICE_API_KEY` environment variable.

```sh
OPENROUTESERVICE_API_KEY=YYY uvx openroute-mcp
```

In VSCode `mcp.json` file you should have:

```json
{
  "servers": {
    "openroute-mcp": {
      "command": "uvx",
      "args": [
        "openroute-mcp"
      ],
      "env": {
        "OPENROUTESERVICE_API_KEY": "YOUR_API_KEY"
      }
    }
  }
}
```

> [!IMPORTANT]
>
> Click on `Start` just on top of `"openroute-mcp"` to start the connection to the MCP server.
>
> You can click the wrench and screwdriver button 🛠️ (`Configure Tools...`) to enable/disable specific tools

Full details of the CLI options:

```sh
usage: openroute-mcp [-h] [--http] [--port PORT] [--openroute-api OPENROUTE_API] [--openroute-api-key OPENROUTE_API_KEY]
                     [--data-folder DATA_FOLDER] [--no-save] [--no-img] [--no-html]

A Model Context Protocol (MCP) server for building routes using OpenRouteService.

options:
  -h, --help            show this help message and exit
  --http                Use Streamable HTTP transport
  --port PORT           Port to run the server on
  --openroute-api OPENROUTE_API
                        OpenRouteService API URL (default: https://api.openrouteservice.org)
  --openroute-api-key OPENROUTE_API_KEY
                        OpenRouteService API key (default: taken from env var OPENROUTESERVICE_API_KEY)
  --data-folder DATA_FOLDER
                        Folder to save generated routes
  --no-save             Don't save generated routes to disk (also disable image and HTML generation)
  --no-img              Do not add PNG image visualization of the routes to the response (image not supported by all LLMs)
  --no-html            Do not add HTML interactive map for routes to the response
```

## 🧑‍💻 Development

Checkout the [`CONTRIBUTING.md`](https://github.com/vemonet/openroute-mcp/blob/main/CONTRIBUTING.md) page for more details on running in development and contributing.

<!-- mcp-name: io.github.vemonet/openroute-mcp -->
