Quickstart

Gate your first agent action.

From pip install to a recorded gate decision in about five minutes. This is the end-to-end first run; for all three install paths see the install guide.

This walks the shortest path from nothing to a recorded policy decision. It uses only the pure Python primitive — no MCP server or Docker required — so you can see the gate return a verdict before wiring it into an agent. For the full install matrix (Python library, MCP server, Docker), see the install guide.

1. Install the policy primitive

The gate is a pure function with no I/O. That is the whole point — it is unit-testable and reproducible from a git commit.

terminal
pip install closegate-policy

2. Write a minimal policy.yaml

Declare your tiers, one materiality threshold, and a sensitive account. closegate adapts to your shape — this is deliberately small.

policy.yaml
materiality:
  default_usd: 10000          # above this, escalate to a human
sensitive_accounts:
  - "1000-CASH"               # any touch requires approval
tiers:
  auto_confirm:
    max_tier: 1               # T0/T1 below materiality auto-confirm
  require_approval:
    tier: 2                   # T2 needs one human, distinct identity
  require_dual_approval:
    tier: 3                   # T3 (irreversible) needs two

3. Evaluate an action through the gate

Feed the gate the proposed action, the match context, the actor identity, and your config. It returns exactly one of three decisions.

first_gate.py
from decimal import Decimal
from closegate_policy.gate import (
    Action, ActorContext, MatchContext, PolicyConfig, evaluate,
    Allow, RequireHumanApproval, Deny,
)

config = PolicyConfig.from_file("policy.yaml")

decision = evaluate(
    action=Action.CONFIRM,
    match=MatchContext(
        match_id="m-1042",
        state="PROPOSED_MATCH",
        proposed_by="llm:claude",
        source="llm",
        match_type="exact_match",
        amount_usd=Decimal("42000"),      # above materiality
    ),
    actor=ActorContext(id="llm:claude", kind="llm"),
    accounts={"5000-COGS"},
    rationale="PO-88 / GRN-88 / INV-88 three-way match",
    config=config,
)

4. Handle the three decisions

Because $42,000 is above the $10,000 materiality threshold, this action routes to RequireHumanApproval. The clause carries the verbatim policy text and a JSON-pointer into your policy.yaml.

first_gate.py
match decision:
    case Allow():
        commit_match(match_id="m-1042")           # + write audit row
    case RequireHumanApproval(clause):
        open_envelope(clause.text, clause.pointer)  # LLM can't self-confirm
    case Deny(clause):
        raise PolicyViolation(clause.text)

5. Add the MCP server and audit log

Once the primitive behaves the way you expect, run the MCP server so any MCP-compliant client (Claude Desktop, Cursor, OpenAI Apps SDK) drives the same gate — with the append-only audit log recording every decision.

terminal
uvx closegate-engine --policy ./policy.yaml

From here, wire the Slack or Teams approval bot so a human with a different actor identity confirms above-materiality actions. That is segregation of duties, enforced server-side.

Where to go next

  • How it works — the three-step gate walkthrough with the architecture diagram.
  • Features — all four primitives and what ships with them.
  • The policy gate — the chokepoint pattern in depth.
  • The audit log — how tamper-evidence is enforced at the database layer.
  • Glossary — every term used above, defined.

closegate is open source (Apache-2.0), built by Neul Labs.

Inbound

Talk to the maintainer

Two design-partner slots open this quarter. One real workflow, your real policy.yaml, monthly 30-min call, direct line. Apache-2.0, self-hosted, no seat licensing — forever.