Guide · Claude Code

Approval workflows for Claude Code agents

What you want is for Claude Code to stop before something that matters, for the person who owns that decision to be asked, and for a record of who decided to be kept. Claude Code already pauses for whoever is at the keyboard; an approval workflow sends the question to the right person instead, and brings their answer back to the session.

What Claude Code gives you on its own

Claude Code asks before it runs a tool you have not allowed, and its settings let you allow, ask or deny tools and commands by pattern. That is the right control for the developer at the keyboard. It is not an approval workflow: the person asked is always whoever started the session, the answer is not kept, and an agent running unattended — in CI, on a schedule, through the Agent SDK — has nobody to ask.

Three ways to add an approval

ApproachHow it works
Let Claude ask, through a connected toolConnect an approval service as an MCP server and tell Claude, in CLAUDE.md or a skill, which actions need a person. Claude calls the tool to ask, waits for the answer and carries on. Quick to set up; it relies on Claude following the instruction.
Check it in a PreToolUse hookA hook runs before every tool call that matches its pattern, outside the model. It can send the call to your policy and return allow, deny or ask, so a deploy or a payment cannot run without an answer whatever the model decides.
Handle permissions in code, with the Agent SDKWhen you run Claude through the Claude Agent SDK, a permission callback decides each tool call. It can wait for a named person's answer before returning, which suits an agent with nobody at a keyboard.

What a hook should do

  • Match only the calls that matter — a deploy, a payment, a merge to main, a delete — and let everything else run as before.
  • Send the exact command or tool arguments, so the person sees what will run rather than a summary of it.
  • Treat a refusal as an answer: stop, and tell the user which rule refused and why, rather than retrying a variation.
  • Find the same decision again when the same call is retried, so one approval is not asked for twice.
  • Record what ran afterwards, so the decision and the action sit in the same record.

Choosing between them

Start with the connected tool: it takes minutes and covers the common case of Claude asking before it does something consequential. Add a hook for the actions that must never run without an answer, because a hook does not depend on the model choosing to ask. Use the Agent SDK's callback when Claude runs as part of your own product.

How Deliverd does it

Connect Deliverd with one claude mcp add command, and Claude Code signs in through your browser, with no token pasted. Claude can then ask a named person for approval, a review or information, and the person answers from an email link, Slack, Teams or their phone. The approval skill, and a Claude Code plugin with all of the skills, are open source.

To make the check outside the model, a PreToolUse hook can declare the call at a gate: your organisation's rules allow it, refuse it or send it to a person, and a call nobody wrote a rule for goes to a person. The Claude Agent SDK adapter does the same from a permission callback. Afterwards the agent records what ran, and the whole exchange exports as evidence.

Questions

Can a Claude Code hook wait for a person to approve?
Yes, within the hook's timeout. A hook can wait for the answer, or refuse the call with a link to the pending approval so the same call goes ahead once someone approves it.
Does the approver need Claude Code or a terminal?
No. With Deliverd they answer from an email link, a Slack or Teams card, or a page that works on a phone, signed in through their own organisation.
Can Claude approve its own request?
Not in Deliverd. An agent may not approve anything, and that is refused by the service rather than left to the prompt.