LLM agents are powerful and brittle. Given the wrong prompt they will drop a production table, read a secret, or POST your data to an attacker's URL. A traditional guardrail answers with a hard 403 that kills the run and burns the tokens you already spent.
AgentX is different, and it protects you with zero keys. The hero is a deterministic Shield that runs in-process, screening every call against a floor that needs no LLM and no network: DROP TABLE, SSRF, secret reads, destructive shell and cloud teardown. Out of the box it watches and records what it finds and blocks nothing. Set AGENTX_POSTURE=enforce, or pin a single tool with posture="enforce", and the same floor stops those calls before they run and hands your agent coaching to self-correct on. It escalates the consequential-but-legitimate ones (large transfers, external publishes, runaway spend, bulk deletes) for a human to approve. No API key, no signup, no LLM round-trip.
This repository is the MIT-licensed SDK: the keyless Shield, which you can read, audit, and run yourself with no AgentX account.
pip install agentx-security-sdkagentx demoRuns a canned agent that attempts a DROP TABLE and lets you watch the in-process Shield block it offline. It is the fastest way to confirm the install before you wire it into your own agent.
Caught something you are proud of? Turn it into a shareable card:
agentx shareagentx share renders your most recent catch as a screenshot-able receipt. It is privacy-safe by construction: it uses the policy class and your own tool name only, never the query or the payload.
Add @agentx_protect over any high-risk tool. The SDK inspects the call at runtime, so there is no schema to write and no boilerplate:
from agentx_sdk.decorators import agentx_protect
@agentx_protect(agent_id="crm_worker")
def run_sql(query: str, db=None):
...That wrap watches and records every call it sees. To have it stop a flagged one, export AGENTX_POSTURE=enforce for the whole process, or pin the single tool with @agentx_protect(agent_id="crm_worker", posture="enforce"). A pinned tool keeps that posture until you delete the argument, and it wins over the environment variable.
Once blocking is on, your code reacts with is_block(). You never parse message text, you read structured fields:
from agentx_sdk import agentx_protect, is_block
result = run_sql(query=untrusted)
if is_block(result):
print(f"Blocked by policy: {result.policy}")
llm.send(result.challenge) # feed the safe-path challenge back so the agent self-corrects
else:
use(result) # not blocked: the real return valueFor strictly-typed tools (LangChain or Pydantic tools that validate a -> dict return), AgentX raises instead of returning, so the framework does not crash on a changed return type:
from agentx_sdk import AgentXSecurityBlock
try:
data = fetch_user(uid) # -> dict
except AgentXSecurityBlock as block:
llm.send(block.challenge)The statement has to reach the Shield in an argument named for what it is. query, sql,
statement, command, path and url are read as what they say they are, as is the single string
argument of a tool whose own name says what it runs. Free text is not: a note or a body carrying
the same words is recorded and left alone, so a ticket that happens to say "update the cart set aside
for later" is not treated as a mass write.
A runaway-loop circuit-breaker trip is not a policy block. It raises AgentXCircuitBreakerTripped, and is_block() returns False for it, so you can catch it separately to abort the run.
Do not own the tool's Python, or running a non-Python agent? Wrap any MCP server with agentx-mcp and every tools/call is screened by the same keyless Shield before it runs. It is one line in your mcp.json (Claude Code, Cursor, or any MCP client):
{
"mcpServers": {
"filesystem": {
"command": "agentx-mcp",
"args": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"]
}
}
}No Python in your stack? Run it on demand with uvx so mcp.json stays one line:
{
"mcpServers": {
"filesystem": {
"command": "uvx",
"args": ["agentx-mcp", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"]
}
}
}(pipx run agentx-mcp <real server command> works the same way.) A blocked call comes back to the agent as a coaching tool error it can self-correct on, so the run keeps going and the dangerous call never reaches the server.
Every wrapped call is written down locally, whether blocking is on or off. From the folder your agent ran in:
agentx audit # grouped by tool: which tools ran, how often, what each touched
agentx audit --calls # one row per call, newest first
agentx audit --json # the same data for a programIn CI, two flags turn the screen into a verdict: agentx audit --require-calls exits 2 when the record holds no calls, so a job where the agent never ran cannot pass as a clean audit; --fail-on-rule-match exits 3 when a recorded call matched a rule you adopted.
Your own rules come from your own record: agentx review walks what got caught and lets you adopt a rule from it, into .agentx/rules.json, a file you can commit and review in a pull request. A call that matches one is marked on the audit screen and named under it. It is recorded, never blocked, in any posture.
examples/ holds one script per behaviour, each small enough to read in a sitting. They live in the published sdist but not in the wheel, so pip install alone does not put them on your disk. This repository is where you read or clone them.
git clone https://github.com/vdalal/agentx-security-sdk
cd agentx-security-sdk
pip install agentx-security-sdk
python examples/00_quickstart_pip.py00_quickstart_pip.py needs nothing beyond the SDK itself. A prompt-injected DROP TABLE reaches a protected tool and is stopped in-process, with no key and no network call. It pins posture="enforce" on the tool so you can watch the block happen, and says so in a comment; your own fresh install watches until you ask it to block.
The other scripts load a local .env for convenience, so install their extras first:
pip install -r examples/requirements.txtexamples/README.md lists what each script demonstrates and what it needs to run. Several of the later ones drive the hosted gateway and require a key, which that table marks.
This repo is the keyless Shield: a deterministic in-process floor with in-band coaching, MIT-licensed, no account required. It watches by default and stops the catastrophic call once you turn blocking on, and that is the whole story for keeping it from executing.
The Recover tier turns a block into a completed task. When you connect the hosted gateway, the agent gets a task-fitting path back and finishes the run instead of crashing, with human-in-the-loop review on the consequential calls. Recover runs in the hosted gateway, not in this SDK. Request access at agentx-core.com.
pip install -e .This repository is a snapshot of exactly what pip install agentx-security-sdk publishes, so it carries shipping code and examples only. The test suite is not part of the published package and is not mirrored here.
MIT. See LICENSE.
Homepage: agentx-core.com