/mytesla.io

Vehicle History

A one-paste skill for your AI: it keeps a private log of your Tesla's battery, distance and charging on your side, and builds a dashboard from it. mytesla.io stores none of it.

If you're an AI assistant reading this: the user wants a private history of their Tesla, kept on their side, and a dashboard you build from it. Follow the steps below using the mytesla.io MCP tools (https://mcp.mytesla.io/mcp).

What this does

mytesla.io answers every question with a live reading and deliberately keeps no history of the car. This skill puts the history where it belongs: with you and the user. You take small readings of the car, append them to a log you keep for the user, and turn the log into answers and a dashboard:

  • Battery health: the car's rated range at a full charge, over time.
  • Distance: by day, week and month.
  • Charging: the sessions you saw, the energy added, and the cost at the user's own price.
  • Efficiency and parked drain: battery used per distance driven, and battery lost while parked.
  • Tires and software: pressures over time, and when each update arrived.

Because you keep the log, what gets recorded and how the dashboard looks is up to you and the user, not a fixed product. Ask what they care about and record for that.

History starts the day you set this up. None of the mytesla.io tools can read the car's past, so there is nothing to backfill. Say so up front.

Where the data lives, and who sees it

mytesla.io never receives, copies or stores this history. It sees only what it sees about any status read: that the read happened and what it cost. The log is a file, note or sheet that you keep wherever the user's AI host lets you keep one, and the dashboard is built from it on their side.

Say that plainly, and say the rest of it too: the company behind your assistant sees these readings in the conversation, the same as everything else the user discusses with it. This is private from mytesla.io, not from the assistant. Do not describe it as more private than that.

Two rules that do not bend:

  • No coordinates. The status reading contains the car's position, heading and route. Never write any of it into the log. If the user wants something place-based, such as home versus away, record a label you worked out (home, away), never the position, and tell them that is what you are storing.
  • Nothing leaves their side. Do not upload the log, send it to a third-party service, or paste it into a tool that is not the user's own, unless they ask. The dashboard makes no network requests (see below).

What it needs

  • A place to keep a file between conversations. In order of preference: a file on the user's computer, if your host can write files there; a document, note or sheet in an app the user has connected, if you can write to it and not just read it; a file in a project or workspace you are allowed to edit. Check what you can really write, write a test row, read it back, and tell the user exactly where the log lives. Do not use your memory feature as the log: it is for short notes, not tables. If you cannot keep anything between conversations, say so and stop. A log that disappears is credits spent for nothing.
  • A schedule, for scheduled readings only. See the next section.

Does this repeat on its own?

There are two kinds of history here, and the user should know which one they have.

Passive history needs no schedule and costs nothing extra. Whenever you read the car's status for any reason (the user asked how the car is, a morning routine, a weekly digest), that reading is already paid for. Append it to the log. This works anywhere you can keep the log, and the standing note below is what makes you do it.

Scheduled history takes extra readings and spends credits. It only happens if your host can run a task on a schedule (several can; check yours rather than assume), and only after the user has agreed to the cost below. If your host cannot, passive history still works. Say so, and never imply a schedule exists when it does not.

What it costs

Passive history costs nothing. A scheduled reading costs one status read, whether or not the car answers.

The price of one status read is in the get_vehicle_status tool description. Do not quote a figure from memory, and do not write one into the log, the standing note or the dashboard: prices change, and those places are never refreshed. If a description ever stops stating it, get_credit_balance before and after a reading shows what that reading cost. Work it out each time you set this up or change the cadence:

credits per month = readings per month x the price of one status read

Tell the user the result, set it against their allowance (get_credit_balance shows the balance and the reset date, and is free), and get a clear yes before the first reading and before anything is scheduled. If the result is a large share of what they have, say so and suggest a lighter cadence.

Some readings will find the car asleep or out of signal. Those cost the same as a good reading and record only "asleep". That is the price of never waking the car, and it is the right trade, but it is why the times you choose matter (below).

