Skip to main content
Glama
README.md
# route-mcp

MCP server comparing door-to-door travel time in **Île-de-France** by **bicycle**, **motorbike** (estimate)
and **public transport**, with **local weather**, plus a terminal chat client driven by a local LLM (Ollama).

Design decisions and their rationale: [docs/TECHNICAL_REPORT.md](docs/TECHNICAL_REPORT.md).

## Tools exposed

| Tool | What it does | Metered? |
|---|---|---|
| `compare_routes` | Travel time per mode between two places, fastest mode, weather at departure | Google Routes: 1 Essentials call each for bicycle and transit, 1 Pro call for motorbike |
| `get_weather` | Current conditions + hourly forecast (up to 48 h) | Open-Meteo (free, daily cap) |
| `find_place` | Disambiguate an address or place name | Free |
| `get_api_usage` | Calls used / remaining per budget | Free |

## Requirements

- Python 3.12+
- [Ollama](https://ollama.com) with `llama3.1:8b` pulled (client only)
- A Google Maps Platform API key with the **Routes API** enabled (routes only; weather and geocoding need no key)

## Setup

```bash
python3 -m venv .venv
.venv/bin/pip install -e ".[client,dev]"
cp .env.example .env   # then set ROUTE_MCP_GOOGLE_MAPS_API_KEY
```

Before using a real key, apply the Google Cloud Console safeguards described in
[the report](docs/TECHNICAL_REPORT.md#cost-guardrails) (API restriction + daily quota).

Then check the key with one real request (counted in the usage ledger):

```bash
.venv/bin/route-mcp-check-google                  # bicycle, Routes Essentials
.venv/bin/route-mcp-check-google --mode motorbike  # also checks the Routes Pro SKU
```

On failure it prints Google's error reason (API not enabled, key restriction, billing...) and how to fix it.

## Run

```bash
# Terminal chat (starts the MCP server itself over stdio)
.venv/bin/route-mcp-chat
#   commands: /tools  /usage  /viewer  /reset  /help  /quit
#   trace viewer: open http://127.0.0.1:8765 while chatting

# Server alone, for any MCP host (Claude Desktop, MCP Inspector, ...)
.venv/bin/route-mcp-server
```

Example MCP host configuration:

```json
{
  "mcpServers": {
    "route-mcp": {
      "command": "/absolute/path/to/route-MCP/.venv/bin/route-mcp-server",
      "env": { "ROUTE_MCP_GOOGLE_MAPS_API_KEY": "..." }
    }
  }
}
```

## Android app and phone API

- [`android/`](android/README.md): native Android app (Kotlin, Jetpack Compose). Saved places and the API
  token stay on the phone. Built so a home-screen widget can reuse the same data layer.
- `route-mcp-api`: the HTTP API the app calls, meant for a server (Docker + Caddy for HTTPS). Deployment
  guide: [docs/DEPLOY_VPS.md](docs/DEPLOY_VPS.md).
  - `POST /v1/advice`: comparison and rule-based choice, from coordinates sent by the phone.
  - `POST /v1/advice/{id}/explanation`: two or three sentences by Claude Opus 5 (server-side refusal
    fallback enabled), written once per advice and capped per day in the usage ledger.
  - `GET /v1/places/search`, `GET /v1/usage`, and `GET /v1/health` (the only route without a token).
  - Every other route requires `Authorization: Bearer $ROUTE_MCP_API_TOKEN`.

## App: which transport now?

A local web page to save four places (home, pool, athletics track, work), get your position from the
browser, and get advice on the best mode to reach one of them.

```bash
.venv/bin/pip install -e ".[app,dev]"
.venv/bin/route-mcp-app        # then open http://127.0.0.1:8766
```

- Places are searched with `find_place` (free) or set from your current position, and saved in
  `~/.route-mcp/places.json` (owner-only permissions).
- Advice calls `compare_routes` through the MCP server over stdio, from your position to the place.
- **The mode is chosen by fixed rules**, not by the model: travel time, plus penalties for rain, strong
  gusts and cold on two wheels, a warm-up bonus for cycling to the track, and a penalty for a bike ride over
  25 minutes to work. The rules are listed on screen with the result.
- The local model (Ollama) then writes a two- or three-sentence explanation. If it is unavailable, the
  rule-based reasons are shown on their own.
- Cost per advice: at most 2 Routes Essentials calls and 1 Routes Pro call, reused for 5 minutes.
- The browser only shares your position on `localhost` or HTTPS, so the page must be opened on this machine.

## Trace viewer

The chat serves a local debugging page at `http://127.0.0.1:8765` (standard library only, bound to
localhost). It updates live and shows, for each question:

- every LLM round: latency, prompt/output tokens against the context window, thinking text (for models
  that emit it), the tool calls requested, and the exact prompt sent (after history trimming);
- every tool call: arguments, latency, the result as fed back to the model, and errors;
- the final answer, a forced answer when the tool-round limit is hit, or the exception.

The last 50 questions are kept in memory. Change the port or disable it with `ROUTE_MCP_CLIENT_VIEWER_PORT`
(`0` = off).

## Test

```bash
.venv/bin/pytest            # offline: every upstream API is faked
.venv/bin/ruff check src tests
```

## Configuration

All settings are environment variables (or `.env`), listed with their defaults in [.env.example](.env.example).
The usage ledger lives in `~/.route-mcp/usage.sqlite3`: keep one per API key.

## Data sources and licences

- Routes: Google Maps Platform Routes API (Google terms apply).
- Geocoding: Géoplateforme / Base Adresse Nationale (IGN), free service.
- Weather: [Open-Meteo](https://open-meteo.com), CC BY 4.0. **The free API is for non-commercial use only.**

TDQS

A4.2/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: place lookup, route comparison, weather lookup, and API usage monitoring. There is no meaningful overlap between any of the tools.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern: compare_routes, get_weather, find_place, get_api_usage. The naming convention is uniform and predictable.

Tool Count5/5

Four tools is a reasonable, focused scope for a routing assistance server. Each tool serves a necessary function and none feel redundant or excessive.

Completeness4/5

The core workflow is covered: find a place, compare routes, and optionally check weather. Minor gaps exist such as lack of route detail endpoints or alternative route options, but the essential use case is well supported.

Maintenance

ActivityMaintained
ResponsivenessNo issues