Skip to main content
Glama
AgentGuard

AgentGuard

by mohdqrm

AgentGuard

A safety gateway between AI agents and PayPal.

An AI agent gets four guarded MCP tools and no PayPal credentials. Every call is authenticated, validated, risk-scored and checked against policy before anything reaches PayPal. Risky calls stop and wait for a human. Every step is written to a hash-linked audit log.

Built for the PayPal AI Hackathon. Runs against the PayPal sandbox, so no real money moves.

The problem

Give an agent a PayPal API key and it can send any amount, to anyone, as many times as its loop decides to. There is no spending limit, no human in the loop, and no record of why it did what it did.

The usual answer is to tell the agent to behave. That is not a control — it is a request. An agent that has been argued out of its instructions by something it read in an invoice will send the money anyway.

AgentGuard takes a different line: the agent is never trusted, and never holds the credentials. It can ask. Something else decides.

Related MCP server: Tollbooth

What it looks like

AgentGuard is not a separate dashboard you have to go and check. The console is injected straight into sandbox.paypal.com by a browser extension, so reviewing your agent's payments happens where the money already lives.

sandbox.paypal.com/myaccount/agentguard
├── Ask your agent        chat; it calls the guarded tools and reports back
├── Waiting for you       commands held for approval, with the reasons
├── Every command         full history, risk score, policy decision, errors
└── Audit log             the hash chain, verifiable in place

The agent you chat to runs on your own Claude subscription through Claude Code, so the demo costs nothing in API credits. Set ANTHROPIC_API_KEY instead and it switches to the Messages API.

How it works

Claude agent ──MCP──▶ AgentGuard ──▶ PayPal sandbox
                          │
                     auth → validate → risk → policy
                          │
                   allow · block · ask a human
                          │
                    hash-linked audit log

The agent never holds PayPal credentials. It can only reach four tools, and each call runs the same gauntlet.

Step

What it does

Auth

JWT with a role. Agents call tools; merchants approve. An agent cannot approve its own request.

Validate

Zod strict schemas. Unknown fields and malformed amounts are refused.

Risk

Rules and time windows: amount, first-time payee, requests per minute, 24h running total. Scores 0–100.

Policy

OPA (policy/agentguard.rego) returns allow, approval or deny. Fails closed: if OPA is unreachable, the command is blocked.

Approve

Risky commands wait for a human. The request hash is stored and re-checked on approval.

Execute

One PayPal call with an idempotency key.

Audit

Every state change appended to a SHA-256 hash chain.

Command states

received → evaluated ─┬→ blocked
                      ├→ allowed  ─┐
                      └→ pending ──┴→ approved → executing ─┬→ success
                                   └→ rejected              ├→ failed
                                                            └→ uncertain → reconciled

uncertain is the interesting one. If PayPal times out, AgentGuard does not retry, because a retry could pay twice. The command waits and is resolved by a signed webhook or by replaying the same idempotency key as a status query.

Guarantees

  • No money without checks. The agent has no PayPal credentials and no path to the adapter that skips the guard chain.

  • A convinced agent still cannot pay. Persuading the agent is not the same as moving money. The hard cap denies, the first-time-payee rule holds, and the approval still has to come from a human holding a merchant token — whatever the agent has been talked into believing.

  • Approvals cannot be swapped. The request is hashed when it goes to a human and re-hashed on approval. If the amount or payee changed in between, it is rejected.

  • No double payments. Every execution carries an idempotency key. The uncertain path replays the same key rather than issuing a new payment.

  • Tamper-evident history. The audit log is append-only and hash-linked, enforced in Postgres by a trigger. GET /audit/verify names the first broken entry.

Run it

Needs Node 20+. These commands work the same on Windows, macOS and Linux.

npm install
npm run setup

npm run setup writes a .env and generates a signing key. It then asks you for one thing: your PayPal sandbox secret, from the Developer Dashboard under Apps & Credentials, behind the eye icon next to "Secret key 1".

npm test        # 29 tests, no network
npm run dev     # http://localhost:8080

Without SUPABASE_URL it stores state in memory, and without OPA_URL it uses built-in rules that mirror the Rego policy. Both are fine for a local demo.

The PayPal console

npm run extension     # mints a merchant token into extension/config.json

Then in Chrome or Edge: chrome://extensions → Developer mode → Load unpacked → pick extension/.

Log in at sandbox.paypal.com with a sandbox account. An AgentGuard pill appears in the corner, and the full console is at sandbox.paypal.com/myaccount/agentguard.

Connect your own agent

For Claude Code, npm run connect-claude registers the server with a fresh 7-day token. For any other MCP client:

