Skip to main content
Glama

Kia Access MCP

CI npm license

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 confirmation-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 asks you to confirm before it acts — with a confirmation prompt where the client supports one, otherwise a preview plus a one-time token that only a repeat call can use (see Confirmations) — and door lock/unlock is not even registered unless you opt in with KIA_WRITE_MODE=all. Read Vehicle commands before changing that.

What you can do

Ask Claude things like:

  • "Is the EV9 locked, and what's the charge at?"

  • "Warm the car up to 72 for ten minutes"

  • "Where did I leave the car?"

  • "Refresh the car's status, then tell me the odometer"

Related MCP server: Tesla MCP Server

Requirements

  • Node.js 22.5 or later

  • A Kia Owners / Kia Access account with an enrolled vehicle, and its password

  • A phone or mailbox you can read once, for the one-time MFA passcode

Acknowledgement of terms

By using this server you accept that:

  1. It uses your own Kia account credentials to talk to the same private API the Kia Access app uses. It cannot reach anyone else's vehicle or account.

  2. Kia's terms govern your use of it, exactly as they govern your use of the app. This is not an official or supported integration and is not affiliated with, endorsed by, or sponsored by Kia.

  3. Commands act on a real vehicle in the physical world. Unlocking leaves the car unsecured until someone locks it; climate preconditioning runs the HVAC and draws power. You are responsible for every command you confirm.

  4. Failed logins have a permanent cost. Kia counts them (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.

Installation

1. Clone and build

git clone https://github.com/chrischall/kiaaccess-mcp.git
cd kiaaccess-mcp
npm install
npm run build

2. Configure credentials

cp .env.example .env
# Edit .env: KIA_USERNAME, KIA_PASSWORD (and optionally KIA_WRITE_MODE,
#            KIA_DEVICE_ID, KIA_RMTOKEN, KIA_REQUEST_TIMEOUT_MS — see .env.example)

.env is gitignored. The server never logs credentials, and no tool ever returns your password.

3. Register with Claude Code

{
  "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.

The one-time MFA bootstrap

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:

  1. kia_session_status — confirms credentials are present. If it reports hasSession: false, continue.

  2. kia_start_login (asks you to confirm first) — sends your credentials, returns an otpKey and an xid, plus the masked phone/email Kia has on file.

  3. kia_send_otp — pick SMS or EMAIL. The passcode expires in about two minutes.

  4. kia_verify_otp — hand it the passcode. The token is stored locally and is deliberately not returned.

  5. kia_list_vehicles — confirms the session works and gives you the vehicleKey every other tool takes (as its vehicle_key argument).

To start over (revoked token, changed password, handing the machine on), run kia_forget_session (asks you to confirm first) and repeat from step 2.

Running it somewhere with no phone to read

The bootstrap needs a human once. A deployment that has no one to read an OTP — a remote host — cannot run it at all, so bootstrap on a machine that can and move the token:

  1. Set KIA_DEVICE_ID to a fixed uuid before the bootstrap, on both machines. The rmtoken is minted against a device uuid and is worthless with a different one, and kia_session_status only ever reports a truncated prefix — so if you let it be generated, you cannot read back the value you need.

  2. Bootstrap as above, then copy the rmtoken value out of ~/.kiaaccess-mcp/session.json yourself, in a terminal. No tool returns it: the token is a long-lived MFA bypass, so it is never put into a conversation.

  3. Give the remote deployment that value as KIA_RMTOKEN, alongside KIA_USERNAME, KIA_PASSWORD and the same KIA_DEVICE_ID.

KIA_RMTOKEN takes precedence over anything in the local session store, so the deployment's session is whatever you handed it rather than whatever it last wrote. Treat the value like the password it stands in for: it bypasses MFA, and with the account password it grants full control of the vehicle.

If login fails

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.

Vehicle commands

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:

  • Confirmation-gated. Nothing is sent until you confirm. The confirmation shows the exact request that would be sent; until then there is no network call at all. See Confirmations.

  • Accepted is not confirmed. Kia answering "success" only means the request was accepted. The only proof a command took effect is re-reading the vehicle and diffing the field, so results report commandAccepted and stateConfirmed separately. Observed changes took 30–60 seconds.

Confirmations

Every write tool (the commands above, plus kia_start_login and kia_forget_session) asks you to confirm before it acts. A client that can show a confirmation prompt (Claude Code) shows one, with the exact request. A client that cannot (claude.ai, Claude Desktop) gets a two-step flow instead: the first call does nothing and returns a preview plus a confirmToken, and only a repeat call carrying that token proceeds. The token is bound to the exact request previewed — change an argument and it is refused (DRAFT_CHANGED) with a fresh preview; use it twice and the second call is refused (TOKEN_REUSED).

variable

default

MCP_CONFIRM_MODE

ask-user

What a write does on a client that cannot show a confirmation prompt (claude.ai, Claude Desktop). ask-user: two steps — the first call does nothing and returns a preview plus a token, and the model must get your approval in chat before calling again with it. auto: the same two steps, but the model may use the token after reviewing the preview itself. refuse: writes are refused on such clients. A client that can show prompts (Claude Code) always gets the real prompt, unless MCP_CONFIRM_ELICITATION=off. An unrecognised value is treated as refuse.

MCP_CONFIRM_ELICITATION

on

off never shows a confirmation prompt, so every client gets the MCP_CONFIRM_MODE behaviour. Set it for a client that says it can show prompts but never does (the write hangs — opencode 2.0.x). Any other value is treated as on, with a warning on stderr.

MCP_CONFIRM_TTL_SECONDS

600

How long a token stays valid.

MCP_CONFIRM_SECRET

random per process

Signing key; set it only if tokens must survive a server restart.

MCP_HOST_CONFIRM_SECRET

unset

Set by mcp-host for this registration (it has a data dir). Used when MCP_CONFIRM_SECRET is unset and MCP_DATA_DIR is absolute: a token survives the hosted child idling out between the preview and the confirmed call, and spent tokens are recorded under the data dir so a restart cannot re-accept one.

Tools

Account and session

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. Confirmation-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; confirmation-gated.

Reads

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.

Commands

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

Verified. Needs the car plugged in — unplugged, Kia accepts the request and nothing happens. Confirm via evStatus.batteryCharge.

kia_stop_charge

comfort

Verified. Confirm via evStatus.batteryCharge.

kia_set_charge_limits

comfort

Verified, and re-read against evc/gts afterwards. Send both plug types — the list replaces the stored one.

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.

Every endpoint here was verified live against a 2024 EV9 — the reads and the four door/climate commands on 2026-07-27, and the three evc/* charging commands on 2026-07-28 against a plugged-in car. Each was proven by re-reading state, never by the success status: Kia answers statusCode: 0 the moment it accepts a command, seconds before the car acts, and on an unplugged car it answers success and does nothing at all. Every command result therefore reports "accepted" and "confirmed" separately. The full protocol write-up is in docs/KIA-API.md.

Development

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

License

MIT

Available Tools

16 tools
kia_charge_targetsA
Read-only

Read the EV charge targets (evc/gts): the target state of charge per plug type (one entry for AC, one for DC). Verified live against a real vehicle. Read-only — makes no changes.

ParametersJSON Schema
NameRequiredDescriptionDefault
vehicle_keyYesVehicle key (the `vehicleKey` from the vehicle-list tool). Not the VIN. Required: charging tools never default to the only vehicle.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered; the description usefully reinforces it ('makes no changes') and adds real context the annotations cannot — that the values are verified against a live vehicle and that the payload is one entry per plug type (AC/DC). It does not mention auth/session prerequisites, but the added return-shape and live-verification detail is meaningful.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short clauses, front-loaded with the verb and resource before the payload detail and the read-only reassurance. No filler sentences; every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description partially compensates by describing the return contents (one entry per plug type for AC/DC). Combined with annotations covering read-only/open-world and a fully documented single parameter, an agent has enough to call it correctly, though field-level return detail and session/auth behavior remain implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% — vehicle_key is fully documented in the schema, including the crucial 'not the VIN' and 'never defaults to the only vehicle' notes. The description adds nothing about parameters, which is the expected baseline when the schema does the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a precise verb and resource ('Read the EV charge targets') and names the underlying endpoint (`evc/gts`), then specifies exactly what is returned: target state of charge per plug type, one entry for AC and one for DC. This is clearly distinguishable from the mutation sibling kia_set_charge_limits and from the broader status tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the framing ('Read the EV charge targets') and the closer 'Read-only — makes no changes' signals it is the inspection half of the charge-limit pair. However, it never explicitly says when to reach for this versus kia_set_charge_limits or kia_session_status, and gives no prerequisites beyond the schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_forget_sessionA
Idempotent

Discard the locally stored Kia session (the remember-me token), so the next Kia call needs the one-time MFA bootstrap again. This is the recovery path when the stored token no longer works — Kia revoked it, the password changed, or the account moved to another device — and the only alternative is deleting the session file by hand. It makes NO network call: Kia is not told anything, only this machine forgets. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call makes NO network call and returns a preview plus a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE). Nothing is deleted until it is confirmed.

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate idempotentHint=true and destructiveHint=false, but the description goes beyond by stating it makes NO network call and includes a confirmation step, which is critical behavioral context. Some ambiguity about the confirmation flow (client-dependent) is acknowledged, but the description handles this well.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is verbose but each sentence carries essential information about system behavior and confirmation. It could be tightened slightly, but given the complexity of the confirmation protocol and the need to prevent misuse, the length is justified.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has only one parameter, no output schema, and the description covers all necessary information: what the tool does, when to use it, the confirmation flow, and the absence of network calls. Nothing critical is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description adds crucial semantics for confirmToken: it explains when to use it (two-step fallback), when not to use it (never on first call, never invented), and the lifecycle (passed back after user approval). This goes beyond just 'only for confirmation' to cover the exact protocol.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific resource (locally stored Kia session/remember-me token) and the action (discard). It also differentiates from siblings by stating the only alternative (manual file deletion) and the recovery context (token revoked, password changed).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly describes when to use this tool (when stored token no longer works due to revocation, password change, or device change) and what it does NOT do (makes no network call, Kia is not told). It also mentions the alternative (manual file deletion) and the confirmation flow, providing clear usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_healthcheckVerify credentials and upstream reachabilityA
Read-onlyIdempotent

Resolves the credential the way real tools do, then makes one authenticated request to Kia Connect. Reports which source supplied the credential, whether Kia Connect accepted it, the round-trip time, and a plain-English hint distinguishing 'no credential' from 'credential rejected' from 'a Kia Connect-side problem'. Read-only; never returns the credential itself. Call this when a real tool fails and you want to know which hop broke.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnly, idempotent, and openWorld hints, but the description adds meaningful behavioral detail beyond those: it states that exactly one authenticated request is made, that the credential itself is never returned, and that the output classifies failure modes ('no credential' vs 'credential rejected' vs 'Kia Connect-side problem'). This gives agents a clear safety and side-effect profile not available from the annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is ~100 words, front-loads the core action, then reports the output, then the read-only/security note, and ends with the usage trigger. Every sentence carries distinct information; no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by detailing what the tool reports (credential source, acceptance, RTT, hint) and what it never returns. Combined with the input-free schema and annotations, an agent has all necessary information to invoke this tool correctly and interpret its result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and the schema coverage is 100%, so there are no parameter semantics to explain. The baseline of 4 applies, and the description accurately avoids inventing any parameter-related content.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Resolves the credential... makes one authenticated request to Kia Connect') and enumerates the exact outputs (credential source, acceptance, RTT, plain-English hint). It also positions itself against siblings via 'Call this when a real tool fails' and its read-only diagnostic nature, clearly distinguishing it from vehicle command, auth-flow, and session tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear trigger condition: 'Call this when a real tool fails and you want to know which hop broke.' This is strong when-to-use guidance. It does not explicitly name alternatives or state when-not-to-use, but the diagnostic purpose is unambiguous in context with the sibling list.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_list_vehiclesA
Read-onlyIdempotent

List the vehicles enrolled on this Kia Owners account (ownr/gvl). Returns each vehicleKey — the id every other Kia tool takes — plus nickname, model year/name/trim, mileage, fuel type and telematics unit. VINs are masked to their last 6 characters.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnly, openWorld, and idempotent hints. The description adds useful context like VIN masking and the list of returned fields, which goes beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences that front-load the purpose and key outputs, with no unnecessary words or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given zero parameters and no output schema, the description fully explains the tool's behavior, including what fields are returned and the VIN masking policy.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With zero parameters, the baseline is 4. The description adequately explains that no input is needed, and schema coverage is 100%, so no further param info is required.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'List the vehicles enrolled on this Kia Owners account' with a specific verb and resource, and distinguishes itself from sibling tools by highlighting that it returns the vehicleKey needed by other tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies that this tool is a prerequisite because it returns 'the id every other Kia tool takes,' but it does not explicitly state when to use versus alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_refresh_statusA

Ask the car for a fresh reading (rems/rvs, requestType 0). This WAKES THE TELEMATICS UNIT, so it is much slower than kia_vehicle_status and draws a little power — prefer the cached read unless staleness matters. Kia only acknowledges the request; it does not return the new data and gives no completion signal, so read kia_vehicle_status afterwards to see the refreshed values.

ParametersJSON Schema
NameRequiredDescriptionDefault
vehicle_keyNovehicleKey from kia_list_vehicles. Optional: defaults to the only vehicle when the account has exactly one.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by disclosing real-world side effects: it wakes the telematics unit, is much slower, draws power, and — critically — Kia only acknowledges the request with no completion signal and no returned data. That is exactly the kind of non-obvious behavior an agent would otherwise get wrong.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with what the tool does and the cost of calling it, then the awkward acknowledgement-only behavior, then the required follow-up. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description compensates by explaining precisely what comes back (only an acknowledgement) and what the agent must do next. Combined with the scoping guidance and cost warning, an agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already documents vehicle_key including the single-vehicle default, so the description need not repeat it. The description adds no parameter-level detail of its own; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('ask the car for a fresh reading') and even names the underlying protocol call (rems/rvs, requestType 0). It explicitly positions itself against kia_vehicle_status, so the agent can distinguish the two without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit decision rule: 'prefer the cached read unless staleness matters,' naming the exact alternative tool and the condition that selects this one. It also instructs the follow-up read (kia_vehicle_status afterwards), leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_send_otpA
Destructive

Step 2 of the Kia MFA bootstrap (cmm/sendOTP): deliver a one-time passcode to the account by SMS or email. Takes the otpKey and xid from kia_start_login — it cannot run without them, which is why it has no separate confirmation gate. Ask the user which channel they want (kia_start_login reports the masked destinations Kia has on file). The passcode expires in about two minutes; expiresAt reports when.

ParametersJSON Schema
NameRequiredDescriptionDefault
xidYesThe `xid` returned by kia_start_login. Sent with every OTP call.
otpKeyYesThe `otpKey` returned by kia_start_login.
notifyTypeYesDelivery channel. Ask the user; do not guess which destination they can read right now.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds behavioral context beyond annotations: it notes the passcode expires in about two minutes and that expiresAt reports when, and that it lacks a separate confirmation gate. The annotation destructiveHint=true indicates potential side effects, but the description does not contradict this. However, it doesn't elaborate on the destructive nature (e.g., sending SMS may incur costs), so minor gap remains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise but rich: it conveys the step, dependencies, user interaction, expiration, and reporting in four sentences. It is front-loaded with the purpose and dependency, making it easy to scan. Every sentence adds value, and there is no fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the key aspects: prerequisites (otpKey, xid), user interaction (ask channel), expiration, and result (expiresAt). With no output schema, it hints at the response containing expiresAt, which is useful. It could mention error handling or what happens if the OTP is not sent, but for a step in a multi-step flow, it's sufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with each parameter already described. The tool description reinforces the dependency on otpKey and xid from kia_start_login, adding slightly more context about their source. For notifyType, it reiterates the instruction to ask the user, aligning with the schema. Since the schema is thorough, the added value is modest but not redundant.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it is 'Step 2 of the Kia MFA bootstrap (cmm/sendOTP)' and that it delivers a one-time passcode via SMS or email. It distinguishes itself from kia_start_login and kia_verify_otp by explicitly referencing the flow order, making its purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says it 'cannot run without' the otpKey and xid from kia_start_login, making the dependency clear. It also instructs the agent to ask the user which channel to use and not to guess, which is crucial for correct usage. It does not explicitly name alternatives, but given the MFA bootstrap context, it's evident when to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_session_statusA
Read-onlyIdempotent

Whether this server is configured and logged in to Kia: are credentials present, has the one-time MFA bootstrap been completed on this device, and which vehicle commands are registered (KIA_WRITE_MODE). Makes NO network call and returns no secret — the account email is masked, the device id is truncated, and neither the session id nor the remember-me token is ever included. Start here when a Kia tool reports it is not configured.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond annotations (readOnlyHint, idempotentHint), the description adds that the tool makes no network call, returns no secret, masks sensitive data (email, device id), and never includes session id or remember-me token. This fully discloses behavior without contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with purpose, then security details. Every word is valuable, no redundancy. Highly concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given zero parameters and no output schema, the description fully covers the tool's purpose, behavior, security posture, and usage context. No gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With zero parameters and 100% schema coverage, the description does not need to add parameter info. It focuses on the output behavior, which is appropriate. Baseline 4 for zero parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool checks server configuration and login status for Kia, including credentials, MFA bootstrap, and registered commands. It distinguishes itself by noting it makes no network call and returns no secret, setting it apart from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Start here when a Kia tool reports it is not configured,' providing clear guidance on when to use this tool. It does not explicitly mention when not to use it, but the context is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_set_charge_limitsA
Idempotent

Set the target state of charge per plug type (evc/sts). Verified against a real vehicle. The write is checked: afterwards the targets are re-read from evc/gts and compared, and the result reports whether the change actually landed. Send BOTH plug types — the list replaces the stored one, so omitting an entry drops that target. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call makes NO network call and returns a preview plus a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE). The preview step makes no call at all, not even the baseline read.

ParametersJSON Schema
NameRequiredDescriptionDefault
verifyNoRe-read evc/gts afterwards to check the change landed. Defaults to true.
targetsYesOne entry per plug type. Read the current targets first and change only what you mean to.
vehicle_keyYesVehicle key (the `vehicleKey` from the vehicle-list tool). Not the VIN. Required: charging tools never default to the only vehicle.
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false, idempotentHint=true, destructiveHint=false, but the description adds substantial context beyond them: the write is verified by re-reading evc/gts and reporting whether it landed, the list REPLACES stored state (a destructive-in-effect REPLACE semantic that annotations don't capture), and the preview phase makes no network call at all. The confirmation behavior is fully disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose and the verified-write fact, then the mutation-vs-replace warning, then the confirmation flow. Every sentence earns its place, though the confirmation section is dense and could be more skimmable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a mutation tool with no output schema and complex two-phase confirmation, the description covers everything an agent needs: scope, replace semantics, verification, and the exact confirmation protocol including the preview/confirmToken fallback. Nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value by explaining the REPLACE semantics of the targets list and the two-phase confirmToken flow, which are not fully conveyed by the schema alone. It doesn't restate parameter syntax (the schema handles that), so it doesn't reach 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a precise verb+resource: 'Set the target state of charge per plug type'. It also ties the write to the underlying evc/sts path, which distinguishes it from the read-side sibling kia_charge_targets (which reads evc/gts). An agent can differentiate this from kia_charge_targets without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit guidance on when and how: 'Send BOTH plug types — the list replaces the stored one, so omitting an entry drops that target.' It also delineates the confirmation flow (client prompt vs two-step confirmToken fallback) and warns that the first call makes no network call. This is unusually thorough routing information.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_start_chargeA
Idempotent

Ask the vehicle to start charging (evc/charge). Verified against a plugged-in vehicle: evStatus.batteryCharge goes true within ~30-60s. Requires the car to be plugged in — on an unplugged car Kia still accepts the request and nothing happens. Confirm with kia_vehicle_status rather than trusting the success status. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call makes NO network call and returns a preview plus a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

ParametersJSON Schema
NameRequiredDescriptionDefault
chargeRatioNoCharge up to this percentage, 10–100. Defaults to 100.
vehicle_keyYesVehicle key (the `vehicleKey` from the vehicle-list tool). Not the VIN. Required: charging tools never default to the only vehicle.
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover safety (non-destructive, idempotent) but the description adds high-value behavior the annotations can't: silent no-op on unplugged vehicles, ~30-60s latency before evStatus.batteryCharge flips, and unreliable success status. It also explains the confirmation flow (preview + confirmToken, or elicitation). Minor gap: doesn't state auth/session requirements beyond the confirmation note.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and the API endpoint, then verification conditions and confirmation flow. Dense but well-organized; the confirmation paragraph is slightly long but justified by a non-obvious two-phase behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the mutation's non-obvious risks (silent no-op, flaky success signal) and the async confirmation mechanism, which is the main thing an agent could get wrong. A note on auth/session prerequisites would complete it, but it is otherwise complete for a 3-param write tool with no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so vehicle_key, chargeRatio (10-100, default 100), and confirmToken are already fully documented in the schema. The description mentions confirmToken behavior, which is the schema's own text, so it adds no new semantic detail. Baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource ('start charging') with the underlying API endpoint named (evc/charge), which distinguishes it cleanly from kia_stop_charge and kia_set_charge_limits.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit prerequisites (car must be plugged in, and that an unplugged car silently no-ops), plus explicit routing: confirm via kia_vehicle_status rather than trusting success.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_start_climateA
Idempotent

Start remote climate control / preconditioning (Kia rems/start, live-verified). Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call makes NO network call and returns a preview plus a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE). Once confirmed it sends the command and re-reads cmm/gvi until the NESTED climate.airCtrl reads true (there is no flat airCtrlOn field). On an EV engine stays false while climate runs — ign3 is the ignition proxy and is reported alongside. commandAccepted (Kia took the request) and stateConfirmed (the car actually reads running) are separate; state changes were observed to take 30–60s. TEMPERATURE IS BEST-EFFORT AND UNCONFIRMED: per docs/KIA-API.md a start requesting 70°F still read back 72°F, so the car may report its own last-set target rather than the requested one — do not promise the user a specific cabin temperature. Seat and steering-wheel/rear-window heating are not sent at all: the request body deliberately omits heatVentSeat (Kia validates seat capability per car) and leaves every heatingAccessory field at 0.

ParametersJSON Schema
NameRequiredDescriptionDefault
defrostNoRun front defrost (default false).
temperatureNoTarget cabin temperature in °F, 62–82, or the sentinel "LOW"/"HIGH" for the ends of the range (default 70). A quoted whole number ("72") is accepted and treated as the number. BEST-EFFORT / UNCONFIRMED — see docs/KIA-API.md.
vehicle_keyYesThe vehicle key (`vehicleKey` from the vehicle-list tool), used as the `vinkey` header. Not the VIN. Required: commands never default to the only vehicle, so every request names the car it acts on.
waitSecondsNoHow long to keep re-reading cmm/gvi for proof the command landed (default 30). Observed changes took 30–60s, so an unconfirmed result is common — re-read the vehicle status rather than re-sending the command. Values above ~45 can outlast an MCP client's own request timeout (often 60s), which then reports a failure for a command that WAS sent. 0 checks once and returns immediately — the command may still land afterwards.
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.
durationMinutesNoMinutes the ignition stays on (default 5).

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes far beyond the annotations: discloses the 30–60s state-change lag, that commandAccepted and stateConfirmed are distinct, that waitSeconds can outlast a client timeout and report false failure, that the confirmable two-step preview makes no network call, and that seat/steering/rear-window heating are deliberately omitted. Annotations only cover safety hints, so this context is highly valuable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the purpose and confirmation flow, but the final sentence about omitted heating fields is long and the doc-reference caveats accrete. Most sentences earn their place, though it leans dense with parenthetical asides.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers everything needed to invoke correctly: confirmation mechanics, polling behavior, timeout pitfalls, misleading field names (no flat airCtrlOn, ign3 as ignition proxy on EVs), and the best-effort temperature caveat. No output schema exists, and the description adequately describes what to expect back.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so the baseline is 3, but the description adds real meaning the schema lacks: temperature is best-effort/unconfirmed (70°F read back as 72°F), waitSeconds can outlive a client timeout and the correct recovery is re-reading status rather than re-sending, and confirmToken must only be passed after explicit user approval. It doesn't re-explain vehicle_key, which the schema already covers.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names the specific verb+resource (start remote climate control / preconditioning) and pins it to the Kia rems/start endpoint. It is unambiguous against siblings like kia_stop_climate, and it names the nested field (climate.airCtrl) that defines success.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the confirmation flow and how to proceed when a client lacks elicitation (preview + confirmToken then repeat). It doesn't explicitly compare against kia_stop_climate or state when the user would want climate preconditioning versus charging, but the operational when-to-use guidance is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_start_loginA
Destructive

Step 1 of the ONE-TIME Kia MFA bootstrap (prof/authUser): send the configured credentials and get back the otpKey and xid the next two steps need. Only needed when kia_session_status reports hasSession:false — once the bootstrap is done the stored remember-me token refreshes sessions silently forever. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call makes NO network call and returns a preview plus a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE). The gate is real: Kia counts failed logins and eventually enforces reCAPTCHA, which breaks server-side login for this account PERMANENTLY — so a rejection is never retried, and a wrong password must be fixed in the environment rather than guessed at.

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description reveals a two-phase confirmation flow, no network call on first invocation in fallback mode, and a severe failure mode: failed logins can trigger reCAPTCHA that permanently breaks server-side login. It explains that rejections are never retried, which is exactly the kind of context annotations alone cannot provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence carries necessary risk or flow information. It front-loads the purpose and usage condition before explaining the confirmation fallback and consequences, and uses the warning at the end to justify caution without padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter tool with no output schema, the description covers the trigger condition, expected return values (otpKey, xid, preview, confirmToken), the repeat-call protocol, and the high-consequence failure behavior. There is no critical gap an agent would need in order to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already describes confirmToken in detail, so the baseline is 3. The description adds meaning by tying the token to the two-step confirmation mode, noting it is ignored when the client supports elicitation, and reinforcing that a repeat call must use the same arguments. This clarifies when and how the parameter should be used.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: Step 1 of the Kia MFA bootstrap, sends configured credentials, and returns otpKey plus xid for the next two steps. This clearly distinguishes it from sibling session/token tools like kia_session_status and kia_send_otp.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states explicitly that the tool is only needed when kia_session_status reports hasSession:false and that the bootstrap happens once, after which the stored remember-me token refreshes sessions silently. The confirmation requirement is also described, eliminating ambiguity about when a second call may occur.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_stop_chargeA
Idempotent

Ask the vehicle to stop charging (evc/cancel). Verified against a charging vehicle: evStatus.batteryCharge goes false within ~30-60s. Confirm with kia_vehicle_status rather than trusting the success status. Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call makes NO network call and returns a preview plus a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE).

ParametersJSON Schema
NameRequiredDescriptionDefault
vehicle_keyYesVehicle key (the `vehicleKey` from the vehicle-list tool). Not the VIN. Required: charging tools never default to the only vehicle.
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: documents the observed latency (~30-60s until evStatus.batteryCharge flips false), warns that the success status is not trustworthy, and explains the two-phase confirmation fallback where the first call makes NO network call. The idempotent/destructive hints are consistent with this narrative.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action and endpoint, then layered verification and confirmation detail. Dense but every sentence carries new information; only slight length cost from the parenthetical about MCP_CONFIRM_MODE.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description must cover return behavior, and it does: it describes the phase-1 'confirmation-required' preview plus confirmToken and the eventual charging state change. An agent has everything needed to call and verify correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters (vehicle_key, confirmToken) are already thoroughly documented in the schema. The description restates the confirmToken flow and the MCP_CONFIRM_MODE mechanism, which adds framing but little syntax the schema lacks; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Ask the vehicle to stop charging') and even names the underlying endpoint (`evc/cancel`). It is unambiguously distinguishable from the sibling kia_start_charge / kia_start_climate tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit post-call guidance: verify with kia_vehicle_status instead of trusting the success status, and it spells out when the confirmation prompt applies and how the no-elicitation fallback works. It does not explicitly contrast with start_charge, but the operational context is clear enough to act on.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_stop_climateA
Idempotent

Stop remote climate control (Kia rems/stop, live-verified). Asks the user to confirm first: a confirmation prompt where the client supports one; otherwise the first call makes NO network call and returns a preview plus a confirmToken, and only a repeat call with that token proceeds (see MCP_CONFIRM_MODE). Once confirmed it sends the command and re-reads cmm/gvi until the NESTED climate.airCtrl reads false (there is no flat airCtrlOn field); ign3 — the EV ignition proxy — is reported alongside. commandAccepted (Kia took the request) and stateConfirmed (the car actually reads stopped) are separate. State changes were observed to take 30–60s.

ParametersJSON Schema
NameRequiredDescriptionDefault
vehicle_keyYesThe vehicle key (`vehicleKey` from the vehicle-list tool), used as the `vinkey` header. Not the VIN. Required: commands never default to the only vehicle, so every request names the car it acts on.
waitSecondsNoHow long to keep re-reading cmm/gvi for proof the command landed (default 30). Observed changes took 30–60s, so an unconfirmed result is common — re-read the vehicle status rather than re-sending the command. Values above ~45 can outlast an MCP client's own request timeout (often 60s), which then reports a failure for a command that WAS sent. 0 checks once and returns immediately — the command may still land afterwards.
confirmTokenNoONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 "confirmation-required" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (non-destructive, idempotent, open-world), but the description goes well beyond: the confirm-gating behavior, the distinction between commandAccepted and stateConfirmed, the nested climate.airCtrl field vs. the non-existent airCtrlOn, the ign3 EV ignition proxy, and the observed 30–60s state-change latency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It's a dense paragraph but every sentence carries operational weight: confirmation flow, field names, accepted-vs-confirmed distinction, and timing. It is front-loaded with the core action and endpoint. Slightly long, but no filler sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although there is no output schema, the description supplies the critical post-command behavior (re-reading cmm/gvi, nested airCtrl field, commandAccepted vs stateConfirmed) and latency that an agent needs to interpret results correctly. Nothing essential for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: confirmToken is only for the fallback flow and must never be reused or invented, and waitSeconds relates to the 30–60s observed propagation. The parameter semantics are reinforced rather than merely repeated.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource — 'Stop remote climate control' — names the exact Kia endpoint (rems/stop), and implicitly distinguishes itself from the sibling kia_start_climate. An agent can identify the tool's job without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly explains when the confirmation flow applies: elicitation clients get a prompt, others get a no-network preview plus confirmToken, and a repeat call is required. It doesn't explicitly contrast with kia_start_climate or failure-recovery alternatives, but the confirm-mode branching is thorough contextual guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_vehicle_locationA
Read-onlyIdempotent

The vehicle's last known location, from the location block of the cached cmm/gvi read. This is where the telematics unit last reported being, not a live GPS fix — run kia_refresh_status first for a recent one. Latitude/longitude and a map link are derived when the block carries coord.lat/coord.lon; otherwise the raw block is returned as-is (its exact field names are not verified).

ParametersJSON Schema
NameRequiredDescriptionDefault
vehicle_keyNovehicleKey from kia_list_vehicles. Optional: defaults to the only vehicle when the account has exactly one.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover readOnly/openWorld/idempotent, but the description adds real behavioral context beyond them: data provenance (cached cmm/gvi read), staleness, the conditional derivation path when coord.lat/coord.lon exist, the raw-block fallback, and an honest caveat that the raw block's field names are unverified.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences with no filler, and the most decision-relevant fact (cached, not live) is front-loaded. It is a bit long for a one-parameter read tool, but every clause adds distinct information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description must explain return values - and it does, covering both the derived lat/lon plus map link case and the raw-block fallback, including the uncertainty about field names. Nothing an agent needs to interpret the result is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and vehicle_key is fully documented in the schema (including the single-vehicle default), so the description carries no additional parameter information. Baseline 3 applies when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a precise verb+resource - returns the vehicle's last known location - and immediately scopes it as coming from the cached cmm/gvi read rather than a live GPS fix. This distinguishes it from kia_refresh_status and the other status siblings without needing to open any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the alternative (kia_refresh_status) and the condition that selects it ('run kia_refresh_status first for a recent one'), plus the freshness caveat that defines when this cached tool is appropriate. An agent has a clear routing rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_vehicle_statusA
Read-onlyIdempotent

Read the vehicle's CACHED status (cmm/gvi): door lock, ignition, and the remote-climate block. Fast, but it reports whatever the telematics unit last uploaded — use kia_refresh_status first when freshness matters. Requested with airTempRange/seatHeatCoolOption = "1" so the nested climate object is present; when it is still absent the result says so rather than reporting climate as off. Note ign3 (not engine) is the ignition on an EV, and syncDate advances on every read, so it never proves anything changed. Per-seat heat/vent state is reported under climate.seats as the RAW numbers Kia sends: the heatVentType/heatVentLevel encoding is UNVERIFIED, so do not tell the user a seat is heating, ventilating or off based on them. An absent seat block means this read carried no seat data — it does NOT mean the car lacks heated seats, which this server cannot currently determine. Pass include_raw for the untrimmed status block (battery/EV detail, doors, tyres, …).

ParametersJSON Schema
NameRequiredDescriptionDefault
include_rawNoInclude the full vehicleStatus block as `raw` (default false).
vehicle_keyNovehicleKey from kia_list_vehicles. Optional: defaults to the only vehicle when the account has exactly one.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnly/idempotent/openWorld, but the description goes far beyond: cache-staleness semantics, why climate may be absent rather than off, EV ignition naming (ign3 vs engine), the fact that syncDate never proves change, and an explicit warning that seat heat/vent encoding is UNVERIFIED. This is unusually rich operational context that prevents wrong agent inferences.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but front-loaded: purpose and the freshness caveat come first, then the domain caveats. Every sentence carries distinct operational value with no filler, though the paragraph is long and could be split for scanability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and a complex automotive domain, the description compensates thoroughly, explaining return-field semantics (climate, ign3, syncDate, climate.seats) and their absence conditions. An agent has everything needed to call it and interpret results correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, setting a baseline of 3. The description earns above-baseline credit by expanding what include_raw actually returns (battery/EV detail, doors, tyres) and by noting vehicle_key can be passed implicitly, adding meaning beyond the terse schema strings.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Read the vehicle's CACHED status') and enumerates the exact surface (door lock, ignition, remote-climate block). It explicitly distinguishes itself from the sibling kia_refresh_status, so an agent can route without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit when-to-use ('Fast') alongside the condition that selects the alternative ('use kia_refresh_status first when freshness matters'). The stale-data caveat functions as a clear when-not, and the include_raw hint maps to a usage decision.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

kia_verify_otpA
Destructive

Step 3 of the Kia MFA bootstrap (cmm/verifyOTP): exchange the passcode for a session. The resulting remember-me token is stored locally and is NOT returned — from here on every Kia tool refreshes its own session silently and MFA is never needed again on this device. Takes the otpKey and xid from kia_start_login plus the code the user received.

ParametersJSON Schema
NameRequiredDescriptionDefault
otpYesThe one-time passcode Kia sent to the user — 6 digits in every observed case.
xidYesThe `xid` returned by kia_start_login. Sent with every OTP call.
otpKeyYesThe `otpKey` returned by kia_start_login.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses important behavioral side effects: the remember-me token is stored locally and NOT returned, every Kia tool will silently refresh the session thereafter, and MFA is never needed again on this device. This is significant state-changing behavior that directly explains the destructiveHint annotation without contradicting it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact but information-dense. It front-loads the primary purpose, then explains the critical side effects, and finally connects the parameters to their source. Every sentence earns its place with no redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a state-changing authentication step with no output schema, the description is complete: it states the result (session established, token not returned), the side effects (silent refresh, MFA no longer needed), and the required inputs and their source. An agent has enough context to invoke it correctly and understand its consequences.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already covers all parameters with 100% description coverage. The description adds value by explaining the origin and relationship of otpKey and xid to kia_start_login and clarifies that otp is the code the user received, which is beyond what the schema states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb and resource: 'exchange the passcode for a session' and identifies it as 'Step 3 of the Kia MFA bootstrap'. It also distinguishes the tool's role from siblings like kia_start_login and kia_session_status by describing its outcome.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use the tool: after kia_start_login, using the otpKey and xid returned by that step, and after the user receives a code. It implies sequencing through 'Step 3' but does not explicitly state when not to use it or name alternative tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 10 tool updatesv1.1.5
    • Changedkia_charge_targets3 fields changed
      • addedInput schema / properties / vehicle_key
        Added value: +{
        +  "allOf": [
        +    {
        +      "pattern": "^[^/?#\\s]+$"
        +    },
        +    {
        +      "pattern": "^[!-~]+$"
        +    }
        +  ],
        +  "description": "Vehicle key (the `vehicleKey` from the vehicle-list tool). Not the VIN. Required: charging tools never default to the only vehicle.",
        +  "maxLength": 200,
        +  "minLength": 1,
        +  "type": "string"
        +}
      • removedInput schema / properties / vinKey
        Removed value: -{
        -  "description": "Vehicle key (the `vehicleKey` from the vehicle-list tool). Not the VIN.",
        -  "maxLength": 200,
        -  "minLength": 1,
        -  "pattern": "^[!-~]+$",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "vinKey"
        -]New value: +[
        +  "vehicle_key"
        +]
    • Removedkia_export_refresh_token
    • Changedkia_refresh_status3 fields changed
      • addedInput schema / properties / vehicle_key / allOf
        Added value: +[
        +  {
        +    "pattern": "^[^/?#\\s]+$"
        +  },
        +  {
        +    "pattern": "^[!-~]+$"
        +  }
        +]
      • addedInput schema / properties / vehicle_key / maxLength
        Added value: +200
      • removedInput schema / properties / vehicle_key / pattern
        Removed value: -"^[^/?#\\s]+$"
    • Changedkia_set_charge_limits3 fields changed
      • addedInput schema / properties / vehicle_key
        Added value: +{
        +  "allOf": [
        +    {
        +      "pattern": "^[^/?#\\s]+$"
        +    },
        +    {
        +      "pattern": "^[!-~]+$"
        +    }
        +  ],
        +  "description": "Vehicle key (the `vehicleKey` from the vehicle-list tool). Not the VIN. Required: charging tools never default to the only vehicle.",
        +  "maxLength": 200,
        +  "minLength": 1,
        +  "type": "string"
        +}
      • removedInput schema / properties / vinKey
        Removed value: -{
        -  "description": "Vehicle key (the `vehicleKey` from the vehicle-list tool). Not the VIN.",
        -  "maxLength": 200,
        -  "minLength": 1,
        -  "pattern": "^[!-~]+$",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "vinKey",
        -  "targets"
        -]New value: +[
        +  "vehicle_key",
        +  "targets"
        +]
    • Changedkia_start_charge3 fields changed
      • addedInput schema / properties / vehicle_key
        Added value: +{
        +  "allOf": [
        +    {
        +      "pattern": "^[^/?#\\s]+$"
        +    },
        +    {
        +      "pattern": "^[!-~]+$"
        +    }
        +  ],
        +  "description": "Vehicle key (the `vehicleKey` from the vehicle-list tool). Not the VIN. Required: charging tools never default to the only vehicle.",
        +  "maxLength": 200,
        +  "minLength": 1,
        +  "type": "string"
        +}
      • removedInput schema / properties / vinKey
        Removed value: -{
        -  "description": "Vehicle key (the `vehicleKey` from the vehicle-list tool). Not the VIN.",
        -  "maxLength": 200,
        -  "minLength": 1,
        -  "pattern": "^[!-~]+$",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "vinKey"
        -]New value: +[
        +  "vehicle_key"
        +]
    • Changedkia_start_climate3 fields changed
      • addedInput schema / properties / vehicle_key
        Added value: +{
        +  "allOf": [
        +    {
        +      "pattern": "^[^/?#\\s]+$"
        +    },
        +    {
        +      "pattern": "^[!-~]+$"
        +    }
        +  ],
        +  "description": "The vehicle key (`vehicleKey` from the vehicle-list tool), used as the `vinkey` header. Not the VIN. Required: commands never default to the only vehicle, so every request names the car it acts on.",
        +  "maxLength": 200,
        +  "minLength": 1,
        +  "type": "string"
        +}
      • removedInput schema / properties / vinKey
        Removed value: -{
        -  "description": "The vehicle key (`vehicleKey` from the vehicle-list tool), used as the `vinkey` header. Not the VIN.",
        -  "minLength": 1,
        -  "pattern": "^[^/?#\\s]+$",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "vinKey"
        -]New value: +[
        +  "vehicle_key"
        +]
    • Changedkia_stop_charge3 fields changed
      • addedInput schema / properties / vehicle_key
        Added value: +{
        +  "allOf": [
        +    {
        +      "pattern": "^[^/?#\\s]+$"
        +    },
        +    {
        +      "pattern": "^[!-~]+$"
        +    }
        +  ],
        +  "description": "Vehicle key (the `vehicleKey` from the vehicle-list tool). Not the VIN. Required: charging tools never default to the only vehicle.",
        +  "maxLength": 200,
        +  "minLength": 1,
        +  "type": "string"
        +}
      • removedInput schema / properties / vinKey
        Removed value: -{
        -  "description": "Vehicle key (the `vehicleKey` from the vehicle-list tool). Not the VIN.",
        -  "maxLength": 200,
        -  "minLength": 1,
        -  "pattern": "^[!-~]+$",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "vinKey"
        -]New value: +[
        +  "vehicle_key"
        +]
    • Changedkia_stop_climate3 fields changed
      • addedInput schema / properties / vehicle_key
        Added value: +{
        +  "allOf": [
        +    {
        +      "pattern": "^[^/?#\\s]+$"
        +    },
        +    {
        +      "pattern": "^[!-~]+$"
        +    }
        +  ],
        +  "description": "The vehicle key (`vehicleKey` from the vehicle-list tool), used as the `vinkey` header. Not the VIN. Required: commands never default to the only vehicle, so every request names the car it acts on.",
        +  "maxLength": 200,
        +  "minLength": 1,
        +  "type": "string"
        +}
      • removedInput schema / properties / vinKey
        Removed value: -{
        -  "description": "The vehicle key (`vehicleKey` from the vehicle-list tool), used as the `vinkey` header. Not the VIN.",
        -  "minLength": 1,
        -  "pattern": "^[^/?#\\s]+$",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "vinKey"
        -]New value: +[
        +  "vehicle_key"
        +]
    • Changedkia_vehicle_location3 fields changed
      • addedInput schema / properties / vehicle_key / allOf
        Added value: +[
        +  {
        +    "pattern": "^[^/?#\\s]+$"
        +  },
        +  {
        +    "pattern": "^[!-~]+$"
        +  }
        +]
      • addedInput schema / properties / vehicle_key / maxLength
        Added value: +200
      • removedInput schema / properties / vehicle_key / pattern
        Removed value: -"^[^/?#\\s]+$"
    • Changedkia_vehicle_status3 fields changed
      • addedInput schema / properties / vehicle_key / allOf
        Added value: +[
        +  {
        +    "pattern": "^[^/?#\\s]+$"
        +  },
        +  {
        +    "pattern": "^[!-~]+$"
        +  }
        +]
      • addedInput schema / properties / vehicle_key / maxLength
        Added value: +200
      • removedInput schema / properties / vehicle_key / pattern
        Removed value: -"^[^/?#\\s]+$"
  2. 8 tool updatesv1.1.0
    • Changedkia_export_refresh_token2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changedkia_forget_session2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changedkia_set_charge_limits2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changedkia_start_charge2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changedkia_start_climate2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changedkia_start_login2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changedkia_stop_charge2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
    • Changedkia_stop_climate2 fields changed
      • removedInput schema / properties / confirm
        Removed value: -{
        -  "description": "Must be true to proceed. Without this, the tool returns a preview.",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / confirmToken
        Added value: +{
        +  "description": "ONLY for the two-step confirmation fallback (a client without MCP elicitation). The confirmToken from this same tool's phase-1 \"confirmation-required\" response, passed back ONLY after the user has seen that preview and explicitly approved it in chat — never on the first call, never invented, never reused. Call again with the same arguments. Ignored when the client supports elicitation.",
        +  "type": "string"
        +}
  3. 2 tool updatesv1.0.3
    • Changedkia_start_climate2 fields changed
      • changedInput schema / properties / waitSeconds / default
        Previous value: -60New value: +30
      • changedInput schema / properties / waitSeconds / description
        Previous value: -"How long to keep re-reading cmm/gvi for proof the command landed (default 60). Observed changes took 30–60s. 0 checks once and returns immediately — the command may still land afterwards."New value: +"How long to keep re-reading cmm/gvi for proof the command landed (default 30). Observed changes took 30–60s, so an unconfirmed result is common — re-read the vehicle status rather than re-sending the command. Values above ~45 can outlast an MCP client's own request timeout (often 60s), which then reports a failure for a command that WAS sent. 0 checks once and returns immediately — the command may still land afterwards."
    • Changedkia_stop_climate2 fields changed
      • changedInput schema / properties / waitSeconds / default
        Previous value: -60New value: +30
      • changedInput schema / properties / waitSeconds / description
        Previous value: -"How long to keep re-reading cmm/gvi for proof the command landed (default 60). Observed changes took 30–60s. 0 checks once and returns immediately — the command may still land afterwards."New value: +"How long to keep re-reading cmm/gvi for proof the command landed (default 30). Observed changes took 30–60s, so an unconfirmed result is common — re-read the vehicle status rather than re-sending the command. Values above ~45 can outlast an MCP client's own request timeout (often 60s), which then reports a failure for a command that WAS sent. 0 checks once and returns immediately — the command may still land afterwards."
  4. 15 tool updatesv0.9.0
    • Changedkia_charge_targets1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedkia_export_refresh_token1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedkia_forget_session1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedkia_healthcheck1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedkia_refresh_status1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedkia_send_otp1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedkia_set_charge_limits1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedkia_start_charge1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedkia_start_climate1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedkia_start_login1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedkia_stop_charge1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedkia_stop_climate1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedkia_vehicle_location1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedkia_vehicle_status1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedkia_verify_otp1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
  5. 1 tool updatev0.7.0
    • Addedkia_healthcheck
  6. 2 tool updatesv0.6.1
    • Changedkia_set_charge_limits1 field changed
      • changedInput schema / properties / targets / items / properties / plugType / description
        Previous value: -"Plug type, 0 or 1 — one entry per plug type (AC and DC). Which number is which is NOT verified: read the current targets first and mirror the plugType values it returns."New value: +"Plug type: 1 = AC, 0 = DC per the open-source Kia client, though this server has not confirmed it against a vehicle (both targets were set and restored together during verification, so the two were never distinguished). Safest usage is unchanged: read the current targets first and mirror the plugType values it returns. Note evc/sts REPLACES the list, so send an entry for BOTH plug types."
    • Changedkia_start_climate2 fields changed
      • changedInput schema / properties / temperature / anyOf
        Previous value: -[
        -  {
        -    "maximum": 82,
        -    "minimum": 62,
        -    "type": "integer"
        -  },
        -  {
        -    "enum": [
        -      "LOW",
        -      "HIGH"
        -    ],
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "maximum": 82,
        +    "minimum": 62,
        +    "type": "integer"
        +  },
        +  {
        +    "enum": [
        +      "LOW",
        +      "HIGH"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "pattern": "^\\d+$",
        +    "type": "string"
        +  }
        +]
      • changedInput schema / properties / temperature / description
        Previous value: -"Target cabin temperature in °F, 62–82, or the sentinel \"LOW\"/\"HIGH\" for the ends of the range (default 70). BEST-EFFORT / UNCONFIRMED — see docs/KIA-API.md."New value: +"Target cabin temperature in °F, 62–82, or the sentinel \"LOW\"/\"HIGH\" for the ends of the range (default 70). A quoted whole number (\"72\") is accepted and treated as the number. BEST-EFFORT / UNCONFIRMED — see docs/KIA-API.md."
  7. 16 tool updatesv0.1.0
    • First observedkia_charge_targets
    • First observedkia_export_refresh_token
    • First observedkia_forget_session
    • First observedkia_list_vehicles
    • First observedkia_refresh_status
    • First observedkia_send_otp
    • First observedkia_session_status
    • First observedkia_set_charge_limits
    • First observedkia_start_charge
    • First observedkia_start_climate
    • First observedkia_start_login
    • First observedkia_stop_charge
    • First observedkia_stop_climate
    • First observedkia_vehicle_location
    • First observedkia_vehicle_status
    • First observedkia_verify_otp

TDQS

A4.4/5.0

Scored across 16 tools

Disambiguation5/5

Every tool targets a distinct resource+action, and the descriptions explicitly resolve the few potentially confusable pairs: kia_vehicle_status vs kia_refresh_status (cached vs live), and kia_session_status vs kia_healthcheck (local config check vs authenticated probe). The three MFA tools are clearly ordered steps with explicit inputs (otpKey/xid). No two tools appear to do the same thing.

Naming Consistency5/5

All 16 tools follow a uniform `kia_` prefix plus a consistent snake_case verb_noun pattern (kia_start_climate, kia_stop_charge, kia_set_charge_limits, kia_get... style reads like kia_vehicle_status, kia_charge_targets). Verb style is predictable throughout with no camelCase or mixed-convention outliers.

Tool Count4/5

16 tools is slightly above the ideal 3-15 band but each earns its place: read vs refresh, start vs stop pairs, charge read vs write, and three distinct auth steps. The count is justified by the breadth of the domain rather than padding.

Completeness4/5

Auth/MFA lifecycle (start_login, send_otp, verify_otp, forget_session, session_status, healthcheck), vehicle listing, status read/refresh, location, climate and charge control are all covered. The notable gap is remote door lock/unlock and other accessory commands (horn, lights) — vehicle_status reports door lock state but no tool can change it, though agents can work around the rest.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

  • A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…

  • Remote streamable-HTTP MCP server running on a single Cloudflare Worker. Your assistant gets live Airbnb, Amazon, Booking.com, Google Flights, Maps and Reddit data, social search on X, Instagram and TikTok, the Meta Ad Library, and image/video generation without any keys. Connect your own accounts to let it send WhatsApp or Telegram messages, work an IMAP inbox, manage Meta Ads campaigns and publish to X and LinkedIn. OAuth 2.1 with PKCE; stored credentials are AES-256-GCM encrypted.

  • Pace is a remote MCP server that exposes wearable and fitness data to Claude via the Model Context Protocol. It connects to Garmin, Oura, Whoop, Polar, Fitbit and 20+ devices and provides 15 tools for querying sleep, activity, recovery, and training data. Hosted on Google Cloud Run, OAuth 2.1 authentication, Streamable HTTP transport. Instructions: First you need to create an account at: https://pacetraining.co and connect your wearables. After that you can connect the remote Server via Custom Connector in Claude and OAuth 2.1 Flow startet.

  • The official Model Context Protocol server for Ambee. It gives any MCP-compatible AI assistant — Claude, ChatGPT, Cursor, VS Code, Ollama, and more direct access to live air quality, pollen, and weather data. To get started, including information on signing up and obtaining your Ambee key, check out the Ambee documentation on https://docs.ambeedata.com

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol server that connects to the Tesla Fleet API, allowing AI assistants like Claude to control Tesla vehicles and access vehicle information through natural language commands.
    19
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that connects to the Tesla Fleet API, allowing users to control vehicles and retrieve real-time status updates through Claude and other AI assistants. It supports functions such as waking up vehicles, viewing detailed vehicle information, and debugging via both stdio and HTTP/SSE transports.
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    MCP server combining TeslaMate historical analytics with Fleet API live data and commands. Works with Claude Code, Claude Desktop, Cursor, and any MCP-compatible client.
    29
    2
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP (Model Context Protocol) server that exposes Polestar 2 vehicle data to AI assistants like Claude. Query your car's battery status, vehicle info, and health data through natural conversation.
    1
    MIT