惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
F
Fortinet All Blogs
阮一峰的网络日志
阮一峰的网络日志
Apple Machine Learning Research
Apple Machine Learning Research
爱范儿
爱范儿
WordPress大学
WordPress大学
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
J
Java Code Geeks
罗磊的独立博客
S
SegmentFault 最新的问题
V
V2EX
V
Visual Studio Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
美团技术团队
博客园 - 三生石上(FineUI控件)
Stack Overflow Blog
Stack Overflow Blog
Y
Y Combinator Blog
MyScale Blog
MyScale Blog
D
Docker
Google DeepMind News
Google DeepMind News
Blog — PlanetScale
Blog — PlanetScale
M
Microsoft Research Blog - Microsoft Research
Martin Fowler
Martin Fowler
S
Secure Thoughts
B
Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Recent Announcements
Recent Announcements
MongoDB | Blog
MongoDB | Blog
C
Cisco Blogs
C
CERT Recently Published Vulnerability Notes
T
True Tiger Recordings
GbyAI
GbyAI
P
Proofpoint News Feed
P
Privacy International News Feed
Jina AI
Jina AI
The Cloudflare Blog
I
Intezer
AWS News Blog
AWS News Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
S
Security Archives - TechRepublic
NISL@THU
NISL@THU
The Register - Security
The Register - Security
Recent Commits to openclaw:main
Recent Commits to openclaw:main
P
Palo Alto Networks Blog
S
Schneier on Security
L
LINUX DO - 热门话题
C
CXSECURITY Database RSS Feed - CXSecurity.com
Security Latest
Security Latest
C
Cybersecurity and Infrastructure Security Agency CISA

DEV Community

