Abe

Free, local check before an AI agent acts: your rules return ACT, BLOCK or ESCALATE.

AI & MLPythonv0.2.3

Abe

Abe, a friendly traffic light giving a thumbs up

Act. Block. Escalate.

Abe is a free, open-source guardrail that checks every AI agent action before it happens.

Your agent is about to pay an invoice, buy servers, delete a table or email a customer. Abe checks the action against your rules in under a millisecond, on your machine, and answers ACT, BLOCK or ESCALATE, with a tamper-evident record of why.

▶ Watch the 40-second demo: an AI agent tries to spend $12,500 twice. Rules decide the easy calls; Flow catches the duplicate and approves the real renewal. (Run it yourself)

Free. Really.

Apache-2.0. No account, no API key, no network, no model, no usage limits. Every check runs on your machine, at no cost, forever.

Why teams put Abe in front of their agents

  • Stops expensive mistakes: duplicate payments, over-budget purchases, force-pushes to main, DROP TABLE in production.
  • Same answer every time: plain YAML rules you can read, test, and replay against past decisions before going live.
  • Proof for auditors: every decision gets a hash-verified record (optionally Ed25519-signed) showing which rule fired and why.
  • Works with any agent: Python, TypeScript, a local HTTP sidecar, Docker, or MCP (Claude, Cursor and other MCP clients).
  • No-risk rollout: shadow mode runs beside your current approval process and shows where Abe would agree.
  • Fails closed: bad input or a broken rule returns ESCALATE, never ACT.

Pay only for the close calls (optional)

When rules can't decide, Abe returns ESCALATE. By default that goes to a person. Add --resolver flow and only that action is sent to Flow (redacted), which returns a decision, a reason, and what would prove it wrong, for about $0.03 to $0.05 each. ACT and BLOCK never leave your machine. Details below.

Quick start

pip install abe-ai            # or: npm install abe-ai
abe init                      # writes abe-policy.yaml + request.json
abe check request.json
Decision: ESCALATE
Reason: FINANCIAL_THRESHOLD_EXCEEDED
Rules: purchase_review_limit
Risk: MEDIUM
Record: jgr_01M3Q4...

Python

from abe import Abe

abe = Abe("abe-policy.yaml")

result = abe.check(
    action={"type": "wire_transfer", "amount": 50000},
    context={"agent_id": "finance-agent"},
)

if result.decision == "ACT":
    ...                                   # execute exactly as evaluated
elif result.decision == "BLOCK":
    ...                                   # do not execute; tell the user result.reason_code
else:  # ESCALATE
    ...                                   # hold; ask a human, or let a resolver decide

result.record.to_dict()                   # the Judgment-Grounded Record (store it, ship it to your SIEM)

TypeScript

import { Abe } from "abe-ai";

const abe = new Abe({ policy: "./abe-policy.yaml" });
const result = await abe.check({
  action: { type: "purchase", amount: 12500, currency: "USD" },
  context: { agent_id: "procurement-agent", principal_id: "user_123" },
});
console.log(result.decision);             // "ESCALATE"

A policy

version: "0.1"
defaults: { unmatched: ESCALATE }           # nothing matched -> needs judgment (fail closed)
rules:
  - id: purchase_hard_limit
    when: { all: [ { field: action.type, op: eq, value: purchase }, { field: action.amount, op: gt, value: 100000 } ] }
    decision: BLOCK
    reason_code: HARD_POLICY_VIOLATION
  - id: purchase_review_limit
    when: { all: [ { field: action.type, op: eq, value: purchase }, { field: action.amount, op: gt, value: 10000 } ] }
    decision: ESCALATE
    reason_code: FINANCIAL_THRESHOLD_EXCEEDED
  - id: routine_purchase
    when: { all: [ { field: action.type, op: eq, value: purchase }, { field: action.amount, op: lte, value: 500 } ] }
    decision: ACT
judgment_required:
  - action.type: terminate_employee

Also: authorization per agent, required evidence, risk and irreversibility thresholds, confidence minimums. BLOCK beats ESCALATE beats ACT. Bad input or a broken rule returns ESCALATE / EVALUATION_FAILURE, never ACT. Full reference: SPEC.md.

Test before you enforce

Replay saved requests through a policy before it touches real money. Label each case with what your people decided and Abe reports where it disagrees; compare against the live policy to see exactly which decisions a change moves.

# cases.jsonl: one request per line, or {"id": "inv-1042", "request": {...}, "expected": "BLOCK"}
abe replay cases.jsonl --policy new-policy.yaml --baseline abe-policy.yaml
#   Replayed 1204 case(s) against ...      ACT 1088   BLOCK 31   ESCALATE 85
#   Changed vs baseline: 3                 inv-1042: ACT -> ESCALATE  [purchase_review_limit]
#   Agreement with expected: 1198/1204 (99.5%)
abe replay cases.jsonl --policy new-policy.yaml --baseline abe-policy.yaml --fail-on-change   # CI: exit 1 if anything moved

