Skip to content

Open source. Limited beta. Local stdio only. Version 0.4.0b1 on PyPI.

Your agent said ‘done.’ Fourgate checks whether it actually happened.

Independent outcome verification for consequential AI-agent actions.

Install the limited beta, then run the demo locally. No API keys, no network, no hosted endpoint.
python -m pip install --pre "fourgate==0.4.0b1"fourgate demo
PASSThe read-back found the record the tool reported, with the contracted values.
FAILThe read-back proved the record is missing or different.
UNKNOWNFourgate could not confirm either way. It never reports this as success.
  1. 1. Tool says done: Fourgate only checks results the tool reported as success; an error result is recorded as UNKNOWN (not_success_result).
  2. 2. Extract contracted fields: It extracts only the contract-approved fields, such as the record ID; if one is missing, the result is UNKNOWN.
  3. 3. Independent read-back: A separate read-only GET asks the system of record for the record: missing or different is FAIL, unreachable is UNKNOWN.
  4. 4. Verdict: Only a confirmed match is PASS. UNKNOWN is never counted as PASS, and it fails open: the call goes through unchanged.

A tool saying “success” is not the same as the system changing.

An agent that reads a tool result without isError has no protocol-level signal that the call failed. Fourgate checks the outcome itself: after a protected tool reports success, it reads the system of record back and records one of three results. No LLM decides.

PASSAn independent read-back confirmed the record exists with the contracted values. The tool's response passes through unchanged.
CONFIRMED FAILThe read-back proved the record is missing or different. In enforce mode the agent is told before it can report success.
UNKNOWNA timeout, an auth error, an unreachable API: Fourgate could not confirm either way. Recorded as UNKNOWN, never counted as PASS, and the call is not blocked.

Pick a connector and a mode. See what really happened.

Every value below comes from one recorded run of fourgate demo --pace 0 (fourgate 0.4.0b1): a simulated connector, with a local file standing in for the system of record. Only the five recorded combinations can be selected.

Connector

Mode

Or jump to a recorded scene

S2: Fourgate enforce: broken connector. FAIL record_missing.

S2

Fourgate enforce: broken connector

FAILrecord_missing

The agent is told the write did not land, before it can report success.

What the agent receives

  • Agent receives, first:[FOURGATE] outcome_failed (reason: record_missing, recovery: stop)
  • then the original:"Created ISSUE-001"
  • isError=false

System of record

0 issues saved

Outcome log

FAIL record_missing (mode: enforce)

Raw terminal output for S2
FOURGATE DEMO - local only: no API keys, no network, nothing leaves this machine
Simulated connector; a local file stands in for the system of record.

An agent asks the demo-crm connector to create_issue "Q3 renewal follow-up".
Each scene is a real MCP session; scenes S2-S5 run through a real `fourgate guard` process,
which reads the system of record back after the connector reports success.

[2/5] S2  Fourgate enforce: broken connector
  Same broken connector, now behind `fourgate guard --mode enforce`.
  Agent receives, first:  [FOURGATE] outcome_failed (reason: record_missing, recovery: stop)
  then the original:      "Created ISSUE-001"
  isError=false
  System of record: 0 issues saved
  Outcome log:      FAIL record_missing  (mode: enforce)
  -> The agent is told the write did not land, before it can report success.

A local guard, an independent read-back, a local record.

fourgate guard sits on the local stdio path between your agent and your MCP server. When a protected tool reports success, it extracts only the contracted fields, and a local verifier reads the record back with a separate, read-only credential.

  1. tools/call

  2. unchanged

  3. its own write

  4. read back by the verifier: independent read-only GET

  5. structure only

  6. local HTML

Wrap the command. Leave the server alone.

Fourgate goes in front of the command your MCP client already runs. Start in shadow mode: verdicts are recorded and the agent sees nothing different.

Illustrative client config
{  "mcpServers": {    "my-server": {      "command": "python",      "args": ["your_server.py"]    }  }}

Same thing as a shell command

python your_server.py

The file name and shape depend on your MCP client; only the command changes. runtime.json is the contract file fourgate init writes.

Six commands, in order.

Each step shows the real command. Where we captured a run, you see its exact output; where we did not, you see what the README says to expect.

See it work: local, simulated, no keys, no network.

