Run a local process as if it were inside your cluster: prefix any command
with plug and it resolves the cluster DNS and reaches the cluster services like
any workload of the stack - no code change, no proxy configuration in your app. One
tiny agent container on the cluster side, one static CLI on yours. Docker, Swarm, Kubernetes
and OpenShift.
How plug compares
mirrord and Telepresence are two established tools for running local code against a remote Kubernetes cluster. The table below sets them beside plug, row by row. What it says about them comes from their public documentation, read in October 2026; both move quickly, so check a row that matters to you against their current docs.
One difference shapes several rows. To receive traffic from the cluster, mirrord and
Telepresence attach to a workload that is already deployed. plug publishes a name instead:
plug -s my-api:8080:3000 npm run start:dev puts my-api in the
cluster for the session, whether a my-api was deployed or not. When one is, plug
sets it aside and restores it on exit.
| Criterion | plug | mirrord | Telepresence |
|---|---|---|---|
| Cluster targets | Docker Compose · Swarm · Kubernetes · OpenShift / OKD | Kubernetes (OpenShift after SCC changes, per its FAQ) | Kubernetes · OpenShift |
| Your machine | Linux - amd64, arm64 macOS - amd64, arm64 Windows - amd64, arm64 | Linux - amd64, arm64 macOS - amd64, arm64 Windows - amd64 | Linux - amd64, arm64 macOS - amd64, arm64 Windows - amd64, arm64 |
| What a developer needs | the cluster's address: plug installs itself from it | a kubeconfig with rights to start its agent pod, or the Operator (paid plans) | a kubeconfig; little or no RBAC once an administrator installed the traffic-manager |
| To receive cluster traffic | a name, which need not exist in the cluster, and can take over one that does | an existing workload, named with --target (targetless mode: outgoing traffic only) | an existing workload, attached with replace, intercept or wiretap |
| Setup, your machine | one ssh command, served by the cluster, at the version its agent runs | brew, curl, choco or an MSI | a package, an installer or brew |
| Staying up to date | the launcher runs the version each cluster's agent serves, one cached core per version; plug update moves the agent | reinstall the CLI; the Operator, where used, is upgraded separately | reinstall the CLI; the traffic-manager is upgraded separately, with Helm |
| Setup, cluster side | one agent container | none: an agent pod per session (the Operator on paid plans) | the traffic-manager, installed once |
| Reach cluster services by name | ✓ | ✓ | ✓ |
| Be reachable by a cluster name | ✓ -s name:8080:3000: the name is created for the session, no existing service needed | by stealing or mirroring an existing workload's traffic | by replacing or intercepting an existing workload |
| Runtimes | any, unchanged (IP layer) | programs linked against libc, and Go; not statically linked binaries | any, unchanged (network level) |
| Run a container as a member | ✓ --dockerrun | ✓ mirrord container | ✓ --docker-run |
| Inherit the workload's environment | ✓ by default on a takeover; the cluster's value wins over an inherited one, and --no-env keeps yours, whole or key by key | ✓ by default, from the target | ✓ on any attach |
| Borrow another workload's environment | ✓ --env-of <name>, without parking it | only the --target | ✓ telepresence ingest <workload>, traffic untouched |
| Its mounted secret and config files | ✓ read through the agent and written for the session, the variables that name them repointed; Kubernetes and Compose secrets, Swarm configs | ✓ file calls relayed into the pod by its in-process layer; remote reads by default, read-write configured per path | ✓ volume mounts through sshfs: FUSE-T on macOS, WinFsp and SSHFS-Win on Windows; none in Docker mode |
| Its data volumes, live | ✓ by default on a takeover, read-write, with the SMB client the OS already has; nothing to install | ✓ through its in-process file layer | ✓ mounted by default, through sshfs (FUSE-T or WinFsp to install) |
| Several developers on one cluster | ✓ each with their own sessions. A name already served is refused, and the refusal says where it is held from | ✓ on the paid Team plan; the free version is for one developer | ✓ |
| Two developers on the same service at once | one holder per name: the next one is refused | split per request on HTTP headers, path or method, or a queue message attribute; concurrent use on the paid Team plan | split per request on a header or a path (HTTP) |
| Who gets in | open by default; by approval with PLUG_ADMISSION=invite, each key accepted by a member and revocable, no account in the cluster (how) | whoever holds a kubeconfig the cluster issued | whoever the cluster lets reach its traffic-manager |
| What each person may do | every member, everything plug does; per-person rights through a gateway such as Meerkat | Kubernetes RBAC; Operator policies on paid plans | Kubernetes RBAC |
| IDE extensions | none, CLI only | VS Code · JetBrains | JetBrains (a JetBrains plugin) |
| For an AI coding agent | plug mcp: the clusters a machine knows, doctor, a workload's environment, DNS lookups | mirrord mcp, plus agent skills | telepresence mcp |
| Mechanism | userspace TUN over SSH, an agent in the cluster | libc and syscall hooks loaded into your process, an agent pod in the cluster | a virtual network interface on your machine, a traffic-manager and traffic-agents in the cluster |
| Behind it | Softwarity | MetalBear | a CNCF Sandbox project, created by Ambassador Labs |
| Price | free, every feature | free for one developer; the Team plan, per seat, for a shared cluster | free |
| License | FSL-1.1-Apache-2.0 | MIT | Apache-2.0 |
Green marks whichever tool is ahead on the fact stated in that row, whichever it is, and every one of them when several are. Rows where all three are level are left plain.
Where plug differs: a developer needs the cluster's address and nothing else: no kubeconfig, no Kubernetes tooling, no account in the cluster. That is also why it works where there is no kubeconfig at all: Docker Compose and Swarm. And the name it serves does not have to exist yet: the service you are writing, deployed nowhere, is reachable from the rest of the stack by its future name.
Where they are ahead: both rest on Kubernetes RBAC, which says per person what each one may do; plug decides who gets in, not what each member may do once in (see the security model). Both split one shared service between several developers request by request, provided the header is set where the request enters and every service in between passes it on. And both have IDE extensions.