Skip to content

Repository files navigation

portmap

A local development service registry that eliminates port conflicts across projects.

If you've ever started a new project only to discover port 5432 is already taken by another project's Postgres, or an AI agent assigned a port that collides with something you're already running — portmap solves that.

What it does

  • Single source of truth — One registry.json file tracks every project, service, and port on your machine
  • 10 CLI commands — Check, register, scan, validate, allocate, and detect conflicts
  • Auto-scanner — Discovers ports from docker-compose, .NET appsettings, .env files, and start scripts
  • AI-agent friendly — Documentation designed so Claude, Cursor, Copilot, or any agent can self-serve port allocation
  • Zero dependencies — Python 3.11+ stdlib only. No pip install needed

Quick Start

# Clone it
git clone https://github.com/djcdevelopment/portmap.git
cd portmap

# Copy the example registry and customize it
cp registry.example.json registry.json

# See everything registered
python portmap.py list

# Check if a port is available (also probes if something is listening)
python portmap.py check 8080

# Find available port ranges
python portmap.py gaps

# Register your first project
python portmap.py add-project my-app "My Application" "/path/to/my-app" --category project --stack python,postgres
python portmap.py register my-app api 8080 --protocol http --process python
python portmap.py register my-app postgres 5432 --protocol tcp --process docker

# Auto-discover ports from project config files
python portmap.py scan

# Compare registry to live ports (what's actually listening?)
python portmap.py validate

# Detect conflicts
python portmap.py conflicts

Why

When you run multiple projects locally — web servers, databases, gRPC services, Docker containers — port conflicts are inevitable. Typical problems:

  • Two projects both default their Postgres to port 5433
  • An AI agent sets up a new project and picks ports already in use
  • You forgot what's running on port 3000 — was that Langfuse or the new React app?
  • Docker Compose starts but silently fails because the port is taken

portmap makes every port assignment explicit, discoverable, and conflict-checked.

Commands

Command What it does
list [--project ID] [--json] Show all registered services
check <port> Who owns this port? (exit 0=free, 1=claimed, 2=unregistered listener)
register <project> <service> <port> Claim a port (--protocol http --process python)
unregister <project> <service> Release a port
add-project <id> <name> <path> Add a project (--category project --stack python,postgres)
scan [--project ID] Auto-discover ports from project files
validate Check live ports vs registry (live / dormant / rogue)
allocate <project> [--range S-E] [--count N] Get next free port(s)
gaps [--min N] Show all unallocated port ranges
conflicts Show port conflicts

Setup

Requirements

  • Python 3.11+
  • That's it. No pip install, no virtualenv, no Docker.

First-time setup

git clone https://github.com/djcdevelopment/portmap.git
cd portmap

# Start from the example or create an empty registry
cp registry.example.json registry.json

# Register your projects
python portmap.py add-project my-api "My API" "/home/you/projects/my-api" --category project --stack node,postgres
python portmap.py register my-api server 3000 --protocol http --process node
python portmap.py register my-api postgres 5432 --protocol tcp --process docker

# Or let the scanner find them automatically
python portmap.py scan

Reserve port ranges (optional)

Edit registry.json and add entries to the ranges object to reserve contiguous blocks for a project:

{
  "ranges": {
    "my-api": { "start": 3000, "end": 3009 },
    "my-other-project": { "start": 4000, "end": 4009 }
  }
}

Then allocate will prefer those ranges, and gaps will exclude them from "available" output.

AI Agent Integration

This is where portmap gets interesting. Any AI agent pointed at this repo can:

  1. Read CLAUDE.md — the agent-facing quick reference with exact commands
  2. Read registry.json — self-documenting JSON with a schema
  3. Run CLI commands — check ports, allocate, register, all with machine-parseable output

Cross-repo discovery

Add a portmap reference to each project's CLAUDE.md (or equivalent agent instructions):