An open source LLM eval tool with two independent quality signals Using Dashboard Filtering to Get Customer Usage in Seconds from TBs of Data Skills, Java 17, And Theme Accents 4 Hard Lessons on Optimizing AI Coding Agents Arctype: Cross-Platform Database GUI for LLM Artifacts Your robots.txt says GPTBot is welcome. Your server says 403. Organizing How to Use AWS Glue Workflow 5 n8n Automations Every Digital Agency Should Be Running (Bill More, Work Less) Getting Started with TorchGeo — Remote Sensing with PyTorch Designing a Scalable Cross-Platform Appium Framework Google Antigravity 2.0 & Slash Commands Building a Unified Adaptive Learning Intelligence with Gemma 4, Flutter, and Multi-Model Orchestration Looking for beta testers for a £60 server management application The Disk-Pressure Incident That Taught Me to Always Set LimitRanges and Other Lessons from Mirroring EKS Locally. Why AI Should Not Write SQL Against ERP Databases Vibe coding works until it doesn't. The debt is real. Shipping at the Edge: Migrating a Coffee Subscription Platform to Cloudflare Workers Stop Tab-Switching: A Developer's Guide to Color Tools That Actually Fit the Workflow DevOps vs MLOps vs AIOps: What Changes, What Stays, and a Simple Roadmap to Get Started Run Powerful AI Coding Locally on a Normal Laptop 5 n8n Automations Every WooCommerce Store Needs (Save 10+ Hours/Week) What I Learned Building My Own AI Harness Hytale Servers Will Fail Treasure Hunts Until We Fix Our Event Handling Redux in React: Managing Global State Like a Pro Unfreezing Your GitHub Actions: Troubleshooting Stuck Deployments and Protecting Your Git Repo Statistics Unlocking Project Discoverability on GHES: A Key to Software Engineering Productivity When the Cleanup Code Becomes the Project Rockpack 8.0 - A React Scaffolder Built for the Age of AI-Assisted Development Mismanaging the Treasure Hunt Engine in Hytale Servers Will Get You Killed Why Hardcoded Automations Fail AI Agents Stop Calling It an AI Assistant. It’s Already Managing Your Company Why I built a post-quantum signing API (and why JWT is on borrowed time) Weekend Thought: Frontend Build Tools Suffer From Work Amnesia A 10-Line Playwright Trick That Saved Me Hours on Every Sephora Run AI Is Changing Engineering Culture More Than We Realize Everyone Was Focused on Gemini, But Infinite Scaler Was the Real Twister "Gemma 4 Analyzed My Bank Statements – Apparently I 'Have a Problem' with Coffee and Late-Night Apps" #css #webdev #beginners #codenewbie The Hidden Layer Every AI Developer Must Learn AlphaEvolve: Google DeepMind's Gemini-Powered Evolutionary Coding Agent RDS Reserved Instance Pricing: Every Engine, Every Rule, Real Dollar Savings How To Build An AI-Powered MVP Without Burning Your Startup Budget In 2026 Reading a Psychrometric Chart Without Getting Lost LMR-BENCH: Can LLM Agents Reproduce NLP Research Code? (EMNLP 2025) How to turn text into colors (without AI) Building Real-Time Apps in Node.js with Rivalis: WebSockets, Rooms, Actors, and a Binary Wire This Week In React #282 : Security, Fate, TanStack, Redux, Jotai | Hermes-node, Expo, Rozenite, Harness | TC39, Bun, pnpm, npm, Yarn, Node AI Copilot vs AI Agent Architecture - What's Actually Different (And Why It Matters) Smart Contract Security: NEAR's Futures Surge and AI Token Risks Database Maintenance: Tracing Production Incidents to Their Root Cause Stop juggling AI SDKs in PHP — meet Prisma Google Quietly Changed What “Apps” Mean at I/O 2026 The Infrastructure Team Is the Real Single Point of Failure Building SQLite from Scratch: 740 Lines of C++23 to Understand Every Byte of a .db File The 4 Levels of Hermes Agent Scaling Framework: From One Hermes Agent to a Fully Automated Team Your AI Has a Memory. It Just Doesn’t Know What to Remember. Claprec: Engineering Tradeoffs - Limited time vs. Perfection (6/6) Building a Daily Google News API Monitor in Python Building RookDuel Avikal: From Chess Steganography to Post-Quantum Archival Security Google I/O e IA: o que realmente muda na vida do dev? Color Contrast Failures: The Number One Accessibility Issue and How to Fix It # I Watched 15 Hours of Hermes Agent Videos So You Don't Have To Cómo solucionar el bucle infinito en useEffect con objetos y arrays en React The First Agent-Centric Cloud Security Platform — And Why We Didn't Build It That Way On Purpose Most Treasure Hunts Engines on Hytale Servers Are Built to Fail - Lessons from a Burned Database GhostScan v3.0 — From Closed-Source EXE to Open-Source Pentest Framework De hojas de cálculo a IA: construyendo una plataforma SRM moderna When is AI fine in education? Python Tools for Managing API Rate Limits in Data Pipelines How to Implement Exponential Backoff for Rate-Limited APIs in Python "My Web Chat Wasn't a Real Channel. That Broke My Agent Pipeline" next-advanced-sitemap v1.0.7 — safer URL ingestion & automatic trimming for Next.js sitemap generation I keep seeing people build an AI lead processing agent when they really need a 6-step rules engine AI Powered Student Learning Assistant Using Gemma 4 How I Built a Drop-In Proxy to Slash My OpenAI Bills by 20%+ Automatically Building a Sarcastic AI English Tutor with Persona-as-Code and Gemini Audio Input for Pronunciation Correction Five Years Later, I Finally Have 96GB VRAM — What It Actually Unlocks for Agent Loops Turning a 1-Line Idea Into a 40-Second Short with a 10-Beat Local Video Pipeline Running LTX-2.3 Alongside TTS on a Single 96GB GPU with a Cold-Start Architecture Cutting LTX-2 22B Peak VRAM by 40% with fp8_cast — and Why optimum-quanto Was a Trap HiDream Skeleton Mode: Prompt Beats OpenPose Ref — 8 Patterns Benchmarked Replicating a Language-Learning Comedy Short with Claude Code — Gemini as a Multimodal Sub-Agent HiDream-O1-Image 3–8x Faster: Benchmarking Steps, CFG, and Resolution AWS Savings Plan Buying Strategy: How to Layer, Size, and Time Commitments application.properties I built a macro tracker powered by AI + attitude Solace: A Global Mental Health First Responder Built with Gemma 4 Why Blocking Prompt Injection Is Wrong — and What to Do Instead The AI code tools Dutch developers actually use in 2026 (field notes) Automatic Error Recovery in AI Agent Networks You Are Not Choosing Building a Cinematic Adaptive Learning Intelligence with Gemma 4, Gemini, and OpenAI(Powered by Gemma 4) CLAUDE.md for Angular: 13 Rules That Make AI Write Idiomatic, Production-Ready Components I tested 7 vector databases for my RAG stack in 2026, here's the one nobody is talking about (yet) Claude agreed with a false fact I gave it. Confidently. That broke my workflow Google's "Budget" Model Just Beat Its Own Flagship. Here's What That Actually Means for Developers. How I built a monitoring SaaS for Joomla, WordPress & PrestaShop agencies Shifting from Passive Dashboards to Automated Remediation: A Guide to Next-Generation FinOps and CloudZero Alternatives Automating CSV WooCommerce Imports Without Plugins Why Wobbly Plugs and Overheating Outlets Are More Dangerous Than You Think (UL 498 Explained)
DIY AI Car Diagnostics with a $15 Bluetooth Adapter and Python
Petr Pátek · 2026-05-19 · via DEV Community

