Agent Frameworks vs Agent Harnesses. 7 things that Langchain and CrewAI don’t do

An agent framework decides what an agent should do next. An agent harness decides what the agent is allowed to do, where its code runs, and what happens when the process dies. LangChain and CrewAI are frameworks. Mecatl is a harness. Most production teams need one of each, and the trouble starts when a team ships a framework and assumes it has a harness.

This post covers the seven jobs that fall on the floor when you deploy a framework alone. Each one is a question a platform or security team will eventually ask, with what LangChain or CrewAI gives you today and what a harness adds. Where the frameworks have partial answers, the post says so; LangGraph’s checkpointers and CrewAI’s AMP platform are real, and the comparison table at the end gives them credit.

What an agent framework does

A framework is a library you import to build the agent’s logic. It gives you abstractions for prompts, tools, state and control flow, and it runs inside your Python or TypeScript process alongside everything else you wrote.

LangChain started as a toolkit for chaining model calls and binding tools. LangGraph is where most serious LangChain agents live now: you define nodes and edges, the graph carries typed state between them, and a checkpointer can save that state at each super-step so a thread can be resumed, forked or inspected. The interrupt() call pauses a node and waits for a human to resume it. LangSmith traces the whole thing if you connect it.

CrewAI models work as roles. You define agents with a goal and a backstory, give them tasks, and group them into a crew that runs sequentially or hierarchically. Flows add routing and state across crews. A task with human_input=True pauses for review. CrewAI AMP, the company’s commercial platform, deploys crews behind a REST API with SSO, role-based access control, scheduling and a /resume endpoint for approvals.

Both are good at what they are for, which is expressing the shape of an agent: which steps, in which order, with which tools. Neither owns the machine the agent runs on, and that is the gap the rest of this post is about.

What an agent harness does

A harness is the runtime that turns a model into an agent. It runs the loop that calls the model, dispatches tool calls, executes code, and decides what the agent is allowed to touch while it does so. Claude Code and Codex are harnesses. So is Mecatl, Stacklok’s open source harness, which is the example in this post because its docs spell out the boundaries explicitly.

Mecatl splits the harness into five separately owned parts:

  • The agent loop: reasoning, tool dispatch, permissions, hooks and event emission.
  • Clients: a terminal, a web UI, an API or an application, none of which owns the loop.
  • Execution environments: the workspace and command runner assigned to a session.
  • The tool ecosystem: built-in tools, MCP services, skills and application integrations, exposed through a catalog.
  • Supporting services: model providers, session state, event history, identity and coordination.

The same loop runs on a laptop inside mecatui, as a standalone mecated service, or on Kubernetes as mecak8s, with clients connecting over gRPC, HTTP/SSE or a TypeScript SDK. That split is what makes the seven questions below answerable by configuration instead of by code you write.

1. Where does the code actually run?

When a LangGraph node or a CrewAI tool executes, it runs in the process that imported the framework, with that process’s filesystem, network and environment variables. If the agent has a shell tool, the shell is your shell. If it has a Python REPL tool, the REPL is your interpreter. The framework has no concept of an execution environment because it is a library, and libraries run wherever they are called. Isolation is whatever you wrap around the process: a container, a VM, a sandbox product.

A harness treats execution as an assigned resource. In Mecatl, every session is bound to an execution environment at creation: the deployment’s default workspace, an operator-approved execution template with a pinned revision, or execution.none, which strips the file and shell tools out of the catalog entirely. On Kubernetes, file tools and shell commands run in the harness pod’s namespace, and a remote client never uploads its checkout. A local deployment can point the default at a repository-scoped microVM. Every agent-facing shell is secret-scrubbed before a command runs, so provider keys and cloud credentials in the server’s environment do not leak into ls -la.

The model cannot change its environment mid-run. The choice is fixed when the session is created, by whoever created it.

2. Who approves a dangerous action?

