Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

87 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AgentOps

Give your autonomous agents granular control over execution: financial, operational, and regulatory control for every agent you run.

AgentOps is a spending firewall that sits in front of AI agents. Before an agent can pay for anything, trade anything, or deploy anything on Casper, AgentOps checks it against one company-wide budget and rulebook, reserves the money, and only then produces a signature. Every approval that actually settles is stamped onto Casper through our own contract — live on mainnet.

Infra/API · Security · Casper Network · DeFi · AI Agents

Live app · MCP endpoint · x402 services · npm i @agops-labs/sdk · Mainnet contract

This repository is the client — console, landing page, and visual builder. The engine, contracts, and SDK live in Casper-AGOPS.Server.


The problem

A company gives an employee a corporate card, not the bank account: a limit, a list of approved merchants, a receipt per swipe.

AI agents today get the bank account — a private key sitting inside the agent process, buying APIs, pulling paid data, placing trades, pushing transactions. If that agent is tricked, buggy, or simply over-eager, nothing stands between it and the money.

AgentOps is the corporate card system for AI agents, and Casper is what makes the receipts real.

The clearest way to explain it is to walk through what actually happened when we ran it.


What happened when we ran it

The job we gave a team of AI agents:

"Evaluate a 5 CSPR swap on CSPR.trade. Buy whatever market data you need. Report price, liquidity, slippage, fees, and risk. Wait for me to approve before executing anything."

One job, three different ways to spend money. That's the point.

1 · The agent asked permission before touching anything

It called casper_guard_policy_check — a dry run, like checking a card limit before you swipe. Six checks in one call:

  • Is this agent still active?
  • Is trading an allowed action for it?
  • Is this specific swap inside its scope?
  • Is this network permitted?
  • Is 5 CSPR under its per-transaction limit?
  • Is it under the organization ceiling?

Passed. No money moved.

2 · Two agents bought data over Casper's x402 rail

Each paid endpoint returned a real HTTP 402 naming the asset (WCSPR, a CEP-18 token), the recipient, and the price. AgentOps evaluated policy and, only on ALLOW, produced the PAYMENT-SIGNATURE header the service demands.

Agent Bought Paid Settled on Casper
Trade agent Order-book depth 2 WCSPR e1541674… · block 8434250
Risk agent Risk score 3 WCSPR ac53efe1… · block 8434251
  • Both are real transfer_with_authorization calls on the WCSPR contract
  • Broadcast by the CSPR.cloud hosted facilitator — not by us. The rail is Casper ecosystem infrastructure, not something we simulated
  • Data came back real: best ask $0.05015 · spread 60 bps · risk 32/100 LOW · max size 7.47 CSPR
  • Without the header the service returns 402 and refuses to serve. The block is structural, not advisory

3 · A valid key got refused

We took the trade agent's perfectly working credential and tried to buy the risk agent's data with it:

{
  "outcome": "DENY",
  "reason": "service_not_allowed",
  "policy_id": "…@v2",
  "allowed_resource_ids": ["svc:order-book"]
}

A working key is not the same thing as permission. That is the entire product in one response.

4 · The agent's own account was empty — funded just in time

Each agent transacts from its own Casper account. A fresh one holds no WCSPR and has no purse, so settlement failed on-chain with error 60001. The fix runs after the budget reservation passes and never before:

  1. Wrap CSPR
  2. Dust transfer to create the agent's purse → 25215187…
  3. Move 4 WCSPR into the agent's account → 5d4ca4fc…

The agent is funded for exactly what it was just authorized to spend, at the moment it needs it — never a standing balance it could drain. Policy first, money second.

5 · It stopped and waited for a human

Report written, agent paused. No swap authorization existed. Nothing was reserved. Only after the human approved did it come back and request the 5 CSPR swap.

6 · The money was set aside before the "yes"

When a bank approves a card transaction it doesn't wait for the merchant to charge you — it places a hold immediately so the same money can't be spent twice. AgentOps does the same:

  • Atomically reserves 5 CSPR from the organization budget before returning the authorization
  • The reservation and the solvency check run inside a single script, not next to each other — no gap between "checked" and "acted" for a second agent to slip through
  • Approval is never treated as spending. It's a temporary, policy-bound reservation, open until we learn what really happened

7 · The swap broke. Nothing was lost.

CSPR.trade returned no transaction hash. Twice. AgentOps classified both attempts as terminal failures and released both holds:

  • 0 CSPR of swap principal debited
  • 0 holds left stuck
  • 0 failures reported as settled
  • The earlier 5 WCSPR of purchases still correctly booked
  • Full history exportable as audit JSON

We lead with a failure deliberately, because it's the insight the product is built on:

Saying "yes" is the easy half. Real financial autonomy needs money reserved before the signature and an explicit recovery path after an execution you can't confirm. A system that only says yes or no leaks money the moment reality gets ambiguous.

