v0.1.12 for macOS 14+

Your agents keep starting the same server.

Portly runs it once. Every agent, terminal, and task then reads the same live state: what is running, on which port, under which PID, and whether it is actually healthy.

The Portly window: five registered projects in the sidebar, each server showing its port and status, with the website server running on port 3000 and its live terminal output on the right.

The cost

Five parallel tasks, five copies of your app.

An agent starts a background job because nothing told it the server already exists. Do that across four terminals and two editors and you get duplicate process trees, fallback ports nobody wrote down, logs split across tabs, and a laptop doing the same work five times over.

5 dev servers · 5 bundlers · 5 file watchers

  1. codexpnpm devpid 82104:3000
  2. claudepnpm devpid 82391:3001port 3000 in use
  3. cursorpnpm devpid 82618:3002port 3001 in use
  4. codexpnpm devpid 82943:3003port 3002 in use
  5. claudepnpm devpid 83117:3004port 3003 in use

Four of these should not exist.

Agent interface

Inspect first. Launch only if needed.

Portly ships a skill that Claude Code, Codex, and Cursor pick up from ~/.agents/skills/portly. It teaches one rule: read the live state before you spawn anything. The CLI answers in JSON so the agent never has to parse a spinner.

Read the skill
127.0.0.1:7737

Before anything is launched, the agent reads live state.

$ portly status --json
{
  "apiPort" : 7737,
  "projects" : [
    {
      "color" : "#0A84FF",
      "icon" : "shippingbox.fill",
      "id" : "prj_62bafa3d",
      "name" : "NowStack",
      "root" : "/Users/you/Developer/nowstack",
      "servers" : [
        {
          "command" : "pnpm dev",
          "healthy" : true,
          "id" : "srv_db263513",
          "name" : "web",
          "pid" : 82104,
          "port" : 3000,
          "restartCount" : 0,
          "startedAt" : "2026-08-01T06:44:52Z",
          "state" : "running",
          "url" : "http://localhost:3000"
        }
      ]
    }
  ],
  "version" : "0.1.0"
}

The app

A native window, a menu bar, nothing in the background.

Portly looks and behaves like part of macOS. It is the same supervisor whether you drive it by hand, from the menu bar, or through the CLI.

The Ports screen: every listening TCP port grouped by the process that owns it, with the servers Portly manages marked Managed and a process started outside Portly marked External.
Every listening port, grouped by ownerWhat Portly manages, what something else started, and what macOS will not let anyone touch.
Explicit takeoverYou see who owns the port before anything is stopped. Nothing is killed silently.

Capabilities

What the supervisor actually does.

No cloud account, no dashboard subscription, no process manager buried inside an agent framework.

Install

Two lines, then it is yours.

The script builds the app, ad-hoc signs it, installs the portly binary on your PATH, and drops the agent skill in ~/.agents/skills/portly. On Linux, skip the app — use the headless CLI.

$ git clone https://github.com/Melvynx/portly.git
$ cd portly && ./build.sh --run

✓ Portly.app installed in /Applications
✓ portly on PATH
✓ skill linked at ~/.agents/skills/portly