
WTF is this? ๐ค
Stop guessing which process is hogging port 3000! ๐
Eliminate the operational friction of diagnosing port collisions and orphaned workloads. PortScope is an advanced CLI observability suite that aggregates real-time metrics from active development servers, databases, and system daemons into a high-fidelity control plane. Engineered with heuristic framework detection and native Docker container mapping, it accelerates local debugging by providing intelligent context aggregation, interactive process lifecycle management, and integrated AI orchestration for natural language state querying.
[!NOTE]
An important question to ask is: Why not use a
skill.mdinstead?Well, essentially two reasons,
- A plain
skills.mddoesnโt behave well with smaller/local models. They donโt have strong instruction hierarchy or long-context discipline, so they either ignore it or overfit to it. In a tool-driven loop (like this CLI setup), that becomes unstable, because the model canโt reliably separate system intent from user intent or tool state.
Also, considering slightly larger setups (think sandboxed REPL-style agents), โskillsโ are usually mediated through structured tool schemas, guarded execution, and controlled context injection. That layer acts like a safety boundary between the model and the runtime ... and a rawskills.mdbypasses that and gets dumped straight into the prompt, so thereโs no isolation, no validation, and no execution guardrails. On smaller/local models, that can lead to prompt pollution (or better context rot), bad tool calls, or the model hallucinating actions it shouldnโt take.
- I also have another take (honest one): itโs also just more fun and flexible this way. Most people running this arenโt on big sandboxed models, theyโre on cheaper or local SLMs. A naive
skills.mddump can actually mess with the modelโs flow instead of helping it.
What it looks like ๐
https://github.com/user-attachments/assets/41009a31-9a40-4503-b4d4-54698eca2148
PortScope stays alive after showing your ports โ type commands, ask questions in natural language, or use /help for the full command list.
Install
npm install -g github:Neilblaze/portscope
Or run it directly without installing:
npx github:Neilblaze/portscope
[!TIP] You can install and run it directly using Claude Code / Gemini CLI.
Usage
Interactive mode (default)
portscope
Shows your port table and drops into an interactive prompt. From there you can:
- Type a port number (e.g.
3000) โ inspect it - Type a command (e.g.
kill 3000,ps,clean) โ execute it - Ask in natural language (e.g.
"what's using the most CPU?") โ AI answers and acts - Use slash commands (
/provider,/models,/help) โ configure AI - Fish-style Autocomplete โ Intelligent ghost-text suggestions appear as you type (press
โto accept)
Type exit or press Ctrl+C to quit.
[!TIP] You can launch PortScope with the
--verboseflag (e.g.portscope --verbose) to enable real-time SSE streaming for AI responses, complete with token metrics and latency stats.
Show all listening ports
portscope --all
Includes system services, desktop apps, and everything else listening on your machine.
Inspect a specific port
portscope 3000
# or
whoisonport 3000
Detailed view: full process tree, repository path, current git branch, memory usage.
Kill a process
portscope kill 3000 # kill by port
portscope kill 3000,5173,8080 # kill comma-separated
portscope kill 3000-3010 # kill a port range
portscope kill 42872 # kill by PID
portscope kill -f 3000 # force kill (SIGKILL)
portscope kill all # kill all dev server ports
[!IMPORTANT]
portscope kill alland all destructive operations always require explicity/Nconfirmation โ including when initiated by AI.
Port ranges expand into individual kills โ empty ports are silently skipped:
$ portscope kill 3000-3005
Killing :3000 โ node (PID 41245)
โ Sent SIGTERM to :3000 โ node (PID 41245)
Killing :3001 โ node (PID 91248)
โ Sent SIGTERM to :3001 โ node (PID 91248)
Range summary: 2 killed, 4 empty
Pause / Resume a process
portscope pause 3000 # suspend (SIGSTOP) โ frees CPU, keeps state
portscope resume 3000 # resume (SIGCONT)
Useful for temporarily freeing resources โ e.g., pausing a 10 GB inference server to run a Docker build, then resuming it.
[!NOTE] Pause/resume uses POSIX
SIGSTOP/SIGCONTand is available on macOS and Linux. Not supported on Windows.
View process logs
portscope logs 3000 # show last 50 lines and exit
portscope logs 3000 -f # follow (stream new lines)
portscope logs 3000 --lines 10 # show last 10 lines
portscope logs 3000 --err # stderr only
Discovers log files automatically using lsof file descriptor detection. Falls back to system log (log show on macOS, journalctl on Linux) when no log files are found.
$ portscope logs 3000 --lines 5
PortScope โ logs for :3000 (node, PID 41245)
โธ Tailing stdout: /tmp/next-dev.output
โฒ Next.js 16.2.4 (Turbopack)
- Local: http://localhost:3000
โ Ready in 192ms
GET / 200 in 920ms
GET /api/auth/session 200 in 5ms
Show all dev processes
portscope ps
A beautiful ps aux for developers โ full process names, CPU%, memory, framework detection, environment detection (dev/prod/test/staging), and a smart description column.
$ portscope ps
โญโโโโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโโฌโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ PID โ PROCESS โ CPU% โ MEM โ PROJECT โ FRAMEWORK โ ENV โ UPTIME โ WHAT โ
โโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโผโโโโโโผโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 584 โ Docker โ 1.5 โ 842.1 MB โ โ โ Docker โ โ โ 2d 5h โ 12 processes โ
โโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโผโโโโโโผโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 32194 โ python3 โ 0.4 โ 45.2 MB โ backend โ Python โ dev โ 5h 10m โ uvicorn main:app --reload โ
โโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโผโโโโโโผโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 21245 โ node โ 0.2 โ 112.5 MB โ frontend โ Node.js โ dev โ 45m โ vite โ
โฐโโโโโโโโดโโโโโโโโโโโโโโดโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโโดโโโโโโดโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
3 processes ยท --all to show everything
Other commands
portscope clean # Kill orphaned/zombie dev servers
portscope watch # Monitor port changes in real-time (with live traffic metrics)
portscope watch --ar # Monitor ports with Autoreload (auto-restart crashed processes)
portscope watch --fe,be # Monitor only specific port roles (e.g. frontend + backend)
portscope chat # Jump directly into AI chat mode
Watch mode displays live metrics for every active port including Memory Usage (RAM), Process Uptime, Bind Address (127.0.0.1 vs 0.0.0.0), Process ID (PID), active connection counts, request rates (req/s), and real-time Bandwidth / Throughput (โ...B/s โ...B/s), helping identify load issues and monitor live traffic without additional/external tools.
- Autoreload (
--autoreload/--ar): Automatically restarts crashed processes using their recorded start/dev commands if they crash. - Port Filtering (
--fe,--be,--db,--api,--ml,--ui): Filter watch list by specific process roles (frontend, backend, database, API, machine learning, UI). Multiple roles can be comma-separated (e.g.--fe,be).
[!TIP] Aliases
portsandwhoisonportalso work:ports kill 3000,whoisonport 8080
MCP Server Support
PortScope can run as a Model Context Protocol (MCP) server, securely exposing its port management and system diagnostic tools to external AI agents like Claude Desktop, Cursor, and Windsurf.
# Local usage (stdio) - For Claude Desktop, Cursor, etc.
portscope mcp --transport stdio
# Remote/Network usage (SSE) - Stand up a headless HTTP server
portscope mcp --transport sse --port 3000
# Verify the SSE server is working
curl -N http://localhost:3000/sse
Environment Variables
You can also configure the server by adding the following to your project's .env or ~/.portscope/.env:
PORTSCOPE_MCP_PORT=3000โ Overrides the default SSE server port.
Capabilities
The MCP Server exposes not just tools, but also prompts and resources to improve AI orchestration:
- Tools: 11 tools โ
list_ports,inspect_port,kill_process,kill_all_dev_ports,list_processes,find_orphaned,clean_orphaned,view_logs,get_system_stats,restart_process,get_port_connections. - Prompts: Access
portscope-helpto provide usage examples directly to the LLM context. - Resources: Access
portscope://statusto read real-time Server Status, uptime, and memory usage.
[!NOTE] When running in MCP mode, destructive tools (like killing processes) run in headless mode and defer confirmation to the client's built-in UI safeguards. The MCP server is blazing fast and dynamically loaded, ensuring zero performance penalty to your standard CLI commands.
AI Chat
PortScope's AI lets you manage ports with natural language โ "kill whatever's on 3000", "show me what's using the most CPU", "stop all dev servers". It works right from the default interactive prompt, or via portscope chat for a dedicated AI session.
[!TIP] System Telemetry: The AI has direct access to a
get_system_stats()tool. You can ask it to diagnose machine-level performance bottlenecks, check CPU load averages, or analyze memory pressure.
Supported Providers
| Provider | Default Model | Browse Models | Env Variable |
|---|---|---|---|
| Anthropic | claude-haiku-4-5 |
curated list | ANTHROPIC_API_KEY |
| OpenAI | gpt-5-nano |
curated list | OPENAI_API_KEY |
| Google Gemini | gemini-2.5-flash |
curated list | GEMINI_API_KEY |
| OpenRouter | qwen/qwen3.5-flash-02-23 |
โ live browse | OPENROUTER_API_KEY |
| NVIDIA NIM | deepseek-ai/deepseek-v4-flash |
โ live browse | NVIDIA_API_KEY |
| Cerebras | llama-4-scout-17b-16e-instruct |
curated list | CEREBRAS_API_KEY |
| Groq | llama-3.3-70b-versatile |
curated list | GROQ_API_KEY |
| Ollama (Local) | llama3 |
โ local list | none โ runs locally |
Setup
Type /provider in the interactive prompt โ pick a provider, paste your API key, and you're ready. Keys are validated and saved to ~/.portscope/.env, and your provider/model choice persists in ~/.portscope/config.json โ no re-configuration needed on restart.
For Ollama, no API key is needed โ PortScope auto-detects the local server at localhost:11434, or you can set your custom endpoint on your own. Just select Ollama via /provider and start chatting.
[!NOTE] Ollama provides cost-free, local AI chat using locally running models. Tool-calling (kill, inspect via AI) is not supported โ use Ollama for conversational Q&A and cloud providers for full AI orchestration.
Slash Commands
| Command | Description |
|---|---|
/provider |
Switch AI provider and configure API key |
/revoke |
Revoke a saved API key |
/models |
Browse and select a model (live listing for OpenRouter & NVIDIA NIM) |
/model <name> |
Set model directly |
/status |
Show current provider, model, and key status |
/usage |
Display token consumption and estimated session costs |
/history |
List saved conversation sessions |
/load <n> |
Restore a previous conversation session |
/export [md\|html\|txt] |
Export current conversation to file |
/verbose |
Toggle verbose/streaming mode and detailed telemetry |
/clear |
Reset conversation history |
/help |
List all commands |
Configuration
Environment variables 
Set in .env (project root), ~/.portscope/.env, or shell environment:
ANTHROPIC_API_KEY=...
OPENAI_API_KEY=...
GEMINI_API_KEY=...
OPENROUTER_API_KEY=...
NVIDIA_API_KEY=...
CEREBRAS_API_KEY=...
GROQ_API_KEY=...
Provider is selected interactively via /provider โ no env var needed.
Config file 
Create portscope.config.json in your project root or home directory:
{
"ai": {
"provider": "anthropic",
"model": "claude-haiku-4-5",
"maxTokens": 4096,
"maxContextTokens": 32000,
"sanitizePatterns": []
},
"display": {
"showBanner": true
}
}
Security & Permissions
[!IMPORTANT] Destructive operations (kill, kill all, clean) always require explicit
y/Nconfirmation before executing, even when initiated by the AI.
- Sudo Interception: PortScope dynamically intercepts permission errors (
EPERM) when interacting with root-owned processes (e.g. Docker, system daemons). It safely prompts forsudoelevation directly in the terminal without requiring a CLI restart. - API Key Masking & Sanitization: All API keys are automatically masked in the UI and thoroughly sanitized from any error logs to prevent credential leakage.
How it works
Three shell calls, runs in ~0.2s:
lsof -iTCP -sTCP:LISTENโ finds all processes listening on TCP portsps(single batched call) โ retrieves process details for all PIDs at once: command line, uptime, memory, parent PID, statuslsof -d cwd(single batched call) โ resolves the working directory of each process to detect the project and framework
For Docker ports, a single docker ps call maps host ports to container names and images.
Framework detection reads package.json dependencies and inspects process command lines. Recognizes Next.js, Vite, Express, Angular, Remix, Astro, Django, Rails, FastAPI, and many others.
Framework Detection
PortScope automatically detects 40+ frameworks by analyzing process commands, port conventions, and project files. For more context refer below.
Supported frameworks 
- JavaScript: Next.js, Vite, React, Vue, Angular, Svelte, SvelteKit, Remix, Astro, Gatsby, Nuxt, Express, Fastify, NestJS, Hono, Koa
- Python: Django, Flask, FastAPI
- Other: Rails, Go, Rust, Java, Docker, PostgreSQL, Redis, MySQL, MongoDB, nginx, LocalStack, RabbitMQ, Kafka, Elasticsearch, MinIO, Webpack, esbuild, Parcel
- MLOps / AI: vLLM, Triton Inference Server, Ollama, llama.cpp, LM Studio, Jupyter, TensorBoard, Gradio, Streamlit, MLflow
Flow

