How it works

A thin layer between your agent and its tools.

Agent (MCP client / SDK)
      |
      v
Keeprun  ->  1 auth + tenant      ->  2 pre-checks + policy (allow | hold | block)
      |      3 forward w/ timeout  ->  4 post-checks (pass | annotate | note)
      v
Upstream MCP / HTTP tools

Shadow, then hold

Shadow mode (first)

Nothing is blocked. Keeprun shows what it would have held or flagged, and your team labels each one.

Hold mode (when you are ready)

Rules are enforced. Irreversible actions wait for a human. One click per agent to turn on.

The four jobs

Catch tool failures

Timeouts, rate limits, errors, empty or partial results, schema drift, confidently wrong answers.

Diagnose, don't blindly retry

Return a short diagnosis note the agent can act on, instead of looping.

Hold irreversible actions

Above your rules or thresholds, route to a human for approval.

Check consistency across runs

Flag when the same input gives divergent outcomes.

Rules in plain English

- id: hold-big-refunds
  when: { tool.risk_class: refund, amount: { gt: 2000, currency: INR } }
  then: hold
  expire: 30m

- id: refund-exceeds-order
  when: { tool.risk_class: refund, expr: "input.amount > lookup('orders.get', input.order_id).total" }
  then: block

Latency and failure

Synchronous checks are designed to be light. The optional LLM judge runs after the fact, not in the hot path. If Keeprun itself errors, calls fail open by default and are logged as unchecked, so your agent keeps working. You can set payments and refunds to fail closed.