Which API hosts your coding agents connect to. On your own machine.
Samples TCP connections on Windows, follows each process up to its
parent, and reads the certificate name of a new public host. A Node
helper under Cursor counts as Cursor.
MIT licensed · no account · 0 runtime dependencies · Windows
node bin/talk.mjs oncereal output
== 2026-10-24 01:24:30
conns 13380 orphaned 3647 agents 15
ALERT 22124 Cursor.exe 9113
us4p.cursorvm.com
us3p.cursorvm.com
ALERT 32664 died before the first sample 3591
us3p.cursorvm.com
Pid Alive Total Name Parent
22124 true 9113 Cursor.exe Cursor.exe
22736 true 16 Cursor.exe Cursor.exe
34332 true 12 claude.exe pwsh.exe
8728 true 10 grok.exe pwsh.exe
43492 true 8 Grok Bot.exe explorer.exe
One sample, top of the table. A Cursor helper held 9,113 connections
to two of its own hosts. A process that had already exited still held
3,591, and could no longer be named. The client port range on Windows
is 16,384.
The situation
It looks like the network died.
A long agent session can open connections and never close them. When the
port range fills, curl fails in about 20 milliseconds and tests
die with EADDRINUSE.
The owner is a helper
The process in that sample was not the window you clicked. It was
Cursor.exe running as a Node helper. The same helper type
is used by VS Code, so the name of the utility is not enough. talk
walks up to the parent.
The host is on the certificate
The URL path stays encrypted. The certificate name does not. talk
opens one extra connection to a new public address, reads that name,
and stores the name. It does not store a prompt or a header.
What was missing
A record you can leave running, so the next leak is caught while the
process is still alive: who, which host, and whether the count is
climbing. It does not close a socket and it does not restart anything.
Running it
There is no npm install, because there is nothing to install.
A fresh clone with Node 22 does everything below. The sampler is
core/win-snapshot.ps1, inside the repository. Logs go to
data/, which is gitignored.
git clone https://github.com/gledach/talk && cd talk
node bin/talk.mjs once # one samplenode bin/talk.mjs watch # every 60 seconds, until you stop itnode bin/talk.mjs doctor # node, powershell, and the sampler in this clone
The command is gledach-talk. npm link puts that name
on your PATH. The copy block above calls the same file and needs no link.
Nothing named talk is installed. That name is an npm package and
a Unix program.
gledach-talk once --no-cert skips the certificate read.
gledach-talk watch --interval=30 --peeks=4 changes the cadence
and how many new hosts are named per sample.
gledach-talk report prints the last one.
The commands
Command
What it does
gledach-talk once
One sample. Prints the agents, the hosts it could name, and any alert.
gledach-talk watch
The same sample on a loop. The default is 60 seconds. It stays in the terminal. It does not install a service.
gledach-talk report
The last sample, from data/latest.json.
gledach-talk doctor
Node, the platform, PowerShell, and whether the sampler file is in this clone.
A line is written when a process holds 500 connections or more, when an
agent's count climbs by 30 in one interval, when orphaned sockets grow, or
when an agent asks for a host it has not used before.
What it records
Who, which host, and whether the count is climbing.
The sampler is read only. It never closes a socket and it never kills a
process. Restarting the agent releases sockets it still owns. Orphans from
a dead process stay until reboot, or an admin restart of winnat.
The parent, not the subtype
Cursor, Claude, Grok, Codex, Windsurf and Aider count, and so does a
child whose parent is one of them. VS Code's Node helper uses the same
utility subtype and does not count, unless the path or the parent says
otherwise.
The name, once
A new public address on port 443 is looked up by reading its certificate,
then cached. The default budget is four lookups a sample, spent on the
busiest agent first. Private addresses are left alone.
The log stays local
samples.jsonl, alerts.log, and a small cache of
hosts already named. Nothing is uploaded. There is no account and no key.
What it cannot see
Stated here rather than buried in a wiki.
Every tool on this shelf ships a written audit of its own blind spots. This
is talk's, in full, from its own README.
A hostname that was never sent in the TLS handshake.
The certificate read connects to the IP, a few times per sample, heaviest
agent first. A server that will not present a name without the right
hostname comes back blank.
The path after the host./v1/messages versus a telemetry route is encrypted, and this
tool does not decrypt it. Prompts and Authorization headers
are never stored.
Encrypted DNS that never presents a certificate name.
An agent that resolves names that way, and never shows a name on the
certificate, is a gap.
A process that exited before the first sample.
Its sockets still count, and the owner can no longer be named.
Anything that is not TCP.
The sampler reads the Windows TCP table.
Any operating system other than Windows.report can print a log you already have. once and
watch cannot take a sample elsewhere.
0 runtime dependencies. The offline tests check who counts as an agent,
including a Cursor helper and a VS Code helper that must not match, and they
check that a one-element parent chain still counts. They do not open a socket.
Elsewhere on the shelf
Same author. Different shapes.
Each takes whatever shape suits it, from a single command to a dashboard.
What they share is the promise rather than the plumbing: free, installable,
and honest about what each one cannot see.