Frameworks give you a pause primitive. LangGraph’s interrupt() stops a node and saves state until something resumes it. CrewAI’s human_input=True pauses a task, and AMP exposes /resume for the approve-or-retry decision. These work, and they are the right tool for “show the draft to a reviewer before sending.”

The limit is that the pause goes where the developer put it. If a tool call happens in a node without an interrupt, it runs. A framework has no policy layer that sees every tool call and decides allow, ask or deny regardless of what the graph says.

A harness puts that layer in the loop. Mecatl’s permission system has a built-in floor (read-only tools allowed, Shell, Edit, Write ask first), a YAML rule language with Tool(pattern) matching, and six configuration scopes from managed policy down to the built-in defaults. A deny always wins. A configured ask cannot be loosened by an allow. On top of that sits a posture ladder, strict through yolo, that an operator sets per deployment, and a session mode (default, plan, accept-edits) the user can cycle. Optional guardrails add a checker model that inspects tool arguments before execution and results before delivery, fail-closed if the checker is down.

That is the difference in one line: a framework lets you ask for approval; a harness makes every tool call ask for permission.

3. Whose identity is the agent acting under?

Ask a LangGraph or CrewAI agent who it is and the answer is “whatever is in the environment.” The model provider key, the GitHub token, the database password: all of them are process-level secrets, shared by every agent, subagent and tool in that process. When the agent calls an internal API, the API sees the service account, not the person who asked. AMP adds SSO and RBAC at the platform door, which controls who can kick off a crew, but it does not change what the crew runs as once it starts.

A harness carries identity through the loop. Mecatl verifies the caller through OIDC and separates the session owner from the service identity that operates the infrastructure. MCP servers get their own OAuth profiles and credential storage, so a tool’s token is not the agent’s token. When the main agent delegates, the child receives an authority set that can only narrow the parent’s, and a resumed child is rechecked against the parent’s current authority. Authority on MCP is granted per tool (mcp__github__list_pull_requests), not per server. An optional Cedar evaluator lets operators add denials from policy the project cannot override.

Stacklok has published working drafts for the next step, a SPIFFE trust domain and a JWT delegation chain that tells an external system which user, agent and subagent acted with which authority. That part is a direction, not a shipped feature. The per-caller, per-tool, narrowing-only model above is what runs today.

4. What happens when the process dies mid-task?

Here the frameworks deserve more credit than they usually get. LangGraph with a checkpointer saves state at every super-step boundary and persists node writes within a step, so a crashed graph can restart from the last successful step on the same thread_id. The managed Agent Server handles checkpointing for you. CrewAI Flows have persistence, and AMP runs crews on infrastructure that scales and restarts. Without those pieces configured, state lives in memory and dies with the process, but the pieces exist.

What a framework still cannot do is survive the loss of the thing running it, because the framework is the thing running it. A checkpointed LangGraph still needs you to build the service that notices a dead worker, picks up the thread, and resumes it, and to make sure two workers never resume the same thread at once.

Mecatl’s session continuity is built for that case. On Kubernetes, session state and the event log live in Redis, Kubernetes leases decide which replica owns a session, and a worker can be drained and replaced while the session persists. A replacement resumes from the last persisted turn boundary. The docs are specific about the limits, which is worth repeating: an in-flight operation is not resumed, and work after the last successful save can be lost. The execution environment reattaches by exact identity, and if it cannot, the run fails rather than silently falling back to a local workspace.

The framework saves your state. The harness keeps your session alive across the machines that run it.

5. Which tools exist, and who governs them?

In a framework, the tool list is a Python list. You decorate a function with @tool, pass it to the agent, and it is available. MCP support exists in both ecosystems, and CrewAI AMP adds a tool repository and custom MCP servers. But the governance is in your code: if you want some tools denied to subagents, or a tool that can be called but only after review, you write that logic into the graph or the crew.

