SuperAPI AI Directory

port-keeper-mcp

Leases development port blocks to each clone or git worktree, writes .env files and resolves service names to URLs so parallel agents get their own ports.

Open website

About this tool

Purpose

port-keeper-mcp solves the development port conflict problem in parallel coding agent scenarios. When running multiple agents simultaneously (for example, five agents, five branches, five working copies), git worktree can provide each agent with independent files, but it does not give them independent ports. Each working copy carries the same .env, so the development server, API, and database all request the same port numbers. The agent that starts first gets the port, and the other agents encounter "address already in use," or worse—tests silently run against another agent's server and database. An agent that cannot start its own stack cannot verify its own end-to-end tests or any test that goes through the database. The tool's core goal is: let each agent have its own set of ports and be able to run the entire stack simultaneously.

Main capabilities

  • Port allocation by slot: Each working copy gets a slot, and each slot gets its own block of ports. No two leases for any project on the machine will share a port, even if multiple agents request at the same time.
  • Agents ask via MCP instead of guessing: Agents can get URLs by service name via MCP, and hooks can export slot ports to the agent's shell at session startup. A new working copy without its own slot will be denied use of the main copy's ports.
  • No resident process required: No daemon, no agent, no network listener. Each command opens the ledger, performs the operation, and exits.
  • Project manifest declares services: A project declares services through a small manifest (only names and environment variable names, no port numbers). port-keeper allocates a block of ports from the pool for each slot, writes .env, and can answer "what is the URL for shop/5/admin" from the CLI or MCP.
  • Streamlined agent interface: Provides eight MCP tools, six of which are enabled by default. Agents can quickly understand the entire interface with almost no context usage.
  • Integrates with existing toolchains: Writes ordinary environment variables to .env, shell, direnv, or mise, and development commands do not need to change. The documentation examples show how to wire it up with mise, direnv, docker compose, Vite, Playwright, and a reverse proxy.
  • Easy to remove: Delete the MCP entry and hooks, then delete the binary and ledger file. The .env.local it writes is an ordinary file and can still continue to be used.## Usage

port-keeper is a static binary with no runtime dependencies. Put it in PATH, and the shell, agent hooks, and MCP client all call the same port-keeper command, so one installation serves all three, and there is only one version on the machine.

The installation script selects the archive suitable for the operating system and CPU from the latest GitHub Release, refuses to install unless its SHA-256 matches the release's checksums.txt, and places port-keeper in ~/.local/bin. It never requests sudo. You can set PORT_KEEPER_INSTALL_DIR to install elsewhere, and set PORT_KEEPER_VERSION to pin the version. Run it again to update; it replaces the binary but leaves the ledger and configuration untouched.

Build with the Go toolchain (1.25 or later):

go install github.com/gridhra/port-keeper-mcp@latest

The second working copy of the same project gets its own slot:

port-keeper slot new

Give coding agents the same view:

# 注册 MCP 服务器(用户级,配置中没有端口号,只有命令)
claude mcp add port-keeper port-keeper mcp

Then add hooks in ~/.claude/settings.json. At SessionStart, it exports the current slot's ports into the agent's shell and adds the project and slot to Claude's context; at CwdChanged (when Claude cd's to another worktree), it replaces the exported ports with that worktree's slot ports. Outside a project the command prints nothing and exits 0, so the hook never fails a session.

Tell the agent that the tool exists: an agent will only use a tool if it knows it exists. Add two lines to the user-level instruction file (for Claude Code, ~/.claude/CLAUDE.md; other agents have equivalent files), because these two lines apply to every project on the machine. If you run multiple agents (Claude Code, Codex, Cursor, etc.), put the same block in each agent's global instructions. MCP registration is per client, and the ledger is shared.

Applicable scenarios and limitations

Applicable scenarios: Large web service projects that need to run multiple agents, multiple branches, and multiple worktrees simultaneously, especially when end-to-end tests or tests that go through a database need to be run. Typical use cases include: scheduling for the fifth worktree (port-keeper slot new hotfix), opening the correct admin interface without having to remember the port (port-keeper url shop/3/admin --open), sharing a database between two application environments (port-keeper slot new 2 --infra-from 1), finding out who is occupying a port (port-keeper status compare the ledger with actual listeners and list PIDs), migrating an existing project without breaking bookmarks (port-keeper pin web=3000 admin=3001 api=8080 --reason "docs and bookmarks").

Guaranteed properties: No two leases share a port (guaranteed by the UNIQUE constraint in the ledger and the write transaction around each allocation); only the configured pool is used (default 20000–31999), avoiding common ports, ports occupied by macOS services, and the OS ephemeral port range, and the only way to leave the pool is an explicit, justified pin; a slot reserves its port block until it is released, and this persists across restarts; ports are never reclaimed behind your back (port-keeper gc lists slots that appear abandoned, and releases them only when --yes is added); one slot per worktree; no listener, no daemon; no secrets are stored (there are no password, token, or connection string columns in the ledger, and .env rendering never writes to tracked files).

Explicitly unsupported features (Non-goals): No reverse proxy or named hosts (such as http://admin.shop.localhost),因为代理会引入常驻进程,当它停止时所有环境同时不可达,且浏览器按源(包括端口)隔离 cookies and local storage; different ports are exactly what keeps slot sessions isolated; no container images; no npx launcher. port-keeper is only responsible for deciding which port belongs to which service of which worktree; starting the server is left to the task runner.

Limitations: The material does not provide further details about charging, pricing, platform support scope, performance metrics, or specific user cases. See docs/DESIGN.md for the complete design (in Japanese).