Metadata-Version: 2.4
Name: trackline-mcp
Version: 0.1.0
Summary: Trackline MCP Client — Device Flow Auth + stdio<->SSE Bridge for the Trackline railway data platform
License: MIT
Keywords: ai,claude,mcp,railway,trackline
Requires-Python: >=3.9
Provides-Extra: dev
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest-timeout>=2.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Description-Content-Type: text/markdown

# trackline-mcp

[![PyPI](https://img.shields.io/pypi/v/trackline-mcp)](https://pypi.org/project/trackline-mcp/)
[![Test & Lint](https://github.com/Trackline-Live/trackline-mcp/actions/workflows/test.yml/badge.svg)](https://github.com/Trackline-Live/trackline-mcp/actions/workflows/test.yml)

A zero-dependency Python MCP client that bridges Claude Code (and other MCP hosts) to the [Trackline](https://trackline.live) railway data platform via SSE. Distributed as a `uvx`-runnable package — no manual installation or virtualenv required.

---

## Installation

### Via uvx (recommended)

No installation needed. Run directly:

```bash
uvx trackline-mcp --auth
```

### Via pip

```bash
pip install trackline-mcp
trackline-mcp --auth
```

---

## Authentication

Trackline MCP uses OAuth 2.0 Device Authorization Grant (no browser redirect required). You authenticate once and the token is cached at `~/.pyrail/token.json` with automatic refresh via an offline token.

**Step 1 — Authenticate in a terminal:**

```bash
uvx trackline-mcp --auth
```

This opens a URL. Visit it, log in, and the token is cached automatically.

**Step 2 — Connect from Claude Code** (see config below — no manual step needed).

---

## Claude Code / MCP Configuration

Add to your `.mcp.json` (project or global):

```json
{
  "mcpServers": {
    "trackline": {
      "command": "uvx",
      "args": ["trackline-mcp"]
    }
  }
}
```

---

## Dev Environment Overrides

For local development or custom deployments, you can override the default URLs:

### Via CLI flags

```bash
uvx trackline-mcp --auth-url https://auth.local --mcp-url http://localhost:8080/sse
```

### Via environment variables

```bash
export TRACKLINE_AUTH_URL=https://auth.local
export TRACKLINE_MCP_URL=http://localhost:8080/sse
uvx trackline-mcp
```

**Config priority:** CLI flag > environment variable > hardcoded default

### In .mcp.json with overrides

```json
{
  "mcpServers": {
    "trackline-dev": {
      "command": "uvx",
      "args": ["trackline-mcp", "--mcp-url", "http://localhost:8080/sse"],
      "env": {
        "TRACKLINE_AUTH_URL": "https://auth.local"
      }
    }
  }
}
```

---

## CLI Reference

```
usage: trackline-mcp [-h] [--auth] [--auth-url AUTH_URL] [--mcp-url MCP_URL]

options:
  --auth              Authenticate via device flow and cache token, then exit
  --auth-url URL      Override Keycloak base URL
                      (default: TRACKLINE_AUTH_URL env or https://auth.trackline.live)
  --mcp-url URL       Override MCP SSE URL
                      (default: TRACKLINE_MCP_URL env or https://mcp.trackline.live/sse)
```

---

## Development

### Setup

```bash
git clone https://github.com/Trackline-Live/trackline-mcp
cd trackline-mcp
uv venv && uv pip install -e ".[dev]"
```

### Run tests

```bash
pytest --cov=src --cov-report=term-missing
```

### Lint

```bash
ruff check src/ tests/
ruff format src/ tests/
```

---

## How It Works

1. On first run (`--auth`), the client performs a Device Authorization Grant with Keycloak, opening a short URL for you to approve.
2. The token (including an offline refresh token) is cached at `~/.pyrail/token.json`.
3. On subsequent runs, the client reads the cached token, refreshes it automatically if needed, then opens an SSE connection to the Trackline MCP server.
4. JSON-RPC messages from Claude Code arrive on stdin and are POSTed to the server; server SSE events are forwarded to stdout.