A few weeks ago the folding roof on my 2010 Ford Focus CC stopped working.

The obvious suspect was the roof module, but FORScan showed nothing there: zero stored fault codes. The useful clues were somewhere else, in the passenger door module, and they didn't look related at first glance.

I wanted to see whether Claude could work with that kind of diagnostic state directly instead of me copy-pasting screenshots from FORScan. So I built a small MCP server around an OBD-II adapter.

This is not a story about Claude magically fixing a car. It's a story about giving an LLM a narrow, read-only set of tools, fighting a BLE adapter for a few hours, and seeing whether the model could produce a useful explanation from real diagnostic state.

The setup

┌──────────┐    Bluetooth    ┌───────────────┐    Python    ┌──────────────┐    MCP    ┌─────────┐
│   Car    │ ◄─────────────► │  vLinker FD   │ ◄──────────► │  MCP Server  │ ◄───────► │  Claude │
│  OBD-II  │                 │  ($15 dongle) │              │  (250 lines) │           │         │
└──────────┘                 └───────────────┘              └──────────────┘           └─────────┘

Enter fullscreen mode Exit fullscreen mode

For this experiment I used only read-only tools:

Tool What it does
read_dtc Read stored fault codes from all or specific modules
get_live_data Real-time sensor readings (RPM, coolant temp, speed, etc.)
get_vehicle_info VIN, calibration IDs, ECU name
list_modules Enumerate all ECUs on the CAN bus
get_freeze_frame Sensor snapshot from when a DTC was set
explain_dtc Look up a code in the local DTC database

There is a guarded clear_dtc command in the repo (requires explicit confirmation), but I didn't use it for this experiment and wouldn't include it in a truly read-only profile.

The server is about 250 lines of Python and intentionally boring. Claude helped with the Python boilerplate, but the useful work was figuring out the adapter behavior and the diagnostic boundaries.

The BLE problem (where most of the time went)

The car side was straightforward. Plug the Vgate vLinker FD into the OBD port, turn the ignition on, pair via Bluetooth (PIN is 1234, not the 0000 macOS suggests).

macOS created a serial port:

$ ls /dev/tty.*vLinker*
/dev/tty.vLinkerFD-Android

Enter fullscreen mode Exit fullscreen mode

Looks good. Let's talk to it:

import serial
conn = serial.Serial('/dev/tty.vLinkerFD-Android', baudrate=115200, timeout=2)
conn.write(b'ATZ\r')  # Reset the ELM327 chip
response = conn.read(100)
print(response)  # b''

Enter fullscreen mode Exit fullscreen mode

Nothing. Empty bytes. I tried every common baud rate (9600, 38400, 115200, 500000). All of them opened the port without error, accepted writes, and returned nothing.

I spent a couple of hours on this. Tried different AT commands, reconnected the adapter, verified the ignition was on. The port was there, it opened cleanly, and nobody was home.

The actual problem: the vLinker FD is a BLE device, not classic Bluetooth. These are two completely different protocols. Classic Bluetooth creates a serial port (SPP/RFCOMM) and you talk to it like a USB cable. BLE uses GATT characteristics instead, small read/write endpoints organized into services.

