# Delphi Visual Studio Code Debugger

> A debugger for delphi in visual studio code, and also a MCP server to give claude/copilot/etc authonomous delphi debugging capabilities

- **Type:** MCP server
- **Install:** `agentstack add mcp-csm101-delphi-visual-studio-code-debugger`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [csm101](https://agentstack.voostack.com/s/csm101)
- **Installs:** 0
- **Category:** [Developer Tools](https://agentstack.voostack.com/c/developer-tools)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [csm101](https://github.com/csm101)
- **Source:** https://github.com/csm101/delphi-visual-studio-code-debugger

## Install

```sh
agentstack add mcp-csm101-delphi-visual-studio-code-debugger
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Delphi Win64 Debugger

Debug Delphi Win64 applications outside the Embarcadero IDE — a real debugger
built on the Windows Debug API, written in Delphi.

The repository contains **three programs** that share one debugger engine:

| | What it is | Where it lives |
|---|---|---|
| **Debug adapter** | A **Debug Adapter Protocol (DAP)** server. This is the debugger itself: breakpoints, stepping, call stacks, variables, expression evaluation. Any DAP client can drive it. | `VisualStudioCodeDelphiDebugger\` |
| **VS Code extension** | The client that makes it usable in the editor: the `delphi-win64` debug type, the process picker for attaching, status-bar progress, and an editor for the exception rules. | `install\local.delphi-win64-debug\` |
| **MCP server** | The same engine exposed to an **AI agent** over the Model Context Protocol — 33 tools (`set_breakpoint`, `step_into`, `get_locals`, `evaluate_expression`, `get_call_stack`, `read_memory`, …). It lets an agent run a program, stop it, and read its actual state instead of guessing from the source. | `MCPDebugger\` |

The engine is shared: `DebuggerCore\` holds the Windows Debug API loop, the
symbol readers (`.rsm`, TD32, `.map`, `.dcp`, JCL) and the expression evaluator.
The three front ends are thin.

> **You will almost certainly also want the [Delphi IDE plugin](https://github.com/csm101/EditInVsCodeDelphiPlugin).**
> It adds an *Open in VS Code* command to the Delphi IDE that generates the
> workspace and the launch configuration for the current project: output paths,
> source root, unit search paths, and the package list for a BPL project. A real
> Delphi project carries a couple of hundred search paths, and nobody wants to
> write that by hand. The debugger works without it if you write `launch.json`
> yourself, but the plugin is what makes it practical — install it first.

> ⚠️ **Compile the program you want to debug with full debug information, or
> most of this will not work.** A debugger can only show what the compiler
> emitted. In the Delphi project options, for the **Win64 Debug** configuration:
>
> - *Compiling* → **Optimization off**, **Debug information** on, **Local symbols** on;
> - *Linking* → **Debug information** on, **Include remote debug symbols** on
>   (this is the `.rsm`), and **Map file: Detailed**.
>
> On the command line that is `-$O- -V -VN -VR`, which is what `Debugme.cfg` in
> this repository uses. Measured on that project: those four flags alone already
> emit the `.exe` with its TD32 section, the `.map` **and** the `.rsm` — `-GD`
> (Map file: Detailed) turned out not to be required for a `.map` to appear,
> though it is what the IDE sets and it does no harm. Keep the `.map` and `.rsm`
> next to the `.exe`.
>
> To step **into the RTL and VCL** rather than over them, also enable
> *Compiling* → **Use debug .dcus**.
>
> What each one buys you:
>
> | Artefact | Without it |
> |---|---|
> | TD32 section, `.map`, or JCL data — **any one** | no source lines: no breakpoints, no stepping |
> | **`.rsm`** | breakpoints and stepping still work, but local variables, types and expression evaluation are severely limited |
> | optimizations **off** | breakpoints land on the wrong line and locals read as garbage, because the code no longer matches the source |
>
> The same applies to every **runtime package** you want to step into: a BPL
> compiled without debug information stays a black box even when the host has
> full symbols.

> **Status**: working and feature-rich. Launch and attach, breakpoints
> (line / conditional / hit-count / log-points), stepping (over/into/out)
> and set-next-statement, call stack with function names, variable
> inspection (locals, registers, globals, nested object / record /
> dynamic-array expansion) with type-aware formatting, a full Pascal
> expression evaluator for watch/hover/REPL, `setVariable` (primitives,
> strings, enums, sets, `var` parameters), and a configurable exception
> engine (filters + per-exception rules) are all functional. See
> [What works](#what-works) for the full list.

---

## Prerequisites

| Tool | Purpose |
|---|---|
| **Delphi 10.3 Rio or later** (`dcc64` in PATH after `rsvars.bat`) | Compiling the adapter and the debug target |
| **VS Code** | The editor the extension plugs into |
| **[Delphi IDE plugin](https://github.com/csm101/EditInVsCodeDelphiPlugin)** | Generates the workspace and launch configuration from a Delphi project. Not strictly required, but see the note above |
| **DelphiLSP extension** (`embarcaderotechnologies.delphilsp`) | Delphi language support in VS Code (syntax, autocomplete). A separate Embarcadero extension; this one only debugs |
| **JCL sources** (optional) | Only for the default JCL debug-info support; build with `JCL_DEBUG_OFF` to omit it — see [Optional: JCL debug-info support](#optional-jcl-debug-info-support) |

---

## Quick start

> **Just want to use it?** Do not build anything. Grab
> `delphi-win64-debugger-setup-*.zip` from the
> [latest release](https://github.com/csm101/delphi-visual-studio-code-debugger/releases),
> extract it anywhere and run `Setup.exe`. The debug adapter, the MCP server and
> the VS Code extension are already compiled inside it, so no Delphi toolchain
> and no build step are needed on that machine. Windows will warn that the
> executables are unsigned — see the notes in the release.
>
> The rest of this section is for working **on** the debugger from a source
> checkout.

Assumes Delphi (Athens or later) is installed and `dcc64` is on PATH after
`rsvars.bat`, plus VS Code.

This is the path for working **on** the debugger from a source checkout — it
installs the extension in development mode, where VS Code launches the adapter
straight from the compiler output, so rebuilding is enough to pick up changes
(no copy step). To install the debugger only to *use* it, or to ship it to a
machine without the sources, see the alternatives right after.

```bat
:: 1. Get the repository
git clone  Win64Debugger
cd Win64Debugger

:: 2. Build the adapter and install the extension in DEVELOPMENT mode. It writes
::    a manifest whose "program" points directly at the build-output exe, so a
::    rebuild is reflected on the next debug session with no copy. Run once.
call install-dev.bat

:: 3. Build the bundled sample so there is something to debug. A fresh clone
::    has no .exe/.map/.rsm (they are gitignored), so build them once.
call rsvars.bat
dcc64 Debugme.dpr
```

Now open the project and start a session:

1. If VS Code prompts to install the recommended **DelphiLSP** extension
   (`embarcaderotechnologies.delphilsp`, from `.vscode/extensions.json`), accept.
2. Open **`Win64DebuggerProj.code-workspace`** — open the *workspace file*, not
   the folder; it wires up DelphiLSP and the compiler settings.
3. Reload the window (`Ctrl+Shift+P` → *Developer: Reload Window*).
4. In **Run and Debug** (`Ctrl+Shift+D`) pick **"Debug Debugme (Delphi DAP)"**
   and press `F5`. You should hit the entry point and be able to step, set
   breakpoints, and inspect variables.

After a change to the adapter source, the edit/test loop is just:

1. Stop the running debug session (`Shift+F5`) — the exe is locked while it runs.
2. `call build_dap.bat`
3. `F5` — VS Code relaunches the freshly built adapter. No re-install, no copy.

To debug your **own** application instead, compile it with debug info
(`-V -VN -VR`, optimizations off) so it emits `.map` and `.rsm` next to the
`.exe`, then add a launch configuration — see
[Launch configuration](#launch-configuration).

> **Install to use, not develop** — to copy the adapter into the extensions
> folder (so it no longer depends on the checkout) run `build_installer.bat`
> then `install\Install.exe`. It is interactive: builds the adapter if needed,
> detects VS Code / VS Code Insiders, updates an existing install in place after
> confirmation. See [VS Code extension setup](#vs-code-extension-setup).

> **Ship to another machine** — to install on a machine **without** the
> repository or a Delphi toolchain, build a self-contained zip with
> `build_setup_zip.bat` and ship it — see
> [Distributable zip](#distributable-zip-no-repo-no-delphi-on-the-target).

---

## Build

### One-shot: build everything

```bat
call build_debug.bat
```

This initializes the Delphi compiler environment (`rsvars.bat`), compiles `Debugme.exe` (emitting its `.map` and `.rsm`), and compiles `VisualStudioCodeDelphiDebugger.exe`.

### Adapter only (faster iteration)

```bat
call build_dap.bat
```

### Compiler flags for the debug target

Key flags that must be active when compiling the program you want to debug:

| Flag | Purpose |
|---|---|
| `-$O-` | Disable optimizations |
| `-V -VN -VR` | Generate debug info and `.map` file |
| `-DDEBUG` | Optional conditional define |
| `-E.\Win64\Debug` | Output directory |

For `Debugme` these are set in `Debugme.cfg` (one per line, without the leading `-`).

### Optional: JCL debug-info support

The adapter can additionally read **JCL** (JEDI Code Library) debug data — the
MAP-derived symbol table JCL stores either as a linked `JCLDEBUG` PE section or a
sidecar `.jdbg` file — as an address→location and procedure-name fallback for
modules that ship JCL data but no embedded TD32 / no `.map`. It is implemented in
`DebuggerCore\JclDebugReader.pas` and gated by the `JCL_DEBUG` conditional.

`JCL_DEBUG` is **ON by default**, which requires the JCL sources to be present.
The build configurations point at the default install location
`C:\Athens\jcl\jcl\source` (subdirectories `windows`, `common`, `include`); adjust
those paths if your JCL lives elsewhere. The affected configs are the adapter
`VisualStudioCodeDelphiDebugger\VisualStudioCodeDelphiDebugger.cfg`, the test
runner `DebuggerTests\RunTests.cfg`, and `build_mcp.bat`.

**To build without JCL** (e.g. JCL is not installed): compile with the
`JCL_DEBUG_OFF` conditional defined. This removes the `uses JclDebug` entirely, so
JCL need not be installed and the JCL search paths are ignored (they are harmless
when the define is off). Add the define to the relevant `.cfg` files, e.g.:

```text
-DJCL_DEBUG_OFF
```

into `VisualStudioCodeDelphiDebugger.cfg`, `DebuggerTests\RunTests.cfg`, and pass
`-DJCL_DEBUG_OFF` on the `dcc64` command line in `build_mcp.bat`. With the define
off, `JclDebugReader` compiles to a no-op factory (it never registers a provider);
everything else — TD32, `.map`, `.rsm`/`.dcp` symbol resolution — is unaffected.

> If you build the adapter, MCP server, or test runner from the **IDE** (msbuild
> via the `.dproj`) rather than these command-line scripts, apply the same choice
> there: add the JCL search paths (to keep it on) or the `JCL_DEBUG_OFF` define (to
> turn it off) in the project options, since an IDE build regenerates the `.cfg`
> from the `.dproj`.

### Optional: pre-build the symbol-index sidecars

The first time the debugger reads a module's `.rsm` or `.dcp`, it scans the whole
container to build a lookup index, then caches that index in a `.idx`
sidecar next to it. The scan costs roughly half a second for a 45 MB package;
every later session reloads the sidecar in a few milliseconds instead.

The catch is *when* that scan happens: lazily, at a stop, on the thread the
debugger answers requests on. Stopping somewhere that first touches several
runtime packages therefore pauses the session while they are indexed.

The RTL and third-party packages never change between your builds, so their
sidecars can be built once, offline:

```bat
cmd /c "C:\Athens\GitHub\Win64Debugger\DevTools\build_all.bat"

rem the Delphi DCP corpus - a few hundred files, one pass, a few minutes
DevTools\Win64\Debug\PrebuildIdx.exe "C:\Users\Public\Documents\Embarcadero\Studio\23.0\Dcp\Win64" -j 2
```

Add `-force` when sidecars already exist but were written by an older build of
this project: a change to the index format or to the parser leaves them stale,
and a stale sidecar is ignored, so the cold scan is paid again in every session
until they are rebuilt.

This does **not** help your own packages — you recompile those constantly, which
invalidates their sidecars by design. If it is worth automating, run the tool
over your output directory as a post-build step.

Source is `DevTools\PrebuildIdx.dpr`; `DevTools\README.md` documents the full
flag list, including `-verify`, which rebuilds every sidecar and compares it by
SHA-256 against the one already on disk (useful after touching a parser).

---

## Tests

An automated integration suite lives in `DebuggerTests\`. It builds a dedicated
test target, launches the real DAP adapter against it, and asserts correctness of
breakpoints, stepping, locals, and the expression evaluator. Run the full suite
after any change to the adapter or the RSM/TD32 parsers.

```bat
:: build the target + the runner, then run everything
call DebuggerTests\build_and_run.bat
```

The scripts use `cd /d %~dp0` internally, so they can be called from any working
directory. Finer-grained entry points:

| Script | Purpose |
|---|---|
| `DebuggerTests\build_and_run.bat` | Build the test target and runner, then run the suite |
| `DebuggerTests\build_target.bat` | Build only the debuggee (`TestTarget.exe`) |
| `DebuggerTests\build_runner.bat` | Build only the test runner (`RunTests.exe`) |
| `DebuggerTests\run_tests.bat` | Run the already-built tests |

Separate diagnostic tools (RSM/TD32 inspectors, PE dumpers) live in `DevTools\`;
see `DevTools\README.md`.

---

## VS Code extension setup

The extension lives in a local directory under VS Code's extension folder. It is **not** published to the marketplace.

### Recommended: the installer

After building the adapter (`build_dap.bat`), run:

```bat
call build_installer.bat
install\Install.exe
```

`Install.exe` stages the freshly built adapter next to the extension
manifest, detects your VS Code installation(s), and copies the extension
into `%USERPROFILE%\.vscode\extensions\local.delphi-win64-debug\`. If a
previous version is already installed it updates it in place (after
confirmation). Reload VS Code afterwards.

### Scripted alternative

```bat
:: build the adapter and stage it into install\local.delphi-win64-debug\
call update-install.bat
:: copy the staged folder into your VS Code extensions directory
call install\install.bat
```

### Manual

1. Build the adapter (`build_dap.bat`).
2. Create the folder
   `%USERPROFILE%\.vscode\extensions\local.delphi-win64-debug\`.
3. Copy `install\local.delphi-win64-debug\package.json` and the built
   `VisualStudioCodeDelphiDebugger.exe`
   (`VisualStudioCodeDelphiDebugger\Win64\Debug\`) into it.
4. Reload VS Code (`Ctrl+Shift+P` → *Developer: Reload Window*).

The bundled `package.json` registers the `delphi-win64` debug type and
points at the adapter via the relative path `./VisualStudioCodeDelphiDebugger.exe`,
so no path editing is needed as long as the executable sits beside it.

### Where the adapter executable ends up

The build, the staging step and the install each hold a copy:

| Stage | Location |
|---|---|
| Build output | `VisualStudioCodeDelphiDebugger\Win64\Debug\VisualStudioCodeDelphiDebugger.exe` |
| Staging (gitignored, inside the repo) | `install\local.delphi-win64-debug\VisualStudioCodeDelphiDebugger.exe` |
| Installed (what VS Code launches) | `%USERPROFILE%\.vscode\extensions\local.delphi-win64-debug\VisualStudioCodeDelphiDebugger.exe` |

### Distributable zip (no repo, no Delphi on the target)

To install the debugger on another machine that has neither the repository nor a
Delphi toolchain, build a self-contained zip on a development machine:

```bat
call build_setup_zip.bat
```

It builds the adapter, builds the portable installer, and bundles everything into
`dist\delphi-win64-debugger-setup-v.zip`:

```text
Setup.exe                     ← portable installer / updater
local.delphi-win64-debug\     ← the extension (manifest + prebuilt adapter exe)
INSTALL_INSTRUCTIONS.md
```

On the target machine: extract the zi

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [csm101](https://github.com/csm101)
- **Source:** [csm101/delphi-visual-studio-code-debugger](https://github.com/csm101/delphi-visual-studio-code-debugger)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-csm101-delphi-visual-studio-code-debugger
- Seller: https://agentstack.voostack.com/s/csm101
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