Shadow mode runs Abe beside your current approval process. Decisions, results and exit codes are exactly what enforce mode would return, and every record is marked "mode": "shadow". Keep approving the way you do today, report what your people decided, and each record's falsifier shows whether they agreed.

from abe.stores import SQLiteStore

abe = Abe("abe-policy.yaml", mode="shadow", store=SQLiteStore("abe.db"))    # or: abe serve --shadow · ABE_MODE=shadow
r = abe.check(action={"type": "purchase", "amount": 48000}, context={"agent_id": "ap-agent"})
# ... your existing approval happens ...
abe.record_outcome(r.records[0], "approved")    # people approved; if Abe said BLOCK, the falsifier triggers

When the agreement rate is where you want it, drop mode="shadow" and Abe enforces.

Every way to run it

Librarypip install abe-ai · npm install abe-ai
CLIabe check · replay · validate-policy · validate-record · conformance · keygen
Local HTTP sidecarabe serve --policy abe-policy.yaml → POST http://127.0.0.1:8787/v1/check (any language)
Docker sidecardocker run -e ABE_TOKEN=… -v $PWD:/policy:ro -p 127.0.0.1:8787:8787 ghcr.io/flowinfosystems-index/abe
MCP serverpip install "abe-ai[mcp]" → abe mcp --policy /abs/abe-policy.yaml (tool: fjp_check_action)
+ Flow on escalationsadd --resolver flow (or ABE_RESOLVER=flow) with FLOW_API_KEY to check, serve, mcp or the Docker image

Records you can audit

Every call returns a record with the decision, every matched rule, the exact policy hash, the request hash, and a SHA-256 record_hash (optionally Ed25519-signed with abe keygen). Records never change: outcomes and resolutions are appended as linked records. Each one is a valid FJP-CONF v0.1 Judgment-Grounded Record.

abe check request.json --record-out jgr.json --sign-key abe-signing-key.pem
abe validate-record jgr.json --public-key abe-signing-key.pub.pem

When rules aren't enough: Flow

Abe is deliberately useful without Flow. When it returns ESCALATE, you can hand that one action to Flow's judgment service and get a verb, a reason and a falsifiable record back:

from abe import Abe
from abe_flow import FlowResolver                     # pip install abe-flow

abe = Abe("abe-policy.yaml", resolver=FlowResolver(api_key=os.environ["FLOW_API_KEY"]))

No Python? The CLI, sidecar and MCP server take the same resolver (pip install "abe-ai[mcp,flow]"):

{"mcpServers": {"abe": {"command": "abe",
  "args": ["mcp", "--policy", "/abs/abe-policy.yaml", "--resolver", "flow"],
  "env": {"FLOW_API_KEY": "fjp_live_..."}}}}

abe serve --resolver flow and docker run -e ABE_RESOLVER=flow -e FLOW_API_KEY=… … work the same way. If Flow is out of credits, the MCP result says so and links to the refill page; the action stays ESCALATE.

ACT and BLOCK never leave your machine. Only escalations are sent (redacted), and if Flow is unreachable the answer simply stays ESCALATE. Human-approval escalations are never auto-resolved.

Conformance

abe conformance --bench        # FJP-CONF v0.1 Gate profile, Level 3 — 160 checks, offline

Repository

SPEC.md                  the normative specification
schemas/                 JSON Schemas (request, response, record, policy)
python/                  abe-ai (PyPI): core, CLI, HTTP, MCP, stores, signing, conformance
typescript/              abe-ai (npm): same API, same records, same hashes
flow-resolver/           abe-flow (PyPI): Gate → Flow for ESCALATE only
conformance/fixtures/    golden decisions + canonical-JSON vectors shared by every SDK
examples/                the $12,500 demo, purchasing, software agent, physical agent, travel (+ Judd), Flow

Apache-2.0. FJP™, Abe™ (Abe) and FJP-CONF™ are trademarks of Flow Information Systems — see TRADEMARKS.md.

Installation

Source-derived launch command. Check the maintainer’s required arguments and credentials before running:

bash
uvx abe-ai

Set up in your AI client

Merge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.

json
{
  "mcpServers": {
    "io-github-flowinfosystems-index-abe": {
      "command": "uvx",
      "args": [
        "abe-ai"
      ]
    }
  }
}

Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.

Claude Desktop setup reference

Package

abe-aipypi

Compatible MCP Clients

Abe works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.

  • Claude Desktop~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.
  • Cursor~/.cursor/mcp.jsonRestart Cursor for changes to take effect.
  • VS Code.vscode/mcp.jsonReload VS Code window for changes to take effect.
  • Windsurf~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect.
  • Claude Code.mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.

Learn More