Get started · Human approval
MCP human approval for AI agent actions
Hold an agent's sensitive tool call until a person allows it. The approver answers in the agent's own chat, in Claude Code, ChatGPT and other MCP clients, with an optional one-time passcode (OTP) from their email, or in the Meandr console. Every decision is logged with their name.
Meandr is a gateway and cloud workspace for MCP servers and AI agents. Your agents connect to one workspace URL, and every tool call they make passes the workspace's policies: it is allowed, denied, or held for a person. Holding a call is human-in-the-loop approval. Meandr asks through MCP elicitation, the standard way an MCP server requests input, so the approval prompt appears inside the agent's own app. Here is how to set it up for one action, a Stripe refund over $300.
Add an Approve policy for the action
In Policies, add a policy for the call that needs a person's yes, set its action to Approve and seat the people who may decide. Stripe's MCP server writes through one tool, stripe_api_write, so an arguments matcher narrows the policy to the risky case: refunds over $300, which Stripe counts in cents.
Refunds over $300×
Policy in the Support workspace
ActionAllowApproveDeny
Applies toStripe · stripe_api_write
Arguments matcher$.stripe_api_operation_idEqualsPostRefunds
$.parameters.amountGreater than30000
InteractiveOffline
180
Sam LeePriya Shah
- Require an OTPEach approver gets a one-time passcode by email and enters it to decide
CancelSave
The one-time passcode (OTP) is optional. Require an OTP is off by default. Without it, the prompt asks only for a decision and a comment, and an approval given in the chat carries no name. Switch it on when you need to know who said yes.
Meandr holds the call and emails each approver
When the agent calls the tool, the call waits and every approver seated on the policy gets an email. With Require an OTP on, each email carries that approver's own code. It has eight letters and digits, works once and stops working when the deadline passes.
meandr
Hello Sam L.,
Claude Code wants to call stripe_api_write on Stripe.
Review it by October 23, 2026 at 14:05 UTC.
To allow or deny straight from the approval prompt, enter your code:
K7QM2RVA
Review request
Cheers,
The Meandr Team
You're receiving this because you're a member of Acme.
Review request opens the call in the console, for approvers who would rather decide there.
The approver answers in the agent's chat
The agent's app shows Meandr's approval prompt: what is waiting, a link to approve it in the console instead, an optional comment and, when the policy requires it, the one-time passcode (OTP). Accept, and the call runs and the agent carries on with the result. It looks like this in Claude Code and in ChatGPT.
> Refund order 4821, the customer was charged twice
● stripe · stripe_api_write(PostRefunds, amount: 124000)
MCP server “meandr” requests your input
meandr: approval required — stripe_api_write on Stripe
Comment: Charged twice, refund approvedOptional note recorded on the audit trail.
* OTP: K7QM2RVAOne-time code sent to your email.
AcceptDecline
Refund order 4821, the customer was charged twice
Calling meandr · stripe_api_write
meandr: approval required — stripe_api_write on Stripe×
Or approve at: console.meandr.com/actions/01a2…
CommentOptional note recorded on the audit trail.
Charged twice, refund approved
OTPOne-time code sent to your email.
K7QM2RVA
DenyAccept
The first valid code decides. The other approvers' codes stop working. A wrong code ends the request, and the agent has to call the tool again. The comment is saved with the decision.
Or decide in the console, on the Tasks page
Every held call is also listed under Tasks, in Actions requiring approval. View shows what would run: the agent, the server, the tool, the policy that held it and the request itself. Allow releases the call, Deny rejects it, and a request nobody answers lapses at its deadline.
Actions requiring approval
Held by a policy for a decision. Allowing releases the held call to run, denying rejects it.
Pending 1ResolvedAll
stripe_api_write on StripePendingInteractiveRequested 14:02 · expires in 3 min
- Agent
- support-bot
- Server
- Stripe
- Tool
- stripe_api_write
- Policy
- Refunds over $300
- Request
{"stripe_api_operation_id": "PostRefunds", "parameters": {"charge": "ch_3Q…", "amount": 124000}}
Approvers seated on the policy can decide here, and their sign-in names them. The console works in any browser, so a decision can come from a phone too.
Every decision lands in the log
The call's record keeps the policy that held it, the decision, the approver's name when the code or the console names them, and the comment. Denied and expired requests are recorded too, so "we stopped this" is always on the record.
Activity
- stripe_api_write · Stripeapprovedsupport-bot · PostRefunds · Refunds over $300 · by Sam Lee with OTP · "Charged twice, refund approved"
- drop_table · Postgresdeniedqa-agent · Protect production data · by policy
- send_message · Slackexpiredsupport-bot · Posts to customers · nobody answered in 180 s
Questions about MCP human approval
What is human-in-the-loop approval for AI agents?
Is the one-time passcode (OTP) required?
Which AI agents show the approval prompt?
What happens if nobody approves before the deadline?
Which actions are worth holding for approval?
Next steps
Write your first policy
Allow a call, deny it, or ask a person first, by agent, server, tool or argument.
Stripe refunds with approval
The full setup behind this example, from connecting Stripe to the $300 threshold.
Actions worth holding
Guardrails for the calls that can cost money or lose data.
Hold your agents' risky actions for a person
Add an Approve policy, seat the people who decide, and switch on the one-time passcode (OTP) when the approval needs a name.
Try for freeQuestions? Email us