This release is a pre-release and may not be stable for production use.
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):
alias licli='uvx liauto'
licli help
# or
alias licli='npx -y @liauto/cli'
licli version
Commands
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:
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). Bind to a loopback address, set --token, or pass --allow-control to enable the control endpoints.
Endpoints:
| Method | Path | Description |
|---|---|---|
| GET | /healthz |
Liveness probe (unauthenticated) |
| GET | /vehicles |
List vehicles; query limit (default 20), offset, refresh=true |
| GET | /vehicles/{vin}/status |
Vehicle state (state, platform, fetched_at, location when available) |
| GET | /vehicles/{vin}/travel |
Travel month history (months) |
| GET | /vehicles/{vin}/travel/{ym} |
One month's detail; {ym} is YYYY-MM |
| POST | /vehicles/{vin}/control |
Send a control command |
| GET | /vehicles/{vin}/control/{requestId} |
Query a prior command's result |
All endpoints except /healthz require Authorization: Bearer <token> when a token is configured. The two control endpoints return 403 control_disabled unless the control gate is open (loopback bind, a configured token, or --allow-control).
POST /control body (strict JSON, unknown fields rejected):
{ "action": "lock", "temp": 22.5, "pos": "front-left", "level": 2, "open": true }
action is one of lock, unlock, find, wake, ac_on, ac_off, ac_auto, ac_temp, ac_fast_cool, ac_fast_heat, seat_vent, seat_heat, wheel_heat, window, trunk. The other fields are per-action; unset fields take the action's default:
| Field | Applies to | Values |
|---|---|---|
temp |
ac_temp |
number, 16–32 |
pos |
seat_vent |
fl | fr |
pos |
seat_heat |
fl | fr | rl | rr |
pos |
window |
fl | fr | rl | rr | all |
level |
seat_vent, seat_heat |
int, 0–3 (0 = off) |
level |
window |
int, 0–99 |
open |
trunk |
bool |
pos is only valid for seat_vent/seat_heat/window; any other action rejects it. Errors use a unified envelope {"ok": false, "error": {"code", "message", "retryable"}}.
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 suiteauth.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:
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.
Release files for liauto 0.1.0b3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| liauto-0.1.0b3-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| liauto-0.1.0b3-py3-none-musllinux_1_2_x86_64.whl | Python 3 | none | Linux musl 1.2+ x86-64 | Details |
| liauto-0.1.0b3-py3-none-musllinux_1_2_aarch64.whl | Python 3 | none | Linux musl 1.2+ ARM64 | Details |
| liauto-0.1.0b3-py3-none-manylinux_2_17_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| liauto-0.1.0b3-py3-none-manylinux_2_17_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details |
| liauto-0.1.0b3-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
| liauto-0.1.0b3-py3-none-macosx_10_9_x86_64.whl | Python 3 | none | macOS 10.9+ x86-64 | Details |
Total release size: 48.0 MB
Release files / liauto-0.1.0b3-py3-none-win_amd64.whl
| Download URL | liauto-0.1.0b3-py3-none-win_amd64.whl |
|---|---|
| Size | 7.7 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
0b2a27f87e068412bd8b4759a83dbd36c49b91fcf6bfbcaf8643bf484dd60893
|
|
BLAKE2b-256 checksum How to use checksums |
5dd52dd46ac0bd183d4027fb8b18f37b4329223f655010ae21bf4363a739da29
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / liauto-0.1.0b3-py3-none-musllinux_1_2_x86_64.whl
| Download URL | liauto-0.1.0b3-py3-none-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 7.0 MB |
| Tags | Linux musl 1.2+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
3b8614e2328599b55631f66eb0edadee70209c3fbd29599b3cbb6cd11ef525af
|
|
BLAKE2b-256 checksum How to use checksums |
80d76b6d2e09ebc3ee6b974c98822a75badf8f66672f699bb92aa061fbeafa19
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / liauto-0.1.0b3-py3-none-musllinux_1_2_aarch64.whl
| Download URL | liauto-0.1.0b3-py3-none-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 6.3 MB |
| Tags | Linux musl 1.2+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
3a0bb9081662232c329f04b42826bff5c0b39c78a778e0ceb417bd65e05bb381
|
|
BLAKE2b-256 checksum How to use checksums |
399c4e0d336e51222254c5df585cd7f5b208ebba12de257c943c79025ef07490
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / liauto-0.1.0b3-py3-none-manylinux_2_17_x86_64.whl
| Download URL | liauto-0.1.0b3-py3-none-manylinux_2_17_x86_64.whl |
|---|---|
| Size | 7.0 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
cc16416582b002f510fd979f2c26d97a0fd63514f8c9da8553ba33ab519c7812
|
|
BLAKE2b-256 checksum How to use checksums |
31739e12deb6f403937b3b190539d37edb088ae1411e272c03daf1af48b799b5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / liauto-0.1.0b3-py3-none-manylinux_2_17_aarch64.whl
| Download URL | liauto-0.1.0b3-py3-none-manylinux_2_17_aarch64.whl |
|---|---|
| Size | 6.3 MB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
5987f13e4b0fd9b87c487fdb62c771a4f43fe44751b17702677b7398fe297bd7
|
|
BLAKE2b-256 checksum How to use checksums |
cfb1a3cfca9bfb8b3ac48e0c91af0b9019f1e917f8e5b47d9e883cc3003cce8a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / liauto-0.1.0b3-py3-none-macosx_11_0_arm64.whl
| Download URL | liauto-0.1.0b3-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 6.6 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
6014e21c9142b9ea6f83719c132567f6167acd40a74927a8e6132b83abb3e93f
|
|
BLAKE2b-256 checksum How to use checksums |
7c7b4b9c4b429c939a33054ac94676c4ba6b302cc925651c0460adaa5ed5e2e7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / liauto-0.1.0b3-py3-none-macosx_10_9_x86_64.whl
| Download URL | liauto-0.1.0b3-py3-none-macosx_10_9_x86_64.whl |
|---|---|
| Size | 7.1 MB |
| Tags | Python 3 macOS 10.9+ x86-64 |
|
SHA-256 checksum How to use checksums |
b57addab1afc3b5bd70e69a74dc1d1093cecd7fe2244f29d664f8248c8b7caa6
|
|
BLAKE2b-256 checksum How to use checksums |
dc7fd0a0342fe9c6dc4e610c89ad28b221a38989b044a71fc15edbca340a6adb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|