Před pár týdny přestala na mém Fordu Focus CC (ročník 2010) fungovat skládací střecha.
Podezření padlo na modul střechy, jenže FORScan tam nic nenašel: nula uložených kódů. Užitečné stopy byly úplně jinde, v modulu dveří spolujezdce, a na první pohled spolu vůbec nesouvisely.
Zajímalo mě, jestli by Claude dokázal pracovat s takovými diagnostickými daty přímo, místo abych mu kopíroval screenshoty z FORScanu. Tak jsem postavil malý MCP server nad OBD-II adaptérem.
Tohle není příběh o tom, jak Claude zázračně opravil auto. Je to o tom, jak jsem dal jazykovému modelu úzkou sadu read-only nástrojů, pár hodin se pral s BLE adaptérem a zjišťoval, jestli model dokáže ze skutečných diagnostických dat vyrobit něco užitečného.
Sestava
Celá architektura jsou čtyři krabičky: OBD-II port v autě mluví s Bluetooth adaptérem za 15 dolarů (Vgate vLinker FD), ten mluví s 250řádkovým Python MCP serverem a ten mluví s Claudem.
Pro experiment jsem použil jen read-only nástroje:
Nástroj | Co dělá |
|---|---|
`read_dtc` | Přečte uložené chybové kódy ze všech nebo vybraných modulů |
`get_live_data` | Živá data ze senzorů (otáčky, teplota chladicí kapaliny, rychlost atd.) |
`get_vehicle_info` | VIN, kalibrační ID, název řídicí jednotky |
`list_modules` | Vypíše řídicí jednotky dostupné přes aktuální backend |
`get_freeze_frame` | Snímek senzorů z okamžiku, kdy vznikl chybový kód |
`explain_dtc` | Vyhledá kód v lokální DTC databázi |
V repozitáři je i chráněný `clear_dtc` (vyžaduje explicitní potvrzení), ale pro tenhle experiment jsem ho nepoužil a do opravdu read-only profilu bych ho nedal.
Server má kolem 250 řádků Pythonu a je záměrně nudný. Claude pomáhal s boilerplate kódem, ale ta skutečná práce byla pochopit, jak se chová adaptér a kde jsou hranice diagnostiky.
Problém s BLE (kam šla většina času)
Na straně auta nic složitého. Zastrčit Vgate vLinker FD do OBD portu, zapnout zapalování, spárovat přes Bluetooth (PIN je `1234`, ne `0000`, jak macOS rád navrhuje).
macOS vytvořil sériový port: `/dev/tty.vLinkerFD-Android`. Vypadá to slibně. Tak se připojíme.
Otevřel jsem port přes `serial.Serial`, poslal `ATZ\r` na reset ELM327 čipu a čekal na odpověď. Nic. Prázdné bajty.
Vyzkoušel jsem všechny běžné rychlosti (9600, 38400, 115200, 500000). Každá port otevřela bez chyby, přijala zápis a nevrátila nic.
Tím jsem strávil pár hodin. Různé AT příkazy, opakované připojování adaptéru, kontrola zapalování. Port tam byl, otevíral se čistě, jenže nikdo nebyl doma.
Jádro problému: BLE versus klasický Bluetooth
vLinker FD je BLE zařízení (Bluetooth Low Energy), ne klasický Bluetooth. To jsou dva úplně jiné protokoly. Klasický Bluetooth vytvoří sériový port (SPP/RFCOMM) a komunikujete přes něj jako přes USB kabel. BLE funguje jinak: používá GATT charakteristiky, malé read/write endpointy organizované do služeb.
Když macOS vLinker spároval, ze zvyku vytvořil záznam sériového portu. Dělá to u všech Bluetooth zařízení. Jenže adaptér na RFCOMM nikdy nic neposílá. Naslouchá výhradně na svých BLE GATT charakteristikách. Ten sériový port byl fantom.
Proto FORScan na iOS funguje bez problémů. Používá Core Bluetooth a mluví BLE přímo. O sériový port se nikdy nepokouší.
Řešení: knihovna bleak (Python BLE klient). Adaptér vystavuje GATT službu s konkrétními charakteristikami:
- Služba: `0000fff0-0000-1000-8000-00805f9b34fb`
- Zápisová charakteristika: `0000fff2-0000-1000-8000-00805f9b34fb`
- Notifikační charakteristika: `0000fff1-0000-1000-8000-00805f9b34fb`
ELM327 příkazy posíláte do zápisové charakteristiky, odpovědi čtete z notifikační. První úspěšná komunikace po hodinách debugování: `ATZ` vrátilo `ELM327 v1.5`, pak `AT SP 6` vrátilo `OK` a `0100` vrátilo `41 00 BE 3E B8 13`. Konečně.
Pořád se k tomu vracím: na připojení jazykového modelu k hardwaru nebyla nejtěžší AI. Nejtěžší bylo dostat bajty z bodu A do bodu B správnou vrstvou.
Proč MCP a ne prostě kopírovat logy?
MCP tady není užitečné kvůli sofistikovanosti. Je užitečné kvůli hranici.
Claude nedostane volný přístup k počítači ani k autu. Dostane malou sadu pojmenovaných nástrojů s typovanými vstupy a výstupy: vypiš moduly, přečti kódy, vysvětli jeden kód, stáhni freeze-frame. To je všechno.
Díky tomu šlo celou interakci auditovat. Viděl jsem přesně, co si Claude vyžádal, co adaptér vrátil a odkud vzešlo konečné vysvětlení. Když Claude řekl něco špatně, mohl jsem vysledovat, jestli dostal špatná data, nebo jestli chyboval v uvažování.
Když mluvíte se skutečným hardwarem, tahle hranice záleží víc než pohodlí.
DTC databáze
Auto vrací kódy, ne popisy. Diagnostické nástroje vám dají kódy jako `B1310`, ale standard žádné popisy neobsahuje. Kódy specifické pro výrobce nejsou v žádné univerzální referenci.
Pro prototyp jsem sestavil lokální vyhledávací databázi z veřejně dostupných DTC zdrojů pomocí Apify crawleru. Pokrývá přes 20 značek (Ford má nejhlubší pokrytí, kódy napříč pohonným řetězcem, karoserií i podvozkem). Tuhle databázi bych nepovažoval za směrodatnou a rozhodně ne za náhradu OEM servisních dat. Šlo o to, aby Claude nemusel vymýšlet významy kódů z hlavy.
Co Claude vlastně udělal
Teď ten kontext, který jsem zatím nezmínil. Stahovač okna spolujezdce je rozbitý: motorek se točí, sklo se nehýbe. U kabrioletu to je zásadní, protože skládací sekvence střechy závisí na tom, že boční okna klesnou dřív, než se střešní panely přeloží.
Zajímavý diagnostický hlavolam: modul skládací střechy neměl uložené žádné DTC. Jediné relevantní závady seděly v modulu dveří spolujezdce.
Důležité upozornění: sken modulů Focus CC uvedený níže pochází z mock adaptéru, který reprodukuje můj reálný výstup z FORScanu. MCP server umí komunikovat s BLE adaptérem a číst standardní ELM327 odpovědi, ale plný výčet modulů na Fordově MS-CAN sběrnici (kde žijí karosérní moduly jako řadič střechy) potřebuje rozšířené příkazy nad rámec generického OBD-II. Mock existuje proto, aby šel celý MCP workflow otestovat end-to-end, aniž by se předstíralo, že generické OBD-II dává data z karosérních modulů zadarmo.
Zjednodušený výstup skenu z mock režimu (adresy modulů a kódy odpovídají mému reálnému výstupu z FORScanu):
Modul | Adresa | Protokol | DTC |
|---|---|---|---|
PCM (řízení pohonného řetězce) | 0x7E0 | HS-CAN | 0 |
Modul ABS | 0x760 | HS-CAN | 0 |
Přístrojový panel | 0x720 | MS-CAN | 0 |
Řídicí jednotka dveří řidiče | 0x740 | MS-CAN | 0 |
Řídicí jednotka dveří spolujezdce | 0x741 | MS-CAN | 2 |
Modul skládací střechy | 0x750 | MS-CAN | 0 |
Modul klimatizace | 0x733 | MS-CAN | 0 |
Na dveřích spolujezdce dva kódy: B1310 (selhání obvodu elektrického zámku) a B166A (přerušený obvod vyhřívaného zrcátka).
Rekonstruovaná sekvence volání nástrojů z mock režimu:
- `list_modules()` — nalezeno 7 řídicích jednotek
- `read_dtc()` — proskenovány všechny moduly, 2 kódy na dveřích spolujezdce
- `explain_dtc("B1310")` — „Selhání obvodu elektrického zámku dveří"
- `explain_dtc("B166A")` — „Přerušený obvod vyhřívaného zrcátka"
- `get_freeze_frame("B1310")` — snímek senzorů z okamžiku vzniku kódu
Samotné kódy neříkají „rozbitý stahovač okna." B1310 a B166A ukazují na elektrické závady dveří spolujezdce. Chybějící dílek byla historie symptomů: motorek okna se točí, ale sklo se nehýbe, a střecha přestala fungovat přibližně ve stejné době.
Zeptal jsem se Clauda: „Střecha nefunguje, ale modul střechy nemá žádné kódy. Proč?"
Claudova hypotéza: řadič střechy před skládací sekvencí kontroluje předpoklady. Požádá okna, aby se pohnula. Když spolujezdcova strana nereaguje (protože je stahovač rozbitý), sekvence se přeruší. Modul střechy sám přitom neselhává, takže si DTC neuloží. Relevantní závady jsou na modulu dveří, ne na střeše.
Podstatné nebylo konkrétně B1310. Podstatné bylo, že jediný modul se závadami patřil do subsystému, na kterém řadič střechy závisí při své předstartovní sekvenci.
Odpovídalo to tomu, co jsem později našel v servisní dokumentaci Fordu. Stahovač jsem zatím nevyměnil, takže je to pořád jen hypotéza, i když dost přesvědčivá. Ale jako vstupní triáž od člověka, co není mechanik, to bylo užitečné: propojit živý stav modulů, historii symptomů a referenční data do jednoho koherentního „zkontroluj tohle." Víc, než jsem měl předtím.
Co tohle nedokázalo
Nedokázalo to, že Claude umí diagnostikovat auta. Dokázalo to něco mnohem užšího:
- MCP je čisté rozhraní, jak zpřístupnit diagnostické nástroje jazykovému modelu.
- Model je užitečnější, když se může ptát na skutečný stav, místo aby pracoval s nakopírovanými screenshoty.
- Těžké zůstává zpracování protokolů, zvláštnosti adaptérů a neúplná dokumentace.
- Výsledek byla věrohodná diagnostická hypotéza, ne certifikovaný servisní postup.
Co jsem záměrně nepostavil
Server je read-only. Testy aktuátorů, kódování modulů, servisní resety, nic z toho tam není. Nic, co by mohlo změnit stav auta.
DTC databáze obsahuje i diagnostické postupy pro jednotlivé značky: jak spustit autotesty, cyklovat aktuátory, resetovat servisní intervaly. Teoreticky by šly zabalit jako MCP nástroje. Záměrně jsem to neudělal.
Jsem vývojář, ne automechanik. Číst chybové kódy je pasivní: ptáte se auta na to, co už ví. Jenže posílat aktivní příkazy modulům je úplně jiná věc. Špatné ID rutiny, příkaz ve špatnou chvíli, test aktuátoru, když má někdo ruku u pohyblivé části. Tohle je reálné riziko. Propast mezi „technicky proveditelné přes UDS Service $31" a „bezpečné nechat jazykový model spustit samostatně" je obrovská.
Kde jsou limity
Standardní OBD-II je omezené. Pokrývá jen emisní PID. Karosérní moduly (řadiče střech, moduly dveří) žijí na CAN sběrnicích specifických pro výrobce. Knihovna `python-obd` neumí skenovat Fordovu MS-CAN sběrnici. Mock adaptér to simuluje podle reálných dat z FORScanu, ale skutečné skenování MS-CAN z MCP serveru by potřebovalo rozšířené příkazy na úrovni FORScanu, které zatím nejsou naimplementované.
DTC databáze je nascrapovaná, ne směrodatná. Postavená z veřejně dostupných zdrojů, ne z oficiální Fordovy databáze FRIDA/DRIS. Některé popisy můžou být neúplné nebo zastaralé.
Claude může halucinovat. Pro můj problém se střechou vyrobil věrohodné vysvětlení, ale jazykové modely umí taky vyrobit přesvědčivě znějící nesmysly. Tohle je vysvětlovací vrstva, ne servisní příručka. Cokoliv řekne, ověřte oproti skutečné servisní dokumentaci, než se podle toho zařídíte.
Repozitář
Kód je tady: github.com/petrpatek/obd2-mcp-server
Naklonujte, spusťte `./setup.sh`, aktivujte virtualenv a `obd2-mcp --mock` běží se simulovanými daty, žádný hardware potřeba. Mock simuluje scénář Focus CC se stejnými adresami modulů a kódy, které jsem viděl ve FORScanu. Máte-li ELM327 kompatibilní adaptér, vyměňte `--mock` za `--ble` (nebo `--port` pro USB) a namiřte na skutečné auto.
Prochází 28 testy a funguje pro ten úzký scénář, pro který jsem ho stavěl. Ale je to prototyp. Na skutečnou diagnostiku bych se bez ověření oproti řádné servisní dokumentaci nespoléhal.
Co dál
Pracuju na dynamickém objevování PID (zeptat se každé řídicí jednotky, jaké standardní PID podporuje), streamování živých dat a lepším pokrytí značek v DTC databázi. Pořád jen čtení.
Vzorec, o který mi jde, je užší než „AI pro každé odvětví": vzít systém, který už vystavuje diagnostický stav, zabalit pár bezpečných read-only dotazů jako nástroje a nechat model vysvětlit, co vidí. Aniž by mohl mačkat tlačítka.
Mimo auta to vypadá taky užitečně, ale jen pokud se ty nudné části udělají pořádně: zvláštnosti protokolů, neúplná dokumentace, podivnosti adaptérů, bezpečnostní hranice a vědět, kdy model nenechat jednat.
Jestli jste zkoušeli podobné MCP wrappery pro CAN, Modbus nebo jiné diagnostické protokoly, rád porovnám zkušenosti.
*Netechnický pohled na to, co tenhle vzorec znamená mimo auta: Stroje už mluví. Jen jsme přestali poslouchat.*