A fast, cross-platform CLI tool for managing processes on specific ports. Perfect for developers who need to quickly identify and kill processes occupying ports during development.
- π List processes on specific ports or all ports
- β‘ Kill processes by port, PID, service, or user
- π₯οΈ Interactive TUI for visual management
- π Watch mode for real-time monitoring with notifications
- π‘ Port scanning for local and remote hosts
- π οΈ Developer shortcuts (quick kill, find free ports)
- π¨ Beautiful output with colored tables
- π‘οΈ Safety features with confirmation prompts
- π JSON output for scripting and automation
- π Zero dependencies - single binary
This project uses a modular, MCStack-compliant Dagger pipeline for full SDLC, compliance, and meta-architecture automation:
- Full pipeline:
dagger call build --src=.
- Individual steps:
dagger call lint --src=. # Lint code dagger call test --src=. # Run tests dagger call build --src=. # Build binaries dagger call release --src=. export --path=./artifacts # Release (GoReleaser) and export artifacts dagger call docs --src=. # Build mdBook docs dagger call generate-manifest --src=. # Generate MCP manifest dagger call well-known --src=. # Validate metadata
- CLI output is regression-tested with Cupaloy.
- Run via Dagger:
dagger call snapshot-test --src=.
- Docs are in
docs/and built with mdBook:dagger call docs --src=.
- SLSA 4, SBOM, Keyless Signing: Release pipeline uses GoReleaser for multi-platform, signed, and SBOM-compliant builds.
- MCP Server:
/mcpendpoint serves a machine-readable manifest for AI/LLM and tool ecosystem integration. - .well-known/: All compliance, AI, and SBOM metadata is published for discoverability and audit.
- MCStack Principles: Modular, auditable, and anti-fragile by design.
The MCP server exposes the real capabilities of the portctl CLI via a gRPC API for automation, LLMs, and agentic workflows.
ListProcesses(ListProcessesRequest) β ListProcessesResponse- List processes by port, user, or all.
KillProcess(KillProcessRequest) β KillProcessResponse- Kill a process by PID or port.
GetStatus(StatusRequest) β StatusResponse- Returns the current portctl version and server uptime.
- Start the server:
go run ./cmd/portctl mcp
- Call from a gRPC client:
- Use Go, Python, or
grpcurl:grpcurl -plaintext localhost:57251 mcp.PortctlService/GetStatus
- Use Go, Python, or
- Integration Test:
- Ensure server is running, then:
go test ./internal/tests/ -run TestGetStatus
- Ensure server is running, then:
proto/mcp.proto(see for full message definitions)
- Only exposes safe, real portctl features.
- All actions are logged for auditability.
git clone https://github.com/ckodex-labs/portctl.git
cd portctl
go build -o portctl
sudo mv portctl /usr/local/bin/ # Optional: add to PATHgo install github.com/ckodex-labs/portctl@latestDownload the latest binary from the releases page.
Full documentation is available at https://ckodex-labs.github.io/portctl/ (or in the docs/ directory).
# List all processes with open ports
portctl list
# List processes on a specific port
portctl list 8080
# Kill processes on port 8080
portctl kill 8080
# Kill a specific process by PID
portctl kill --pid 12345
# Force kill without confirmation
portctl kill 8080 --force --yes# List all processes with open ports
portctl list
# List processes on port 8080
portctl list 8080
# Output in JSON format
portctl list 8080 --json
# List all processes (explicit)
portctl list --allExample output:
| PID | PORT | PROTOCOL | STATE | COMMAND |
| ----- | ---- | -------- | ------ | -------- |
| 12345 | 8080 | tcp | LISTEN | node |
| 12346 | 3000 | tcp | LISTEN | python3 |
| 12347 | 5432 | tcp | LISTEN | postgres |
Found 3 process(es)
# Kill processes on port 8080 (with confirmation)
portctl kill 8080
# Kill process by PID
portctl kill --pid 12345
# Force kill (SIGKILL/taskkill /F)
portctl kill 8080 --force
# Skip confirmation prompt
portctl kill 8080 --yes
# Combine flags
portctl kill 8080 --force --yesExample interaction:
$ portctl kill 8080
Found 1 process(es) on port 8080:
PID 12345: node (tcp)
Are you sure you want to kill 1 process(es) on port 8080? [y/N]: y
Killing process 12345 (node)...
Successfully killed process 12345
Successfully killed all processes on port 8080# Get JSON output for automation
portctl list 8080 --json | jq '.[0].pid'
# Kill all Node.js processes on various ports
for port in 3000 8080 8081; do
portctl kill $port --yes 2>/dev/null || true
done# Find and kill all Node.js processes
portctl list --json | jq -r '.[] | select(.command | contains("node")) | .pid' | \
xargs -I {} portctl kill --pid {} --yes
# Monitor port usage
watch -n 2 'portctl list'--help, -h: Show help--version, -v: Show version
List processes on ports.
Arguments:
port(optional): Specific port number to check
Flags:
--json, -j: Output in JSON format--all, -a: List all processes (same as omitting port)
Kill processes on ports.
Arguments:
port: Port number (required unless --pid is used)
Flags:
--pid, -p INT: Kill specific process by PID--force, -f: Force kill (SIGKILL on Unix, /F on Windows)--yes, -y: Skip confirmation prompt
- Uses
lsofwhen available (more accurate) - Falls back to
netstatiflsofis not installed - Supports
SIGTERM(graceful) andSIGKILL(force) signals
- Uses
netstatandtasklistfor process discovery - Uses
taskkillfor termination - Supports normal and force (
/F) termination
- Confirmation prompts: Always asks before killing processes (unless
--yes) - Process listing: Shows exactly what will be killed before doing it
- Graceful termination: Uses SIGTERM by default, SIGKILL only with
--force - Error handling: Clear error messages and non-zero exit codes on failure
- PID validation: Verifies processes exist before attempting to kill them
# Check what's running on your dev ports
portctl list
# Kill that stuck dev server
portctl kill 3000
# Clean up after testing
portctl kill 8080 8081 8082 --yes# Find what's using port 80
portctl list 80
# Kill it if it's safe to do so
portctl kill 80#!/bin/bash
# cleanup-dev-ports.sh
PORTS=(3000 8080 8081 8082 5000)
echo "Cleaning up development ports..."
for port in "${PORTS[@]}"; do
if portctl list "$port" &>/dev/null; then
echo "Killing processes on port $port"
portctl kill "$port" --yes
fi
done
echo "Cleanup complete!"portctl provides clear error messages and appropriate exit codes:
0: Success1: General error (invalid arguments, process not found, etc.)2: Permission denied (may need sudo/admin privileges)
- Fast startup: Minimal dependencies and efficient process discovery
- Low memory: Typically uses <10MB RAM
- Cross-platform: Single codebase works on all major platforms
Requirements:
- Go 1.21 or later
# Clone the repository
git clone https://github.com/ckodex-labs/portctl.git
cd portctl
# Download dependencies
go mod download
# Build for current platform
go build -o portctl
# Build for all platforms
make build-all # If Makefile is available
# Run tests
go test ./...- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License. See the LICENSE file for details.
Some processes may require elevated privileges to kill:
# On Unix systems
sudo portctl kill 80
# On Windows (run as Administrator)
portctl kill 80Make sure the binary is in your PATH:
# Add to ~/.bashrc or ~/.zshrc
export PATH=$PATH:/path/to/portctl
# Or install globally
sudo mv portctl /usr/local/bin/Some processes may ignore SIGTERM. Use force kill:
portctl kill 8080 --forcelsof: More powerful but complex syntaxnetstat: Basic but requires manual PID lookupfuser: Unix-only, limited output formattingss: Modern netstat replacement, but no kill functionality
portctl combines the best of these tools with a developer-friendly interface! π
This project aims to comply with the OpenSSF Best Practices for open source security and quality. See the OpenSSF Badge for more info.
- Automated CI/CD with GitHub Actions
- Security and vulnerability scanning
- Static analysis and code quality checks
- Documentation and artifact publishing
The project uses Dagger for all quality checks. You can run them directly or via the Makefile:
make lint # Runs dagger call lint
make test # Runs dagger call test
make sec # Runs dagger call security-scanAll pushes and pull requests are checked by GitHub Actions for build, test, lint, security, and documentation. See .github/workflows/ci.yml for details.