When macOS paired with the vLinker, it created a serial port entry because that's what macOS does with Bluetooth devices. But the adapter never actually serves data on RFCOMM. It only listens on its BLE GATT characteristics. The serial port was a phantom.

This is why FORScan works fine on iOS. It uses Core Bluetooth to talk BLE directly. It never tries the serial port.

The fix was the bleak library (Python BLE client). The adapter exposes a GATT service with specific characteristics for communication:

Service: 0000fff0-0000-1000-8000-00805f9b34fb
Write:   0000fff2-0000-1000-8000-00805f9b34fb
Notify:  0000fff1-0000-1000-8000-00805f9b34fb

Enter fullscreen mode Exit fullscreen mode

You send ELM327 commands to the write characteristic and listen for responses on the notify characteristic:

async with BleakClient(address) as client:
    await client.start_notify(NOTIFY_UUID, on_response)
    await client.write_gatt_char(WRITE_UUID, b'ATZ\r')

Enter fullscreen mode Exit fullscreen mode

First successful adapter interaction after hours of debugging:

> ATZ
ELM327 v1.5

> AT SP 6
OK

> 0100
41 00 BE 3E B8 13

Enter fullscreen mode Exit fullscreen mode

The lesson I keep coming back to: the hard part of connecting an LLM to hardware was not the LLM. It was getting bytes from point A to point B through the correct abstraction layer.

Why MCP instead of just pasting logs?

The useful part of MCP here is not sophistication. It's the boundary.

Claude doesn't get arbitrary access to my laptop or the car. It gets a small set of named tools with typed inputs and outputs: list modules, read DTCs, explain one code, fetch freeze-frame data. That's it.

That made the interaction auditable. I could see exactly what Claude asked for, what the adapter returned, and where the final explanation came from. If Claude produced a bad answer, I could trace it back to which tool call returned unexpected data versus where the model's reasoning went wrong.

For a system that talks to actual hardware, that boundary matters more than convenience.

The DTC database

The car returns codes, not rich explanations. OBD-II gives you hex strings like B1310, but the standard doesn't include descriptions. Manufacturer-specific codes aren't in any universal reference.

