It Started with a Complaint
Day three.
This little dev board is seriously tough. Claude Code’s free-tier generosity let me sprint hard, but I still hit the usage limit. I went to a conference that morning, and the whole time one thought kept looping in my head:
How much time have I spent copy-pasting?
JTAG call stack, SWD register dumps, Serial Console logs — paste a chunk over, AI gives a suggestion, I tweak the code, rebuild, flash, grab the logs, paste them back. Over and over. Sometimes I paste into the wrong window. Sometimes I miss the critical three lines.
Compared to debugging purely on my own, it’s unquestionably faster. But not fast enough. The bugs are like Russian nesting dolls — pull one out, there’s another inside. Every “this should fix it” → “why is it hanging again” cycle makes you want to shove the keyboard away.
So I started wondering: what if we could eliminate the human factor entirely?
An Idea: Give AI Eyes and Hands
Once the problem is stated clearly, the solution becomes obvious.
What I need isn’t a smarter AI. I need an AI that can see, act, and verify — by itself.
Instead of me acting as a “human data pipe” — reading hardware signals with my eyes, then transcribing them for the AI — I want the AI to connect directly to the hardware’s sensing interfaces, receive first-hand signals, make decisions, and then drive the toolchain itself: build, flash, reset, confirm.
That idea became AI-HIL (AI Hardware-in-the-Loop).
Giving hardware the soul of AI, realizing automated closed-loop development in the physical world.
What Is AI-HIL?
AI-HIL upgrades Claude Code from a “code generator” to a “system-level engineer.”
Through the Model Context Protocol (MCP), Claude Code connects to physical hardware and gains three capabilities:
- Perception: Reading serial logs, JTAG call stacks, power waveforms, camera frames
- Action: Build/flash firmware, hard reset, power control
- Closed-Loop Validation: Automatically verify fixes, record bug patterns
In other words, the AI is no longer just sitting next to me offering suggestions — it’s an AI Employee that can get to work on its own.
System Architecture
┌─────────────────────────────────────────────┐
│ Decision Brain │
│ Claude Code CLI + CLAUDE.md │
└───────────────────┬─────────────────────────┘
│ MCP
┌───────────────────▼─────────────────────────┐
│ Nervous System — FastMCP │
└──────┬──────────────────────────┬───────────┘
│ │
┌──────▼──────────┐ ┌───────────▼────────────┐
│ Perception │ │ Action Plane │
│ Serial / SSH │ │ Build / Flash │
│ JTAG / SWD │ │ Hard Reset │
│ Webcam / CV │ │ GPIO / Sim │
│ PPK2 Power │ └────────────────────────┘
│ SDR / RF │
│ Thermal / Mic │ ┌────────────────────────┐
└─────────────────┘ │ Context Plane │
│ Datasheets / PDFs │
│ Golden Samples │
└────────────────────────┘
All MCP Servers are built with FastMCP (Python). Each server encapsulates one hardware dimension and returns semantic diagnostic conclusions — not raw binary data.
The AI sees Stack overflow detected in task foo, not 0xE000ED28 = 0x0400.
How the Closed Loop Works
Triage Diagnosis Remediation
(anomaly) → (JTAG + PPK2 → (Claude Code
detected + Vision) fixes code)
│ │
└───────────────────────────────────────┘
▼
Verification
PASS ──► Record bug → next Triage
FAIL ──► Diagnosis (retry)
Five steps form the automated closed loop:
- Triage — Perception plane detects anomaly (current spike, log error)
- Diagnosis — AI simultaneously checks JTAG stack, thermal image, power waveform
- Remediation — Claude Code modifies the C/Zig/Rust source
- Build & Flash — Auto-compile and flash to the target board
- Verification — Serial log + PPK2 confirm the fix; result recorded in
CLAUDE.md
Every successfully resolved bug becomes knowledge. The next time the AI encounters a similar pattern, it converges faster.
Standard Diagnostic SOP
When Claude Code hits a hardware issue, the standard sequence is:
read_serial_log() # check for obvious log errors
read_call_stack() # if HardFault or hang suspected
measure_current(5000) # if power anomaly suspected
capture_frame() # if physical state unclear
build_firmware()
→ flash_firmware()
→ read_serial_log() # confirm clean boot
Why This Is Worth Building
To be honest, this project is still firmly in the “Ideally?” phase — some tasks require physical hardware and are being added incrementally. But the underlying logic is clear:
Give AI cleaner, more precise data, and it will do the job better.
When I’m manually copy-pasting logs, I’m a high-overhead human pipe. I get distracted, I paste wrong, I drop critical signals. When the AI can read JTAG directly, measure current itself, flash a new build, and verify the result — it’s working from complete, high-fidelity, real-time signals. Less noise in, better reasoning out.
This isn’t just about “automating debugging.” It’s about freeing embedded engineers from the repetitive perceive-transmit-instruct loop, letting humans focus on what actually requires genuine judgment.
As for “lying back and counting $$ 💰” — that’s still a long way off. First, let’s finish the closed loop.
The Project
If you work on embedded systems or are curious about MCP + hardware integration, check it out:
👉 github.com/kuochenfu/ai-hil-mcp
Quick start:
git clone https://github.com/kuochenfu/ai-hil-mcp.git ~/ai-hil-mcp
cd ~/my-firmware-project
bash ~/ai-hil-mcp/setup.sh
Once set up, Claude Code auto-connects to the MCP servers when you open any firmware project.
claude mcp list
# serial-mcp: ... ✓ Connected
Closing Thought
Sometimes the best engineering solutions start with a complaint.
“Why do I keep pasting logs manually?”
State the problem clearly enough, and the answer is right there: let the AI go look for itself.
The road ahead is long. But the direction is right.
Project repo: kuochenfu/ai-hil-mcp
Comments & Feedback