
Human-in-the-loop for agentic AI: an approval gate with Amazon Bedrock, MCP, and Slack
Human-in-the-loop for agentic AI
AI agents have crossed a line. With tool use, they don't just answer questions — they take actions: issuing refunds, running migrations, messaging customers. On AWS, an agent powered by Amazon Bedrock can decide and execute in a single loop. That's the promise of agentic AI, and also its risk: "autonomous" must not mean "unsupervised."
I built Aegis to draw that line cleanly: a human-approval control plane that lets any agent pause before a high-risk action and ask a person to Approve, Deny, or Edit & Approve it — in Slack.
- ▶️ Demo: https://youtu.be/c1jqPDPo6AU
- 💻 Code: https://github.com/yama3133/aegis-slack-app
Two roles for Amazon Bedrock
Bedrock shows up twice in Aegis, in two very different jobs.
1) The autonomous agent (Claude Sonnet 4.6, Converse + tool use)
The agent runs a Converse API tool-use loop. Its safety behavior isn't hard-coded into an orchestrator — it comes from a system prompt plus the approval tools it's given:
1
2
3
4
5
6
const res = await bedrock.send(new ConverseCommand({
modelId: "us.anthropic.claude-sonnet-4-6",
system: [{ text: SYSTEM_PROMPT }], // "before ANY high-risk action, call request_approval..."
messages,
toolConfig: { tools }, // request_approval / check_approval / wait_for_approval
}));Before a risky action the model calls
request_approval, then blocks on wait_for_approval until a human decides. If the human edits the arguments, the prompt requires the agent to use the returned values. The model gates itself — no extra framework.2) The reviewer's co-pilot (Claude Haiku 4.5)
An approval is only as good as the reviewer's understanding of it. So every request is summarized in plain language by a fast, inexpensive Bedrock model (Claude Haiku 4.5) before the card is posted:
📋 In plain language: ops-agent will issue a $1,200 refund to ACME Corp for order ORD-4413 due to a reported duplicate charge.
The reviewer reads one sentence instead of a JSON blob. Two models, two cost/latency profiles, one workflow — a very natural fit for Bedrock's model choice.
The gate is decoupled via MCP
I didn't want approval logic tangled into the agent. The Model Context Protocol (MCP) is the seam: Aegis is an MCP server exposing three tools, and any Bedrock (or non-Bedrock) agent can adopt it without changing its reasoning.
| Tool | Purpose |
|---|---|
request_approval | Post a Slack approval card; return a request id (may auto-approve by policy) |
check_approval | Current status and any edited arguments |
wait_for_approval | Block until a human decides, or until timeout |

Policy: don't page a human for a $45 refund
A gate that interrupts every action is a gate nobody uses. A small policy engine decides who must sign off:
- Auto-approve low-risk, low-amount actions (a $45 goodwill refund clears instantly).
- N-of-M for critical actions — dropping a production table requires two approvers.
- TTL — pending requests expire; fail-safe by default.
Context from the workspace: Real-Time Search
Beyond the Bedrock summary, Aegis attaches related Slack messages to each card using Slack's Real-Time Search API (
assistant.search.context) — so the approver sees the conversation that led here, with permalinks, without leaving the card.Architecture
An agent on Amazon Bedrock calls
request_approval over MCP. Aegis evaluates policy, enriches the request with a Bedrock summary and Real-Time Search context, and posts a Block Kit card to Slack. The human's decision returns to the agent via wait_for_approval, and every step is written to an audit log.
Takeaways for builders
- Bedrock's model variety is a feature. Use a strong model (Sonnet 4.6) for the agent's reasoning and a fast one (Haiku 4.5) for summarization — same API, different trade-offs.
- Guardrails belong outside the agent. MCP keeps the approval gate reusable across agents and frameworks.
- Human-in-the-loop is a UX problem. Summary + context + the ability to edit an action are what turn an approval into a real decision instead of a rubber stamp.
Built for the Slack Agent Builder Challenge. Stack: TypeScript · Amazon Bedrock (Claude Sonnet 4.6 + Claude Haiku 4.5) · Model Context Protocol · Slack Bolt (Socket Mode) · Slack Real-Time Search API.
- ⭐ Code & setup: https://github.com/yama3133/aegis-slack-app
- ▶️ Demo: https://youtu.be/c1jqPDPo6AU
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article