Command
fourgate demo --pace 0
Real outputCaptured 2026-11-14 with fourgate 0.4.0b1. Paths shortened.
FOURGATE DEMO - local only: no API keys, no network, nothing leaves this machineSimulated connector; a local file stands in for the system of record.An agent asks the demo-crm connector to create_issue "Q3 renewal follow-up".Each scene is a real MCP session; scenes S2-S5 run through a real `fourgate guard` process,which reads the system of record back after the connector reports success.[1/5] S1  Without Fourgate: broken connector, called directly  The connector reports success but never saves the issue. No Fourgate in the path.  Agent receives:  "Created ISSUE-001"  (isError=false)  System of record: 0 issues saved  Outcome log:      no record (Fourgate is not in the path)  -> The agent believes the issue exists. It does not.[2/5] S2  Fourgate enforce: broken connector  Same broken connector, now behind `fourgate guard --mode enforce`.  Agent receives, first:  [FOURGATE] outcome_failed (reason: record_missing, recovery: stop)  then the original:      "Created ISSUE-001"  isError=false  System of record: 0 issues saved  Outcome log:      FAIL record_missing  (mode: enforce)  -> The agent is told the write did not land, before it can report success.[3/5] S3  Fourgate enforce: healthy connector  A healthy connector that really saves the issue, behind `fourgate guard --mode enforce`.  Agent receives:  "Created ISSUE-001"  (isError=false)  The response is identical to scene S1: no [FOURGATE] verdict  System of record: 1 issue saved  Outcome log:      PASS postcondition_satisfied  (mode: enforce)  -> A real success passes through untouched.[4/5] S4  Fourgate shadow: broken connector  The broken connector behind `fourgate guard --mode shadow` (the default mode).  Agent receives:  "Created ISSUE-001"  (isError=false)  The response is identical to scene S1: no [FOURGATE] verdict  System of record: 0 issues saved  Outcome log:      FAIL record_missing  (mode: shadow)  -> The agent is unaffected; you still learn the write did not land.[5/5] S5  Fourgate enforce: broken connector, system of record unreachable  The broken connector in enforce mode, but the read-back cannot reach the system of record.  Agent receives:  "Created ISSUE-001"  (isError=false)  The response is identical to scene S1: no [FOURGATE] verdict  System of record: 0 issues saved  Outcome log:      UNKNOWN verifier_error  (mode: enforce)  -> Fourgate could not confirm either way: recorded UNKNOWN, never PASS, and the call is not blocked.Summary  Totals (from fourgate summary): PASS 1 / FAIL 2 / UNKNOWN 1  Outcome log:  ./fourgate-demo/demo-outcomes.jsonl  Summary page: ./fourgate-demo/fourgate-demo-summary.htmlSelf-check: every scene behaved as narrated.

Built to be checked, not trusted.

  • Runs on your machine

    A laptop, a server or your CI. There is no Fourgate cloud service, account, database or telemetry.

  • No code changes

    Wrap the MCP server's launch command with fourgate guard. Your agent and server code stay as they are; you add a short contract per protected tool.

  • Any HTTP API read-back

    If the system of record exposes a GET endpoint for the written record, Fourgate can check it, with a Bearer token, a custom header or Basic auth.

  • Shadow first, byte-identical

    In shadow mode, the default, your agent receives exactly the same bytes it would without Fourgate. Verdicts are only recorded.

  • UNKNOWN is never PASS

    Timeouts, auth errors and Fourgate's own faults are UNKNOWN and fail open. Nothing uncertain is reported as success.

  • Open source

    MIT licensed. Read the code, install from PyPI, and check release files against the SHA-256 digests GitHub lists.

What we have tested, and what we have not seen yet.

Operator-run tests against official vendor MCP servers, as of 2026-10-01. Vendors are not named. Small numbers, stated as they are.

4
official vendor MCP servers tested, run locally against the vendors' live APIs using disposable test accounts or deliberately invalid credentials.
3 of 4
surfaced API failures as successful tool results without MCP isError. Each was reproduced at least twice and reported upstream.
Exercised
Hosted authoritative read-back: a real hosted write verified PASS by an independent HTTPS read-back, with FAIL and UNKNOWN controls behaving as specified.
Exercised
Real-agent shadow calls: a real agent client made 2 protected send calls through the runtime wrap in shadow mode against a hosted MCP server. Both recorded PASS.
0not observed yet
naturally occurring read-back-proven silent-success incidents observed so far: no write reported as done whose record turned out missing or wrong.

The failures found so far are error-reporting bugs, which Fourgate reports as UNKNOWN / success_without_record_id rather than PASS. One hosted integration does not establish production reliability, and two shadow calls are a smoke test, not production traffic. The full field record is in the README.

Free to run. Paid help to get it right.

Open Source

Free

MIT licensed. All six commands. Community support on GitHub.

Fourgate Founding Pilot

$300 one-time

Founder-assisted setup, outcome checks for up to three write tools in your CI, and a fix report with evidence.

Enterprise

Contact us

More workflows or tools than the pilot scope.

Questions a careful buyer asks.

Check up to three write tools, in your CI, with us.

Pick 1–3 state-changing tools that matter. We write the checks with you, run them in your CI against a test account you create, and send a fix report with evidence.