Skip to main content
Glama
KhulaNode

Cartrack MCP

by KhulaNode
README.md
# Cartrack MCP

A small, portable MCP server that exposes a **read-only** view of a Cartrack fleet through any MCP client that can launch a stdio process.

The server exposes only:

- `list_vehicles` — an allowlisted vehicle inventory.
- `get_vehicle_status` — last-known status and location for one exact registration.

It does not expose vehicle commands, account changes, geofence changes, driver edits, or raw upstream responses.

## Requirements

- Python 3.10 or newer
- Cartrack Fleet API credentials with read access
- An MCP client that supports stdio servers

The server uses HTTPS-only requests, sends HTTP Basic Authentication only in the `Authorization` header, enforces exact normalized registration matching, and calculates telemetry freshness from the provider timestamp.

## Installation

Create an isolated environment and install the project:

```bash
python3 -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install .
```

For development and tests:

```bash
python -m pip install -e .
python -m pip install pytest
```

## Configuration with environment variables

Set all three variables in the environment used to launch the server:

```bash
export CARTRACK_BASE_URL='https://fleetapi.example.com'
export CARTRACK_API_USERNAME='your-api-username'
export CARTRACK_API_PASSWORD='your-api-password'
cartrack-mcp
```

The base URL must be a complete HTTPS URL. Credentials are never printed or included in request URLs.

## Configuration with a credentials file

Create a file outside the repository, for example `~/.config/cartrack/credentials.env`:

```text
CARTRACK_BASE_URL=https://fleetapi.example.com
CARTRACK_API_USERNAME=your-api-username
CARTRACK_API_PASSWORD=your-api-password
```

Point to a different file when needed:

```bash
export CARTRACK_CREDENTIALS_FILE=/path/to/credentials.env
cartrack-mcp
```

The default lookup is user-relative and XDG-compatible: `$XDG_CONFIG_HOME/cartrack/credentials.env`, or `~/.config/cartrack/credentials.env`. Environment variables take precedence over values from the file. Keep the file readable only by the account running the server (for example, mode `600` on Unix); the application does not claim to enforce file permissions.

A missing file, malformed line, missing value, or non-HTTPS URL produces an actionable configuration error on startup.

`.env.example` contains placeholders only and is safe to copy as a starting template. Do not commit a populated copy.

## MCP client configuration

The exact configuration format varies by client. A generic stdio configuration uses the installed console command:

```json
{
  "mcpServers": {
    "cartrack": {
      "command": "cartrack-mcp",
      "args": [],
      "env": {
        "CARTRACK_BASE_URL": "https://fleetapi.example.com",
        "CARTRACK_API_USERNAME": "your-api-username",
        "CARTRACK_API_PASSWORD": "your-api-password"
      }
    }
  }
}
```

Prefer the client’s secret-management facility instead of storing passwords in a shared configuration file.

### Optional: Hermes integration

Hermes can launch the same installed stdio command as one MCP server option. Hermes is not required at runtime and is not a project dependency. Configure it using the normal Hermes MCP configuration for a command named `cartrack-mcp`, with credentials supplied through its environment mechanism.

## Tools

### `list_vehicles`

Input: none.

Returns safe fields such as registration, manufacturer, model, model year, colour, vehicle name, vehicle ID, and timezone. Chassis numbers, tracker serials, credentials, and unrelated provider fields are excluded.

Example shape:

```json
[
  {
    "registration": "TEST123",
    "manufacturer": "Example Motors",
    "model": "Example Model",
    "model_year": 2024,
    "timezone": "Africa/Johannesburg"
  }
]
```

### `get_vehicle_status`

Input:

```json
{"registration": "TEST 123"}
```

Spaces and hyphens are normalized for lookup, but the server independently requires one exact normalized match. The result contains last-known event time, telemetry age in minutes, speed, ignition, idling, odometer, bearing, road speed limit, and an allowlisted location object.

Example shape:

```json
{
  "registration": "TEST123",
  "event_ts": "2025-01-01 12:39:42+02",
  "telemetry_age_minutes": 9.0,
  "speed_kmh": 0,
  "ignition": false,
  "location": {
    "latitude": -23.9,
    "longitude": 29.45,
    "position_description": "Example location"
  }
}
```

## Development and tests

From the repository root:

```bash
python -m unittest discover -v
python -m compileall -q src tests
```

After installing development dependencies, pytest can also be used:

```bash
pytest -q
```

Tests use synthetic fixtures and injected transports. They do not contact the Cartrack API.

## Troubleshooting

- **`cartrack-mcp: command not found`** — activate the virtual environment or use its absolute executable path; reinstall with `python -m pip install .`.
- **Missing configuration** — set all three `CARTRACK_*` variables, or set `CARTRACK_CREDENTIALS_FILE` to an existing file containing all required keys.
- **Malformed credentials file** — use one `KEY=VALUE` entry per line; blank lines and comments are allowed.
- **HTTPS error** — use the documented Cartrack API HTTPS base URL, not an HTTP URL.
- **No exact vehicle match** — check the registration; partial and ambiguous matches are intentionally rejected.
- **Stale telemetry** — `telemetry_age_minutes` reflects the age of the provider’s last event, not a live position guarantee.
- **MCP client cannot start the server** — confirm the command is available to the client process, configuration uses stdio, and credentials are supplied in that client’s environment.