npm run token -- agent my-agent 7d
{
  "mcpServers": {
    "agentguard": {
      "type": "http",
      "url": "http://localhost:8080/mcp",
      "headers": { "Authorization": "Bearer <agent token>" }
    }
  }
}

The agent sees create_order, capture_order, refund_capture and create_payout, and gets back plain-language results including "this needs human approval, do not resubmit".

Scripted demo

npm run demo

An auto-approved order, a payout held for review, a refused tampered approval, a blocked burst, and the audit chain. Point it at a deployment with npm run demo -- https://your-app.onrender.com.

Current status

Honest state of things, because this is a hackathon build in progress:

  • ✅ Guard chain, state machine, audit chain, MCP server, extension console, agent chat — working, 29 tests passing.

  • ✅ End-to-end against the live sandbox: agent requests → policy holds it → human approves in the PayPal page → hash re-checked → PayPal called.

  • ⚠️ Payouts return PAYOUT_NOT_AVAILABLE on the current sandbox business account because it is India-region. Needs a US-region sandbox account and a REST app bound to it.

  • ⚠️ Webhooks are not configured. PAYPAL_WEBHOOK_ID is empty, so inbound webhooks are rejected by design. Needs a deployed URL first.

  • ⬜ Not yet deployed; render.yaml is ready.

  • ⬜ Injection-resistance test suite not yet written.

Deploying

render.yaml deploys to Render as-is. After the first deploy:

  1. Run supabase/schema.sql in the Supabase SQL editor, then set SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY.

  2. In the PayPal Developer Dashboard, add a webhook at https://<your-app>.onrender.com/webhooks/paypal subscribed to: PAYMENT.CAPTURE.COMPLETED, PAYMENT.CAPTURE.DENIED, PAYMENT.CAPTURE.REFUNDED, PAYMENT.PAYOUTSBATCH.SUCCESS, PAYMENT.PAYOUTSBATCH.DENIED, PAYMENT.PAYOUTS-ITEM.SUCCEEDED, PAYMENT.PAYOUTS-ITEM.FAILED. Copy the Webhook ID into PAYPAL_WEBHOOK_ID or every webhook will be rejected.

  3. Optional: set ZAPIER_WEBHOOK_URL to a Zapier Catch Hook for Slack or email alerts on held and uncertain payments.

  4. Optional: run OPA with opa run --server policy/ and set OPA_URL.

API

Method

Path

Who

What

POST

/mcp

agent

MCP endpoint, the four guarded tools and get_command_status

POST

/agent/chat

merchant

The dashboard agent

GET

/commands?state=pending

merchant

Review queue

GET

/commands/:id

merchant

One command plus its audit trail

POST

/commands/:id/approve

merchant

Body: {"request_hash":"..."}

POST

/commands/:id/reject

merchant

Body: {"reason":"..."}

POST

/commands/:id/reconcile

merchant

Resolve an uncertain command by status query

GET

/audit · /audit/verify

merchant

Full chain, and verification

POST

/webhooks/paypal

PayPal

Signature-verified events

Layout

src/guard/      auth (JWT/RBAC), Zod schemas, risk scoring, OPA client
src/gateway/    state machine and the orchestration that enforces it
src/paypal/     sandbox adapter, idempotency, webhook verification
src/agent/      the dashboard agent (Claude Code and Messages API backends)
src/audit/      hash chain
src/store/      in-memory and Supabase stores
src/mcp/        the four guarded tools and the read-only status check
extension/      the console injected into sandbox.paypal.com
policy/         agentguard.rego
supabase/       schema.sql
test/           29 tests, no network

Built with

PayPal sandbox REST (Orders, Payments, Payouts, Webhooks) · Model Context Protocol · Claude, via Claude Code or the Messages API · OPA/Rego · Supabase (Postgres, append-only trigger) · Express · Zod · jose · Chrome MV3 extension · Render · Zapier

Contributing

TEAMMATES.md is the cold-start guide: setup, the extension, what to type to see an allow, a pending and a block.

.env and extension/config.json are gitignored and must stay that way. The PayPal sandbox secret is shared person to person, never in the repo.

MIT licensed.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to request policy-governed payments through MCP tools, with server-side enforcement of spending limits, merchant allow-lists, Pix BR Code validation, approval thresholds, and hash-chained audit logging in a sandbox. It lets agents check wallets, create card or Pix payment intents, and poll or list payments while keeping approval and limit changes out of agent control.
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to use paid MCP tools within a human-approved budget by holding a PayPal sandbox authorization, checking each call against policy, recording usage in a durable ledger, and capturing or voiding the authorization at session close.
    11 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to route PayPal money-moving requests through deterministic spending rules, AI injection and intent checks, human approvals, and tamper-evident audit logging.
    10 npm
    MIT