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.

CriterionplugmirrordTelepresence
Cluster targetsDocker Compose · Swarm · Kubernetes · OpenShift / OKDKubernetes (OpenShift after SCC changes, per its FAQ)Kubernetes · OpenShift
Your machineLinux - 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 needsthe cluster's address: plug installs itself from ita 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 traffica name, which need not exist in the cluster, and can take over one that doesan existing workload, named with --target (targetless mode: outgoing traffic only)an existing workload, attached with replace, intercept or wiretap
Setup, your machineone ssh command, served by the cluster, at the version its agent runsbrew, curl, choco or an MSIa package, an installer or brew
Staying up to datethe launcher runs the version each cluster's agent serves, one cached core per version; plug update moves the agentreinstall the CLI; the Operator, where used, is upgraded separatelyreinstall the CLI; the traffic-manager is upgraded separately, with Helm
Setup, cluster sideone agent containernone: 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 neededby stealing or mirroring an existing workload's trafficby replacing or intercepting an existing workload
Runtimesany, unchanged (IP layer)programs linked against libc, and Go; not statically linked binariesany, 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 itonly 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 onceone holder per name: the next one is refusedsplit per request on HTTP headers, path or method, or a queue message attribute; concurrent use on the paid Team plansplit per request on a header or a path (HTTP)
Who gets inopen 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 issuedwhoever the cluster lets reach its traffic-manager
What each person may doevery member, everything plug does; per-person rights through a gateway such as MeerkatKubernetes RBAC; Operator policies on paid plansKubernetes RBAC
IDE extensionsnone, CLI onlyVS Code · JetBrainsJetBrains (a JetBrains plugin)
For an AI coding agentplug mcp: the clusters a machine knows, doctor, a workload's environment, DNS lookupsmirrord mcp, plus agent skillstelepresence mcp
Mechanismuserspace TUN over SSH, an agent in the clusterlibc and syscall hooks loaded into your process, an agent pod in the clustera virtual network interface on your machine, a traffic-manager and traffic-agents in the cluster
Behind itSoftwarityMetalBeara CNCF Sandbox project, created by Ambassador Labs
Pricefree, every featurefree for one developer; the Team plan, per seat, for a shared clusterfree
LicenseFSL-1.1-Apache-2.0MITApache-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.

Set it up