A harness owns the catalog. Mecatl exposes built-in tools, streaming-HTTP MCP services, skills and application-supplied integrations through one catalog, and the session reports which of them are effective, since host tooling or session authority can narrow the list. Hooks can observe, block or transform a tool call at lifecycle points. Permission rules apply to the catalog by tool and pattern, with a separate subagent: block so a child can be denied gh pr merge while the parent keeps it. Guardrails review selected tool arguments and results with a checker model the project cannot disable.

The stated direction in Mecatl’s docs is to make shell less necessary over time by adding purpose-built, permissioned tools for common tasks, so that the most dangerous tool is reached for less often. Shell stays available, and governed, in the meantime.

6. Can you see what the agent did afterward?

Frameworks give you tracing if you add it. LangSmith is good at this for LangGraph, and CrewAI AMP has tracing with OpenTelemetry export. Both record model calls, tool calls and outputs as the framework saw them. What they record is the framework’s view: they cannot tell you what a shell command touched on disk, which identity a request went out under, or whether a permission decision was made and by whom, because none of that happened inside the framework.

A harness emits those records from the loop itself. Mecatl’s agent loop produces events for turns, tool dispatch, permission pauses and terminal states, and durable deployments keep that event history alongside session state. Permission decisions and tool executions carry audit records. The observability layer adds runtime signals, model-call recovery and product metrics, and operators collect metrics and traces with standard tooling. Guardrail result reviews can hold a tool’s output before the model, the client or the session history sees it.

The practical test for a compliance review is “show me every tool call, with its arguments, under whose identity, and what approved it.” A framework trace answers the first two. A harness answers all four.

7. Can it run without a developer at the keyboard?

A framework is a library. To run a LangGraph agent unattended you build the service around it, or use LangGraph Platform. To run a crew on a schedule you use AMP’s cron scheduling or wire your own. Either way, the question of what the agent does when it hits a decision that would normally ask a human is yours to answer, per deployment, in code.

A harness is already a service. mecated and mecak8s run headless, with scheduled tasks for recurring and one-shot runs under the same permission rules and event history as interactive sessions. The headless case is handled explicitly rather than by accident: mecak8s is headless by default, so an unresolved permission ask needs a configured headless-reviewer strategy or it is denied. Allow-all postures are refused when running as root unless the deployment declares an isolated sandbox. Plan-mode approval in headless mode is denied unless an operator opts in with --plan-mode-auto-approve, which the docs call what it is, an autonomous approval capability.

None of that is exotic. It is the difference between a thing you run and a thing that runs.

Framework vs harness at a glance

ResponsibilityLangChain / LangGraphCrewAI (open source + AMP)Mecatl (harness)
Where code runsIn your process; isolation is whatever you wrap around itIn your process, or on AMP’s managed containersAssigned execution environment per session: workspace, template, no-FS or microVM; secret-scrubbed shells
Approving dangerous actionsinterrupt() where the developer places ithuman_input=True per task; /resume on AMPPolicy on every tool call: allow/ask/deny rules, posture ladder, session modes, optional guardrail model
IdentityProcess-level secrets shared by all agentsSame; AMP adds SSO and RBAC at the platform doorOIDC caller identity, per-source MCP OAuth, per-tool authority, narrowing-only delegation, optional Cedar policy
Surviving a dead processCheckpointer saves state per super-step; you build the worker recoveryFlow persistence; AMP restarts and scalesRedis-backed sessions, Kubernetes leases, replaceable workers, resume from last persisted turn
Governing the tool catalogTool list in code; MCP supportedTool list in code; AMP tool repository and custom MCPExplicit catalog, hooks that block or transform, per-tool and per-subagent rules, guardrails
Audit of what happenedLangSmith traces of model and tool callsAMP tracing with OpenTelemetryLoop-level events, permission audit records, durable event history, operator metrics and traces
Running unattendedYou build the service, or LangGraph PlatformAMP scheduling and REST kickoffHeadless servers with scheduled tasks, explicit headless-reviewer strategy, sandbox checks on allow-all postures