## Ports
This project's ports are registered in portmap (project id: "my-app").
Before changing ports: `python /path/to/portmap/portmap.py check <port>`
Allocate new ports: `python /path/to/portmap/portmap.py allocate my-app`

Now any agent working in that repo will discover portmap and use it.

Agent source tracking

# Entries are tagged with who created them
PORTMAP_AGENT_NAME=claude python portmap.py register my-app api 8080
# source field: "agent:claude"

See docs/INTEGRATION.md for the full integration guide covering:

  • Human CLI workflows
  • AI agent patterns (Claude, Cursor, Copilot)
  • Programmatic access from PowerShell, Python, Node.js
  • Cross-repo setup
  • Scheduled scanning

How the Scanner Works

The scanner reads project config files and extracts port assignments:

Source What it extracts
docker-compose.yml ports: mappings (handles env vars, bind addresses, protocols)
launchSettings.json .NET applicationUrl ports
appsettings.json Kestrel endpoint ports
.env files PORT= and *_PORT= assignments (skips dependency URLs)
start-all.ps1 etc. Port = N assignments, localhost:N patterns

Scanner entries are tagged with source: "scan:*" and auto-update on each scan. Manual and agent entries are never overwritten by the scanner.

Scheduled Scanning (Windows)

# Install a Task Scheduler job (scans every 15 minutes)
.\setup-scheduled-scan.ps1

# Custom interval
.\setup-scheduled-scan.ps1 -IntervalMinutes 30

# Remove
.\setup-scheduled-scan.ps1 -Remove

Project Structure

portmap/
├── CLAUDE.md                    # Agent-facing documentation
├── README.md                    # You are here
├── registry.json                # Your registry (gitignored — local to you)
├── registry.example.json        # Example registry to start from
├── schema/
│   └── registry.schema.json     # JSON Schema for validation + IDE completion
├── portmap.py                   # CLI entry point (zero dependencies)
├── scanner/
│   ├── core.py                  # Scan orchestrator + merge logic
│   ├── conflict.py              # Conflict detection
│   └── extractors/              # Per-format parsers
├── docs/
│   └── INTEGRATION.md           # Human / Agent / API integration guide
├── setup-scheduled-scan.ps1     # Windows Task Scheduler installer
└── web/                         # Future: local dashboard

Product Vision

Goal

Eliminate port conflicts and provide a local "application registry" that any developer or AI agent can query to understand what's running, what's claimed, and where to put new things.

What portmap is

  • A source of truth for local service port assignments
  • A machine-readable manifest with a JSON Schema
  • A CLI for querying, registering, and detecting conflicts
  • An auto-scanner that discovers ports from project config files
  • A reference that any AI agent can read and act on autonomously

What portmap is NOT

  • Not a service mesh or proxy (use Traefik for that)
  • Not a process manager (it doesn't start/stop services)
  • Not a Docker replacement (it works alongside Docker)
  • Not cloud infrastructure (it's strictly local dev)

Guardrails

  • Zero dependencies — stdlib Python only, no pip install needed
  • File-based — registry.json is the only state, checked into git
  • Non-destructive scanner — auto-discovery never overwrites manual or agent entries
  • No magic — explicit registration, explicit port assignment
  • Agent-first docs — CLAUDE.md is the primary interface for AI agents

Roadmap

Phase Status Description
1. Foundation Done CLI + manifest + schema + docs
2. Scanner Done Auto-discover from docker-compose, appsettings, .env, scripts
3. Validator + Allocator Done Live port checking, gap finding, port allocation
4. Automation Done Scheduled scanning via Task Scheduler
5. Cross-repo Done CLAUDE.md integration pattern
6. Web View Future Local dashboard for visual overview

Contributing

Issues and PRs welcome. The codebase is intentionally small (~500 lines of Python, zero dependencies) — keep it that way.

License

MIT — see LICENSE.

About

Navigate your local tooling request to use default or common ports -- a proactive or reactive port manifest for local projects

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages