
Key takeaways
MCP human in the loop should match the action. Let low-risk reads run. Give ordinary writes approve or reject controls. Let reviewers edit high-risk email or delete calls. Pause uncertain actions, review reversible writes afterward, and put standing prohibitions in policy.
What does MCP human in the loop mean?
Human-in-the-loop gives an acting system a controlled pause. The agent reaches a proposed tool call, execution stops, a person sees the pending action, and the run resumes only after an explicit decision. In other words, the human does not merely comment on the final output. The person can decide whether a specific action is allowed to happen.
That answers the basic question, "Does agentic AI have a human-in-the-loop?" It can. The control sits in the harness around the model and tool path. AI applications use human interaction for feedback, approvals, and clarification, depending on what the system needs at that point.
For MCP, the useful unit is the proposed tool call. A human-in-the-loop control can inspect that call before its side effect occurs. Middleware can pause a call that requires review and wait for a decision. This is more precise than putting an approval dialog in front of every tool. The intervention should follow the action's risk, reversibility, and uncertainty.
The pause creates a specific decision. A person is shown the action that has not yet run, then chooses whether execution resumes. Feedback and clarification are also forms of human interaction in an AI application, but approval has a narrower job: it controls the pending action.
That boundary is part of the execution path. The model can propose a tool call, while the harness decides whether the proposal may continue immediately or must wait. The person enters the run at the point selected by that policy.
Which MCP tool calls need a human?
Classify the action before selecting the intervention. Risk-based tool configuration supports different controls for reads, writes, deletes, and email.

| Action condition | Example | Control | Reviewer or runtime handling |
|---|---|---|---|
| Low-risk read or list | read_file, ls | No interrupt | Runtime continues |
| Medium-risk write | write_file | Approve or reject | Record owner or delegated reviewer decides |
| High-risk delete or external message | delete_file, send_email | Approve, edit, or reject | Reviewer can change the proposed call before execution |
| Reversible write | A write that can be reversed | Post-hoc review | Reviewer inspects the action after execution |
| Low-risk but uncertain action | The agent is unsure what it is doing | Pause | A person resolves the uncertainty |
| Standing prohibition | An action disallowed by policy | Block | Access control, tool exposure, or policy prevents the call |
Pre-execution approval belongs at the consequential boundary. Sending an email, deleting a record, and executing a financial transaction require review before execution. Irreversibility, cost, regulation, high blast radius, scale, ambiguity, compliance requirements, and novelty can all trigger a pause.
Reversibility changes the timing of review. A reversible write can receive post-hoc review, while irreversible, costly, regulated, or high-blast-radius actions warrant approval before execution. Uncertainty is its own trigger. A low-risk action still pauses when the agent is unsure what it is doing.
A denial applies to the action currently before the approver. A standing block is different. Access control, tool exposure, or policy should prevent actions that remain prohibited across runs. This keeps a permanent rule out of a queue of repeated human decisions.
The reviewer also matters. For actions that affect records, the approver should be the record owner or a delegated reviewer, not simply whoever is available. That turns an interruption into a real decision boundary. Our definitions of approval flow and bounded autonomy can help name these two different parts of the harness.
When is MCP elicitation enough?
Use elicitation when the tool needs synchronous input during its current call. Use workflow approval when the decision may remain pending outside that call. MCP elicitation is synchronous, while workflow approval can wait asynchronously for days. Those are different runtime shapes, even when both place a person inside the work.
A GitHub MCP elicitation demo makes the synchronous shape concrete with test-form and URL-mode elicitation. It is useful as a visible Human MCP GitHub example of the interface modes. It does not, by itself, establish a durable approval workflow.
The distinction changes what the runtime must hold open. Elicitation occurs within the tool call. Durable workflow approval can remain pending for days. The first gathers input in the current interaction. The second needs a workflow that can preserve its state while the decision is outstanding.
The approval interaction is an implementation choice. The MCP tool specification recommends human control but leaves the user-interaction model to implementations instead of defining one universal approval protocol. A builder therefore has to decide what the client presents, how the decision reaches the runtime, and what happens while work is pending.
No single protocol-level approval dialog settles that design. Form or URL elicitation can collect synchronous input, while the asynchronous path needs an implementation that represents a pending decision and later returns it to the waiting workflow.
That last question separates a prompt from an execution control. A call that can wait for minutes, hours, or days needs state that survives beyond the interface session. The human decision may arrive later, but the system still has to know exactly what was proposed and where the run stopped.
A durable pause preserves state and controls retries
A pause is only durable if the execution state survives it. A configurable policy can inspect each tool call, interrupt when intervention is needed, save graph state, and resume later. With LangGraph interrupts and checkpoints, execution can continue from the stopped point without replaying the whole run.
The sequence is explicit. Policy examines the proposed call. An interrupt records the pause. Saved graph state preserves the run, and the later decision releases execution to continue. A durable workflow can preserve its state through a wait of minutes, hours, or days.
The saved state should be scoped to the run that produced the proposed action. LangGraph checkpointers persist thread-scoped graph state for human-in-the-loop workflows, conversation continuity, time travel, and fault tolerance. Temporal provides another concrete model: it preserves workflow state while a human-in-the-loop wait lasts minutes, hours, or days.
Persisting state answers where to resume. It does not, on its own, prove that the action being executed is the action a person approved. For that, persist a hash of the proposal at interrupt time and check it on resume. The comparison verifies that the action released for execution matches the approved proposal.
The proposal hash protects the content of the decision across the wait. The resume check compares the proposed action with the version approved by the person and verifies whether they match.
A resumed workflow can retry a side-effecting action. Every side-effecting action in a durable agent should be idempotent, reversible, or approval-gated. Before retrying, the harness should check whether a prior attempt succeeded. When the external system has no idempotency support, an operation ledger can record the attempt.
The checkpoint, proposal hash, and retry record each preserve a different part of the paused run: its execution state, the exact action approved, and the history of a side-effect attempt. All three remain relevant after the approval interface closes.
The approval screen should show the change, not a raw payload
Consider a proposed record update. The reviewer should see plain language, a clear risk level, the before and after values of affected fields, the number of impacted rows, and a dollar amount when one applies. Those details let the person inspect the actual change without decoding a raw tool payload.

