Read the real values
Stop where the bug happens and check the locals that changed. Evaluate an expression in that exact frame, using the values the program actually has at runtime.
eyedbg is a CLI-first debugger built for AI coding agents. Breakpoints, stepping, locals and eval, one shell command at a time, in a live session you can join from VS Code whenever you want to look, or take the wheel.
Works with Claude Code, Codex and any agent that can run a shell command.
Animation: you ask Claude Code to debug a wrong order total, and it starts a debug session with eyedbg and stops at a breakpoint; you join the same session from VS Code; Claude Code runs to the iteration with the bug and reads a value; you ask for control, and Claude Code hands it over.
Drives proven debuggers for you
eyedbg is free and open source. Your AI coding agent runs it from the terminal to set breakpoints, step through code and read the program's real values while it runs. Join the same session from VS Code any time you want to look, or take over.
A CLI debugger for .NET, Python, Go, C, C++ and Rust. A daemon holds the session; the agent, and you if you join, are just clients of it.
When a fix based on reading the code doesn't work, agents start guessing and printing more logs. eyedbg lets an agent stop at the real line and check the real values instead.
Developers using a coding agent on .NET, Python, Go, C, C++ or Rust, who don't want to buy a commercial IDE just to get a debugger.
No remote or mobile debugging, no browser JavaScript, and it's not an IDE, just a debugger for a program on your machine. You don't need it for a compile error either.
Curious how it works? Keep reading, or jump straight to install.
When a fix based on reading the code fails once or twice, the fastest way forward is to see what the program is actually doing. eyedbg gives your agent a real debugger to drive from the shell, and gives you a seat in the same session.
Stop where the bug happens and check the locals that changed. Evaluate an expression in that exact frame, using the values the program actually has at runtime.
One stateless command per step, each answering with the full picture. Output is budgeted to fit a context window, JSON and error codes are stable, and the built-in help is the documentation. No MCP server to install or configure.
With eyedbg, a daemon owns the session, and every client joins it: the agent's CLI, your VS Code, any DAP client. You can both be in the same session at once, seeing the same stops and variables.
The eyedbg CLI is stateless. Each command is a short call to eyedbgd, a per-user daemon that holds your debug sessions and runs a Debug Adapter Protocol (DAP) debugger for each language. Your editor connects to the same daemon, so you and the agent always see the same program state.
eyedbg CLI · stateless, one call per stepeyedbg dapEach command is one short-lived process: it connects, does one thing and exits. Agent harnesses that run every command in a fresh shell just work.
The first command starts eyedbgd; it serves all your sessions and exits after 30 idle minutes. An adapter crash ends only its own session.
A Unix socket in a directory only you can enter, and a fresh random token checked on every connection. No TCP listener, even for editors.
eyedbg adds no engine of its own: it drives DAP adapters, each described by a JSON manifest that says how to install, find and launch it.
A wrong order total, found the way your agent would find it. Every execution command answers with where the program stopped, the source around it and the locals that changed, so there's never a follow-up call just to see where it is.
Builds the project, runs it and stops on the one line that contains var total =. Text anchors keep working when lines move; Orders.cs:14 and func:Orders.Total work too.
$ eyedbg start dotnet --project src/Shop --bp 'Orders.cs@"var total ="'
session s-7f3k (dotnet, netcoredbg) stopped: breakpoint, thread 4242
at Shop.Orders.Total() Orders.cs:14
13 | {
> 14 | var total = 0m;
15 | for (var i = 0; i < orders.Count; i++)run-until continues to line 18 and stops there only once i == 3. The answer is the stop itself: location, source and what changed since the last one.
$ eyedbg run-until Orders.cs:18 --if 'i == 3'
session s-7f3k (dotnet, netcoredbg) stopped: breakpoint, thread 4242
at Shop.Orders.Total() Orders.cs:18
17 | var order = orders[i];
> 18 | total += order.Price * order.Quantity;
19 | }
changed since the previous stop:
i: int = 3 (was 0)
total: decimal = 127.50 (was 0)
order: Order = {Shop.Order} {…} (new)eval runs in the stopped frame. The fourth order is a refund with a negative quantity, which explains the wrong total in two reads.
$ eyedbg eval 'order.Quantity'
-2 (int)
$ eyedbg eval 'order.Refunded'
true (bool)An expression that could change the program is refused, with a stable code and a hint. --allow-side-effects runs it: that takes the control lease and is recorded in the session's events.
$ eyedbg eval 'order.Recalculate()'
eyedbg: eval would call a method (Recalculate), which can change the program [SIDE_EFFECTS]
hint: add --allow-side-effects (it takes the control lease)eyedbg stop ends the session and the program, or detaches from a program you attached to. The daemon goes away by itself once it's idle.
$ eyedbg stop
session s-7f3k endedEyeDebugger is a real, first-party VS Code extension (id eyedebugger.eyedbg). Join the agent's live session, or press F5 and let the agent join you. Either way, you're both looking at the same breakpoints and the same stops, and one control lease decides who's driving.
Grab the VSIX from a GitHub release that has one (0.2.0 and later) and install it: code --install-extension eyedebugger_X.Y.Z_vscode.vsix. It finds eyedbg on your PATH, or set eyedbg.path yourself. Full steps are in Install below.
Exactly one client holds execution control: continue, step, pause, set and side-effecting eval. Everyone else can read state, set their own breakpoints and ask for control.
The agent's breakpoints show in your editor with whose they are and what they do (⬥ agent · if total > 3). Removing one only hides it for you; Copy as My Breakpoint makes it yours.
When the agent's step stops, VS Code shows the line without taking your keyboard focus. The Activity and Clients views list what each client did, who is connected and who has control.
When an agent starts debugging a program in your workspace, VS Code offers to join, once per session and never without your click.
The CLI's launch options work in launch.json too: language, program or project, args, env, exceptions and more. For Python, console: integratedTerminal (0.2.0 and later) runs it in a real terminal, so input() works.
eyedbg dap speaks standard DAP on stdio and joins a running session under the same rules, for nvim-dap, scripts or another editor.
freeThe default. Anyone can take control; running or stepping takes it automatically.handoffOnly the holder releases control or gives it to someone.human-priorityLike handoff, but a human can always take control from an agent. Agents never take it from one another.{
"type": "eyedbg",
"request": "attach",
"name": "Join eyedbg session"
}{
"type": "eyedbg",
"request": "launch",
"name": "Debug Shop",
"lang": "dotnet",
"project": "${workspaceFolder}/src/Shop",
"leasePolicy": "human-priority"
}{
"type": "eyedbg",
"request": "launch",
"name": "app.py (eyedbg)",
"lang": "python",
"program": "${workspaceFolder}/app.py",
"console": "integratedTerminal"
}{
"type": "eyedbg",
"request": "launch",
"name": "eyedbg: dotnet web",
"lang": "dotnet",
"project": "${workspaceFolder}/dotnetweb.csproj",
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
}
}local dap = require('dap')
dap.adapters.eyedbg = {
type = 'executable',
command = 'eyedbg',
args = { 'dap', '--as', 'human:alex' },
}
dap.configurations.cs = {
{ type = 'eyedbg', request = 'attach', name = 'Join eyedbg session' },
}eyedbg sessions # who is connected, who has control
eyedbg lease request --message 'let me step into Total()'
eyedbg events --wait --kind lease # wait for the answer
eyedbg lease grant human:alex # hand control to a humanA walkthrough of one shared session: the agent's first breakpoint, you joining from VS Code, and the handoff of control.
Every language uses the same commands and the same output. You add one with a JSON adapter manifest; there's no driver code to write.
Builds your project and debugs it, attaches to a running process or a test run. SharpDbg adds lambdas and LINQ in eval. You install either one with a single eyedbg command. Since 0.3.0 it also debugs a .NET service in a docker container or compose stack (see the FAQ).
eyedbg adapters install netcoredbg
eyedbg start dotnet --project src/Shop --bp Orders.cs:18
eyedbg test dotnet Adds --bp 'CalculatorTests.cs@"Assert.Equal"'Runs a script or a module like python -m. Finds your interpreter: --opt python=PATH, your active virtualenv, the project's .venv, then PATH.
eyedbg adapters install python
eyedbg start python --program app.py --bp app.py:7
eyedbg start python --opt module=pytest -- -x tests/test_orders.pyDebugs a package, a built binary (--opt mode=exec) or a package's tests, over a private Unix socket. Function breakpoints are package-qualified.
eyedbg adapters install delve
eyedbg start go --program ./cmd/shop --bp main.go:20
eyedbg start go --program ./internal/orders --opt mode=testUses the lldb-dap on your PATH, or the one EYEDBG_LLDB_DAP names. In C++, --exceptions all stops at every throw.
eyedbg start c --program ./build/app --bp main.c:20
eyedbg start cpp --program ./build/app --exceptions allDebugs your debug build with lldb-dap. Import Rust's LLDB formatters in ~/.lldbinit to read String, Vec and HashMap values.
cargo build
eyedbg start rust --program ./target/debug/shop --bp src/main.rs:20A JSON manifest says how to download, find and launch a DAP adapter and how to fill its launch request. Yours live in ~/.eyedbg/adapters, trusted like your shell config, never read from a project.
eyedbg adapters ls # bundled and your own
eyedbg adapters doctor # checks each one it knowsdocs/adapter-manifests.md).
Give your agent the prompt below and it handles all of this, or do each step yourself. Either way, it's once per machine.
Copy this into your agent's chat. It works out your OS and downloads the right release, and checks it against checksums.txt. It asks what you want before it changes anything.
Please install eyedbg (EyeDebugger) on this machine for me. It's a free, open-source debugger that
AI coding agents drive from the terminal, and I can join the same debug session from VS Code.
Project: https://github.com/EyeDebugger/eyedebugger
1. Work out my OS (Linux, macOS or Windows) and CPU (x64 or arm64).
2. Before installing anything, ask me which of these I want. Use your question tool if you have
one, otherwise show a numbered list; I can pick several.
- eyedbg itself: the eyedbg CLI and its eyedbgd daemon (always installed)
- .NET: netcoredbg (the default), and optionally SharpDbg (it bundles a Microsoft library under
a license that isn't open source and may send data to Microsoft; `eyedbg help adapters
install` explains)
- Python: debugpy
- Go: Delve
- C, C++ and Rust: LLVM's lldb-dap (from my OS's LLVM package, not from eyedbg)
- The VS Code extension
- The eyedbg skill for you (the agent)
3. Open https://github.com/EyeDebugger/eyedebugger/releases. It lists releases newest first, each
with its assets. Pick the release to use: the newest stable release whose assets include a file
named exactly eyedebugger_<version>_vscode.vsix; if no stable release has one yet, the newest
pre-release that does. Use that release's own <version> for everything below, and don't mix
assets from two different releases. Download checksums.txt and the archive for my system:
eyedebugger_<version>_<os>_<arch>.tar.gz on Linux and macOS, .zip on Windows, where <os> is
linux, darwin or windows and <arch> is amd64 or arm64.
4. Check the archive before using it. checksums.txt has one "<sha256> <file name>" line per file.
Find the line whose file name is exactly the archive's name, compute the archive's SHA-256, and
compare (ignore upper/lower case). If there is no such line, more than one, or the hashes differ,
stop and tell me; don't continue without that check. If the gh CLI is installed, also run
gh attestation verify <archive> -R EyeDebugger/eyedebugger and stop if it fails.
5. Unpack the whole archive into a folder of its own that my user owns (for example
~/.local/share/eyedbg, or %LOCALAPPDATA%\Programs\eyedbg on Windows). Keep eyedbg, eyedbgd and
the helpers folder together in it. Add that folder to my PATH for new terminals (or link eyedbg
and eyedbgd into a folder already on PATH). Don't use sudo or admin rights unless I say so.
6. Run: eyedbg version
7. For each language I picked, run the matching command:
eyedbg adapters install netcoredbg
eyedbg adapters install sharpdbg
eyedbg adapters install debugpy
eyedbg adapters install delve
For C, C++ or Rust, install lldb-dap 18 or newer with my OS's package manager (ask me first). If
it isn't on PATH as lldb-dap, set EYEDBG_LLDB_DAP to its full path.
Then run eyedbg adapters doctor with the languages I picked (for example:
eyedbg adapters doctor dotnet python) and fix what it reports.
8. VS Code extension: download eyedebugger_<version>_vscode.vsix from the same release, and check
it exactly as in step 4: checksum against checksums.txt, then gh attestation verify if the gh
CLI is installed. Then run:
code --install-extension <the .vsix file>
9. The skill: eyedbg skill install puts it where Claude Code looks. For another agent, use
eyedbg skill install --dir <your skills folder>. Tell me to restart you so you load it.
Only use the debug adapters eyedbg installs or finds itself. Don't download or set up any other
debugger. When you're done, tell me what you installed, where, and anything I still need to do.
Prefer doing it by hand? Here's every step.
Download the archive for your platform from a GitHub release: eyedbg, eyedbgd and the .NET side helper. Keep them together on your PATH, and check the archive was built by the project's release workflow. With Go 1.26 or later, go install works too (without the .NET helper).
gh attestation verify eyedebugger_X.Y.Z_linux_amd64.tar.gz -R EyeDebugger/eyedebuggergo install github.com/eyedebugger/eyedebugger/cmd/eyedbg@latest github.com/eyedebugger/eyedebugger/cmd/eyedbgd@latestPinned and checksum-verified. Name an adapter or a language; C, C++ and Rust use the lldb-dap on your PATH. doctor checks what you have.
eyedbg adapters install netcoredbg # or: python, delve, sharpdbg
eyedbg adapters doctorInstalls the skill for Claude Code. For another agent, use --dir with its skills folder, or point it at eyedbg help --all.
eyedbg skill installInstall the EyeDebugger extension from the VSIX attached to releases from 0.2.0 on. It finds eyedbg on your PATH, or set eyedbg.path.
code --install-extension eyedebugger_X.Y.Z_vscode.vsixLaunch and attach, breakpoints of every kind, stepping, threads, stacks, variables, eval and set.
continue, next, step-in, step-out and run-until wait until the program stops, exits or times out (30 s by default), then print the reason, the location, the source around it and the locals that changed. A timeout isn't an error: the program keeps running and eyedbg wait picks it up.
$ eyedbg next
session s-7f3k (dotnet, netcoredbg) stopped: step, thread 4242
at Shop.Orders.Total() Orders.cs:19
18 | total += order.Price * order.Quantity;
> 19 | }
20 | return total;
changed since the previous stop:
total: decimal = 42.50 (was 127.50)Orders.cs@"var total =" resolves to the one line that holds the text, and reports the line it found. It's an anchor, so it still works after the file changes and the line numbers shift.
File:LINEFile@"text"func:NameStop only when it matters, or print instead of stopping. eyedbg runs hit counts and logpoints itself, so they behave the same on every adapter.
--if 'i == 3'--hit '>=3'--log 'i={i}'Variables are cut to --budget tokens (2,000 by default), and every cut says how to see the rest, like eyedbg vars --expand orders.
Method calls, assignments, new and ++ are refused as SIDE_EFFECTS unless you pass --allow-side-effects, which needs the control lease and is logged.
eyedbg bp exceptions uncaught (or all) stops where an exception is thrown; the stop shows its type, message, stack and inner exception, and $exception evaluates it.
eyedbg attach dotnet --pid 4321 joins a running process of yours. eyedbg test dotnet Adds runs dotnet test attached to the test host, so breakpoints in the tests and the code they call hit; Go runs tests with --opt mode=test. For a .NET service in a docker container, eyedbg attach dotnet --container NAME joins it.
eyedbg events --since 12 --wait long-polls the session's event log: stops, steps, breakpoints, lease changes and output, from every client. A late joiner catches up in one call.
--json on any command returns output with a "schema" version. Errors carry a stable code, a message and a hint to follow, and exit codes group them: 1 usage, 2 state, 3 setup, 4 adapter.
{
"schema": 1,
"error": {
"code": "LEASE_HELD",
"message": "the lease of session s-7f3k is held by human:alex (policy human-priority)",
"hint": "ask human:alex to run 'eyedbg lease grant agent'; 'eyedbg events --wait --kind lease' waits for a change"
}
}No server to start, no port to pick. The daemon starts with the first command, one per user, and cleans up after itself. eyedbg daemon status shows what it's doing.
eyedbg dotnet answers the questions that usually send you back to a paid IDE. A C# side helper reads EventPipe counters and traces and analyzes dumps with ClrMD. The CLI runs it for one command, no session or lease involved. The same four views are in VS Code.
$ eyedbg dotnet counters --watch --counters cpu-usage,gc-heap-size,exception-count
+1.0s cpu-usage=18.4% gc-heap-size=96.1MB exception-count=0
+2.0s cpu-usage=22.9% gc-heap-size=101.7MB exception-count=2
+3.0s cpu-usage=16.2% gc-heap-size=99.3MB exception-count=0
+4.0s cpu-usage=31.5% gc-heap-size=108.8MB exception-count=1$ eyedbg dotnet trace
cpu trace of pid 4321 (Shop), session s-7f3k: 10s, 9,812 samples on 12 threads (6,001 in managed code, 3,811 waiting or in native code)
/home/alex/.eyedbg/traces/4321-20260925T150300Z-cpu-1f3a9c0e.nettrace (5.3 MiB)
private to you, removed after 7 days (at most 10 kept); open it in PerfView or with 'dotnet-trace convert'
hottest methods (exclusive: at the top of the stack, in managed code):
SAMPLES % METHOD
4,120 68.7% Shop.Pricing.ApplyDiscounts(Shop.Order) [Shop]
1,210 20.2% System.Text.Json.JsonSerializer.Serialize(System.Object) [System.Text.Json]
671 11.2% Shop.Orders.Total(System.Collections.Generic.IReadOnlyList) [Shop]
waiting or in native code, at:
SAMPLES % METHOD
3,790 99.4% System.Threading.Monitor.Wait(System.Object) [System.Private.CoreLib]
GC: 37 collections (gen0 35, gen1 2, gen2 0), pauses 12.3 ms total (0.1% of the time), 1.2 ms max$ eyedbg dotnet heap --gcroot Shop.CartSnapshot
heap of pid 4321 (Shop), session s-7f3k · dump /home/alex/.eyedbg/dumps/4321-20260925T150300Z-heap-1f3a9c0e.dmp (.NET 10.0.12, workstation GC)
1,204,332 objects, 412.6 MiB: gen0 18.2 MiB, gen1 6.1 MiB, gen2 371.9 MiB, LOH 16.4 MiB, POH 8.0 KiB, frozen 7.7 KiB
top 3 of 2,118 types by size:
BYTES COUNT TYPE
301.4 MiB 820,114 Shop.CartSnapshot
48.2 MiB 211,902 System.String
22.0 MiB 13 Shop.CartSnapshot[]
…2,115 more types (--top N, --type PATTERN)
why alive: Shop.CartSnapshot (820,114 objects): 2 paths, more may exist (--paths N):
static Shop.CartCache.History → System.Collections.Generic.List<Shop.CartSnapshot> 0x7f3a1c809c18 → Shop.CartSnapshot[] 0x7f3a2e84a008 → Shop.CartSnapshot 0x7f3a2e864988
stack thread 1 Shop.Program.Main() → …2 more… → Shop.CartSnapshot 0x7f3a2e8649b8$ eyedbg dotnet threads
threads of pid 4321 (Shop), session s-7f3k · dump /home/alex/.eyedbg/dumps/4321-20260925T150412Z-heap-8c21d7aa.dmp (.NET 10.0.12, workstation GC)
14 threads
locks:
System.Object 0x7f3a2e86eb78 held by thread 9, 3 waiting
thread 9 (holds a lock):
System.Threading.Monitor.Enter(System.Object) +0x18
Shop.Inventory.Reserve(Shop.Order) +0x5c (Inventory.cs:58)
Shop.Orders.Checkout(Shop.Order) +0x21 (Orders.cs:37)
…4 more frames (--frames N)
threads 11, 12, 13 (3 threads, background, threadpool):
System.Threading.Monitor.Enter(System.Object) +0x18
Shop.Inventory.Release(Shop.Order) +0x2a (Inventory.cs:74)
…3 more frames (--frames N)Since 0.3.0, eyedbg compose attaches to the .NET services of a running docker compose stack, with no change to your Dockerfile or compose files. Breakpoints go in by host path, compose wait tells you which service stopped, and the ordinary commands take it from there. For a single container, eyedbg attach dotnet --container NAME.
$ eyedbg compose attach --bp Program.cs:42
group myapp: attached to 2 of 4 service(s)
web s-k3f9 attached container myapp-web-1; its healthcheck fails after 18s of a stop
consumer s-m2n4 attached container myapp-consumer-1
db - skipped pid 1 runs postgres
api - failed container myapp-api-1 is not running [ATTACH_FAILED] (start it first)
path map: /src=/work/app
breakpoint Program.cs:42:
web bp 1 Program.cs:42 verified
consumer bp 2 Program.cs:44 (requested line 42) pending: module not loaded
next: eyedbg compose wait -g myapp | eyedbg compose bp add FILE:LINE -g myapp | eyedbg compose stop -g myapp$ eyedbg compose wait
group myapp: s-k3f9 (web) stopped: breakpoint
session s-k3f9 (dotnet, netcoredbg; service web, container myapp-web-1, group myapp) stopped: breakpoint, thread 4242 (stopped 5s)
at Program.<Main>$() Program.cs:4
3 | {
> 4 | total += i;
5 | Console.WriteLine(total);
also stopped:
consumer (s-m2n4) pause stopped 12s
s-q8x1 exception stopped 3m0s
to act on it: eyedbg vars -s s-k3f9, eyedbg continue -s s-k3f9; 'eyedbg compose wait --new -g myapp' waits for the next stop$ eyedbg compose launch --bp Program.cs:6
group myapp: launched 2 of 3 service(s)
producer s-k3f9 launched built Producer/Producer.csproj in 2.1s -> recreated -> launched; container myapp-producer-1; its healthcheck fails after 18s of a stop
consumer s-m2n4 launched built Consumer/Consumer.csproj in 2.1s -> recreated -> launched; container myapp-consumer-1; its healthcheck fails after 18s of a stop
db - skipped its entrypoint isn't exec-form 'dotnet X.dll'
path map: /src=/work/app
breakpoint Program.cs:6:
producer bp 1 Program.cs:6 verified
consumer bp 1 Program.cs:6 pending: module not loaded
override: /home/me/.eyedbg/compose/myapp/override.yml
build log: /home/me/.eyedbg/compose/myapp/build.log
undo with: eyedbg compose restore producer consumer
next: eyedbg compose wait -g myapp | eyedbg compose bp add FILE:LINE -g myapp | eyedbg compose events --kind output -g myapp | eyedbg compose stop -g myapp$ eyedbg compose restore
group myapp: restored 2 of 4 service(s)
producer restored recreated as built; ended 1 session (s-k3f9)
consumer restored recreated as built
db skipped not in fast mode
api failed docker compose up failed: container myapp-producer-1 is unhealthy [ATTACH_FAILED] (see 'docker compose ps')
note: recreated as built, with this shell's compose environment (variables and --env-file files); whatever the old containers wrote outside volumes is gone.eyedbg help compose has the details.
No schema to register and no server to run. An agent learns eyedbg the way it learns any command-line tool, by reading its help. A test keeps every page of that help in sync with the code.
What it does, when to use it, how long it blocks, its effect on the program, its output and its exit codes, with real examples. eyedbg help --all prints the whole tree in one read; --json returns it as data.
eyedbg help --all # every command, one read
eyedbg help run-until # one command
eyedbg help --all --json # the same, as dataeyedbg skill install writes SKILL.md (when to reach for the debugger, the standard loop, budgets, sharing etiquette and "always stop") into Claude Code's skills folder. --dir targets another agent's.
$ eyedbg skill install
installed /home/alex/.claude/skills/eyedbg/SKILL.md
restart your agent (or start a new session) to load itEvery error has a stable code and a hint that says what to try next. Here, a human holds control, and the hint says how to ask for it.
$ eyedbg continue
eyedbg: the lease of session s-7f3k is held by human:alex (policy human-priority) [LEASE_HELD]
hint: ask human:alex to run 'eyedbg lease grant agent'; 'eyedbg events --wait --kind lease' waits for a changeScripts and agents can tell a usage mistake from a busy session or a missing adapter without parsing text.
| Exit | Means |
|---|---|
| 0 | Success, including a wait that timed out (the output says so) |
| 1 | Usage: a bad request, SIDE_EFFECTS, an anchor not found |
| 2 | State: no session, not stopped, LEASE_HELD, not the owner |
| 3 | Setup: adapter not installed, build or attach failed, run the hint |
| 4 | The adapter or side helper refused or can't do it |
Debug sessions hold secrets: tokens in variables, customer data in memory. eyedbg is built to keep them yours.
The daemon listens on a Unix socket in a private directory (never TCP) and checks a fresh random token on every connection. eyedbg has no telemetry (it even turns off the .NET CLI's for the builds it runs) and goes online only to download adapters you install.
attach and eyedbg dotnet check that a process is yours before anything runs, and show it as pid N (name), never by its command line. A process in a docker container is the exception: there docker is the boundary, and eyedbg attaches wherever your docker user may.
Expressions that would change the program need --allow-side-effects, which takes the control lease and is recorded, so a stray eval can't quietly change state someone else is looking at.
Adapter downloads are https, size-capped and SHA-256-checked before extraction, through a staging directory that refuses escaping paths. Manifests are never read from a project.
Written under fresh random names in a directory only you can read, never overwritten, pruned after 7 days. Session recordings keep control events only, no output or values.
eyedbg only fetches a debug adapter when you run eyedbg adapters install. For .NET that's netcoredbg (MIT) by default. SharpDbg is opt-in, and its license terms are worth a read first (see the FAQ).
No. The CLI is the interface: any agent that can run a shell command can use it, and eyedbg help --all teaches it the whole tool in one read. There's nothing to register and nothing to keep running, the daemon starts by itself.
Any agent with a shell: Claude Code, Codex and others. eyedbg skill install installs SKILL.md for Claude Code; for other agents, install it with --dir, print it with eyedbg skill print, or let the agent read eyedbg help --all.
Yes. The daemon owns the session; the agent's CLI and your editor are both clients of it. One control lease decides who may run, step or pause; everyone else can read state, set their own breakpoints and ask for control. Breakpoints on the same line are merged and keep their owners.
Under the default free policy, whoever acts takes control. Switch to human-priority (VS Code offers it when you take over) and agents have to ask: a human can always take control from an agent, never the other way round. The agent skill tells agents never to force the lease over a human.
netcoredbg (from Samsung, MIT) is the default. SharpDbg is opt-in: it adds lambdas and LINQ in eval and covers Intel Macs, where netcoredbg has no build. SharpDbg itself is MIT, but it bundles a Microsoft library under the Microsoft Software License Terms, which aren't open source. Read eyedbg help adapters install and only install it if you're fine with those terms.
It's read-only by intent: expressions that visibly change the program (method calls, assignments, new, ++) are refused unless you pass --allow-side-effects. The check is best-effort: property getters still run code, as they would in any debugger.
eyedbg itself sends nothing: the daemon has no network listener and no telemetry. The only network access is downloading the adapters you ask for, pinned and checksum-verified. If you install SharpDbg, its own license terms say it may send data to Microsoft (see the question above).
Linux, macOS and Windows, on x64 and arm64. netcoredbg has no build for Intel Macs, so SharpDbg is the default there instead. netcoredbg has no build for Windows on Arm either; SharpDbg works there too, but you need to pass --adapter sharpdbg yourself, and it isn't verified yet.
Since 0.3.0, yes, for .NET in Linux containers, with no change to your Dockerfile or compose files. eyedbg attach dotnet --container NAME attaches to one container, and eyedbg compose attach takes every .NET service of a stack as one group: set breakpoints by host path, eyedbg compose wait for whichever service stops, then use the ordinary commands on it. A stop freezes that whole service, so keep stops short. eyedbg never reads a container's environment, command or arguments.
In verified runs, line breakpoints did not bind when attached to an image's Release build. eyedbg compose launch builds Debug on your machine and launches the app under the debugger inside its container, so startup code can be stopped in. It recreates the containers it names, and the service runs only while its debug session does; eyedbg compose restore puts it back. Verified on Docker Desktop on macOS and docker.io on Linux. Windows hosts, podman and remote engines are not verified. eyedbg help compose has the details.
Nothing. EyeDebugger is open source under the Apache-2.0 license, and contributions are welcome.
Install eyedbg and give your agent the skill. Then debug the next hard bug together.