8 · The receipt went on-chain

The settled authorization was hashed and anchored to our GuardRegistry contract — including a real anchor on Casper mainnet: block 8350189, decision cgd_c8030d99…, hash sha256:6a5fce4f…, 0.6806 CSPR gas against a 3 CSPR limit.

To be exact: we anchor settled authorizations only. Denials and failures stay in the off-chain audit trail and export as signed evidence — we don't burn gas recording things that never moved money.

The loop, end to end:

Intent → Policy check → Budget hold → Fund the agent → Sign
      → Execute → Reconcile what really happened → Anchor the successes to Casper

What's in this repository

The operator-facing surface: the console where a human sets the rules, watches decisions arrive, and funds the fleet.

Area What it does
Console Treasury, agents, policy, decision stream, audit export, members
Visual builder Describe a fleet in plain English → graph → deploy real agents with enforced policy
Landing Product story and live demo entry point
Wallet flows CSPR.click deposit and delegated-key grant, signed in the user's own browser

Visual builder — deploys real enforced policy

An operator describes a fleet in plain English, watches the graph assemble, edits it, clicks Deploy. It's a config surface, not a workflow engine — no node ever "runs." Deploy does exactly three things:

  1. Creates real agents with one-time keys
  2. Writes enforced spend policy through the same code path the firewall checks on every authorization — no second enforcement path to trust
  3. Returns unsigned key-grant handles for the user to sign in their own browser. The server signs nothing here

Policy is attached before any key exists on-chain, so an agent never holds authority without a spend cap already on it.

Delegated keys, signed in the browser

The console never sees the user's master key. A grant is built server-side as an unsigned deploy, handed to the browser, and signed with CSPR.click. The master key never leaves the user.


What's underneath

One budget across three Casper rails

Most spending controls work per-wallet or per-transaction. Companies don't work that way — they have one budget, and it doesn't matter which door the money leaves through.

Rail AgentOps checks
x402 purchase Amount · real recipient · service scope · velocity · budget
CSPR.trade swap Amount · slippage · risk label · action scope · budget
Casper deploy Network · contract and action scope · amount · budget

An agent cannot exhaust its allowance buying data and then quietly keep spending the same budget through the trading rail. That gap is precisely where an autonomous agent gets expensive.

Agents never hold a signing key

An agent holds an API key. Signing happens server-side inside a vault, after the policy check. There is nothing for the agent to sign with — so there is no path around the firewall.

A kill-switch enforced by Casper, not by us

Instead of our server holding a key, each agent gets its own weight-1 key on the user's own Casper account. Full lifecycle, proven on testnet:

Step Transaction
D1 Grant — agent key at weight 1, master raised to 3 97c50ddf…
D2 Agent transacts completely alone — signed with only the agent's key 426495a5…
D3 Revoke — agent key removed 0a6cce33…
D4 The node itself rejects the agent: "invalid associated keys" (rejected — no hash, by design)

D4 is the payoff: after revocation the agent is stopped at the Casper protocol level, not by our policy. Our backend could be offline, compromised, or gone, and the agent still cannot spend.

One detail worth a moment: the obvious implementation bricks the account. The agent must transact alone (deployment threshold 1) but must never touch key management (threshold 3). Naively adding the agent at weight 1 and raising key-management to 3 leaves master(1) + agent(1) = 2, which can never reach 3 — so nobody can ever manage keys on that account again. Our grant raises the master's own weight to 3 in the same deploy, so the master alone still clears the bar.

GuardRegistry — the receipt layer

A deliberately tiny contract: anchor_decision, get_anchor, total_anchored. About 55 lines.

  • Append-only and immutable by construction — the same hash again is a harmless no-op; a different hash for an existing decision reverts
  • History cannot be rewritten. Not by an attacker, not by us, not by the contract owner
  • Emits an event per anchor, so anchors can be counted from the chain without trusting our database
  • Deployed to testnet and mainnet with zero logic changes
  • We anchor a hash, not the decision: the audit payload stays off-chain and exportable, the chain holds the tamper-evidence

Live MCP tools — no SDK required

Claude Code, or any MCP-compatible agent, can use AgentOps right now.

Group Tools For
Discover list_services, legal_context, trade_data Find paid services, fetch terms, read live market data
Decide policy_check, authorize_payment, authorize_action Dry-run, or get a real signed authorization
Settle & prove reconcile, decision_status, audit_export Confirm settlement, anchor to Casper, export audit JSON
Govern the fleet create_agent, attach_trading_flow, revoke_agent Operator-only: provision, attach policy, hard-stop

SDK — published and installable

npm i @agops-labs/sdk

  • createGuardedFetch — drop-in replacement for fetch that runs the whole x402 handshake (call → 402 → policy check → attach signed header → retry) in one line
  • Non-402 responses pass straight through, so it's safe as an agent's only fetch
  • A refusal arrives as a typed PaymentDeniedError carrying the reason and decision ID — not a mystery 402

