Guardian MCP
by izmiradami
README.md
# Guardian — Transaction Firewall for AI Agents
**An OKX.AI A2MCP service. Every agent that can sign can also be tricked. Guardian is the check that runs first.**
The agent economy has a hole in the middle of it. We are handing autonomous agents the ability to move money, and the only thing standing between a prompt-injected agent and an empty wallet is the agent's own judgment. That is not a security model.
Guardian is the layer that says no. An agent submits the transaction it *intends* to sign; Guardian returns **ALLOW**, **WARN** or **DENY**, with every reason. It never sees a private key, and it never signs anything.
```
Agent → "I want to sign this" → Guardian → ALLOW / WARN / DENY → Wallet
│
decode · policy · on-chain scan · simulate
```
---
## What it actually catches
Not a risk score handed down from a black box — deterministic rules, each with a stated reason.
| Rule | What it stops |
|---|---|
| `unlimited_approval` | `approve(spender, MAX_UINT256)` — the single most exploited pattern in crypto. One compromised contract, and the whole balance is gone years later. |
| `set_approval_for_all` | A blanket grant over an entire NFT collection. |
| `approval_to_eoa` | Spending power granted to a personal wallet instead of a contract. Real protocols are contracts. This is a drainer signature. |
| `fresh_recipient` | Recipient with zero balance, zero nonce and no code — a freshly generated address, i.e. the wallet an attacker made ten minutes ago. |
| `zero_address` | Funds sent into the void and destroyed. |
| `max_spend_exceeded` | The agent exceeding its budget. |
| `unknown_selector` | Calldata the agent cannot prove the meaning of. |
| `simulation_revert` | A transaction that reverts on-chain. |
## Tools
| Tool | Purpose |
|---|---|
| `guardian_assess_transaction` | The main event. Full verdict: decode + policy + on-chain scan + simulation. |
| `guardian_decode_calldata` | Raw hex → plain language. "Grant 0xabc… UNLIMITED permission to spend your USDC." |
| `guardian_scan_address` | Contract or wallet? Funded? Ever used? How much bytecode? |
| `guardian_simulate_transaction` | Dry-run: does it revert, what does it cost? |
| `guardian_supported_chains` | Chain list. |
## Chains
X Layer (196, default) · X Layer Testnet (1952) · Ethereum · Base · BNB Chain · Arbitrum · Polygon
Each chain carries several RPC endpoints and fails over between them. A protocol error ("execution reverted") is a real answer from a healthy node, so it propagates immediately; only transport failures (timeout, 5xx, dead origin) move to the next endpoint. `npm run test:live` health-checks every configured URL, so a rotting provider surfaces in CI rather than in front of a user.
---
## The design decision that matters
A security tool that guesses when it cannot see is worse than no security tool, because it is trusted.
An early version of Guardian used soft RPC fallbacks: if a call failed, it substituted an empty value and carried on. The result was a system that, whenever the network hiccuped, confidently reported that Vitalik's wallet was a freshly generated drainer address and that the Uniswap router was a personal wallet — because "no code" and "could not read the code" had collapsed into the same value.
Guardian now separates *the chain says no* from *the chain did not answer*:
- **DENY is deterministic.** Policy checks and hard security rules are computed offline, so a flaky RPC can never soften a DENY.
- **On-chain enrichment may only add risk.** A failed lookup never manufactures a finding.
- **No blind ALLOW.** If the chain is unreachable, the response carries `degraded: true` and the verdict is capped at WARN. Guardian will tell you it does not know.
This is enforced by tests, not by convention. See suite 4, *"an unreachable chain must never be faked."*
---
## Run it
```bash
npm test # 37 assertions: protocol, decoder, policy, degraded mode
npm run test:live # real attack scenarios against live chain state
npm run dev # http://localhost:8787/mcp
```
No dependencies. No build step. Node 18+.
## Deploy
```bash
vercel --prod
```
Your MCP endpoint is `https://<your-domain>/api/mcp`. That HTTPS URL is what you register with OKX.AI.
## Call it
```bash
curl -X POST https://<your-domain>/api/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```
A worked example — an agent about to grant an unlimited USDC allowance:
```json
{
"verdict": "DENY",
"riskScore": 80,
"degraded": false,
"summary": "Grant 0x1111…1111 UNLIMITED permission to spend your USDC",
"findings": [
{ "severity": "critical", "rule": "unlimited_approval",
"message": "Unlimited spend approval… the entire USDC balance can be drained — today or years from now." },
{ "severity": "high", "rule": "approval_to_eoa",
"message": "Spending power is being granted to an EOA, not a contract. Legitimate protocols are contracts." }
],
"recommendation": "DO NOT SIGN. Fix: request an exact-amount approval instead of an unlimited one. Fix: never grant token allowances to a personal wallet address."
}
```
## Pricing
Free. Guardian is infrastructure: the more agents that check before they sign, the safer the marketplace everyone is building on.
MIT.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues