There is a gap between Claude and your Delphi app. Autopilot closes it.
You already work hand in hand with an AI assistant: you give a prompt, Claude writes the code, Claude even compiles it. And then it stops dead. It cannot test/debug the program for you. If your program has an OK button, you have to click it. The AI can’t.
Everything past “compile” is on the far side of a wall. The AI needs you at the keyboard to push the buttons and report back.
That gap was in my way, so I built a bridge across it. Autopilot for Delphi — the Delphi AI Bridge — hands the controls of your running VCL or FMX app to the AI. It can click all controls, type text into edit boxes, read the labels, sets and reads any property, take screenshots — the same loop a human operator runs, except the assistant does it on its own.
Add one line of code to your project, and the wall is gone.
How to use it
Point the AI to the folder where Autopilot for Delphi is installed. Instruct it to read the “AI-INSTRUCTIONS.md” file. In the evening, hand it one big prompt and leave the computer running. Claude writes the code, builds it, drives the running app to check it. Come back in the morning to a GUI app that is built, clicked-through, and working.
Real-life demo
A real session: I told Claude that the “Next page” button in my FMX app (Orinoco eReader) was broken — it wasn’t, but it’s a good test. Claude runs the app, finds and presses the real button, reads the page state before and after, and reports back.
1 — The prompt. “Run the app, press the button, see if the page changes, report back.”

