Skip to main content
Glama
izmiradami

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.