Metadata-Version: 2.4
Name: liauto
Version: 0.1.0b2
Summary: Unofficial CLI for LiAuto/LiXiang vehicles
Author: licli contributors
License: Proprietary (see LICENSE)
Keywords: lixiang,liauto,car,vehicle
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Programming Language :: Go
Classifier: Topic :: Utilities
Requires-Python: >=3.0
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# licli

licli is a CLI for Li Auto (LiXiang) vehicle APIs. It covers auth, real-time status, travel history, control commands, an HTTP API server, and an MCP server.

Run it without installing anything (PyPI via `uvx`, or npm via `npx`):

```bash
alias licli='uvx liauto'
licli help

# or

alias licli='npx -y @liauto/cli'
licli version
```

## Commands

```bash
licli activate          # activate the current device (first activation or re-activation)
licli login             # device login, prints an OAuth URL, then persists the pasted token JSON
licli vehicles          # list cached vehicles
licli status <VIN>      # query vehicle state (--json/--raw)
licli travel <VIN> [YYYY-MM]   # monthly travel history; with YYYY-MM, that month's detail
licli control <VIN> <action>   # lock/unlock/find/wake + ac <on|off|auto|temp|fast-cool|fast-heat> + seat-vent/seat-heat [pos] <1-3|off> + wheel-heat <on|off> + window [pos] <0-99> + trunk <open|close> (action: result <id>)
licli version           # print version
licli serve             # HTTP API server (default 127.0.0.1:18001; --addr/--token/--allow-control)
licli mcp               # MCP server, stdio (default) or --transport http (default 127.0.0.1:18002)
```

Run `licli` with no arguments (or `licli <unknown>`) to print the command list.

Global flags: `--json` (JSON output), `-v` / `--verbose` (verbose logging to stderr).

Exit codes: `0` success, `1` user input error, `2` network failure, `3` HTTP non-200, `4` activation failure, `5` config permission/corrupt, `6` missing/invalid/expired activation code.

## Activation code

Running any licli command except `version` requires a valid activation code, set as an
environment variable:

```bash
export LICLI_CODE=<activation code>
licli login
licli vehicles    # list vehicles
```

A code is issued by the tool's publisher (offline `license-keygen`). It is an
Ed25519-signed token: the binary only verifies it with the built-in public key and
cannot forge codes. Missing/invalid/expired codes exit with code 6.

## HTTP API server (`serve`)

`licli serve` runs a foreground HTTP server (default `127.0.0.1:18001`, override with `--addr`) exposing JSON endpoints for the vehicles/status/travel/control surface. Bind to a loopback address, set `--token`, or pass `--allow-control` to enable the control endpoints.

## MCP server (`mcp`)

`licli mcp` serves the [Model Context Protocol](https://modelcontextprotocol.io) over stdio (default) or Streamable HTTP (`--transport http`, default `127.0.0.1:18002`). It exposes six tools: `vehicles`, `status`, `travel_months`, `travel_month`, `control`, `control_result`. The two `control*` tools are enabled by default under stdio; under `--transport http` they require `--allow-control` or `--token`.

Register it with Claude Code (no install needed):

```bash
claude mcp add licli -- uvx liauto mcp
```

## Configuration

Credentials are stored under the XDG config directory (`~/.config/licli` by default, or `$XDG_CONFIG_HOME/licli`) with `0700` directory and `0600` file permissions:

- `device.json` — activated device + key suite
- `auth.json` — API token, ID token, refresh token, expiry

## Docker Compose deployment

Run the HTTP API server (`serve`) and MCP server (`mcp`) in containers sharing the host config:

```yaml
services:
  licli-api: &licli
    build:
      dockerfile_inline: |
        FROM ghcr.io/astral-sh/uv:python3.13-alpine
        RUN uv tool install liauto
        ENV PATH="/root/.local/bin:$${PATH}"
        ENV XDG_CONFIG_HOME=/config
        ENV LICLI_SERVE_ADDR=0.0.0.0:18001
        ENV LICLI_MCP_ADDR=0.0.0.0:18002
        ENV LICLI_MCP_TRANSPORT=http
        ENTRYPOINT ["liauto"]
    command: ["serve", "--allow-control"]
    ports:
      - "18001:18001"
    environment:
      LICLI_CODE: ${LICLI_CODE:-}
      LICLI_SERVE_TOKEN: ${LICLI_SERVE_TOKEN:-}
    volumes:
      - ${LICLI_CONFIG_DIR:-~/.config/licli}:/config/licli
    restart: unless-stopped

  licli-mcp:
    <<: *licli
    command: ["mcp", "--allow-control"]
    ports:
      - "18002:18002"
```

`licli-api` shares its build, env, volume and restart policy with `licli-mcp` via the `&licli` anchor. Both read the same host credentials (`auth.json` / `device.json` under `~/.config/licli`, or `$LICLI_CONFIG_DIR`). The containers bind non-loopback addresses, so `--allow-control` enables the control endpoints and `LICLI_SERVE_TOKEN` gates them behind a bearer token.