Every other agent-payment SDK gets this ergonomic by putting a private key in the agent process. Here the agent holds only an API key, so the convenience costs nothing in blast radius.

Policy and budget engine

Policy: organization / team / agent-level rules · spend caps and per-transaction limits · hourly velocity controls · service and destination allowlists · network and action restrictions · immutable policy versioning (every decision cites the exact rulebook version that judged it) · human approval boundaries · org-wide emergency suspension.

Money: atomic reservation before authorization · double-spend protection · durable decision lifecycle with terminal-failure and expiry handling · automatic hold release · exact integer accounting, no floats · append-only double-entry ledger.


Running the console locally

pnpm install
cp .env.example .env.local     # point CASPER_GUARD_API_BASE_URL at the server
pnpm dev                       # http://localhost:3000
Command What it does
pnpm dev Development server
pnpm build Production build
pnpm test Unit tests (Vitest)
pnpm test:e2e End-to-end tests (Playwright)
pnpm lint ESLint
pnpm typecheck TypeScript, no emit

Stack — Next.js 15 (App Router) · React 19 · TypeScript · Tailwind CSS 4 · Zod · CSPR.click · React Flow.

The console is a thin, server-rendered layer over the AgentOps API. It holds no keys and no policy logic of its own: every rule shown here is enforced by the server on every authorization, whether or not the console is running.


Verify it yourself

# 1. The mainnet contract exists and holds real anchors
casper-client query-global-state --node-address https://node.mainnet.casper.network/rpc \
  --key hash-a003b2c32c6c7bddbd51d9596a31af72e0cdad62268a3747147d809add7ff629

# 2. A real decision from the running system, anchored on Casper mainnet
casper-client get-transaction --node-address https://node.mainnet.casper.network/rpc \
  0287e36aa351d850c6acb460147a6c8d767755cae3cec5dd2fb4aae6ece0478e

# 3. The live MCP server exposes its tools
curl -s -X POST https://casper-agopsserver-production.up.railway.app/v1/casper-guard/mcp \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq '.result.tools[].name'

# 4. The x402 service really demands payment in WCSPR
curl -s -X POST https://casper-agopsservice-production.up.railway.app/risk-oracle/score \
  -H 'content-type: application/json' -d '{"pair":"CSPR-USDC","side":"buy","size_motes":"1000000000"}'
# → HTTP 402 { "x402Version":2, "accepts":[{ "asset":"3d80df21…", "payTo":"0060854d…" }] }

# 5. The SDK is public
npm view @agops-labs/sdk

Every on-chain operation

All pulled from a Casper node; error_message was null on all of them.

# Network What Transaction
M1 mainnet GuardRegistry install · chain casper e008a246…
M2 mainnet anchor_decision — real decision anchored · block 8350189 0287e36a…
T1 testnet Order-book x402 payment · 2 WCSPR · block 8434250 e1541674…
T2 testnet Risk-oracle x402 payment · 3 WCSPR · block 8434251 ac53efe1…
T3 testnet GuardRegistry anchor · block 8461081 a4eb2071…
T4 testnet GuardRegistry install · block 8281294 1378aa7e…72c8dfb68
D1 testnet Grant delegated key · block 8599174 97c50ddf…
D2 testnet Agent transacts alone · block 8599184 426495a5…
D3 testnet Revoke delegated key · block 8599188 0a6cce33…
D4 testnet Revocation enforced by the node"invalid associated keys" (rejected by design)
F1 testnet Purse-creation dust transfer · block 8623650 25215187…
F2 testnet 4 WCSPR transfer to the agent · block 8623650 5d4ca4fc…

Contracts

  • GuardRegistry mainnet — package a003b2c3… · contract 3f4e5a7c…0802ce54ccd
  • GuardRegistry testnet — package 850b5056…a9e7d7ed · contract 4aac5aaa…c2b61671
  • WCSPR (CEP-18) — 3d80df21…1314847c1e · CSPR.trade's contract, not ours; we only call its entry points

Links

Source


Closing

AI agents are going to buy services, allocate budgets, and push blockchain transactions without a human approving every step. That isn't a prediction — it already happened here. The hard part was never giving an agent money; it's keeping control when the agent, the payment rail, the service provider, or the execution path behaves in a way nobody planned for.

Intent judged before signing. Money reserved before execution. Funding released only against an approval. Outcome confirmed before it's trusted. Proof anchored after success. And a kill-switch the Casper network itself enforces.


LicenseApache 2.0 · ContributingCONTRIBUTING.md · Code of conductCODE_OF_CONDUCT.md

About

AI-powered multi-agent operations platform built on Casper Network — autonomous agent orchestration, on-chain policy enforcement, and real-time compliance.

Topics

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages