ActGate
Local IntentLedger and MCP stdio proxy: propose a tool action, approve or deny in an append-only hash-chained ledger, then let an identical tools/call reach one upstream MCP server.
This is not a SaaS. The ledger path stays on disk. dry-run and approve record decisions only; they do not execute tools. The MCP proxy is what executes, and only after approve.
Install
pip install actgate
Dev:
pip install -e .[dev]
CLI quickstart
actgate init
actgate propose --tool shell.exec --args '{"cmd":"ls"}' --blast-tags fs.read
actgate pending
actgate dry-run <intent_id>
actgate approve <intent_id>
actgate verify
actgate list
MCP proxy
Point your MCP client at ActGate instead of the upstream server:
actgate init
actgate mcp --upstream python -m some_mcp_server
Use the same --root (or the same working directory) for init, approve/deny, and mcp, so they share one ledger.
Flow:
- Client
tools/listis forwarded to upstream. Onlytools/callis gated; other methods are forwarded. - First
tools/callfor a tool+args writes a propose event and returnsACTGATE_PENDING intent_id=...(upstream is not called). - Human:
actgate approve <intent_id>(oractgate deny <intent_id>). - Identical subsequent
tools/call(same tool and args) runs upstream once and appends anexecuteevent. A third call returns already-executed. - Denied intents never hit upstream.
Bare verify checks hash-chain integrity only. Set ACTGATE_SEAL_KEY for
optional HMAC seals, or pass verify --require-seal.
Human loop (HITL)
Typical MCP approval loop:
- Client hits
actgate mcp --upstream ...and getsACTGATE_PENDING. - Human:
actgate pending(oractgate pending --watch) to see undecided proposes. actgate approve <intent_id>oractgate deny <intent_id>.- Client retries the same
tools/call; proxy executes once.
pending is the propose-without-decision queue. --watch polls (default 1s) and
prints newly pending intents as JSON until Ctrl-C (clean exit 0).
Exit codes
| Code | Meaning |
|---|---|
| 0 | ok (propose, approve, verify clean, show/list/pending) |
| 1 | deny recorded, or verify found a broken chain / bad seal |
| 2 | setup error (missing ledger, bad path, invalid args) |
Intent shape
{
"tool": "shell.exec",
"args": {"cmd": "ls"},
"args_hash": null,
"blast_tags": ["fs.read"],
"requested_mode": "execute",
"created_at": "2026-09-06T00:00:00+00:00"
}
What this is not
- Not a hosted approval product
- Not a policy DSL
- No network calls in the ledger core path (the MCP proxy talks to a local upstream process)
Development
pip install -e .[dev]
pytest
Metadata
Release files for actgate 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| actgate-0.3.0.tar.gz | 16.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| actgate-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.2 kB
Release files / actgate-0.3.0.tar.gz
| Download URL | actgate-0.3.0.tar.gz |
|---|---|
| Size | 16.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
733ee92658c845d821c9373aa22e70ae4fd23ee63289473ce37065001c53235f
|
|
BLAKE2b-256 checksum How to use checksums |
635bdf890f3edb6601cdfb314a033acc43960a3660ea3be20ad7b2ef72f023a1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.
Transparency logRelease files / actgate-0.3.0-py3-none-any.whl
| Download URL | actgate-0.3.0-py3-none-any.whl |
|---|---|
| Size | 14.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aaa72356ff5629e060f00881e7935bf457861c1673ad17497ee00fda475b0745
|
|
BLAKE2b-256 checksum How to use checksums |
72002aceaca60c4074af437e26d52f090a4bd3503e6d9e7f998c190e5c6f7126
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.
Transparency log