For the prototype, I built a local lookup database from publicly available DTC references using an Apify crawler. It covers over 20 brands (Ford's coverage is the deepest, with codes across powertrain, body, and chassis categories). The database is not authoritative, and I wouldn't treat it as a replacement for OEM service data. The point was to avoid asking Claude to invent meanings for manufacturer-specific codes from memory.

What Claude actually did

Here's the context I hadn't explained yet. The passenger window regulator on the car is broken: the motor spins, but the glass doesn't move. On a convertible, that matters because the roof sequence depends on the side windows dropping before the roof panels can fold over them.

The interesting diagnostic puzzle was that the folding top module had no stored DTCs. The only relevant faults were in the passenger door module.

Important caveat: the Focus CC module scan shown below is reproduced in the mock adapter from my actual FORScan session. The MCP server can talk to the BLE adapter and read standard ELM327 responses, but full Ford MS-CAN module enumeration (which is where body modules like the roof controller live) needs extended commands beyond what generic OBD-II provides. The mock exists so the MCP workflow can be tested end-to-end without pretending that generic OBD-II gives you all body-module data for free.

Simplified scan output from mock mode (module addresses and fault codes match my real FORScan session):

Module                              Address    Protocol    DTCs
──────────────────────────────────────────────────────────────────
PCM (Powertrain Control)            0x7E0      HS-CAN      0
ABS Module                          0x760      HS-CAN      0
Instrument Cluster                  0x720      MS-CAN      0
Driver Door Control Unit            0x740      MS-CAN      0
Passenger Door Control Unit         0x741      MS-CAN      2
  → B1310: Power door unlock circuit failure
  → B166A: Heated mirror circuit open
Folding Top Control Module          0x750      MS-CAN      0
HVAC Module                         0x733      MS-CAN      0

Enter fullscreen mode Exit fullscreen mode

Reconstructed tool-call sequence from the mock-mode run:

1. list_modules()             → found 7 ECUs
2. read_dtc()                 → scanned all modules, found 2 codes on passenger door
3. explain_dtc("B1310")       → "Power door unlock circuit failure"
4. explain_dtc("B166A")       → "Heated mirror circuit open"
5. get_freeze_frame("B1310")  → sensor snapshot from when the code was set

Enter fullscreen mode Exit fullscreen mode

The codes themselves don't say "broken window regulator." B1310 and B166A point to passenger-door electrical faults. The missing piece was the symptom history: the window motor spins but the glass doesn't move, and the roof stopped working around the same time.

I asked Claude: "The roof won't operate but the roof module has no fault codes. Why?"

Claude's hypothesis: the roof controller performs a live precondition check before the folding sequence. It asks the windows to move. If the passenger side doesn't respond correctly (because the regulator is broken), the sequence aborts. Since the roof module itself isn't failing, it doesn't store a DTC. The relevant faults are on the door module, not the roof module.

The important connection was not B1310 specifically. It was that the only module with faults was in the same subsystem the roof controller depends on for its pre-flight sequence.

That matched what I later found in Ford service documentation. I haven't replaced the regulator yet, so this is still a high-confidence hypothesis rather than a confirmed repair. But it was useful novice-level triage: connecting live module state, symptom history, and reference data into a coherent next thing to check. That's more than I had before building this.

What this did not prove

This didn't prove that Claude can diagnose cars. It proved something narrower:

  • MCP is a clean interface for exposing diagnostic tools to an LLM.
  • The model is more useful when it can query real state instead of working from pasted screenshots.
  • The hard part is still protocol handling, adapter quirks, and incomplete documentation.
  • The result was a plausible diagnostic hypothesis, not a certified repair instruction.

What I intentionally didn't build

The server is read-only. I didn't expose actuator tests, module coding, service resets, or anything that can change vehicle state.

The DTC database includes diagnostic procedures for each brand: how to run self-tests, cycle actuators, reset service intervals. In theory, you could wrap those as MCP tools. I chose not to.

I'm a developer, not a car mechanic. Reading fault codes is passive, you're just asking the car what it already knows. But sending active commands to modules is a different thing entirely. A wrong routine ID, a command sent at the wrong time, or an actuator test while someone's hand is near a moving part. That's real risk. The gap between "technically possible via UDS Service $31" and "safe to let an LLM trigger autonomously" is enormous.

Honest limitations

Standard OBD-II is limited. The OBD-II standard only covers emissions-related PIDs. Body modules (roof controllers, door modules) live on manufacturer-specific CAN buses. The python-obd library doesn't natively scan Ford's MS-CAN bus. The mock adapter simulates this based on real FORScan data, but real MS-CAN scanning from the MCP server needs FORScan-level extended commands that aren't implemented yet.

The DTC database is scraped, not authoritative. It's built from publicly available references, not Ford's official FRIDA/DRIS database. Some descriptions may be incomplete or outdated.

Claude can hallucinate. It produced a plausible explanation for my roof problem, but LLMs can also produce confident-sounding nonsense. This is an explanation layer, not a repair manual. Verify anything it says against actual service documentation before acting on it.

The repo

The code is here: github.com/petrpatek/obd2-mcp-server

git clone https://github.com/petrpatek/obd2-mcp-server.git
cd obd2-mcp-server
./setup.sh
source .venv/bin/activate
obd2-mcp --mock  # runs with simulated car data, no hardware needed

Enter fullscreen mode Exit fullscreen mode

The mock simulates the Focus CC scenario with the same module addresses and fault codes I saw in FORScan. If you have an ELM327-compatible adapter, swap --mock for --ble (or --port for USB) and point it at a real car.

It passes 28 tests and works for the narrow path I built it for, but it's a prototype. I wouldn't rely on it for real diagnostics without verifying the output against proper service documentation.

What's next

I'm working on dynamic PID discovery (asking each ECU what standard PIDs it supports), live data streaming, and better brand coverage for the DTC database. All read-only.

The pattern I care about is narrower than "AI for every industry": take a system that already exposes diagnostic state, wrap a few safe read-only queries as tools, and let the model explain what it sees without letting it push buttons.

That seems useful beyond cars, but only if the boring parts are done well: protocol quirks, incomplete documentation, adapter weirdness, safety boundaries, and knowing when not to let the model act.

If you've tried similar MCP wrappers for CAN, Modbus, or other diagnostic protocols, I'd be curious to compare notes.