betterkey-mcp
OfficialClick on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@betterkey-mcp Lock my Toyota Camry, but ask me to confirm first."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
betterkey-mcp
Model Context Protocol server that lets AI agents inspect and act on your BetterKey-connected vehicles.
Open-source bridge. You mint the key, you keep the control. The server never calls your vehicle's API directly; every request goes to BetterKey's existing /v1/* HTTP API over HTTPS, authenticated with an API key you mint in the BetterKey iOS app.
Tools
Six tools are exposed over stdio:
Tool | What it does | API-key scope required |
| Lists your connected vehicles (id, make, model, color). |
|
| Returns the latest windows/odometer/fuel/battery snapshot with per-signal |
|
| Identity + which signals have fresh data right now + known upstream quirks the agent should respect. |
|
| Lock the vehicle. Destructive. The agent must obtain explicit human confirmation. Returns |
|
| Unlock the vehicle. Destructive, with the same confirmation and confirmation-status semantics as |
|
| Current OEM-reported location. Location-sensitive; coordinates are never logged by the server. |
|
Related MCP server: Tessie MCP Server
What it does not do
It does not read your Firestore directly.
It does not hold a vehicle-manufacturer OAuth token.
It does not call the vehicle manufacturer's API itself.
It does not expose any way to bypass BetterKey's ownership, subscription, or rate-limit checks. Those run server-side on every call.
Setup
1. Mint a BetterKey API key
Open the BetterKey app on iOS → Settings → API Keys → Create. Copy the bk_... secret immediately; it is shown only once.
Scopes. A key minted from the iOS app today holds telemetry.read + vehicle.command by default, enough to drive every tool here. If you'd rather keep this bridge read-only (Homebridge-style), mint the key via a direct POST /v1/account/api-keys with {"label":"...","scopes":["telemetry.read"]}. A read-only key calling a command tool returns a tool-level insufficient_scope error naming the missing scope.
2. Register with your MCP host
Claude Desktop. Edit ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"betterkey": {
"command": "npx",
"args": ["-y", "betterkey-mcp"],
"env": {
"BETTERKEY_API_KEY": "bk_..."
}
}
}
}Restart Claude Desktop. The six tools should appear in the tool palette.
3. Try it
"List my vehicles."
"What's the latest telemetry for <make>?"
"What can BetterKey tell me about <make> right now?"
"Lock <make>." The agent should confirm with you first; a
confirmation: "unconfirmed"result means the lock command was accepted by BetterKey but the automaker's acknowledgement is unavailable (the lock may or may not have actuated)."Where is <make>?" Returns latitude/longitude plus the OEM timestamp.
Environment
Variable | Required | Default | Description |
| yes | (none) | A |
| no |
| Point at |
Revoking access
Agent-host access to your vehicle data lasts only as long as the API key is valid. To revoke:
In the BetterKey app → Settings → API Keys → delete the key.
All subsequent tool calls from the MCP server will fail with
unauthorized.
To rotate: delete the old key, mint a new one, update BETTERKEY_API_KEY in your MCP host config, restart the host.
Known upstream quirks the agent sees
The get_vehicle_capabilities tool returns a knownQuirks list so agents don't over-report:
isLockedWebhookUnreliable. The vehicle's upstream lock-state webhook is defective at the provider level; any lock state reported here is last-known, not live.statusEndpointReturns501. There is no engine-run-state (on/off) tool for your vehicle.
If a tool call returns 401 unauthorized, the API key was revoked or regenerated. If it returns 403 with type: "insufficient_scope" and requiredScope: "vehicle.command", the key does not have the scope the called route requires; mint a new key with that scope and retry.
Security notes
The API key lives in your MCP host's env; it is never written to tool output or error messages.
Zod validates every tool argument before it reaches the HTTP client.
All path segments interpolated into URLs go through
encodeURIComponent.Timeouts default to 20s with
Retry-Afterhonored on 429.fetchis called withredirect: "manual"; redirects fail closed.
Development
git clone https://github.com/CMLabsLLC/betterkey-mcp.git
cd betterkey-mcp
npm install
npm run dev # run with tsx (no build step)
npm run typecheck # strict typecheck without emit
npm test # Node's built-in test runner
npm run build # emit dist/Point at a local backend by setting BETTERKEY_API_BASE=http://localhost:8080 and running make simulator-backend in the main BetterKey repo.
License
Available Tools
6 toolsget_vehicle_capabilitiesGet vehicle capabilitiesA
Describe what BetterKey can currently report for one vehicle: identity (make/model/color), the per-signal freshCapabilities map (true when a fresh reading is available right now), and a knownQuirks list of upstream Smartcar behaviors the agent should respect when reasoning about results.
Inputs: vehicle_id (required).
get_vehicle_locationGet vehicle locationARead-only
Fetch the vehicle's current reported location (latitude, longitude, and the OEM timestamp when known). This is sensitive data — the agent host should treat the result accordingly and should not persist coordinates beyond what the user asked for. Returns 503 with a Retry-After hint when the automaker's location pipe is in-flight or temporarily unavailable; retry only when the user asks.
Inputs: vehicle_id (required).
get_vehicle_telemetryGet vehicle telemetryA
Fetch the latest telemetry snapshot (windows, odometer, fuel, battery) for one vehicle. Each returned signal carries oemUpdatedAt from the automaker and an isStale flag (true when the reading is older than 15 minutes). Pass refresh=true to bypass the server's 15-minute cache; most calls should leave it false.
Inputs: vehicle_id (required), refresh.
list_vehiclesList vehiclesA
List the user's Smartcar-connected vehicles in BetterKey. Returns id, display name, make, model, and exterior color. Use the id as the vehicle_id argument to other tools.
Inputs: no named parameters.
lock_vehicleLock vehicleADestructive
Lock the vehicle. This physically actuates the car's door locks. The agent MUST obtain explicit human confirmation before invoking this tool. The response includes a confirmation field: 'confirmed' means the automaker acknowledged the command; 'unconfirmed' means BetterKey accepted it but the automaker's acknowledgement is unavailable (the lock may or may not have actuated) — report that honestly rather than assuming success.
Inputs: vehicle_id (required).
unlock_vehicleUnlock vehicleADestructive
Unlock the vehicle. This physically actuates the car's door locks and will leave the car unsecured until it is locked again. The agent MUST obtain explicit human confirmation before invoking this tool and should surface a clear reason to the user. The response includes a confirmation field: 'confirmed' means the automaker acknowledged the command; 'unconfirmed' means BetterKey accepted it but the automaker's acknowledgement is unavailable — report that honestly rather than assuming success.
Inputs: vehicle_id (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 6 tools
Each tool maps to a distinct resource plus action, and lock vs unlock vs list are unmistakable. The only candidate for confusion is get_vehicle_telemetry vs get_vehicle_capabilities, both returning per-vehicle diagnostic data, though the descriptions do clarify that one returns readings and the other returns what can be reported.
All six tools follow a strict verb_noun pattern (list_vehicles, get_vehicle_*, lock_vehicle, unlock_vehicle) with the domain noun consistently suffixed. No mixing of conventions or vague verbs.
Six tools is tightly scoped to the server's purpose: enumerate vehicles, read state, read capabilities, and two lock actuation commands. Every tool earns its place and none is redundant.
The surface covers discovery, telemetry, capabilities, location, and the lock/unlock command pair, which is solid coverage for a Smartcar read/control wrapper. Gaps remain for other common actuations (charging, climate, engine start) and there is no bulk/multi-vehicle read, but agents can work around these.
Maintenance
Related MCP Connectors
Control your Tesla from your AI assistant - climate, charging, access, and security.
AI for your car: check charge, start climate, lock/unlock, open trunk via Tesla Fleet API. OAuth.
Tesla Fleet API for AI: send navigation destinations, read battery and location, run car commands.
Tesla data for your AI: battery, range, charging, tires, alerts, history. Controls off by default.
Related MCP Servers
AlicenseNot gradedqualityCmaintenanceEnables AI assistants to access vehicle data from the DIMO Network, including querying telemetry, executing vehicle commands (lock/unlock, charging), decoding VINs, minting vehicle NFTs, and creating verifiable credentials.2MIT- AlicenseAqualityDmaintenanceEnables AI assistants to control and monitor Tesla vehicles via natural language through the Tessie API, supporting battery, climate, security, charging, and more.611MIT
- FlicenseAqualityDmaintenanceExposes a connected-vehicle OBD-II/telematics platform to AI agents, enabling vehicle health scoring, live data queries, DTC decoding, maintenance prediction, and gated remote commands via a pluggable data layer.9-
- AlicenseAqualityBmaintenanceEnables AI assistants to monitor a Hyundai, Kia, or Genesis vehicle's charge, fuel, range, locks, and location, and optionally pre-heat the cabin, lock or unlock doors, and start or stop charging. Reads come from cached Bluelink data with rate-limited refreshes, and all write commands are disabled by default.62MIT