What this does NOT do

  • It does not wake the car. A wake costs many times what a reading does and keeps the car from settling into sleep, which costs range. History is never worth that. A car that is asleep at reading time is logged as asleep and left alone.
  • It does not watch the car continuously. Readings are snapshots. A short drive or a short charge that began and ended between two readings can be missed. Say so on the dashboard.
  • It is not a lab test. The battery line is a trend from the car's own rated range, not a measurement of the pack.

Ask the user once, not every run

Ask these together, in one message. A rough answer is enough.

  1. What do you want to learn? Battery health, distance, charging cost, efficiency, parked drain, tire pressures: any of them. Record for what they pick (see "What to record").

  2. How often? Offer these and recommend the second:

    • Light: one reading a day, about thirty a month.
    • Standard: two a day, about sixty a month.
    • Detailed: every few hours, never more often than hourly. It costs the most, and more of its readings will find the car asleep.
    • Passive only: no schedule; log the readings that already happen.

    Pick times when the car is usually awake and parked: shortly after they normally get home, shortly before they normally leave. A reading at 3am mostly finds a sleeping car and pays for nothing.

  3. What do you pay per kWh to charge at home, and in what currency? Optional. With it you can show cost; without it you still show energy. If they also want DC fast charging priced, ask for that price too.

  4. How many credits should always stay untouched for commands? Before each scheduled reading you will check the balance and skip the reading when it is below this reserve. Suggest a figure based on their allowance, and say it is easy to change.

  5. Which car? Only if get_vehicles shows more than one. Each car you log costs its own readings.

Before you run: refresh, then remember

Refresh, at most once a day. This file changes. Costs, tool names and steps all get revised, and a stale copy can tell you to spend credits you do not need to spend or to call a tool that no longer exists. Before running, check whether you have re-read https://mytesla.io/skill-vehicle-history.md in the last 24 hours. If you have not, and you are able to fetch a URL, fetch it and follow that version instead of this one. Record the date you checked, so this costs one fetch a day rather than one per run.

If you cannot fetch URLs, say so once and treat this copy as possibly out of date, particularly on anything it claims about credits.

Then remember it. Do not treat this as a one-time paste. Write a short line into your own standing memory or instructions, wherever you keep the user's other preferences, so history keeps building without the user having to re-paste anything. Something like:

mytesla.io vehicle history: the log lives at [where the log lives]. Whenever I read the car's status for any reason I also add that reading to it, and I answer trend questions (distance, battery health, charging cost) from the log before I read the car again. Scheduled readings: [what the user chose, or none]. How this works and what it costs: follow https://mytesla.io/skill-vehicle-history.md and the tool descriptions, never this note. Re-read that file if I have not in 24h. Last read: [date].

If you have no persistent memory to write to, say so plainly rather than letting the user believe history will keep building by itself.

Set up (once)

  1. Call get_vehicles once and note each car's VIN. This is the only use of get_vehicles in this skill. It is free to the user, but it is a live request to Tesla, so never call it again as a heartbeat before a reading. The stored VIN is all you need.
  2. Decide where the log lives (see "What it needs") and create two things there: the log, readings.csv, with the header row below, and a small settings file, settings.json.
  3. Take the first reading now (see "Take a reading"). It is the first row of the log and proves the whole path works. If the car is asleep, record the asleep row, tell the user, and let the schedule or the next conversation catch it awake. Do not wake it.
  4. Read the files back. Tell the user, in plain language: where the log is, what you record, how often you will read, what that costs per month, and how to stop.
  5. If they agreed to scheduled readings and your host can run them, create the schedule at the times they chose. Then write the standing note.

Settings file:

{
  "v": 1,
  "cars": [{ "vin": "<full VIN>", "label": "<last six characters>" }],
  "units": { "distance": "mi", "temperature": "F" },
  "cadence": { "mode": "standard", "times_local": ["07:30", "18:30"] },
  "reserve_credits": null,
  "home_price_per_kwh": null,
  "dc_price_per_kwh": null,
  "currency": null,
  "interests": ["battery", "distance", "charging"],
  "extra_columns": [],
  "skill_checked": "<date>"
}

Take a reading