A compact approval card could contain:
- The proposed action in plain language
- The risk level
- Before and after field values
- The number of impacted rows
- The applicable dollar amount
- The reviewer identity, timestamp, and decision
Approval interfaces need plain language, clear risk levels, and audit trails. The audit record should capture every approve, reject, and edit decision, including when it happened and who made it. That history is not a substitute for a readable decision screen. It records what happened after the reviewer received enough context to decide.
An edit deserves its own record. It means the proposal presented at first was not released unchanged. The timestamp and reviewer identity attach that decision to a person and time, while the before-and-after view shows the change the person considered.
A gateway can centralize a consistent audit trail of agent activity for incident response, compliance, and anomaly detection. The audit record should follow the action across the pause. If the reviewer edits the proposal, the recorded decision should be an edit. If the call is rejected, it should remain a rejection rather than disappearing as an unfinished run.
The screen and the audit trail serve different moments. The screen gives the reviewer the risk level, scope, values, and amount needed for the current decision. The trail preserves the resulting approve, reject, or edit event.
What do real MCP human-in-the-loop examples look like?
The clearest MCP human-in-the-loop example places the pause immediately before the consequential action. An invoice agent can prepare invoices automatically, then require approval before charging a customer. A content-moderation system can flag questionable content for review before it acts. In both cases, automated preparation continues until the system reaches the action assigned to a person.
The invoice example separates preparation from charging. The agent prepares the invoice without a decision on each preparatory step. Charging the customer is the action held for approval. In moderation, questionable content is flagged first and a person reviews it before the system takes action.
Repository examples expose the same boundary in code and architecture. One Python tool example combines a delete:database authorization scope with human_approval_required=True before calling delete_database. The visible mechanism matters: the authorization scope and human-approval requirement appear together at the destructive function.
A separate eShop multi-agent learning project combines workflow-state tracking through an MCP server with human-in-the-loop approval workflows and UI coordination. That example makes three pieces visible at once: tracked workflow state, an approval path, and the interface coordinating the decision.
These repositories are implementation examples, not proof of production reliability. Their value here is narrower. They show places where a builder can attach the control: before a charge, before a moderation action, at a database-delete function, or alongside tracked workflow state and an approval UI.
The examples also show that human control is not one framework feature. It can appear as a condition on a Python tool, a coordinated approval interface, or a held action inside a longer workflow. In each case, the visible mechanism identifies the call that cannot continue on its own.
Approval is not authorization
An approval says that a person accepts the action currently before them. Authorization determines whether the caller is allowed to perform that action. In one gateway approval pattern, the human is the decision authority and the gateway is the enforcement point that holds or releases the call. Approval does not replace authorization.
The wire behavior also needs a shared convention. A gateway can hold a gated call while returning a successful result whose _meta.approval_status is pending. That response works only when the client understands what pending means and explicitly decides when to retry.
The status and transport result therefore need to remain distinct. In this implementation-specific convention, transport success can carry a pending approval state. The client must read the metadata, recognize that the call is still held, and make the retry decision.
Tool annotations can inform the policy without becoming the policy's authority. For example, destructiveHint may help classify a call. Clients must treat those annotations as untrusted unless they come from trusted servers.
Trust in the server is part of using the annotation. Without that trust, a client cannot accept the annotation as the source of its approval policy. The enforcement point still has to apply authorization and the configured policy to the call.
Keep the responsibilities visible: authorization limits who can attempt the call, policy classifies whether it is allowed or gated, the gateway holds or releases it, and the human decides the pending case.
Rejection, timeout, and waiting need explicit paths
An approval flow is incomplete if only its happy path has been tested. Rejection and timeout paths need the same rigor as successful approvals. The acceptance plan should cover all three outcomes: the reviewer approves, the reviewer rejects, or no decision arrives before the timeout path runs.
The waiting state needs to be legible too. Long-running agents should not block indefinitely on human review, and the interface should show how long the agent has been waiting. That elapsed time gives the pending state a visible age instead of leaving an apparently active run suspended without context.
Treat waiting as an explicit runtime state. The interface can show the elapsed wait while the harness follows its timeout path.
A rejection should resolve the action before the reviewer. A timeout should follow its tested path. An approval should resume from persisted state and execute the proposal that was actually approved. Those paths are where the intervention becomes part of the harness rather than a dialog placed over it.
Test the three outcomes as acceptance paths, not as incidental errors around the approval UI. Exercise a successful approval, a rejection, and a timeout. Include the elapsed-wait indicator in the same test plan so the pending state remains visible before it resolves.
For a concrete implementation of interrupts, checkpoints, decisions, and resumed execution, see our LangGraph human-in-the-loop guide. Use it to inspect the exact boundary where your run pauses and what must be carried forward when it resumes.