This skill should be used when the user asks about their Kia vehicle through the Kia Access / Kia Owners account. Triggers on phrases like "is the car locked", "unlock the Kia", "start the car's climate", "warm up the car", "where is my car", "what's the EV charge at", "check the car's battery", "lock the doors", or any request to read or command a Kia vehicle.
Documents
kiaaccess-curl
Try itQuery and command a Kia vehicle directly with curl against the Kia Owners API (api.owners.kia.com), without running the MCP server. Use when the user wants a one-off read of their Kia's status, location, or EV charge state, or to lock/unlock/start climate from the shell — "check my Kia", "is the car locked", "what's the EV9 charge", "lock the car from the terminal". Requires KIA_USERNAME/KIA_PASSWORD and a one-time SMS/email MFA bootstrap.
What it does
Query and command a Kia vehicle directly with curl against the Kia Owners API (api.owners.kia.com), without running the MCP server. Use when the user wants a one-off read of their Kia's status, location, or EV charge state, or to lock/unlock/start climate from the shell — "check my Kia", "is the car locked", "what's the EV9 charge", "lock the car from the terminal". Requires KIA_USERNAME/KIA_PASSWORD and a one-time SMS/email MFA bootstrap.
The skill document
Kia Owners API via curl
The Kia Access app's API is reachable server-side — no browser, no bridge, no
extension. This skill talks to it directly with curl.
Prefer the kiaaccess-mcp server for anything conversational or repeated; use
this for one-off shell work, debugging, or when the server isn't running.
Ready-to-run request bodies and jq recipes: references/requests.md.
Full shape reference (verified live): ../../docs/KIA-API.md.
Setup
export KIA_USERNAME='you@example.com'
export KIA_PASSWORD='…'
export KIA_DEVICE=$(uuidgen) # keep this stable across runs
Two rules that will bite you
- Every request needs an RFC-1123
dateheader. Omit it and you geterrorCode 9200 "Missing mandatory data in header"— a message that does not name the culprit. Regenerate it per request; a stale one is rejected. - HTTP is 200 even on failure. Success is
status.statusCode == 0in the body. Never branch on the HTTP code.
Source references/requests.md's kia_headers helper rather than hand-rolling
headers — it handles both.
Auth: one-time MFA, then silent refresh
authUser → sendOTP → verifyOTP yields a sid (session, short-lived)
and an rmtoken (refresh, durable), both as response headers.
Afterwards, authUser with the rmtoken header mints a fresh sid with no
MFA. So you do the SMS dance once and then never again — save the rmtoken.
Never retry a rejected login.
errorCode 1001(bad credentials) or1037(bad email) incrementspayload.loginAttempt; enough failures setenforceRecaptchaand permanently break shell-based login. Fix the credential and try once.
Store the rmtoken at $KIA_SESSION (default ~/.kiaaccess-mcp/curl-session.json)
with chmod 600. It is a credential: it re-authenticates the account without a
password prompt.
Do not write it to
~/.kiaaccess-mcp/session.json. That path belongs to thekiaaccess-mcpserver, whose store is keyed byaccountIdwith a different schema — overwriting it corrupts the server's session and forces it back through MFA.
Calling
Reads and commands take sid (+ vinkey for vehicle-scoped calls). Get the
vinkey from ownr/gvl → payload.vehicleSummary[0].vehicleKey.
| Want | Endpoint |
|---|---|
| vehicles | GET ownr/gvl |
| status (cached) | POST cmm/gvi |
| status (force refresh) | POST rems/rvs |
| EV charge targets | GET evc/gts |
| lock / unlock | GET rems/door/lock / rems/door/unlock |
| climate on / off | POST rems/start / GET rems/stop |
| charge start / stop / limits | POST evc/charge / GET evc/cancel / POST evc/sts |
Confirming a command actually worked
A statusCode: 0 means "accepted", not "done".
- Do not poll
cmm/gts. Despite taking anxid, it returns global flags and never reports per-action completion — polled through a real lock it never changed. - Re-read
cmm/gviand diff the field. That is the only proof. Allow ~30–60s.
Fields to diff:
| Command | Field |
|---|---|
| lock / unlock | vehicleStatus.doorLock |
| climate on / off | vehicleStatus.climate.airCtrl and vehicleStatus.ign3 |
Three traps when writing that comparison:
syncDateadvances on every read. Include it and every command looks successful. Exclude it.- There is no
airCtrlOn. Climate is nested undervehicleStatus.climate, and the whole block is absent unless you requestcmm/gviwithvehicleConfigReq.airTempRange: "1"andseatHeatCoolOption: "1". - On an EV,
enginestaysfalsewith climate running — useign3.
Verification status
Every endpoint here was verified live against a 2024 EV9 — all reads, the door
and climate commands, and (against a plugged-in car) evc/charge, evc/cancel
and evc/sts, each proven by a re-read rather than a 200.
Charging proof fields live under vehicleStatus.evStatus: batteryCharge
(true while charging), batteryStatus (SOC %), batteryPlugin. evc/sts is
proven by re-reading evc/gts.
One caveat: rems/start's temperature may not apply — a start requesting 70
left airTemp.value at 72. Treat it as best-effort.
Related skills
This skill should be used when the user asks about their Kia vehicle through the Kia Access / Kia Owners account. Triggers on phrases like "is the car locked", "unlock the Kia", "start the car's climate", "warm up the car", "where is my car", "what's the EV charge at", "check the car's battery", "lock the doors", or any request to read or command a Kia vehicle.
Put an agent into KAX City and keep it living there — prove your OBC bot, mint an identity token, claim a flat in Standing Wave Residences, move a body in, walk, and talk to the agents standing near you. Use when an agent should BE somewhere in KAX rather than call an API: 'enter the city', 'claim a home', 'who is here', 'say something', 'why can't I move in'. Works over plain HTTP or as an MCP server.
Query and control a SimpliSafe alarm system from the shell with curl — read system state, sensors, locks, events and settings, and arm/disarm or lock/unlock. Use when the user asks about their SimpliSafe alarm, house sensors, door locks, or whether the system is armed. Requires a one-time browser login to mint a refresh token.
Use when working with Auto.dev APIs, vehicle data, VIN decoding, car listings, vehicle photos, specs, recalls, payments, interest rates, taxes, OEM build data, plate-to-VIN, CLI commands, MCP tools, or SDK methods for any automotive data task
Use Keeper Commander CLI and Keeper Secrets Manager workflows when installing Keeper tooling, setting up profiles, signing in, running Keeper interactively,...