cd /news/developer-tools/show-hn-portmarshal-guard-dev-server… · home topics developer-tools article
[ARTICLE · art-68569] src=github.com ↗ pub= topic=developer-tools verified=true sentiment=· neutral

Show HN: PortMarshal – Guard dev servers from cross-agent stops

PortMarshal, a new open-source command-line tool for macOS and Linux, prevents parallel coding agents from accidentally stopping each other's local development servers by mapping TCP listeners to their owning process, project, and agent. The tool, installable via npm, detects port drift, coordinates sticky port claims, and blocks one agent from killing another agent's active service by default. It supports cooperative agents like Claude Code, Cursor, VS Code, and Docker, and requires Node.js 18.17 or newer.

read4 min views1 publishedJul 22, 2026
Show HN: PortMarshal – Guard dev servers from cross-agent stops
Image: source

Know which coding agent owns a local dev server — and stop the wrong one from being killed.

English | 简体中文

PortMarshal is an agent-aware ownership and safety layer for local development services on macOS and Linux. It maps attributable TCP listeners to their PID, project directory, and launching agent; coordinates sticky port claims; detects port drift; and blocks one agent from stopping another agent's active service by default.

npm install -g portmarshal
portmarshal list
portmarshal whois 3000

The last command inspects the process, project, and agent behind a dev server already listening on port 3000.

Parallel coding agents create three recurring problems:

Silent drift— an agent expects port 3000, but the framework silently starts on 3001.** Detached services**— a session exits while its dev server keeps listening.** Friendly fire**— one agent frees a port by stopping another agent's service.

PortMarshal scans first and coordinates second. Existing listeners do not need to be launched through PortMarshal to be discovered. Cooperative agents gain stable claims and stronger ownership signals, while uncooperative services still appear when the operating system exposes their process metadata.

npm install -g portmarshal
portmarshal --help

Requires Node.js 18.17 or newer. The runtime has no npm dependencies.

npm uninstall -g @worsher/portscout @worsher/portmarshal
npm install -g portmarshal

On first use, PortMarshal copies an existing ~/.portscout/registry.json

into ~/.portmarshal/registry.json

, preserving sticky claims without deleting the old data.

Command What it does
portmarshal list [--json] [--all] [--project .]
List listeners with project, source, and state: active, reserved, unregistered, or drift
portmarshal whois <port> [--json]
Inspect one port: PID, project directory, full command, agent or service source
portmarshal claim <name> [--prefer N] [--range A-B]
Allocate a cooperative sticky port claim; stdout contains only the port number
portmarshal release <name>
Release a claim without stopping its process
`portmarshal stop <port name> [--force
Stop a service behind the ownership guard
portmarshal gc [--kill-detached]
Reap stale claims and review or stop detached service candidates
portmarshal watch
Refreshing terminal dashboard; press q to quit
portmarshal menubar [--install]
SwiftBar menu with guarded click-to-stop actions

Typical agent startup:

PORT=$(portmarshal claim web --prefer 3000)
npm run dev -- --port "$PORT"

A claim is a cooperative lease, not an operating-system socket reservation. PortMarshal revalidates a previous claim before reusing it: a port must still be free or be attributable to the same project. There is still an unavoidable handoff window between returning a free port and the application binding it.

PortMarshal follows the process parent chain to identify claude-code

, cursor

, antigravity

, vscode/electron

, terminal

, docker

, and pm2

. PM2-managed listeners are enriched from pm2 jlist

, displayed as pm2:<app-name>

, and attributed to the application's configured cwd; the full PM2 environment is never retained. For published Docker ports, PortMarshal inspects running-container metadata: shared Docker Desktop listeners are split by container, the source is shown as docker:<compose-project>/<service>

, and the host project directory is recovered from Compose, Dev Container, or bind-mount metadata. If managed-runtime metadata is unavailable, attribution safely falls back without inventing ownership. PortMarshal also recognizes launchd:<label>

on macOS and systemd:<unit>

on Linux. A process reparented to PID 1 without a recognized manager is labeled detached

— this is a review signal, not proof that the process is abandoned.

Target Default stop behavior
PM2 application owned by the caller's project/claim Run pm2 stop <id> ; never signal a managed child that PM2 would restart
Docker container owned by the caller's project/claim Run docker stop for that container; never signal the shared Docker backend
Detached service or a service owned by the caller's project/claim Stop with SIGTERM, then SIGKILL after 3 seconds if needed
Another active service Block, print attribution, and exit with code 3

--force

overrides the guard after review. On macOS, --gui

asks through a native confirmation dialog.

PortMarshal can only attribute listeners whose process metadata is visible to the current user. For example, Linux ss

output without PID information is not invented or guessed; those rows are omitted.

Add this policy to AGENTS.md

, CLAUDE.md

, or your editor's agent rules:

- Before starting a dev server, get a port with `PORT=$(portmarshal claim <service> --prefer <default>)`.
- Diagnose conflicts with `portmarshal list --project . --json` and `portmarshal whois <port> --json`.
- Stop services with `portmarshal stop <port>`; exit code 3 means another active service owns it, so show the attribution and ask before using --force.

A ready-to-copy Claude Code skill lives in integrations/claude-code/skills/portmarshal.

andlsof

ss

expose sockets and processes; PortMarshal adds project/agent attribution, claims, drift detection, and stop policy.Sonaris a broad localhost and Docker management CLI; PortMarshal focuses on cross-agent ownership and guarded actions.Portlesslaunches apps behind stable named local URLs; PortMarshal can inspect services whether or not it launched them. The tools can be used together.

pnpm test
pnpm smoke
pnpm build

GitHub Actions runs build, unit tests, and a real listener smoke test on macOS and Linux. Tagged releases publish to npm with provenance.

Design: docs/specs/2026-07-16-portmarshal-design.md ·

Changelog

macOS and Linux · Node.js ≥ 18.17 · zero runtime dependencies · MIT

── more in #developer-tools 4 stories · sorted by recency
── more on @portmarshal 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/show-hn-portmarshal-…] indexed:0 read:4min 2026-07-22 ·