btnNext).
PageIndex 1→2, the spinbox 2→3, the rendered page visibly turned. The button works.
Who said it is only for testing & debugging?
Pushing the real buttons means the AI can operate your program, not just inspect it. If your app were an email client like Thunderbird, the AI could answer customers, search contacts, build templates, harvest addresses — driving your own application, the way the end user would. This is full automation, not just testing.
How does it compare with Embarcadero Kai?
They are not the same thing — and they work well together. Kai is Embarcadero’s agentic-AI add-on for RAD Studio. It writes code, compiles, and fixes compiler errors — all inside the IDE, on your source. The moment the app is built and running, Kai stops: it can’t press a button or read a label. That is the gap. Autopilot lives on the other side of it — in the running app — and that’s exactly where Kai can’t go.
| Kai | Autopilot | |
|---|---|---|
| Write code in the IDE | yes | no |
| Build, fix compiler errors | yes | yes* |
| Drive and operate the running app | no | yes |
| Debug / test the GUI (click, type, read state) | no | yes |
| Screenshot the running app | no | yes |
* Autopilot itself doesn’t compile — but it runs inside Claude Code, which writes and builds the code. So end to end, the Autopilot workflow does build and fix.
Run both and the loop closes with no human in the middle: Kai (or Claude Code) writes and fixes the code; Autopilot drives the running result and reports whether it truly works.
How it works
Three small pieces and one pipe. Your app links in a tiny bridge unit; a separate server process speaks the Model Context Protocol to the AI; the two talk over a private Windows named pipe.
You add one unit and one call to your project:
uses
Vcl.Forms,
Autopilot.Bridge.Vcl, // 1. add the unit (Autopilot.Bridge.Fmx for FireMonkey)
FormMain in 'FormMain.pas' {frmMain};
begin
Application.Initialize;
Application.CreateForm(TfrmMain, frmMain);
Autopilot.Bridge.Vcl.StartBridge; // 2. start the bridge
Application.Run;
end.The bridge is wrapped in {$IFDEF AUTOPILOT}. You add that define to your debug build only — so release builds compile StartBridge to nothing. No thread, no pipe, no automation surface in production. Your shipped binaries are exactly as they were.
The AI sees your form’s real component tree and acts on it through a small set of typed tools (the full list is below). Because it reads and writes properties through RTTI directly, it works with any third-party control pack — DevExpress, TMS, anything — with no OCR and no fragile screen coordinates. Setup is a one-time registration of the server with your AI host — on Claude Code that’s a single line, claude mcp add autopilot -- C:\Path\To\Autopilot.Mcp.exe. From then on it auto-discovers your running app — no port to configure, no manual attach.
What’s in the download
The two bridge units — Autopilot.Bridge.Vcl and Autopilot.Bridge.Fmx — pre-built as DCUs for every supported Delphi version, plus the MCP server Autopilot.Mcp.exe you register once with your AI host. Two ready-to-run demo apps come along (one VCL, one FMX) so you can drive a real form from an AI session in a couple of minutes. And the AI-INSTRUCTIONS.md brief that teaches the assistant how to drive your app efficiently.
The tools the AI calls
No macro recorder, no script to maintain — under the hood it’s a small, typed toolset that the assistant calls straight from a chat session. Thirteen tools cover the whole operate-and-observe loop:
| Tool | What it does |
|---|---|
list_tree | Enumerate every form and control — names, classes, paths, text, enabled/visible state. The AI’s map of your app. |
click | Click a button, or anything with an OnClick. Repeat N times in a single call; override the per-call timeout. An opt-in message mode presses a button that opens a modal dialog without blocking: the click is queued, the answer comes back at once, then dismiss_dialog closes the popup. |
execute_action | Fire a TAction directly — for shortcut-only actions and actions shared by several controls. |
get_text / set_text | Read and write Caption / Text / Lines on edits, memos and labels. Writing fires OnChange. |
set_checked | Toggle a checkbox or radio button; fires OnChange. |
set_property | The Swiss-army knife: write any published property — Tag, Color, Position, ItemIndex, sets, even AI-friendly colors like clRed or #FF8000. Mistype a name and it hands back the full list of writable properties with their live values, so the AI corrects itself without another round-trip. |
read_property | Read any published property via RTTI — and what it returns is exactly what set_property accepts back. |
wait_for | Poll a property until it matches or times out — for async work (TTask, database queries, timers). |
screenshot | Capture the form as a PNG, for visual and layout checks. |
attach | Pick a target when several apps are running. Usually unnecessary — every tool auto-attaches. |
set_keep_awake | Keep the device screen on while the AI drives an Android target, so the OS doesn’t freeze the app mid-session. A no-op on Windows. |
dismiss_dialog | List and dismiss native OS dialogs (MessageBox, Task Dialogs, file dialogs) that the component tools can’t see — details in the next section. |
The assistant bundles several of these into a single turn — find the control, type, click, then check the result — so a whole reproduce-and-verify sequence is one round-trip, not ten.
Native OS dialogs
A TForm.ShowModal dialog is an ordinary VCL/FMX form, so the component tools (click, set_text, …) drive it directly. A native OS dialog — Application.MessageBox, the Vista Task Dialog behind a default ShowMessage/MessageDlg, a common file dialog — is a raw Win32 window with no TComponent, so those tools cannot see it and return not_found. The dismiss_dialog tool reaches it through Win32 instead: it lists the dialogs that are up and dismisses one by clicking a button (by role, caption, or control id). A visible modal dialog runs a message loop, so the bridge still reaches the main thread to act even while the app looks blocked. And the click that opens the dialog doesn’t block either: the AI presses that button in message mode, gets its answer immediately, then dismisses the popup.
| Popup | How the AI drives it |
|---|---|
Your own TForm.ShowModal | Component tools — it is in Screen.Forms[] |
ShowMessage / MessageDlg in a VCL-styled app | Component tools — it renders as a TForm |
ShowMessage / MessageDlg, default (native Task Dialog) | dismiss_dialog |
Application.MessageBox, TOpenDialog / TSaveDialog | dismiss_dialog |
Windows targets only; against an Android FMX target dismiss_dialog reports supported:false.
What it deliberately doesn’t do
Honesty first. Autopilot acts directly on your Delphi objects; it doesn’t fake Windows mouse and keyboard input. That’s a deliberate trade, and it has a flip side — bugs that only show up through the real input pipeline won’t reproduce through it. Things like:
- Focus-change validation (
OnExit, kill-focus handlers) - IME composition and Asian-language input
- Keyboard accelerators that travel through the Windows message loop
- Hover-driven UI (mouse-enter / mouse-leave)
- Drag-and-drop started by a real mouse-down-and-move
A message-based click mode covers some of this for buttons; for full input-pipeline coverage you would pair Autopilot with a SendInput-style tool (TestComplete, Ranorex, AutoIt).
In return for that trade you get direct property access with no OCR and no fragile screen coordinates, sub-millisecond round-trips, and compatibility with any third-party control pack — because RTTI is universal.
I built it because I needed it
I use Claude every day on real Delphi work, and “I can’t see what the app is actually doing” kept stopping me cold. So I built the bridge, used it on my own projects, and it worked well enough that I cleaned it up for other Delphi developers.
Availability, pricing & supported Delphi versions
Autopilot is feature-complete — VCL and FMX bridges, thirteen tools, a passing test suite, plus working VCL and FMX demo apps you can drive from an AI session in about 2 minutes
Supported Delphi versions at launch: 11 Alexandria, 12 Athens and 13 Florence — Win32, Win64 and Android (FMX).
The FMX bridge also drives Android targets — the AI reaches the running app over adb, and set_keep_awake holds the screen on so the OS doesn’t freeze the app mid-session.
Free for private use.
Corporations can purchase a license here.
Found a bug?
Get in touch via my About page. Every session writes a log to %TEMP%\Autopilot\<ExeName>-<PID>.log — every command in and out, plus the dispatch timings. Attach the one from a run that reproduces the problem and I’ll have what I need.
Under the hood
No third-party dependencies — just the standard library and the Windows API. The one borrowed trick, generic-click dispatch, is lifted from Embarcadero’s own Vcl.UIACtrlProvider.pas.
Interested in Delphi and AI? See my Delphi in All Its Glory – AI assisted development book.