IntentGate Python SDK
The official Python client for the IntentGate authorization gateway.
Companion repositories
| Repo | Purpose |
|---|---|
| intentgate-gateway | Go gateway with the four-check pipeline. The thing this SDK talks to. |
| intentgate-extractor | Optional FastAPI service that turns user prompts into structured intent. |
| intentgate-sdk-python | Python SDK for agents (this repo). |
| intentgate-helm | Helm chart that deploys the gateway, extractor, and Redis to Kubernetes. |
What it is
A thin client that lets your AI agent call tools through the
IntentGate gateway with a Pythonic API. The SDK handles the JSON-RPC
envelope, the Bearer token, the X-Intent-Prompt header, and turns
gateway error responses into typed Python exceptions.
Three lines of agent code
from intentgate import Gateway
gw = Gateway(url="http://localhost:8080", token=os.environ["INTENTGATE_TOKEN"])
result = gw.tool_call(
"read_invoice",
arguments={"id": "123"},
intent_prompt="Process today's AP invoices",
)
That's it. Construct once, call as many times as you like. When the
gateway blocks the call, tool_call raises a typed exception you can
catch.
Install
pip install intentgate
Released versions are published to PyPI
on every vX.Y.Z git tag via signed OIDC trusted publishing — see
.github/workflows/release.yml.
To install the development tip:
pip install git+https://github.com/NetGnarus/intentgate-sdk-python.git
Exception hierarchy
Every blocked call raises an exception. The class tells you which gateway check fired:
| Exception | JSON-RPC code | When |
|---|---|---|
CapabilityError |
-32010 |
Token signature invalid, expired, agent mismatch, tool not in caveat allow-list. |
IntentError |
-32011 |
Tool isn't in the intent extracted from the user prompt. |
PolicyError |
-32012 |
OPA policy returned deny. The reason carries the Rego rule's explanation. |
BudgetError |
-32013 |
A max_calls caveat in the token has been exhausted. |
ProtocolError |
other JSON-RPC | Malformed request, method not found, etc. Usually means an SDK ↔ gateway version mismatch. |
GatewayError |
n/a | Couldn't reach the gateway, or got a non-2xx HTTP response. |
IntentGateError |
(base) | Catch this if you don't care which check fired. |
from intentgate import Gateway, PolicyError, BudgetError, IntentGateError
try:
result = gw.tool_call("transfer_funds", arguments={"amount_eur": 50_000})
except PolicyError as e:
log.warning("policy blocked: %s (%s)", e.message, e.data)
except BudgetError:
log.error("agent ran out of budgeted calls")
except IntentGateError as e:
# everything else: re-raise or surface to user
raise
API reference
Gateway(url, token=None, *, timeout=10.0, client=None)
Construct a client.
url— base URL of the gateway, e.g.http://localhost:8080. Trailing slash is tolerated.token— capability token fromigctl mint. WhenNone, noAuthorizationheader is sent.timeout— per-request timeout in seconds.client— pre-configuredhttpx.Clientfor advanced use (test injection, custom transports). The SDK only closes the client it created itself.
Gateway is also a context manager:
with Gateway(url="...", token="...") as gw:
gw.tool_call(...)
# client closed automatically
Gateway.tool_call(tool, arguments=None, *, intent_prompt=None, request_id=None) -> ToolCallResult
Invoke a tool through the gateway.
tool— tool name like"read_invoice". Required.arguments— pass-through dict to the tool. The gateway logs only the keys, never the values.intent_prompt— the user's natural-language request. Sent as theX-Intent-Promptheader. Strongly recommended in production; without it the intent check is skipped (or denies in strict mode).request_id— JSON-RPCid. Defaults to a per-Gateway sequential integer.
Returns a ToolCallResult with:
content: list[ContentBlock]— what the upstream tool returned (MCP shape, currentlytype="text"only).is_error: bool— MCP-level "tool reported an error" flag (distinct from gateway-level errors that raise exceptions).intentgate: IntentGateMetadata | None— gateway decision summary (decision,reason,check,latency_ms).
Typical usage in an agent
The pitch's "three lines" referred to the SDK setup. In practice an agent wraps each tool through the gateway:
from intentgate import Gateway
class FinanceAgent:
def __init__(self, gateway_url: str, token: str, prompt: str) -> None:
self.gw = Gateway(url=gateway_url, token=token)
self.prompt = prompt
def read_invoice(self, invoice_id: str) -> str:
result = self.gw.tool_call(
"read_invoice",
arguments={"id": invoice_id},
intent_prompt=self.prompt,
)
return result.content[0].text
def transfer_funds(self, amount_eur: int, recipient: str) -> None:
self.gw.tool_call(
"transfer_funds",
arguments={"amount_eur": amount_eur, "recipient": recipient},
intent_prompt=self.prompt,
)
Develop locally
make install # creates .venv, installs -e ".[dev]"
make lint # ruff check + ruff format --check
make lint-fix # auto-fix lint + format
make test # pytest
make build # sdist + wheel into dist/ (sanity check before tagging a release)
Tests use respx to mock httpx at the transport level — no real
network required, no running gateway needed.
Project layout
src/intentgate/
__init__.py # public API: Gateway, exceptions, dataclasses
client.py # Gateway client + ToolCallResult dataclasses
exceptions.py # IntentGateError hierarchy (CapabilityError, IntentError, ...)
tests/
test_client.py # respx-mocked HTTP behavior
.github/workflows/ # CI (lint + tests across Python 3.10–3.13) and release (publish to PyPI on tag)
Makefile # install / lint / lint-fix / test / build / clean
pyproject.toml # hatchling build, ruff config, pytest config
Versioning
Pre-release. The wire protocol with the gateway is stable (JSON-RPC
2.0 + the IntentGate-specific error codes), but the Python API surface
may change before 1.0.0. Pin to a minor version when integrating.
Contributing
Apache 2.0 and welcomes community contributions. A formal CONTRIBUTING.md
is coming with the v0.1 → v1.0 polish pass. For now, please open an
issue to discuss any non-trivial change before sending a PR.
Security
If you find a security vulnerability, please do not open a public issue. Email security@netgnarus.com (or open a GitHub Security Advisory on this repo) and we'll respond within two business days.
Metadata
Release files for intentgate 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 | |
|---|---|---|---|
| intentgate-0.3.0.tar.gz | 20.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| intentgate-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.7 kB
Release files / intentgate-0.3.0.tar.gz
| Download URL | intentgate-0.3.0.tar.gz |
|---|---|
| Size | 20.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
352825ef241e8cbeb95f8903f228a90a432307d2d6d1596e5ebbc21428b4490f
|
|
BLAKE2b-256 checksum How to use checksums |
dbb1e32183bfc4b766ed971a4d016c8a55c9185e785028b1ef038a0dff65fa4a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 May 10, 2026.
Transparency logRelease files / intentgate-0.3.0-py3-none-any.whl
| Download URL | intentgate-0.3.0-py3-none-any.whl |
|---|---|
| Size | 18.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f1982d951fcff6f91e7699a4b31ac68fa229aa76e8885a472b9864886af15e4f
|
|
BLAKE2b-256 checksum How to use checksums |
1be1011c29c9da60cd65024d807632648ac74a7383af392da259ae85e93b57c3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 May 10, 2026.
Transparency log