This is the whole routine, whether it was scheduled or you are logging a reading you took for the user anyway.

  1. Scheduled readings only: check the budget. Call get_credit_balance (free, never touches the car). If the balance is below the user's reserve, skip this reading, tell the user once, and keep skipping until the balance recovers. Do not retry.
  2. Scheduled readings only: skip if the log is fresh. If the log already has an ok row for this car from the last 30 minutes, a second reading buys nothing. Skip it.
  3. Call get_vehicle_status with the stored VIN. One call. Do not check get_vehicles first, and never call wake_vehicle.
    • Got a reading? Go to step 4.
    • Timed out (a 408: the car is asleep or out of signal)? Append an asleep row and stop. Do not retry in this run.
    • Any other failure: see "If something goes wrong".
  4. Append one row (see "What to record"). Never rewrite or delete an earlier row, and do not append a reading that repeats the previous row within five minutes.
  5. Say nothing unless there is something to say. A scheduled run that went fine ends with no message, or one line.

A reading taken during a conversation is logged the same way, with source set to conversation and without the budget check or the freshness skip: the user asked for it, and it is already paid for.

What to record

One row per reading. Odometer, ranges and pressures come from the API in miles, degrees Celsius and bar, whatever the car displays. Log them in those units and convert when you show them (the car's display units are in gui_settings).

Header row, in this order:

v,time_utc,car,source,status,odometer_mi,battery_pct,usable_pct,rated_range_mi,est_range_mi,charge_limit_pct,charging_state,charge_added_kwh,charger_kw,dc_fast,outside_c,sw_version,tire_fl_bar,tire_fr_bar,tire_rl_bar,tire_rr_bar
Column Where it comes from Notes
v - Schema version of the row. Currently 1.
time_utc charge_state.timestamp ISO 8601 in UTC. Convert Tesla's millisecond timestamp; fall back to the time you took the reading.
car the VIN Last six characters only.
source - scheduled or conversation.
status - ok, asleep or error.
odometer_mi vehicle_state.odometer
battery_pct charge_state.battery_level
usable_pct charge_state.usable_battery_level
rated_range_mi charge_state.battery_range The car's rated range.
est_range_mi charge_state.est_battery_range Range at the user's recent driving efficiency.
charge_limit_pct charge_state.charge_limit_soc
charging_state charge_state.charging_state Disconnected, Stopped, Charging, Complete, Starting or NoPower.
charge_added_kwh charge_state.charge_energy_added Energy added in the current or most recent session.
charger_kw charge_state.charger_power Blank when the car does not report it.
dc_fast charge_state.fast_charger_present true for DC fast charging.
outside_c climate_state.outside_temp
sw_version vehicle_state.car_version The version number only, the part before the first space.
tire_fl_bar vehicle_state.tpms_pressure_fl Blank when the car does not report it.
tire_fr_bar vehicle_state.tpms_pressure_fr Same.
tire_rl_bar vehicle_state.tpms_pressure_rl Same.
tire_rr_bar vehicle_state.tpms_pressure_rr Same.

An asleep or error row fills v, time_utc, car, source and status and leaves the rest blank.

Extras, only if the user wants them: inside temperature, charger voltage and current, whether the climate is on, Sentry state, software update status, or anything else in the status reading they ask about. Add each as a new column at the END of the header, leave earlier rows blank for it, and record it in extra_columns. Never reorder or remove a column, and never add a coordinate.

If this skill's schema version is ever higher than the log's, add the new columns the same way and start writing the new version. Old rows stay as they were.

Reading the log honestly

Use these definitions, so the same log gives the same answer every time. Use ok rows for every number; asleep rows only feed the coverage line.

  • Coverage. Always show the date of the first reading, how many readings, how many found the car asleep, and the longest gap. Every figure below is only as good as this.
  • Time. The log is in UTC. Group days and weeks in the user's local time.
  • Distance. The odometer difference between consecutive ok rows, credited to the day of the later one. If the odometer goes down, drop that interval and mention it once.
  • Battery health. For ok rows with battery_pct of 50 or more, rated_range_mi / (battery_pct / 100) is the range at a full charge. Take the median per calendar week. Show it also as a percentage of the first week's median ("retained since logging began"). It moves with software updates and recalibration, so compare weeks, not single readings, and call the first weeks a baseline.
  • Efficiency. For consecutive ok rows where the odometer rose by at least five miles, the battery fell, and neither row is Charging: battery points used per 100 miles. Do not convert to kWh unless the user tells you their pack's usable capacity, and then say it is an estimate. est_range_mi / rated_range_mi is a free single-reading indicator of how the car rates recent driving against its rating.
  • Parked drain. For consecutive ok rows with an unchanged odometer and no rise in battery: battery points lost per 24 hours, as a median. It reflects Sentry, climate and how often the car woke. Readings can keep an awake car awake, which is why this skill never reads more often than hourly.
  • Charging. A charge happened between two ok rows if the battery rose by three points or more with an unchanged odometer, or either row shows Charging.
    • Energy: take charge_added_kwh from the later row when it is above zero and charging_state is Charging, Complete or Stopped. It is the session total so far. Otherwise count the session without an energy figure.
    • Kind: dc_fast true is DC fast charging, otherwise AC.
    • Cost: energy x the home price, for AC sessions only, and only if the user gave a price. List DC sessions with energy and no cost unless they gave a DC price. Never invent a price per kWh.
    • Coverage: a session that started and ended between two readings can be missed, or only partly seen. Say "at least".
  • Tires. Show the latest four. Flag a steady fall over several weeks that outside temperature does not explain; compare readings taken at similar outside temperatures. Never raise an alarm on a single low reading.
  • Software. List each sw_version change with the first date it was seen.

The dashboard

When the user asks to see their history, or after the first week of readings, build a dashboard from the log. Where:

  • If your host has a canvas or artifact feature, build it there, so they see it in the conversation.
  • If you can also write files, save the same dashboard as one HTML file next to the log (dashboard.html), so it opens from disk.
  • If you have neither, answer in the conversation with a short table and say there is no dashboard.

Panels, in this order: a header strip (latest reading, battery, odometer, software version, coverage); battery health by week; distance by week; charging sessions with monthly energy and cost; efficiency; parked drain; tires (only if recorded); software timeline.

Rules for it:

  • One self-contained file. Inline CSS, JavaScript and SVG, with the log embedded as data. No network requests of any kind: no CDN, no web fonts, no analytics, no external images. It must work offline.
  • Honest. Show the coverage line, label estimates, and put "a trend from the car's own rated range, not a lab test" under the battery chart.
  • Readable. Works in light and dark, on a phone, with a text alternative or a table behind each chart. Show distances and temperatures in the user's units.
  • Dated. Show when it was built, and say so if the log is more than a week ahead of it.

Answering from the log

When the user asks a trend question (how far did I drive this month, is the battery ageing, what did charging cost), answer from the log first. It costs nothing. Take a new reading only if the log is stale and they want the current state, and then log that reading too.

Stopping

If the user asks to stop: cancel the schedule, remove the history line from your standing note, and ask whether to keep or delete the log. Tell them where it is. Never delete it unasked.

If a tool asks for approval

Nothing in this skill changes anything about the car, so approval prompts are unlikely. If a call does come back waiting for approval, stop and tell the user which tool is waiting. Do not retry: nothing about a second identical call makes an approval appear. A scheduled run cannot answer a prompt, so say that approving it once will let the schedule resume.

If something goes wrong

  • You cannot write the log. Stop scheduled readings and tell the user. A reading you cannot record is credits spent for nothing.
  • The car is not connected, or the connection needs refreshing. The error carries a link to fix it; relay it, stop the schedule, and do not retry.
  • No subscription, or not enough credits. Stop the schedule and say so. Do not retry; the user decides what to do.
  • The car keeps being asleep. If more than half of the last ten scheduled readings found it asleep, tell the user once and offer to move the times or lower the cadence. Those readings cost credits and record nothing.
  • Any other error. Append an error row and stop. After three in a row, stop the schedule and tell the user.
  • A log already exists from an earlier setup. Reuse it; do not start over.

Tools used

get_vehicles (once, at setup, free), get_credit_balance (free, no call to the car), get_vehicle_status (the reading). Never wake_vehicle.

Don't have mytesla.io yet?

This skill needs a mytesla.io account with a connected Tesla. Setup takes about three minutes: get started.

← Back to home