LG Washer MCP Server
# LG Washer MCP Server
An [MCP](https://modelcontextprotocol.io) server that lets an AI assistant monitor
and control an LG ThinQ washing machine through LG's official **ThinQ Connect** API.
It talks to the REST API directly over HTTP (no LG SDK). Your **Personal Access
Token (PAT)** is used as a bearer token.
## How the API works (the short version)
- **Auth**: `Authorization: Bearer <PAT>`. No OAuth flow.
- **Region**: your country code picks the server. India (`IN`) → `https://api-kic.lgthinq.com`.
- **Every request** also sends `x-country`, `x-client-id` (a UUID4 you choose),
`x-api-key` (a public key), `x-message-id` (fresh per request), `x-service-phase: OP`.
- **Endpoints**: `GET /devices`, `GET /devices/{id}/profile`, `GET /devices/{id}/state`,
`POST /devices/{id}/control`.
## Tools exposed
| Tool | What it does |
|------|--------------|
| `list_devices` | Find your washer's `deviceId`. |
| `get_washer_profile` | See the controllable properties/values for *your* model. |
| `get_washer_status` | Live state: running?, cycle, time remaining. |
| `control_washer` | `START` / `STOP` / `WAKE_UP`. |
| `control_washer_raw` | Send an arbitrary control JSON for model-specific properties. |
> ⚠️ Most LG washers only accept a remote **START** when the machine is physically
> set to "Remote Start" with a cycle already loaded. The API resumes/starts a
> pre-selected cycle; it usually can't pick a wash program from scratch.
## Setup
```bash
uv sync
cp .env.example .env # then edit .env with your PAT
```
## Run it
Configuration is read from environment variables (`THINQ_PAT`, `THINQ_COUNTRY`,
`THINQ_CLIENT_ID`). The server speaks MCP over stdio.
```bash
THINQ_PAT=xxx THINQ_COUNTRY=IN uv run washer-mcp
```
### Wire into Claude Desktop / Claude Code
Add to your MCP config (e.g. `claude_desktop_config.json`):
```json
{
"mcpServers": {
"lg-washer": {
"command": "uv",
"args": ["--directory", "/Users/sushmanagaraj/c_drive/Coding/LG", "run", "washer-mcp"],
"env": {
"THINQ_PAT": "your-pat-here",
"THINQ_COUNTRY": "IN",
"THINQ_CLIENT_ID": "your-uuid4-here"
}
}
}
}
```
For Claude Code specifically:
```bash
claude mcp add lg-washer --env THINQ_PAT=xxx --env THINQ_COUNTRY=IN -- uv --directory /Users/sushmanagaraj/c_drive/Coding/LG run washer-mcp
```
## Quick manual test (no MCP client needed)
```bash
uv run python -c "import asyncio, os; from washer_mcp.thinq_client import ThinQClient; \
print(asyncio.run(ThinQClient(os.environ['THINQ_PAT'],'IN',os.environ.get('THINQ_CLIENT_ID','test-id')).list_devices()))"
```
TDQS
Scored across 5 tools
Most tools are clearly distinct: listing devices, fetching profile, fetching status, and sending commands all serve different purposes. The only mild overlap is between control_washer and control_washer_raw, but the descriptions make the intended boundary clear.
All tools follow a clean snake_case verb_noun pattern: list_devices, get_washer_profile, get_washer_status, control_washer, control_washer_raw. The naming is consistent and predictable.
Five tools is well-scoped for an LG washer MCP server: discovery, model introspection, status, high-level control, and a raw escape hatch. Each tool earns its place without adding redundancy.
The server covers the core washer workflow: find the device, inspect its capability profile, read live status, and issue commands. The raw control tool helps fill model-specific gaps, though common operations like pause/resume are not explicitly exposed beyond the raw payload path.