Architecture
graph TB
subgraph CLI_Entry_Point["CLI Entry Point"]
CLI([src/index.js<br/>Command Router])
end
subgraph Command_Layer["Command Layer"]
DIRECT[Direct Commands<br/>list ยท inspect ยท kill<br/>clean ยท logs ยท watch ยท ps]
INTERACTIVE{{Interactive Mode<br/>REPL + AI Chat}}
end
subgraph Scanner_Layer["Scanner Layer - System Introspection"]
PORTS[Port Scanner<br/>lsof TCP listeners]
PROCESS[Process Info<br/>ps batch queries]
FRAMEWORK[Framework Detection<br/>package.json ยท Docker images]
ENV[Environment Detection<br/>NODE_ENV ยท process flags]
LOGS[Log Discovery<br/>lsof file descriptors]
end
subgraph Platform_Abstraction["Platform Abstraction"]
PLATFORM([Platform Layer<br/>darwin ยท linux ยท win32])
SYSCALLS[System Calls<br/>lsof ยท ps ยท docker ยท git]
end
subgraph AI_Orchestration["AI Orchestration"]
CONVERSATION{{Conversation Manager<br/>message history ยท tool routing}}
CLIENT[Multi-Provider Client<br/>Anthropic ยท OpenAI ยท Gemini<br/>OpenRouter ยท NVIDIA ยท Cerebras<br/>Groq ยท Ollama]
EXECUTOR[Tool Executor<br/>permission checks ยท execution]
TOOLS[Tool Definitions<br/>list_ports ยท kill_process<br/>inspect_port ยท clean_orphaned]
USAGE[Usage Tracking<br/>tokens ยท cost estimation]
HISTORY[Conversation History<br/>save ยท load ยท export]
end
subgraph UI_Rendering["UI Rendering"]
TABLES[Table Renderer<br/>cli-table3 ยท rounded borders]
MARKDOWN[Markdown Renderer<br/>bold ยท code ยท tables]
SPINNER[Animated Spinner<br/>3ร3 grid ยท action verbs]
GHOST[Autocomplete<br/>fish-style suggestions]
end
subgraph Configuration["Configuration"]
CONFIG[Config Loader<br/>portscope.config.json<br/>~/.portscope/]
SCHEMA[Provider Schema<br/>defaults ยท validation]
end
CLI --> DIRECT
CLI --> INTERACTIVE
DIRECT --> PORTS
DIRECT --> PROCESS
DIRECT --> LOGS
INTERACTIVE --> CONVERSATION
INTERACTIVE --> DIRECT
CONVERSATION --> CLIENT
CONVERSATION --> EXECUTOR
CLIENT --> TOOLS
EXECUTOR --> PORTS
EXECUTOR --> PROCESS
EXECUTOR --> LOGS
PORTS --> FRAMEWORK
PORTS --> ENV
PORTS --> PLATFORM
PROCESS --> PLATFORM
LOGS --> PLATFORM
PLATFORM --> SYSCALLS
DIRECT --> TABLES
INTERACTIVE --> MARKDOWN
INTERACTIVE --> GHOST
CONVERSATION --> SPINNER
CONVERSATION --> USAGE
CONVERSATION --> HISTORY
CLI --> CONFIG
CONVERSATION --> CONFIG
CONFIG --> SCHEMA
%% Rounded nodes
classDef rounded rx:12,ry:12;
class CLI,DIRECT,INTERACTIVE,PORTS,PROCESS,FRAMEWORK,ENV,LOGS,PLATFORM,SYSCALLS,CONVERSATION,CLIENT,EXECUTOR,TOOLS,USAGE,HISTORY,TABLES,MARKDOWN,SPINNER,GHOST,CONFIG,SCHEMA rounded;
%% Subgraph styling (pseudo-transparent)
style CLI_Entry_Point fill:#fcfcfd,stroke:#e5e7eb,stroke-width:1px,stroke-dasharray:4 4
style Command_Layer fill:#fcfcfd,stroke:#e5e7eb,stroke-width:1px,stroke-dasharray:4 4
style Scanner_Layer fill:#fcfcfd,stroke:#e5e7eb,stroke-width:1px,stroke-dasharray:4 4
style Platform_Abstraction fill:#fcfcfd,stroke:#e5e7eb,stroke-width:1px,stroke-dasharray:4 4
style AI_Orchestration fill:#fcfcfd,stroke:#e5e7eb,stroke-width:1px,stroke-dasharray:4 4
style UI_Rendering fill:#fcfcfd,stroke:#e5e7eb,stroke-width:1px,stroke-dasharray:4 4
style Configuration fill:#fcfcfd,stroke:#e5e7eb,stroke-width:1px,stroke-dasharray:4 4
%% Highlighted nodes
style CLI fill:#4a9eff,stroke:#2563eb,color:#fff
style INTERACTIVE fill:#8b5cf6,stroke:#7c3aed,color:#fff
style CONVERSATION fill:#ec4899,stroke:#db2777,color:#fff
style PLATFORM fill:#10b981,stroke:#059669,color:#fff
style SYSCALLS fill:#f59e0b,stroke:#d97706,color:#fff
[!NOTE] PortScope provides native OS-level observability and is fully validated across ๏ฃฟ macOS, Linux, and Windows environments.
Development
git clone https://github.com/neilblaze/portscope.git
cd portscope
npm install
npm test # Run tests
npm start # Run locally (interactive mode)
npm run dev # Same as npm start
node src/index.js --help # See all commands
Contributing ๐ค
Got an idea to make PortScope better? Whether you want to add support for a new framework, optimize the port scanner, or just fix a typo, we'd love to see your pull requests!
[!IMPORTANT] If you are using LLMs or AI assistants to help write code, please review our AI Usage Policy to ensure your PR complies with our security and licensing standards.