Skip to main content
A guardrail flags an MCP tool your agent has never called in production. Instead of blocking outright, your policy requires human approval. The agent pauses, an approval request appears in the dashboard, and execution resumes only after someone approves or rejects. When you finish this page, you’ll understand the approval flow, timeouts, and how to handle approval in both SDK and MCP proxy paths.

How approval works

  1. Guard evaluates an action → decision is require_approval
  2. Apie emits agent.approval.requested
  3. SDK polls the dashboard via approvals.wait()
  4. Human approves or rejects in the Apie dashboard
  5. Apie emits agent.approval.resolved
  6. If approved, the callback proceeds; if rejected or timed out, an error is thrown
This only blocks in Enforce mode. In Monitor mode, approval requirements are logged but execution proceeds.

Configure timeout

Default approval wait is 5 minutes. Adjust with approvalTimeoutMs:
const apie = new Apie({
  approvalTimeoutMs: 600_000, // 10 minutes
});

Automatic approval in withTool

When Enforce mode is active and a policy decision is require_approval, withTool handles the full flow automatically — you don’t call approvals.wait() manually.
// In Enforce mode — approval is automatic inside withTool
await apie.withTool(
  {
    runId: run.id,
    tool: { name: "unknown_mcp_tool", riskLevel: "high" },
    action: { type: "execute", name: "unknown_mcp_tool" },
    resource: { type: "file", environment: "production" },
  },
  async () => mcpClient.callTool("unknown_tool", {}),
);

What you’ll see

A pending approval in the Apie dashboard with the action details, matched guardrail, and approve/reject buttons. After resolution, the run timeline shows the approval requested and resolved events.

Manual approval polling

For custom flows, poll approval status directly:
const status = await apie.approvals.wait({
  approvalId: "appr_123",
  timeoutMs: 300_000,
});
// status: "approved" | "rejected" | "expired" | "cancelled" | "timeout"

const current = await apie.approvals.getStatus("appr_123");

MCP proxy approvals

In MCP proxy Enforce mode, approval-required tool calls are blocked at the proxy layer. The MCP host receives JSON-RPC error -32002 if approval is denied or times out. Configure approval timeout in apie.mcp.json:
{
  "agentKey": "my-agent",
  "mode": "enforce",
  "approvalTimeoutMs": 600000,
  "upstream": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"] }
}
See MCP enforcement recipe.

Approval statuses

StatusMeaning
approvedHuman approved — execution proceeds
rejectedHuman rejected — execution throws
expiredApproval window expired in dashboard
cancelledApproval was cancelled
timeoutSDK wait timed out before resolution

Next steps

MCP enforcement

Enforce mode + approval through MCP proxy.

Enforce guardrails

Configure Enforce mode and failure handling.