A small CLI for running and snapshotting Docker containers from a YAML config, with an MCP server so AI agents can drive the same workflows.
Scoop
scoop bucket add maple 'https://github.com/kevinboss/maple.git'
scoop install portWinget
winget install kevinboss.portManual
Grab a binary from the releases page
and put it on your PATH.
Port reads ~/.port (or %USERPROFILE%\.port on Windows). If the file does
not exist, a default one is written on first run. You can also drop a
docker-compose.yml next to where you invoke port and the services in it are
merged in.
version: 1.1
dockerEndpoint: unix:///var/run/docker.sock
imageConfigs:
- identifier: Nginx
imageName: nginx
imageTags:
- alpine
- alpine-slim
ports:
- 8080:80
environment: []
- identifier: Alpine
imageName: alpine
imageTags:
- '3.19'
- latest
ports: []
environment: []identifier is the human-friendly name port uses everywhere (commands, container
names, tags); imageName is the actual Docker image; imageTags are the tags
port knows how to launch.
port config prints the path of the config file. Pass --open to open it in
your editor.
port list [identifier] shows every configured image, every tag, every
snapshot, and the running container if any. With an identifier, the listing is
restricted to that group.
port pull <identifier:tag> fetches the image. Per-layer download progress is
shown live.
port run <identifier:tag> [-r] launches a container. Any container holding
the same host port is stopped first. -r recreates the container instead of
restarting an existing one. Pulls the image if it isn't local yet.
port stop <containerName> stops a running container by its full name (e.g.
Nginx.alpine). With no name, you get a picker.
port reset <containerName> stops, removes, and recreates a container — useful
to discard mutations made inside it.
port commit <containerName> [-t tag] [-s] [-o] snapshots a running container
into a new image. -t sets the tag (defaults to a timestamp); -s switches
the running container to the new snapshot; -o overwrites the source tag.
port remove <identifier:tag> [-r] removes the image and any containers using
it. -r also removes descendant snapshot images.
port prune [identifier] removes dangling (digest-only) images. Restrict to
one identifier with the optional argument.
port mcp starts a Model Context Protocol
server over stdio. AI agents can then drive port the same way you do from the
shell.
The exposed tools mirror the CLI verbs: run, stop, reset, commit,
pull, remove, prune, list, config. A few have stricter inputs than
their CLI siblings — reset always requires a container name, commit
requires an explicit tag — to remove ambiguity for an agent.
claude mcp add port -- port mcpAdd to your claude_desktop_config.json:
{
"mcpServers": {
"port": {
"command": "port",
"args": ["mcp"]
}
}
}To get proper rendering of port's output in PowerShell, add this to your
$profile:
[console]::InputEncoding = [console]::OutputEncoding = [System.Text.UTF8Encoding]::new()PRs welcome. Fork, branch, commit, open a pull request.