The honest reading of the table is that the frameworks have a partial answer in every row, and the partial answers are where teams get caught. “We have checkpointing” is true and is not the same as “a pod can die mid-task.” “We have human-in-the-loop” is true and is not the same as “every shell command is subject to policy.”

Do you need both?

Usually, yes. The framework describes the work; the harness runs it under rules. Three patterns cover most teams.

Framework on top of a harness. Your LangGraph or CrewAI code owns the plan and the prompts, and hands execution to a harness session. Mecatl exposes gRPC and HTTP/SSE APIs and a TypeScript SDK for exactly this, and the Go engine can be embedded in your own application. The framework keeps its graph; the harness keeps the permissions, identity, execution environment and audit trail. This is the right shape when you already have framework code you like and a security team that wants a single enforcement point.

Harness alone. Coding agents, ops agents and anything that mostly needs a model, a workspace, tools and rules do not need a graph library in front of them. Mecatl’s named agents, subagents and teams, skills and scheduled tasks cover a lot of what people reach for a framework to express. Start here if you are not sure.

Framework alone. Prototypes, demos, and agents that only ever read public data and never execute code. The moment one of them gets a shell tool or a production credential, it has graduated to pattern one.

Frequently asked questions

Is LangChain an agent harness? No. LangChain and LangGraph are frameworks: libraries for composing prompts, tools, state and control flow inside your own process. They do not own the execution environment, enforce per-call permissions, carry caller identity, or keep a session alive across worker failures. LangGraph’s checkpointers and interrupt() cover state and pauses, which is part of a harness’s job, not the whole of it.

Is CrewAI an agent harness? No. CrewAI is a framework for role-based multi-agent workflows. CrewAI AMP, the commercial platform, adds deployment, SSO, RBAC, scheduling and human-in-the-loop resume, which moves it closer to a managed runtime for CrewAI crews specifically. It still does not govern where tool code executes or apply policy to every tool call.

Can I run LangGraph agents inside Mecatl? Not by dropping LangGraph into Mecatl’s loop. Mecatl is both the harness and the runtime. The supported pattern is for your framework code to drive a Mecatl session through the gRPC or HTTP/SSE APIs or the TypeScript SDK, or to embed the Go engine in your application. The Mecatl docs say the same about Claude Code and Codex: another harness would need a dedicated integration to hand its loop to Mecatl.

Is Claude Code a framework or a harness? A harness. Claude Code runs the loop, dispatches tools, executes commands and enforces permission rules. It bundles the client, loop, context and tools on one machine, which is the desktop-harness shape. Mecatl’s docs describe the contrast directly: Mecatl separates those pieces so the engine can run locally or on Kubernetes while clients connect to it.

Do I need an agent harness if I already use LangGraph with a checkpointer? If the agent executes code, calls internal tools or touches production data, yes. The checkpointer saves state; it does not isolate execution, decide which tool calls are allowed, attribute actions to a verified caller, or recover a session when the worker running it is replaced. Those are the harness’s jobs, and you either adopt one or build one.

Where to go next

If you run LangChain or CrewAI today, the quickest check is to list the seven questions above and write down who answers each one in your current deployment. Any answer that starts with “we wrote some code that” is a harness responsibility living in the wrong place.

The Mecatl docs dig deeper into these definitions, with an answer to What is a cloud-native harness? For the wider landscape, see Stacklok’s comparison of agent harnesses by category and the most common questions about agent harnesses.

October 29, 2026

Comparisons

Scott Buchanan

CMO

Scott Buchanan is the Chief Marketing Officer at Stacklok. Scott leads the company's first-party research efforts that define benchmarks for AI agent and MCP adoption. He's also an example of how a non-developer can lean into MCP and agentic workflows to increase productivity.

More by Scott Buchanan