Portboard MCP Server
Detects Docker containers as owners of listening ports and displays container details alongside process and systemd ownership on the services dashboard.
Sends alerts and daily or weekly digests to ntfy for watched ports and devices, new-device notices, and new-port notices.
Optionally reads a Proxmox host and its containers over a read-only SSH key, including them in the devices network map and port usage view.
Integrates with Tailscale to discover tailnet devices, bind the dashboard to the Tailscale IP, publish loopback HTTP services to the tailnet via tailscale serve, and restrict writes to the owner's Tailscale login.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Portboard MCP Serverreserve a port for my feature branch and start its dev server"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Portboard
Portboard coordinates ports and dev servers on one Linux machine shared by people and AI coding agents, so parallel Claude Code sessions and worktrees pick ports, start servers and clean up without colliding or killing each other's.
It is also a dashboard of every TCP port listening on that machine, the devices on your Tailscale tailnet and your dev
worktrees: open any service from your laptop or phone with one click, no ssh -N -L … needed.
Live demo: the dashboard in your browser on example data, read-only, nothing to install (docs/demo.md; the link works once GitHub Pages is turned on for the repo).

Port reservations.
free_port {for: "<repo>@<branch>"}returns that owner's reserved port first and never offers another owner's;reserve_portkeeps a port for a worktree across restarts, so two sessions don't both guess 3000.Dev servers agents start and stop.
start_dev_server {path}runs a worktree'sdev/start/preview/servescript as a transient systemd unit on its reserved port;tail_logsreads its output andstop_dev_serverstops it.A nudge on raw port commands. In the Claude Code plugin, a PreToolUse hook notices a Bash command that starts a server on a hard-coded port or kills by port, and adds a
[portboard]note: who holds or reserved that port, which port to use, and the MCP call to make instead. It never blocks the command.Cleanup after sessions. Servers whose worktree was deleted, whose branch is merged or whose Claude session ended become cleanup candidates. A SessionEnd hook marks a session's servers at once and, only if you turn it on, stops them. Installed services, containers and pinned ports are never touched.
A measure of whether agents use it.
node scripts/adoption.ts --days 7(or theadoption_statstool) reads this machine's Claude Code transcripts and counts Portboard MCP calls against rawss/lsofinspection, kill-by-port, servers started on a hard-coded port, and nudges shown and followed.MCP for any client. A local stdio MCP server that any MCP-capable agent CLI can run, the Claude Code plugin (the server plus a skill and the hooks), and an optional read-only remote connector for claude.ai and ChatGPT. Guide: running several coding agents on one machine.
Services. Every listening port with its owner: process, project folder, systemd unit or docker container, HTTP title, bind scope (loopback / tailnet / all), who is connected now and when it was last used.
One click to open. A loopback-only HTTP port can be published to the tailnet with
tailscale servefrom its row, and unpublished again.Devices. Tailnet devices with their load and the ports they use; optionally a Proxmox host and its containers and a desktop's Windows side, read over a read-only SSH key.
Worktrees. Start and stop a worktree's dev server from the dashboard, and find worktrees and servers that are safe to clean up.
Alerts. Down alerts for watched ports and devices, new-device and new-port notices, daily or weekly digests, over ntfy or a webhook.
Zero runtime dependencies. Node.js and the standard library only. TypeScript runs directly on Node ≥ 22.18 (type stripping);
typescriptand@types/nodeare dev dependencies for the typecheck.
The dashboard speaks English and Korean. It follows the browser's language unless the server sets one (locale in
portboard.json or PORTBOARD_LOCALE), and each device can pick its own under Settings › Display › Language
(docs/i18n). The code, docs and API are in English.
Devices | A service's page, dark mode |
|
|
The screenshots and the live demo use example data: none of these machines exist.
Quick start
Requirements: Linux with ss (iproute2), Node.js ≥ 22.18 (24 recommended), and Tailscale
for anything beyond localhost. systemd and docker are used when present. It also runs on macOS (ports through
lsof; no restart, dev servers or memory view) and as a read-only Docker image over the host's ports:
docs/platforms.md.
npx portboard start # try it: dashboard + REST API on 127.0.0.1:8790 and this machine's Tailscale IPTo keep it running, install it and let it write a systemd user unit for the node you ran it with:
npm i -g portboard
portboard install-service # writes ~/.config/systemd/user/portboard.service, prints the line below
systemctl --user daemon-reload && systemctl --user enable --now portboardportboard install-service --enable runs those two for you; --dry-run only prints the unit. Or from a checkout, to
hack on it or follow main:
git clone https://github.com/c10dev/portboard.git ~/projects/portboard
cd ~/projects/portboard
npm start # same as bin/portboard start
bin/portboard install-service # the unit then runs this checkoutOpen http://127.0.0.1:8790. From another tailnet device, publish it over HTTPS (tailnet only):
tailscale serve --bg --https=8443 http://127.0.0.1:8790and open https://<host>.<tailnet>.ts.net:8443. Writes (stop, restart, publish, delete) work only through that HTTPS
address and only for your own Tailscale login; plain http://<tailscale-ip>:8790 is read-only.
The unit names the node binary and the install it was written from: after a node upgrade (a new nvm version) or a
move, run portboard install-service again. portboard --help lists the other commands (remote, mcp,
uninstall-service); docs/setup.md has the details.
Nothing has to be configured: the host name, tailnet and user come from the machine. To name a Proxmox host, a Windows
desktop, other repo folders or a compute-pool monitor, copy portboard.example.json to
~/.config/portboard/portboard.json and edit it (docs/config.md). More: docs/setup.md.
Related MCP server: tidyports
Security model
Portboard can stop services and delete worktrees, so read docs/security.md before exposing it. In short:
Reachable only from this machine and your tailnet. It binds to loopback and the Tailscale IP, and answers 421 to any
Hostit doesn't recognise (DNS rebinding).Owner-only writes. Every write needs the
X-Portboard: 1header (CSRF) and the owner: a local process, or your own Tailscale login throughtailscale serve. Other tailnet users, tagged nodes, direct connections and Funnel traffic are read-only.writeDevicesin~/.config/portboard/access.jsonnarrows writes to the devices you list. Every write, allowed or denied, goes to an audit log.Reads are open to the tailnet. Anyone who can reach it sees port lists, command lines and device names. Share your tailnet accordingly.
The remote MCP server is read-only.
src/remote.ts(port 8794) is meant for Tailscale Funnel, so claude.ai and ChatGPT can ask what is running. It offers only read tools, with redacted addresses and paths, behind OAuth with a one-time approval code (docs/remote-mcp, review). It is off unless you run it.Never put the dashboard (8790 / its serve port) on Funnel, never bind it to a public interface, and never commit
~/.config/portboard/(it holds tokens and secrets).
Found a vulnerability? See SECURITY.md.
Claude Code plugin
This repository is also a Claude Code plugin marketplace. The portboard plugin adds the MCP server, a
dev-servers-and-ports skill, a hook that nudges when a Bash command hard-codes or kills a port, and session-end
cleanup of dev servers:
/plugin marketplace add c10dev/portboard
/plugin install portboard@portboardThe plugin runs the MCP server from your checkout (~/projects/portboard, or PORTBOARD_HOME). Details:
docs/claude-plugin. Without the plugin: docs/mcp.md. The workflow
across several sessions, and other agent CLIs: docs/agents.md.
Mac app
A native SwiftUI app (macOS 14+) shows the dashboard in a window, with a menu bar item and native notifications. Build it on the Mac with your server's address:
PORTBOARD_SERVER_URL=https://<host>.<tailnet>.ts.net:8443 mac-app/build.sh --installDetails: docs/mac-app.
Docs
Topic | |
environment variables, previews, systemd, Mac app, one-time | |
Linux, macOS (lsof, launchd) and the read-only Docker image: what works where | |
| |
rows, last-used history, service page, devices, alerts, new devices | |
endpoints and guards | |
several agents on one machine: reserve, start, clean up, measure; other agent CLIs | |
the local stdio server: tools, resources, prompts | |
the read-only connector for claude.ai and ChatGPT | |
| |
who can reach and write, audit log, headers and files | |
deploy, profiles, files, the SSH readers, runtime footprint | |
setting up and rotating every credential Portboard holds | |
source layout, adding a feature | |
the static, read-only demo and landing page on GitHub Pages, from example data | |
releases, how to add an entry |
Optional integrations
compute-pool: a separate monitor (
cpool monitor,PORTBOARD_POOL_URL) whose hosts the Devices tab shows with load and state. Without it the tab lists tailnet devices only. Any endpoint serving the same JSON works: integrations/compute-pool.md.Proxmox VE: an API token for VM/CT state and trends, and a forced-command SSH key for container ports (runbooks).
ntfy or a webhook for alerts.
Contributing
Issues and pull requests are welcome: CONTRIBUTING.md. Please follow the Code of Conduct.
License
This server cannot be deployed
Maintenance
Related MCP Connectors
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Linux VMs for AI agents: create VMs, run commands, edit files and open preview URLs.
Persistent Linux computers for AI agents: desktop, signed-in browser, vault, apps and shell.
Provides capabilities that let LLM agents perform a range of infrastructure management tasks.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to discover, configure, and manage local development servers. Provides tools for app registration, port allocation, lifecycle control, and log access without manual config editing.124 npmMIT
- AlicenseNot gradedqualityDmaintenanceSee and control the local dev servers your coding agents leave running. Lists listeners with provenance — which agent, terminal and git worktree started each — kills strays, and allocates collision-free ports so parallel agents stop fighting over :3000.MIT
- AlicenseNot gradedqualityAmaintenanceMCP server for managing local dev ports on macOS. It enables AI agents to inspect listening ports, identify owning processes and parent chains, kill processes safely, wait for ports, and report LAN exposure.3 npm1MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to securely create, manage, and monitor local processes such as dev servers, docker-compose, and test watchers, including restarting, checking status, and retrieving logs via MCP, HTTP, or WebSocket messaging.4 npm1MIT

