Desktop Agent Harness vs Cloud-Native Harness: 8 Differences That Matter in Production
A desktop agent harness ties the client, the agent loop, the filesystem, the tools, the credentials and the conversation state to one long-lived machine. A cloud-native agent harness gives each of those a separate owner, so the loop can run as a service and a worker can be replaced without losing the session. Putting a desktop harness in a container changes where it runs, not how it is built.
This post walks through the eight things that have to come apart before an agent can be operated the way you operate any other application, with Mecatl as the worked example because it runs both ways from the same engine. Where a desktop harness is the better choice, the post says so.
What a desktop harness is
Claude Code, Codex CLI, Cursor’s agent mode, OpenCode, Pi and the Goose desktop app are desktop harnesses. Each one is a single process on the developer’s machine that draws the UI, runs the agent loop, reads and writes the developer’s checkout, runs shell commands as the developer, uses the keys in the developer’s environment, and keeps the conversation in a local file.
That shape is good at what it was built for. The developer is right there to approve a command, the agent sees the same files the developer sees, and there is nothing to deploy. For an individual writing code, a desktop harness is the fastest loop available, and Mecatl’s own mecatui is one.
The shape becomes a problem when the agent needs to outlive the laptop, serve more than one person, run on a schedule, or act with an identity that is not the developer’s. Every one of the bundled pieces was a convenience on the desktop and is a coupling everywhere else.
Why a container does not change the architecture
The usual first move is to put the desktop harness in a container and run it on a server. Claude Code’s cloud sessions do a version of this, and since August 2026 Team and Enterprise customers can point those sessions at self-hosted environments: long-lived runners on your own hosts that register with Anthropic’s control plane and spawn a Claude Code process per session. Codex has a cloud mode in the same spirit. These are useful, and they move the work inside your network.
What they do not do is take the harness apart. The runner still spawns the same bundled process: UI protocol, loop, workspace, tools and session state together, on one host, for the life of the session. If that host or container goes away, the session goes with it. The Mecatl docs put the three cases side by side:
| Harness | What changes when it moves to a server? |
|---|---|
| Desktop | Client, loop, workspace and local state stay coupled to one machine. |
| Containerized desktop | The coupled runtime moves into a container; replacing it still means handling its workspace and state. |
| Cloud-native | Clients, loop, execution and durable state have separate owners, so workers can be replaced while services keep the state. |
Source: What is a cloud-native harness?
The middle row is where most “we run agents in the cloud” setups sit today. The rest of this post is about what separates it from the bottom row.
1. Where does the agent loop run?
On a desktop harness the loop runs inside the client. Close the terminal and the loop stops. You cannot upgrade it without upgrading the client, and you cannot observe it except through whatever the client prints.
In a cloud-native harness the loop is a service. Mecatl runs the same Go engine in three places: embedded in mecatui behind a private Unix socket, as the standalone mecated server, and as mecak8s on Kubernetes. The capability matrix lists what each deployment adds, but the loop itself does not change. Once it is a service, it gets the treatment every other service gets: versioned, rolled out, logged and scraped. The mecak8s chart ships with readiness and drain behavior so a deployment controller can replace a replica during normal operations.
2. Where do files and shell commands execute?
A desktop harness runs ls, git and go test on the developer’s checkout, in the developer’s home directory, with the developer’s PATH. The workspace is wherever the process was started.
Mecatl assigns an execution environment to each session when it is created, and the client does not get to choose it. The options are the deployment’s default workspace, an operator-approved execution template pinned to a revision, or execution.none, which removes Read, Write, Edit, Shell and the rest of the file tools from the catalog and leaves web tools, memory, MCP and delegation. On Kubernetes, file tools and shell run in the harness pod’s namespace, not on the caller’s machine, and a remote mecatui never uploads its local checkout. A local deployment can set the default to a repository-scoped microVM on Linux with KVM.
# Create a session with no filesystem and no shell
curl -s -X POST http://127.0.0.1:8081/v1/sessions \
-d '{"execution":{"none":{}}}'
The selection is fixed for the life of the session. The model cannot talk its way into a shell it was not given.
3. Who holds the session state?
A desktop harness writes the conversation to a file on disk. Mecatl’s embedded mecatui does the same, in a per-workspace JSONL store. That is fine on a laptop. On a server it means the session is pinned to the host that holds the file, and a containerized harness has to mount, back up and migrate that file to move the session anywhere.
In mecak8s, session state and the durable event log live in Redis, outside any worker. A Kubernetes Lease records which replica currently owns a session, so only one writer touches it at a time. The session continuity docs describe what that buys you: a worker can be disposable while the session is not, and a replacement process resumes from the last persisted turn boundary. The same docs are explicit about the edge: an in-flight operation is not resumed, and anything after the last successful save can be lost.
4. Who approves a risky action when nobody is watching?
A desktop harness asks the person at the keyboard. That works because there is one. The moment the harness runs unattended, the question of what happens to a permission prompt has to be answered in advance, and a containerized desktop harness usually answers it by running in an allow-everything mode and hoping the sandbox holds.
Mecatl separates the deployment posture from the permission rules. The posture ladder runs strict, trusted, auto, yolo; an interactive mecated defaults to strict, and the docs note that unattended mecak8s deployments commonly use auto, which allows tools while keeping every configured deny and ask in force. Rules use Tool(pattern) syntax in YAML, with six precedence scopes and a hard ordering: a matching deny always wins, an ask beats an allow, and a configured allow can only loosen the built-in floor.
permissions:
allow:
- 'Read'
- 'Shell(go test:*)'
ask:
- 'Shell(git push:*)'
deny:
- 'Shell(rm:*)'
subagent:
deny:
- 'Shell(gh pr merge:*)'
mecak8s is headless by default, so an ask that nothing resolves needs an explicit headless-reviewer strategy or it is denied. Allow-all postures are refused when the process runs as root unless the deployment declares an isolated sandbox. An optional guardrail checker model reviews tool arguments before execution and results before delivery, configured at the operator tier so a project cannot turn it off. The developer’s judgement has been replaced by policy that was written down while someone was paying attention.
5. Whose credentials does the agent use?
A desktop harness uses whatever the developer has: the API key in their shell, the GitHub token in their keychain, the cloud profile in their home directory. Every tool call goes out as that person. Containerize it and the container gets a service account instead, which is worse in one way, because now every user’s session shares the same identity and the audit trail says the same name for all of them.
Mecatl verifies the caller through OIDC and keeps the session owner separate from the service identity that operates the cluster. On the Kubernetes execution provider, service mTLS identifies mecak8s to the provider, while the session owner remains the user’s verified OIDC issuer and subject. MCP servers get OAuth profiles and stored credentials of their own. Every agent-facing shell runs with a scrubbed environment: provider keys, MECATL_* credentials, cloud credentials and anything else secret-shaped are removed before the command starts. A subagent’s authority can only narrow its parent’s, and MCP authority is granted per tool rather than per server.
The docs also describe where this is heading: a SPIFFE trust domain and a JWT delegation chain that tells an external system which user, agent and subagent acted with which authority. That is a published draft, not a shipped feature.
6. Can the harness be replaced while work is in flight?
Kill a desktop harness and the session is gone until the developer restarts it and resumes from the local file, on the same machine. Kill a containerized one and someone has to reschedule the container, reattach the volume and hope the state file was flushed.
The Mecatl docs include a walkthrough that does this on purpose. In a two-replica mecak8s cluster with Redis, you start a session from mecatui, find the pod holding the session’s Lease, delete it, wait for the replacement, then reconnect with --resume and the original transcript is there and the session accepts new turns. Redis kept the session; the Lease transferred single-writer ownership to the replica that resumed it.
The execution environment reattaches the same way, by exact identity through the deployment’s placement provider. If the provider cannot reattach it, or returns a different environment, the run fails instead of quietly falling back to a local workspace. Workspace volumes are retained by default, even when the session is deleted or the chart is uninstalled.
7. How many clients can talk to one agent?
One. A desktop harness is its own client, and the loop lives inside it. Claude Code’s Remote Control lets you drive a session from a phone, but the session still belongs to the machine that started it and ends when that machine stops. Wrapping a desktop harness in a web UI gives you a second window onto the same process, not a second client of a shared service.
Mecatl’s loop has no client of its own. mecatui is a terminal client, Studio is a web client, and anything else talks gRPC or HTTP/SSE or uses the TypeScript SDK. The same mecatui binary that runs an embedded server locally will connect to a remote mecated or mecak8s and use that server’s posture and rules instead of its own flags. The Go engine can also be embedded in an application that wants its own front end. A client does not need to own the agent’s filesystem, credentials or session state to interact with it, which is what makes a team’s agents something a team can share.
8. Can it run on a schedule, with no human?
You can put a desktop harness in cron. People do. What you get is a process that starts with whatever permissions its flags grant, has no one to answer its prompts, and leaves its state in a file on the box that ran it. Each scheduled run is a fresh instance of the coupled runtime.
Mecatl’s scheduled tasks run inside the harness, on mecated and mecak8s, for recurring and one-shot jobs. They use the same permission rules, the same execution environments, the same identity model and the same event history as interactive sessions. A scheduled run that hits a permission ask follows the headless path described under difference 4: a configured reviewer, or a denial. Plan-mode approval in headless deployments is denied unless an operator opts in with --plan-mode-auto-approve, which the docs describe as an autonomous approval capability so nobody mistakes it for a convenience flag.
An agent that runs unattended under the same rules as one that runs with a person watching is the thing a cloud-native harness is for.
Desktop vs containerized vs cloud-native at a glance
| Question | Desktop harness | Containerized desktop harness | Cloud-native harness (Mecatl) |
|---|---|---|---|
| Where does the loop run? | Inside the client, on the laptop | Inside the client, in a container | As a service: mecated or mecak8s, versioned and rolled out |
| Where do files and shell execute? | The developer’s checkout | The container’s filesystem | An assigned execution environment: workspace, template, no-FS or microVM |
| Who holds session state? | A local file | A file in the container, or a mounted volume | Redis plus a Kubernetes Lease; the worker is disposable |
| Who approves when nobody is watching? | The developer, interactively | Usually an allow-all flag | Posture plus allow/ask/deny rules plus a headless reviewer or denial |
| Whose credentials? | The developer’s | A shared service account | OIDC caller identity, per-source MCP OAuth, secret-scrubbed shells |
| Can the runtime be replaced mid-session? | No | Only by moving its state by hand | Yes; resume from the last persisted turn on another replica |
| How many clients? | One, built in | One, plus a window onto it | TUI, web Studio, gRPC, HTTP/SSE, SDK, embedded |
| Can it run on a schedule? | Via cron, with fresh state each run | Via cron or a job runner, same | Scheduled tasks inside the harness under the same rules |
The middle column is not a failure. It is the natural first step, and for a single team with a trusted sandbox it may be enough. The right column is what you need when the answer to “who” in any row has to be a real identity, a written policy, or a service that outlives its host.
When a desktop harness is still the right answer
Most of the time, for most individual developers. If you are working in a repository you trust, want to see each command before it runs, and have no need for the session to exist after you close the lid, a desktop harness is faster, simpler and safer than anything with a control plane. The fastest way to find out whether an agent can do a task is still to run it on your own machine and watch.
Mecatl does not argue with this. Bare mecatui is a desktop harness: an in-process server behind a private Unix socket, JSONL state under your XDG directory, permission prompts in the terminal. The point of the architecture is that when the task graduates, you run mecatui connect against a mecated or mecak8s server and the same client, the same skills and the same project rules carry over, with the server’s posture and permission configuration now in charge. You do not rewrite the agent to move it.
What cloud-native does not solve on its own
The Mecatl docs are unusually direct about limits, and they are worth repeating here rather than leaving for a reader to discover.
- A replacement worker resumes from the last persisted turn boundary. It does not resume an operation that was in flight, and work after the last successful save can be lost.
- The native Kubernetes execution provider is designed for an operator-controlled cluster and foreground commands. The docs say it is not a hostile multi-tenancy boundary, and that a RuntimeClass name alone is not an isolation guarantee.
mecak8sis single-user today. Multi-user support is being developed.- Headless deployments can leave a main-session ask waiting if no reviewer strategy is configured. That is the safe failure, but it is a failure you have to plan for.
- Project files are untrusted by default, and a headless root does not gain project trust from its posture. Enabling trust for a repository you have not reviewed is on you.
- The identity delegation chain, scoped resource grants and signed context are drafts.
None of these are reasons to stay on the desktop. They are the list of things a platform team still owns after the architecture has done its part.
Frequently asked questions
What is a cloud-native agent harness? An agent runtime whose clients, execution environments and durable state can be managed as separate application services. The agent loop runs as a service that can be versioned, observed and replaced, while session state lives in a store that outlives any single worker and code executes in an environment assigned by an operator rather than inherited from a client.
Can I run Claude Code on Kubernetes? You can run the Claude Code process in a pod, and Anthropic’s self-hosted environments let a runner on your infrastructure host its cloud sessions. In both cases the session still lives inside that one process, with its state and workspace attached to it. That is a containerized desktop harness: the work moves into your cluster, but a pod that dies takes its session with it.
Is a containerized Claude Code cloud-native? No, by the definition above. Containerizing moves the coupled runtime; it does not separate the loop from the client, the execution environment or the durable state. A cloud-native harness gives each of those its own owner so a worker can be replaced while the session continues.
What is the difference between mecatui, mecated and mecak8s? They are three ways to run the same Mecatl engine. mecatui is a terminal client with an embedded single-user server for local work. mecated is a standalone server for environments outside Kubernetes, serving gRPC and HTTP/SSE with optional durable storage and ACP editor integration. mecak8s is the Kubernetes deployment, with Redis-backed sessions, leases across replicas and headless defaults. mecatui connect attaches the terminal client to either server.
Can Mecatl be a backend for Claude Code or Codex? Not as a drop-in. Mecatl is both the harness and the runtime; what it separates is the client from the runtime. The docs say another harness would need a dedicated integration to hand its loop to Mecatl. The supported route is to build a client on Mecatl’s gRPC, HTTP/SSE or TypeScript SDK, or to embed the Go engine. There is an --import-claude-permissions flag that migrates Claude Code permission rules, fail-safe, which helps with the move.
Where to go next
If you already run agents in containers, the quick audit is the eight questions above with one word each: who or what owns that thing in your setup today. Any row where the answer is “the container” is a row where losing the container loses the work.
The architecture is laid out in What is a cloud-native harness?. To see a session survive its pod, the Kubernetes tutorial runs in a local Kind cluster with a mock model provider and no API key. The production path is Operate mecak8s. For the framework side of the picture, see Agent Frameworks vs Agent Harnesses, and for the wider field, Stacklok’s comparison of agent harnesses by category.
October 29, 2026
Comparisons