Skip to main content

dapper proxy — DAP Proxy Server

Start a Dapper proxy that sits between a DAP client (VS Code, IDE) and a debug adapter backend. The proxy enables multiple clients to share a single debug session and exposes a gRPC control plane for programmatic access.

You typically don't run this directly — an IDE integration starts it automatically when launching a debug session. Understanding this command is useful for manual setups or troubleshooting.

For session targeting (--scope-id, --control-port) see dapper help sessions.

Backend modes​

The proxy connects to a debug adapter in one of four ways:

Process (stdio)​

Spawn a debug adapter process and communicate via stdin/stdout:

dapper proxy --scope-id=vscode-54196 process /path/to/lldb-dap --interpreter=vscode

Arguments after the command name are passed through to the debug adapter.

Pass-through is unconditional, so it swallows Dapper's own global flags too. Put them before the subcommand, or use the environment variable instead (DAPPER_REASON, DAPPER_OUTPUT_JSON), which is placement-proof:

dapper proxy process /path/to/lldb-dap --reason "..."   # adapter gets --reason
dapper --reason "..." proxy process /path/to/lldb-dap # dapper gets --reason

TCP​

Connect to a debug adapter already listening on a TCP socket:

dapper proxy --scope-id=vscode-54196 tcp 127.0.0.1:4711

Unix Domain Socket​

Connect to a debug adapter listening on a UDS (Unix only):

dapper proxy --scope-id=vscode-54196 uds /tmp/debug.sock

From config​

Read a JSON configuration file that specifies the backend, launch request, and breakpoints:

dapper proxy --scope-id=vscode-54196 from-config /path/to/config.json

When a debugRequest is present in the config, the proxy runs in headless mode (no external DAP client needed) and emits structured progress events on stdout (or the fd passed to --events-fd). This is the mode used by automated/agent-driven debugging workflows.

Config keys are camelCase (the schema is dapper_session::DebugSessionConfig). Watch out: snake_case keys like debug_request are silently ignored — the proxy then sees no debug request and hangs waiting for an external DAP client instead of running headless.

spawnConfig.type is the transport (stdio / tcp / uds), not the language; the adapter in cmd must already be installed (e.g. pip install debugpy). Use "console": "internalConsole" for headless runs — integratedTerminal relies on a runInTerminal client capability the headless driver does not advertise. Fields inside debugRequest (other than request) pass through verbatim as DAP arguments, mirroring an IDE launch.json.

Options​

OptionDescription
--control-port PORTPort for the gRPC control plane (default 0 — OS picks an ephemeral port)
--client-port PORTTCP port for external DAP client connections (default: stdio)
--scope-id IDScope identifier for this session (e.g., vscode-54196); defaults to DAPPER_SCOPE_ID

When from-config is used, an extra --events-fd FD flag (Unix only) redirects the progress event stream to that file descriptor as bare JSON lines, instead of [DAPPER_SESSION] -prefixed lines on stdout, giving the driver a dedicated event channel.