licli
licli is a CLI for Li Auto vehicle APIs. It covers device activation/login, real-time status, monthly travel history, control commands, an HTTP API server, and an MCP server.
Run it without installing anything (PyPI via uvx, or npm via npx):
alias licli='uvx liauto'
licli help
alias licli='npx -y @liauto/cli'
licli version
Commands
licli activate
licli login
licli vehicles
licli status <VIN>
licli travel <VIN> [YYYY-MM]
licli control <VIN> <action>
licli version
licli serve
licli mcp
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:
export LICLI_CODE=<activation code>
licli login
licli 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 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):
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) in a container sharing the host config:
services:
licli-api:
build:
dockerfile_inline: |
FROM ghcr.io/astral-sh/uv:python3.13-alpine
RUN uv tool install liauto
ENV PATH="/root/.local/bin:${PATH}"
ENTRYPOINT ["liauto"]
command: ["serve", "--addr", "0.0.0.0:18001", "--allow-control"]
ports:
- "18001:18001"
environment:
XDG_CONFIG_HOME: /config
LICLI_SERVE_TOKEN: ${LICLI_SERVE_TOKEN:-}
volumes:
- ${LICLI_CONFIG_DIR:-~/.config/licli}:/config/licli
restart: unless-stopped
The container reads the same credentials as the host (auth.json / device.json under ~/.config/licli, or $LICLI_CONFIG_DIR).