Kia Access for Claude — vehicle status, location, doors, climate, and charging
Kia Access for Claude — vehicle status, location, doors, climate, and charging
This is a well-architected MCP server for controlling Kia vehicles via the Kia Owners API. Authentication and authorization are properly implemented with deferred credential validation, session-based token management, and confirm-gated commands to prevent accidental vehicle actions. However, there are some moderate concerns: the server handles real vehicle control (locks, climate) requiring careful trust boundaries, credentials are stored in plaintext on disk (though intentional per design), and some command endpoints are marked unverified against live vehicles. The codebase quality is high with comprehensive test coverage and proper error handling. Supply chain analysis found 2 known vulnerabilities in dependencies (0 critical, 1 high severity). Package verification found 1 issue.
4 files analyzed · 9 issues found
Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.
This plugin requests these system permissions. Most are normal for its category.
Set these up before or after installing:
Environment variable: KIA_USERNAME
Environment variable: KIA_PASSWORD
Environment variable: KIA_WRITE_MODE
Environment variable: KIA_DEVICE_ID
Add this to your MCP configuration file:
{
"mcpServers": {
"io-github-chrischall-kiaaccess-mcp": {
"env": {
"KIA_PASSWORD": "your-kia-password-here",
"KIA_USERNAME": "your-kia-username-here",
"KIA_DEVICE_ID": "your-kia-device-id-here",
"KIA_WRITE_MODE": "your-kia-write-mode-here"
},
"args": [
"-y",
"kiaaccess-mcp"
],
"command": "npx"
}
}
}From the project's GitHub README.
A Model Context Protocol server that connects Claude to your own Kia vehicle through the Kia Owners API the Kia Access mobile app uses: vehicle status, location, odometer, EV charge state, and confirm-gated door, climate, and charging commands.
[!WARNING] AI-developed project. This codebase was built and is maintained by Claude Code. No human has audited the implementation. Review the code and the tool permissions before pointing it at a real car.
[!CAUTION] This server can move a two-tonne object and can unlock your car. Every command tool is confirm-gated — without
confirm: trueit makes no network call at all and returns a dry-run preview — and door lock/unlock is not even registered unless you opt in withKIA_WRITE_MODE=all. Read Vehicle commands before changing that.
Ask Claude things like:
By using this server you accept that:
loginAttempt) and eventually sets enforceRecaptcha, after which server-side login for that account is impossible. This server therefore never retries a rejected credential — see If login fails.git clone https://github.com/chrischall/kiaaccess-mcp.git
cd kiaaccess-mcp
npm install
npm run build
cp .env.example .env
# Edit .env: KIA_USERNAME, KIA_PASSWORD (and optionally KIA_WRITE_MODE)
.env is gitignored. The server never logs credentials, and no tool ever returns your password.
{
"mcpServers": {
"kiaaccess": {
"command": "npx",
"args": ["-y", "kiaaccess-mcp"],
"env": {
"KIA_USERNAME": "you@example.com",
"KIA_PASSWORD": "your-password",
"KIA_WRITE_MODE": "comfort"
}
}
}
}
Missing credentials do not stop the server from booting — it starts, answers tools/list, and only reports the configuration error when a tool actually needs to call Kia. Run kia_session_status to see what it thinks it has.
Kia challenges every new device with a one-time passcode. This server bootstraps once, stores the resulting remember-me token (rmtoken) under ~/.kiaaccess-mcp/session.json, and from then on mints fresh sessions silently — Kia does not rotate the token and does not challenge again.
Run it through Claude, in this order:
kia_session_status — confirms credentials are present. If it reports hasSession: false, continue.kia_start_login (needs confirm: true) — sends your credentials, returns an otpKey and an xid, plus the masked phone/email Kia has on file.kia_send_otp — pick SMS or EMAIL. The passcode expires in about two minutes.kia_verify_otp — hand it the passcode. The token is stored locally and is deliberately not returned.kia_list_vehicles — confirms the session works and gives you the vehicleKey every other tool takes.To start over (revoked token, changed password, handing the machine on), run kia_forget_session with confirm: true and repeat from step 2.
Do not retry. Kia increments loginAttempt on every rejection and eventually sets enforceRecaptcha, which breaks server-side login for that account permanently. Verify the email and password in the Kia Access app first, fix .env, restart, and only then try again.
KIA_WRITE_MODE decides which command tools are registered at all. This is a structural gate, not a runtime check: a tool that was never registered cannot be invoked by any host permission setting or by an instruction injected into the conversation.
KIA_WRITE_MODE | Registers |
|---|---|
none | Nothing but the read tools and the account tools |
comfort (default) | Climate start/stop and the charging commands |
all | Also kia_lock_doors and kia_unlock_doors |
An unrecognised value fails closed to none and warns on stderr — a typo must never silently grant the ability to unlock a car.
Two more rules hold for every command:
confirm: true there is no network call at all, just a preview of the exact request that would be sent.commandAccepted and stateConfirmed separately. Observed changes took 30–60 seconds.| Tool | Notes |
|---|---|
kia_session_status | Configured? Bootstrapped? Which write mode? No network call, no secrets — the email is masked and the device id truncated. |
kia_start_login | Step 1 of the MFA bootstrap. Confirm-gated, because a rejection has a permanent cost. |
kia_send_otp | Step 2 — delivers the passcode by SMS or EMAIL. |
kia_verify_otp | Step 3 — exchanges the passcode for a stored session. Returns no secret. |
kia_forget_session | Discards the stored token so the bootstrap can be re-run. Local only; confirm-gated. |
kia_export_refresh_token | Returns the rmtoken in plaintext — a full MFA bypass. Exists only to move a session into the hosted connector. Confirm-gated. |
| Tool | Notes |
|---|---|
kia_list_vehicles | Every enrolled vehicle with its vehicleKey, nickname, model, mileage. VINs are masked to the last 6 characters. |
kia_vehicle_status | Cached status: door lock, ignition (ign3 — on an EV engine stays false), the nested climate block, and more with include_raw. Fast, but only as fresh as the last upload. |
kia_refresh_status | Wakes the telematics unit for a fresh reading. Slower, draws a little power, and returns no data itself — read kia_vehicle_status afterwards. |
kia_vehicle_location | Last reported position plus a map link. Not a live GPS fix. |
kia_charge_targets | Target state of charge per plug type. |
| Tool | Mode | Notes |
|---|---|---|
kia_start_climate | comfort | Preconditioning. Temperature is best-effort: the car may report its own last-set target instead of the one requested. |
kia_stop_climate | comfort | Verified by re-reading climate.airCtrl. |
kia_start_charge | comfort | Unverified endpoint — never exercised against a real vehicle, and the outcome cannot be checked. |
kia_stop_charge | comfort | Unverified endpoint. Do not rely on it to stop a charge that matters. |
kia_set_charge_limits | comfort | Unverified endpoint, but this one is re-read and verified afterwards. |
kia_lock_doors | all | Verified by re-reading doorLock. |
kia_unlock_doors | all | Leaves the car physically unsecured. Only run it when the user explicitly asked. |
The four door/climate endpoints and both reads were verified live against a 2024 EV9 on 2026-07-27; the three evc/* command endpoints were not, and every tool that touches one says so in its description and in its result. The full protocol write-up is in docs/KIA-API.md.
The same tools can run as a Cloudflare Worker for use as a remote connector on claude.ai. The MFA bootstrap cannot work there (the passcode arrives minutes later, on another device), so you bootstrap locally, export the token with kia_export_refresh_token, and hand it to the connector's login page, which stores it in your encrypted credentials. See docs/DEPLOY-CONNECTOR.md.
npm test # unit tests (no network — fetch is mocked throughout)
npm run test:coverage # the same, with the enforced 100% thresholds
npm run build # tsc + esbuild bundle
npm run worker:test # the hosted-connector suite, under the Workers runtime
Be the first to review this server!
by Modelcontextprotocol · Developer Tools
Read, search, and manipulate Git repositories programmatically
by Toleno · Developer Tools
Toleno Network MCP Server — Manage your Toleno mining account with Claude AI using natural language.
by mcp-marketplace · Developer Tools
Create, build, and publish Python MCP servers to PyPI — conversationally.