Warning
Alpha Preview — PortReeve is evolving quickly. Breaking changes remain possible,
and the currently published macOS previews through 0.1.0-preview.4 are immutable
unsigned history. New public previews require Apple Developer ID signing and
notarization. Review the installation and removal guide,
including the narrowly scoped historical-preview guidance, before installing.
The current public alpha preview is available on GitHub Releases. On macOS, install the graphical application with Homebrew after reviewing and narrowly trusting its cask:
brew tap TrentBrown/portreeve
brew trust --cask trentbrown/portreeve/portreeve-app
brew install --cask trentbrown/portreeve/portreeve-appFor terminal and MCP use, install the standalone CLI independently:
brew trust --formula trentbrown/portreeve/portreeve
brew install trentbrown/portreeve/portreeveHomebrew does not silently install or start the supervised service. Direct macOS DMGs, Linux executables, checksum verification, historical unsigned-preview guidance, and removal procedures are covered in the installation guide.
PortReeve gives every development service a stable TCP address and verifies which process or container actually owns it.
On one development machine, every service shares localhost's TCP port space. The familiar defaults—3000, 5432, 8080, and their neighbors—work until several projects need them at once. Concurrent agentic development multiplies that pressure: multiple agents can run independent copies of the same stack from different Git worktrees, and every copy naturally reaches for the same ports.
PortReeve replaces duplicated startup-time probing and remapping with one shared, inspectable source of truth.
Want to try it? Install the alpha preview and open PortReeve from Applications. Desktop is the primary visual experience; CLI, MCP, and JavaScript clients remain independent first-class ways to use the same authority.
A reeve was a person entrusted with local administration. The office took different names—shire reeve, borough reeve, and portreeve—according to the place or responsibility. Shire reeve survives in contracted form as the modern word sheriff.
A portreeve governed a port or market borough, where port could mean a market town rather than only a seaport. PortReeve is the modern local official for your machine's network ports.
One PortReeve server runs at a time for the current operating-system user—normally as a supervised service, or explicitly in the foreground for a temporary session. It owns the durable registry and coordinates every client through the same private HTTP/JSON Unix socket.
flowchart LR
Desktop["PortReeve Desktop"] --> Server[("One PortReeve server")]
MCP["MCP bridge"] --> Server
CLI["portreeve CLI"] --> Server
JS["JavaScript client"] --> Server
Server --> Registry[("SQLite claims")]
Server --> Evidence["lsof and Docker evidence"]
Desktop, MCP, CLI, and the official JavaScript library are peer clients of that authority. PortReeve assigns addresses and verifies bindings. Your project tooling remains responsible for starting, supervising, health-checking, and stopping services.
| Client | Choose it when | Important boundary |
|---|---|---|
| Desktop | A developer wants visual inspection, stack editing, or the lowest-friction built-in launcher | macOS only; explicit UI confirmation protects consequential actions |
| MCP | An agent should inspect and coordinate PortReeve through strict typed tools | No daemon lifecycle, arbitrary shell, raw credentials, or unsafe eviction |
| CLI | A terminal or trusted automation needs complete local administration | Launcher commands may execute project-authored shell commands |
| JavaScript client | Project tooling should own allocation, startup, and binding confirmation in one control flow | The project owns provider lifecycle and confirms only after a successful bind |
The clients share one authority; choosing one does not create a separate installation or registry. Native project integration through the JavaScript client provides the tightest coupling between lease acquisition and real service startup.
Every integration leaves service lifecycle with project-owned commands. The paths differ in what invokes those commands, what must be present at runtime, and how assigned ports reach the services.
Configure shell commands such as npm run dev in Desktop. PortReeve resolves the stack,
injects endpoint environment variables, invokes those commands, and confirms the
resulting bindings. Desktop remains in the runtime path.
sequenceDiagram
actor Initiator as You or agent
participant Desktop as PortReeve Desktop
participant Server as PortReeve Server
participant Command as Shell command
participant Services as Your services
Initiator->>Desktop: Start
Desktop->>Server: Plan and lease
Server-->>Desktop: Resolved endpoints
Desktop->>Command: Inject environment + invoke
Command->>Services: Start services
Desktop->>Server: Confirm bindings
Best for: exploring and proving the integration with the least initial friction.
A generated launcher follows the same coordination protocol but runs without Desktop. It injects resolved endpoints into your existing lifecycle commands and can be checked into or distributed with the project.
sequenceDiagram
actor Initiator as You or agent
participant Launcher as Generated launcher
participant Server as PortReeve Server
participant Services as Your services
Initiator->>Launcher: Start
Launcher->>Server: Plan and lease
Server-->>Launcher: Resolved endpoints
Launcher->>Services: Inject environment + start
Launcher->>Server: Confirm bindings
Payoff: reusable project automation without Desktop at runtime. The generated-launcher interface is an upgrade path and is not yet shipped; Desktop currently exposes it as Coming soon.
Your existing project tooling calls PortReeve directly so acquisition, startup, binding confirmation, and cleanup share one control flow. It may still inject the resolved values into child processes as environment variables, but no PortReeve-owned launcher stands between the project and the authority.
sequenceDiagram
actor Initiator as You or agent
participant Tooling as Your project tooling
participant Server as PortReeve Server
participant Services as Your services
Initiator->>Tooling: Start
Tooling->>Server: Request ports
Server-->>Tooling: Leased endpoints
Tooling->>Services: Inject and start
Tooling->>Server: Confirm after successful bind
Payoff: the strongest lifecycle fidelity. Project tooling confirms a binding only after it succeeds in using the assigned endpoint.
A PortReeve stack is the local development stack you already recognize. Its definition names components, endpoints, and dependencies; it does not preserve current port numbers.
flowchart LR
Client["Web client<br/>frontend.http"] --> API["API<br/>api.http"]
API --> Database["Database<br/>database.postgres"]
PortReeve coordinates two related problems:
- Within one stack: every dependent service resolves the same coherent endpoint plan before startup. The client learns the API address, and the API learns the database address.
- Across stack copies: separate worktrees and concurrent agents receive conflict-free bindings while retaining stable endpoint identities.
One canonical stack root represents one independently runnable stack.
portreeve.stack.json belongs to the project and describes relationships. PortReeve's
database owns current assignments, generations, activations, and leases. Project tooling
still owns execution.
PortReeve separates persistent intent from one startup attempt:
| Concept | Meaning |
|---|---|
| Claim | The durable identity and sticky port preference of one published endpoint |
| Generation | One immutable, coherent endpoint plan prepared for the whole stack |
| Activation | One attempt to run a selected generation |
| Lease | Temporary authority for one activation to bind an assigned endpoint |
sequenceDiagram
actor Initiator as You or agent
participant Tooling as Integration tool
participant Server as PortReeve Server
participant Service as Provider service
participant OS as Listener evidence
Initiator->>Tooling: Start
opt Standalone endpoint
Tooling->>Server: Allocate endpoint
Server-->>Tooling: Assigned port + lease
end
Tooling->>Server: Apply stack definition
Note over Server: Create or update durable claims
Tooling->>Server: Prepare stack
Server-->>Tooling: Immutable generation G17
Tooling->>Server: Begin activation for G17
Server-->>Tooling: Activation A42 + endpoint leases
Tooling->>Server: Resolve A42
Server-->>Tooling: Coherent service addresses
Tooling->>Service: Start with assigned endpoints
Service->>OS: Bind listener
Tooling->>Server: Confirm lease after bind
Server->>OS: Inspect fresh ownership evidence
Server-->>Tooling: Binding confirmed
Note over Tooling,Service: Project health remains project-owned
Tooling->>Server: End activation and release leases
For a standalone service, allocation and withPort() hide much of this negotiation. For
a stack, prepare creates the coherent generation, resolve supplies its
addresses, and confirm proves that the expected provider owns each binding.
Confirmation proves ownership, not application readiness.
Fresh lsof listener evidence is live authority for host ports. A stored process
identifier can help explain history, but it is not proof: PIDs can go stale and be
reused.
Docker confirmation uses running-container state, exact PortReeve labels, and publication evidence. Normal reclaim remains both ownership-bound and evidence-bound. PortReeve refuses to kill an unrelated listener merely because a stale claim remembers the same number. Unsafe any-owner eviction exists only as a separate, explicit last resort.
PortReeve coordinates local TCP addresses. It is not a general project-process supervisor, Docker Compose replacement, startup-order engine, secret manager, application health system, reverse proxy, DNS server, or sandbox control plane. It can verify ordinary Docker-backed endpoints, but it does not currently provide Docker Sandbox orchestration or integration.
PortReeve sends no telemetry and does not load project .env files.
Install the current preview through Homebrew or download
the architecture-specific DMG from the
GitHub Releases page, then open
PortReeve from Applications. In Desktop, open Service and choose Install and
Start PortReeve to place the verified bundled CLI in its managed per-user location and
configure launchd. Then use Quick Start to try one existing project or
Integrations to connect a stack.
To build Desktop from source instead, use the public repository and pinned Bun 1.3.14 toolchain:
git clone https://github.com/TrentBrown/portreeve.git
cd portreeve
bun install --frozen-lockfile
bun run build
PORTREEVE_DESKTOP_CLI_PATH="$PWD/dist/portreeve" bun run desktop:startThe Homebrew formula, direct macOS/Linux downloads, and source build all provide the same complete CLI. Run a temporary foreground server with:
portreeve serveOr install the supervised per-user service directly:
portreeve install
portreeve start
portreeve status --jsonFor a source build, substitute ./dist/portreeve; for example,
./dist/portreeve status --json.
Installation does not require root. PortReeve uses launchd on macOS and
systemd --user on Linux. The JavaScript client archive is retained in the release
evidence, but npm publication remains deferred.
- MCP guide and complete tool reference
- CLI guide and complete command reference
- JavaScript client
- Desktop application
- Installation and future release channels
- Release operator runbook
- Stack definitions and coordination
- Project launchers
- Socket protocol
- Safety model
- Troubleshooting
- Migration from project-local remapping
- Mixed process and Docker example
PortReeve Desktop supports macOS. Standalone CLI and MCP artifacts support macOS and Linux. The JavaScript client supports its documented Node.js and Bun runtimes when it can reach the local Unix socket. Windows is not supported.
