Agent Control

Quick start

Get set up in a few minutes

1-day trial. Agent payments control with spend limits you set. You keep the keys.

Works on

  • Solana
  • Ethereum
  • Base
  1. 01

    Create an account

    Start a 1-day (24 hour) trial. No card.

  2. 02

    Add an agent wallet

    Paste the address. You keep the keys.

  3. 03

    Set spend rules

    A daily cap and where they can send.

  4. 04

    Connect your agent

    Give it an API key. They ask before they pay. You keep the keys.

    How to connect →
  5. 05

    Watch the console

    New or over-limit payments wait in Approval Inbox. Agent Audit builds an on-demand Excel, PDF, or CSV of the check trail. Pause if something looks wrong.

The check only works if you connect your agent. If it skips the check, Inbox cannot stop that send.

New or over-limit payments wait in Approval Inbox: Allow once, always allow that address, or block. No action for 10 minutes = block — the agent must stop / does not send. When a payment is waiting for you, optional email (Settings → Email alerts) and a Slack incoming webhook (if you set the URL in Settings) can ping you with a link to Approval Inbox. Pause and blocklists stop the send right away. Agent Audit generates an on-demand Excel, PDF, or CSV of the Agent Control trail — not a full chain explorer or a replay of every on-chain transfer. Nothing is auto-emailed from Agent Audit. Optional warning alerts can also ping you for a policy alert or spend near the daily cap.

Popular agent payment tools

Connect your agent

Connect your agent so it asks Agent Control before it sends money. You set a spend limit. Over-limit and new addresses wait in Approval Inbox. You keep the keys. External audit for your agents on Solana, Ethereum, and Base.

Works with AgentKit, x402, or any agent that can ask before it sends.

How it works

They ask before they pay. You keep the keys. Starter $29 — 1-day trial, then Pay $29. External audit for your agents.

  1. 1

    Get an API key

    Start the free trial. Add the wallet. Set a daily spend limit. Copy your key.

  2. 2

    Plug it in

    Before your agent sends money, it asks Agent Control first. Works with AgentKit, x402, or MCP — popular agent payment tools. If we say stop, it does not send.

  3. 3

    Try it free

    Full dashboard for 1 day. Over-limit and new addresses wait for you.

  4. 4

    Then Pay $29

    Unlock with $29 USDC on Base, Solana or Ethereum. No card. No KYC.

Same check wherever they pay from. See the connect steps →

  1. 1

    Sign up

    Start at agent-control.net. 1-day trial, no card.

  2. 2

    Enroll the wallet

    Add the agent wallet address. You keep the keys.

  3. 3

    Set policy

    Daily and per-tx caps, plus destinations.

  4. 4

    Create an API key

    Issue an agent API key in the console.

  5. 5

    They ask before they pay

    The agent asks Agent Control first. If the check says stop, do not send.

  6. 6

    Inbox and Audit

    Open Approval Inbox for waiting payments (Allow once / Always allow this address / Block). Open /audit for an on-demand Excel, PDF, or CSV trail.

Coinbase AgentKit (and similar)

If your agent already asks before it sends — like Coinbase AgentKit — send that ask to Agent Control. You set the limit. Over the line → hold vs block.

  • You set the spend limit in Agent Control.
  • The agent asks before every send.
  • Under the limit, it can send.
  • Over the line: over-limit or new addresses wait for you. Block means do not send.
  • You keep the keys.

That ask is POST /api/v1/check:

fetch("https://agent-control.net/api/v1/check", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_AGENT_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ to: destination, value_usd: amount }),
})

If the check says stop, do not send. Prefer the adapter if you do not want to write fetch yourself.

Adapters

Drop-in helpers so you do not write fetch yourself. They only call the same check. Connect your agent. You keep the keys.

Allow means send. Wait is a hold — you decide in Approval Inbox (hold vs block). Stop means do not send.

Coinbase AgentKit — pass the policy helper:

import { createAgentKitPolicyProvider } from "./src/adapters/agentkit.ts";

const policyProvider = createAgentKitPolicyProvider({
  apiKey: process.env.AGENT_CONTROL_API_KEY,
});
// Pass policyProvider into AgentKit BasePayConfig

Daily cap + approval threshold recipe: Policy recipe. Partner signup with ?partner=agentkit.

x402 — run the same check before money moves:

import { createX402BeforePaymentHook } from "./src/adapters/x402.ts";

client.onBeforePaymentCreation(
  createX402BeforePaymentHook({ apiKey: process.env.AGENT_CONTROL_API_KEY }),
);

Copy src/adapters from the repo. If the check says stop, do not send. Wallet and runtime partners: /partners.

AgentKit policy recipe

Daily cap + approval threshold, then Connect your agent. Copy this tiny createAgentKitPolicyProvider helper. You keep the keys.

  1. In the console, set a daily cap and an approval threshold (max single send).
  2. Create an API key for that agent.
  3. Connect your agent with this helper. Over the line → hold vs block. You keep the keys.
import { createAgentKitPolicyProvider } from "./src/adapters/agentkit.ts";

const policyProvider = createAgentKitPolicyProvider({
  apiKey: process.env.AGENT_CONTROL_API_KEY,
});
// Pass policyProvider into AgentKit BasePayConfig

Same check as adapters. If the check says stop, do not send.

Action Gate

Before your agent posts to Slack or changes the CRM, it stops. You tap go, stop, or wait. If you do not answer in 10 minutes, it stops. $49 a month, paid in USDC on Base, Solana or Ethereum. You keep the keys.

The agent wants to post in Slack: "We are investigating the checkout errors." Nothing goes out. You tap go, stop, or wait. If you do not answer in 10 minutes, it stops. A CRM write waits the same way. After you tap go, that Slack post or CRM write can go out. You keep the keys.

Email send stops until email is connected. Nothing is sent.

Pay $49

We accept USDC on Base, Solana and Ethereum. No card. /billing/pay?plan=action

Ask: call check_action (or ask_human). The agent still executes after go. Enforce: call the Write Gate tools email.send, slack.post, and crm.write. Those tools run the same check, then forward only when the decision is go. If the decision is wait, poll get_approval and call the tool again with approval_id. The agent cannot skip the check. Same $49 Action Gate seat (plan=action). Not a second plan.

Durable decisions use DATABASE_URL (Neon already on this project) and migrations/0022_action_gate.sql, applied on boot. If that variable is missing, the check returns stop.

Ask: MCP check_action (alias ask_human) takes the same fields. If decision is wait, poll get_approval until go or stop. No decision in 10 minutes = stop. The agent still executes after go. Enforce: MCP email.send, slack.post, and crm.write. Write Gate forwards only on go. Same $49 seat (plan=action). You keep the keys.

slack.post

curl -s https://agent-control.net/api/v1/check_action \
  -H "Authorization: Bearer YOUR_AGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action_type":"slack.post","summary":"Post the incident note","preview":"We are investigating the checkout errors.","target":"#support","risk":"medium"}'

crm.write

curl -s https://agent-control.net/api/v1/check_action \
  -H "Authorization: Bearer YOUR_AGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action_type":"crm.write","summary":"Update the deal stage","preview":"Move Acme to Closed Won.","target":"deal_8841","risk":"high"}'

email.send

Email send stops until email is connected. Nothing is sent.

curl -s https://agent-control.net/api/v1/check_action \
  -H "Authorization: Bearer YOUR_AGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action_type":"email.send","summary":"Send the order update","preview":"Hi — your order shipped today.","target":"customer@example.com","risk":"high"}'
# Ask: MCP tools/call check_action  (ask_human is the same tool)
# then poll get_approval with approval_id until go or stop
# Enforce: MCP tools/call email.send | slack.post | crm.write
# wait → poll get_approval → call the same tool with approval_id
# Write Gate forwards only on go

Hold notifications

When a payment is waiting for you, we reuse the same email and Slack paths already in Settings. No extra vendor.

  • Email alerts (on by default) send a link to Approval Inbox.
  • Paste a Slack incoming webhook URL in Settings to get the same ping there.
  • No action within 10 minutes = block — the agent must stop / does not send.

Coding agents (Cursor and similar) connect the same way: give the agent the API key, then have it ask Agent Control first. The MCP path is Streamable HTTP: POST JSON-RPC to /api/v1/mcp and the server answers as JSON or as a short event stream, with a session header on initialize. Tools: check_transfer, check_action, email.send, slack.post, crm.write, get_approval, get_agent_status, plus storefront get_pricing, start_trial, attach_human, create_checkout, and get_status. If the check says stop, do not send. If the agent skips the check, Inbox cannot stop that send — funds can move. How to add the connector in Cursor or Grok: Connectors.

Connectors

External audit for your agents. Connect your agent from Cursor, Grok, or Claude so it can ask before a send. You keep the keys. The live MCP is Streamable HTTP at https://agent-control.net/api/v1/mcp. get_pricing is public. Spend, checkout, and status need an agent API key (Authorization: Bearer, env AGENT_CONTROL_API_KEY) or a Claude Connector OAuth token.

  1. Cursor Customize / MCPs. Open Customize, then MCPs. Add a remote server. Paste the URL. Add the Bearer header. Or load this repo as a local plugin and set the key under Plugins → Configure.
  2. Grok Bot Plugins. Once listed, add Agent Control from Settings → Plugins. Until then, custom add: same URL and Bearer header.
  3. Grok.com → connectors → Custom. New Connector, then Custom. Paste the same URL. When asked for auth, use Authorization: Bearer plus the agent API key.
  4. Claude Connectors. Same MCP URL. Claude signs in with OAuth (authorization code + PKCE). You stay the customer of record. You keep the keys. Cursor and Grok Bearer keys still work.

After connect: have it ask Agent Control first. Over-limit and new addresses wait in Approval Inbox. If the agent skips the check, Inbox cannot stop that send.

Using Grok Bot, Muse or any other agent app

Free MCP, no sign-in needed: https://agent-control.net/api/v1/mcp. Free tools: list_your_agent, browse_agents, list_open_jobs, post_job.

Grok Bot, Muse, or any other agent app that lets you add an MCP server. Paste this:

Add the MCP server at https://agent-control.net/api/v1/mcp, then use list_your_agent to list yourself in the Agent Control directory, free.

If the app cannot add an MCP server, paste this:

Read https://agent-control.net/skill.md and follow it

Listing is free. Featured pins it for 7 days for $19 USDC (Base, Solana or Ethereum).

Agent storefront

Price, trial, and checkout for agents

Agents find us via /llms.txt and MCP. A human principal signs up and owns billing and Approval Inbox; agents connect under that account. You keep the keys.

1-day trial, no card, no KYC. Then Starter $29 / Pro $49 / Team $149 in USDC on Base, Solana or Ethereum. The agent opens the pay request. The human pays. Agents cannot decide Approval Inbox.

  1. 1

    Read pricing

    GET /api/v1/storefront/pricing or MCP get_pricing. No API key.

    fetch("https://agent-control.net/api/v1/storefront/pricing")
  2. 2

    Start a trial for a human

    POST /api/v1/storefront/trial with that person's email. Agents cannot open a root account. attach_human is the same idea when you already have a principal.

    fetch("https://agent-control.net/api/v1/storefront/trial", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ human_email: "ops@example.com" }),
    })
  3. 3

    Start checkout

    POST /api/v1/billing/checkout with the agent API key. That opens a pay request for the human principal. The human pays in USDC on Base, Solana or Ethereum. Plan action opens the $49 Action Gate seat. Slack and CRM wait for a person. Email send stops until email is connected.

    fetch("https://agent-control.net/api/v1/billing/checkout", {
      method: "POST",
      headers: {
        Authorization: "Bearer YOUR_AGENT_API_KEY",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ plan: "action" }),
    })

    Wallet console plans stay starter, pro, or team. Send plan starter for the $29 seat.

GET /api/v1/storefront/status returns that human's trial or plan. MCP tools: get_pricing, start_trial, attach_human, create_checkout, get_status. Then connect your agent so every send asks Agent Control first.

Wallet Spend Audit · $49 USDC

External audit for your agents

They ask before they pay. You keep the keys. Within policy = auto. Outside policy = stop.

You keep the keys. Meter is separate — never mix.

Not a package scanner.

Started on Starter? Wallet Spend Audit adds clearer audit reports when you need proof of what your agents tried to pay.

  1. 1

    Paste a wallet

    Open /spend-audit. Solana or 0x. You keep the keys.

  2. 2

    Pay $49 USDC

    USDC on Base (EIP-3009 exact) or Solana (Solana Pay with the invoice reference). You keep the keys. Meter is separate — never mix. GET /api/v1/audit/pricing then POST /api/v1/audit/invoice.

  3. 3

    Download the report

    PDF or CSV of outbound transfers in a 30-day lookback: over-cap days vs a hypothetical $100/day cap, unknown destinations, sink-like addresses.

Agent Meter

Agents pay themselves

Buy looks_20 pack ($0.20) or look $0.10. Stamp ticket $0.05.

Separate from the Human App. Then scan and preflight. No inbox. No email, no API key, no Approval Inbox.

Can I pay this address? Buy looks_20 pack ($0.20) or look $0.10. Stamp ticket $0.05. ok | new | warn | sink. Packs: looks_20 $0.20. addresses_100 $0.15. Ticket: stamp_tx $0.05. Take this ticket or we do not take your USDC. USDC on Base (Solana also accepted). Base is EIP-3009 exact to base_pay_to (CDP/AgentKit). No Solana key needed. After meter_buy_pass, the 402 includes sign_exact and adapter_snippet so CDP/AgentKit can finish in-process. Copy src/adapters/meter-pay-base.ts — signExact, then meter_watch with { invoice_id, payment } (full x402 v2 object, not a raw signature). Optional Solana: src/adapters/meter-pay.ts to pay_to with the 402 reference. Send X-Agent-Pass. No free looks. 402 looks_20 $0.20 pack (look $0.10 is optional one-shot) before the first scan. No email. No Phantom. On a laptop with Phantom, you can still open /meter/pay?invoice_id= plus the invoice id.

# 1 discover
# https://agent-control.net/llms.txt
curl -s https://agent-control.net/api/v1/meter/pricing
# 2 look — Buy looks_20 pack ($0.20) or look $0.10. Stamp ticket $0.05. One address. ok | new | warn | sink
# No free looks. 402 looks_20 $0.20 pack (look $0.10 is optional one-shot) before the first scan.
curl -s -X POST https://agent-control.net/api/v1/meter/scan -H 'content-type: application/json' -H 'X-Agent-Pass: <your-id>' -d '{"chain":"solana","address":"<destination>"}'
# 3 POST /api/v1/meter/pass → 402 looks_20 $0.20 pack. Empty body {} = looks_20; {"sku":"look"} = $0.10 one-shot. Prefer Base USDC (EIP-3009 exact) to base_pay_to (CDP/AgentKit). No Solana key needed. Solana USDC to pay_to WITH reference is optional
curl -s -X POST https://agent-control.net/api/v1/meter/pass -H 'content-type: application/json' -d '{}'
# copy src/adapters/meter-pay-base.ts — Base EIP-3009 exact (CDP/AgentKit). We never take keys.
# https://raw.githubusercontent.com/Cobra-bit-prog/agent-guard/main/src/adapters/meter-pay-base.ts
import { buyMeterPassBase } from "./src/adapters/meter-pay-base.ts";
await buyMeterPassBase({ from, signExact });
# MCP-native (no Solana key): meter_buy_pass (looks_20) → Base sign_exact → meter_watch({invoice_id, payment}) → token → meter_scan
# Buy looks_20 pack ($0.20) → X-Agent-Pass. look $0.10 is optional one-shot. GET /api/v1/meter/pricing (paid_sku looks_20, free_looks=0). We never take keys.
# 4 watch
# Base: POST /api/v1/meter/watch with { invoice_id, payment } = full x402 v2 object from payMeterPassBase / sign_exact. NOT a raw signature string. NOT invoice_id-only for Base.
curl -s -X POST https://agent-control.net/api/v1/meter/watch -H 'content-type: application/json' -d '{"invoice_id":"inv_…","payment":{"x402Version":2,"payload":{"authorization":{},"signature":"<sig>"},"accepted":{"network":"base"}}}'
# 5 packs looks_20 $0.20 · addresses_100 $0.15 · stamp_tx $0.05 ticket
# Take this ticket or we do not take your USDC.
# 6 MCP meter_* at /api/v1/mcp
import { buyMeterPassBase } from "./src/adapters/meter-pay-base.ts";
await buyMeterPassBase({ from, signExact });
  1. 1

    Discover

    Read /llms.txt then GET pricing. Public. No key.

    curl -s https://agent-control.net/api/v1/meter/pricing
  2. 2

    Look

    Can I pay this address? Buy looks_20 pack ($0.20) or look $0.10. Stamp ticket $0.05. ok | new | warn | sink. Never hold. No free looks. 402 looks_20 $0.20 pack before the first scan.

    curl -s -X POST https://agent-control.net/api/v1/meter/scan -H 'content-type: application/json' -H 'X-Agent-Pass: <your-id>' -d '{"chain":"solana","address":"<destination>"}'
  3. 3

    Pay a pack

    looks_20 $0.20 pack (20 looks). look $0.10 is optional one-shot. Prefer Base USDC (EIP-3009 exact) to base_pay_to (CDP/AgentKit). No Solana key needed. Copy src/adapters/meter-pay-base.ts. Optional Solana: pay_to with the reference via meter-pay.ts. We never take keys. No Phantom. Not pass_1h.

    import { buyMeterPassBase } from "./src/adapters/meter-pay-base.ts";
    await buyMeterPassBase({ from, signExact });
  4. 4

    Watch

    Base: POST /api/v1/meter/watch with invoice_id plus the full x402 v2 payment object from payMeterPassBase / sign_exact — not a raw signature string, not invoice_id-only. Until token → X-Agent-Pass. Adapter: https://raw.githubusercontent.com/Cobra-bit-prog/agent-guard/main/src/adapters/meter-pay-base.ts

    curl -s -X POST https://agent-control.net/api/v1/meter/watch -H 'content-type: application/json' -d '{"invoice_id":"inv_…","payment":{"x402Version":2,"payload":{"authorization":{},"signature":"<sig>"},"accepted":{"network":"base"}}}'
  5. 5

    Packs and ticket

    Packs: looks_20 $0.20. addresses_100 $0.15. Ticket: stamp_tx $0.05. Take this ticket or we do not take your USDC. Then MCP meter_* tools.

    curl -s -X POST https://agent-control.net/api/v1/meter/scan -H 'content-type: application/json' -H 'X-Agent-Pass: <pass>' -d '{"chain":"solana","address":"<destination>"}'
    curl -s -X POST https://agent-control.net/api/v1/meter/preflight -H 'content-type: application/json' -H 'X-Agent-Pass: <pass>' -d '{"chain":"solana","wallet":"<wallet>","to":"<destination>","value_usd":10,"cap_usd":100}'

Scan never blocks a send. ok | new | warn | sink. Preflight is allow or stop. Never hold. No inbox. Machine brief: /llms.txt. Discovery: llms → pricing → 402 → MCP. MCP: meter_pricing, meter_buy_pass, meter_watch, meter_scan, meter_preflight, meter_scan_batch, meter_stamp, meter_verify_stamp. Take this ticket or we do not take your USDC.

Stamp seller

Take this ticket or we do not take your USDC.

You sell something. An agent wants to pay you in USDC. Ask for a stamp first. If the stamp is missing or says stop, do not take the USDC.

Can I pay this address? Buy looks_20 pack ($0.20) or look $0.10. Stamp ticket $0.05.

  1. 1

    Ask for the ticket

    Tell the agent: buy stamp_tx $0.05, then call meter_stamp. Can I pay this address? Buy looks_20 pack ($0.20) or look $0.10. Stamp ticket $0.05.

  2. 2

    Take the stamp_id

    They send you a stamp_id. Public verify. No email. No API key.

  3. 3

    Verify, then take USDC

    GET /api/v1/meter/stamp/:id or MCP meter_verify_stamp. If verified is true and decision is allow, take the USDC. If not, do not take it.

  4. 4

    Or hit the live gate

    GET https://agent-control.net/api/v1/gate/demo. Header X-Stamp-Id. No allow stamp → 402 stamp_tx $0.05. Allow → 200.

curl -s https://agent-control.net/api/v1/meter/stamp/<stamp_id>

One-file recipe: stamp.txt

curl -s https://agent-control.net/stamp.txt
# Stamp seller
# https://agent-control.net/stamp.txt
# Take this ticket or we do not take your USDC.
# Seller page: https://agent-control.net/stamp
# Separate from the Human App. Agents pay themselves. No inbox. No email. No API key. No Approval Inbox.
# Shop Shield $49/mo — pay at /billing/pay?plan=shield
# Can I pay this address? Buy looks_20 pack ($0.20) or look $0.10. Stamp ticket $0.05.
# Packs: looks_20 $0.20. addresses_100 $0.15. Ticket: stamp_tx $0.05.
# Base USDC (EIP-3009 exact) and Solana USDC. pass_1h catalog-only.
# 1 agent buys stamp_tx $0.05 via Meter 402
curl -s -X POST https://agent-control.net/api/v1/meter/pass -H 'content-type: application/json' -d '{"sku":"stamp_tx"}'
# 402 stamp_tx $0.05. Prefer Base USDC (EIP-3009 exact) to base_pay_to (CDP/AgentKit). No Solana key needed. Solana USDC to pay_to WITH reference is optional. We never take keys.
# copy src/adapters/meter-pay-base.ts
# https://raw.githubusercontent.com/Cobra-bit-prog/agent-guard/main/src/adapters/meter-pay-base.ts
import { buyMeterPassBase } from "./src/adapters/meter-pay-base.ts";
await buyMeterPassBase({ from, signExact, sku: "stamp_tx" });
# MCP: meter_buy_pass sku stamp_tx → Base sign_exact → meter_watch({invoice_id, payment}) → token
# Base: POST /api/v1/meter/watch with { invoice_id, payment } = full x402 v2 object from payMeterPassBase / sign_exact. NOT invoice_id-only for Base.
curl -s -X POST https://agent-control.net/api/v1/meter/watch -H 'content-type: application/json' -d '{"invoice_id":"inv_…","payment":{"x402Version":2,"payload":{"authorization":{},"signature":"<sig>"},"accepted":{"network":"base"}}}'
curl -s -X POST https://agent-control.net/api/v1/meter/stamp -H 'content-type: application/json' -H 'X-Agent-Pass: <token>' -d '{"decision":"allow","chain":"solana","to":"<merchant>"}'
# 2 merchant verifies free at https://agent-control.net/stamp or GET /api/v1/meter/stamp/:id or MCP meter_verify_stamp. Public. No email. No API key.
curl -s https://agent-control.net/api/v1/meter/stamp/<stamp_id>
# Same GET with the seller slug. Browser preflight allows X-Seller.
curl -s https://agent-control.net/api/v1/meter/stamp/<stamp_id> -H 'X-Seller: your-slug'
# 3 merchant only accepts USDC if verified is true and decision is allow. If not, do not take the USDC.
# Take this ticket or we do not take your USDC.
# 4 dogfood gate. Live on this site. GET or POST /api/v1/gate/demo. Header X-Stamp-Id. No valid allow stamp → 402 stamp_tx $0.05. verified true and decision allow → 200.
curl -s -D - https://agent-control.net/api/v1/gate/demo
# blocked. Buy stamp_tx, mint allow, pass the stamp id:
curl -s -D - https://agent-control.net/api/v1/gate/demo -H 'X-Stamp-Id: <stamp_id>'
# Merchant copy: src/adapters/stamp-gate.ts
# https://raw.githubusercontent.com/Cobra-bit-prog/agent-guard/main/src/adapters/stamp-gate.ts
# 5 drop-in. Header X-Stamp-Id. Take this ticket or we do not take your USDC.
# You sell something. An agent wants to pay you in USDC. Ask for a stamp first. If the stamp is missing or says stop, do not take the USDC.
# Next.js App Router route handler
import { requireMerchantStamp } from "./stamp-gate.ts";
export async function POST(req: Request) {
  const gate = await requireMerchantStamp(req, { seller: "your-slug" });
  if (!gate.ok) return Response.json(gate.body, { status: gate.status });
  // stamp is allow: take the USDC and serve the request
  return Response.json({ ok: true, stamp_id: gate.stamp_id });
}
# Express middleware
app.use(async (req, res, next) => {
  const gate = await requireMerchantStamp(req, { seller: "your-slug" });
  if (!gate.ok) return res.status(gate.status).json(gate.body);
  return next();
});
# Hono
app.use(async (c, next) => {
  const req = c.req.raw;
  const gate = await requireMerchantStamp(req, { seller: "your-slug" });
  if (!gate.ok) return c.json(gate.body, gate.status);
  await next();
});

Seller page: /stamp. MCP meter_stamp then meter_verify_stamp. Public. No email. No API key.

Compare

When to use Agent Control

Agent payments control for agent wallets. Not a package scanner. Not a firewall you run on your own machine. Not a control plane or cards. You keep the keys. You can use a DIY firewall or a control plane beside us.

vs a package scanner

Them. They scan code packages.

Us. Agent payments control — spend limits, approval before agent send, Approval Inbox, Agent Audit on wallet sends.

Pick us when the risk is an agent spending crypto, not a code package.

vs a firewall you run yourself

Them.

  • A firewall you run on your own machine
  • For EVM and x402
  • You run it yourself

Us.

  • Hosted Approval Inbox and Agent Audit
  • Solana, Ethereum, and Base
  • You set the limits. You keep the keys.

They run on your machine. We host the human inbox. You can use both.

vs a control plane or cards

Them.

  • Control plane or cards
  • Or DIY libs you run yourself

Us.

  • Hosted Approval Inbox and Agent Audit
  • Solana, Ethereum, and Base
  • You keep the keys.

You can use both. They are a control plane or cards. We sit beside the wallet you already have.

vs a wallet or key host

Them. Wallets and keys.

Us. Connect your agent. We answer allow / hold vs block. You keep the keys.

Pick us when you already have keys and need hold vs block plus an agent wallet audit.

When to use us

Use Agent Control when an operator runs agent wallets that can send crypto and needs spend limits, approval before agent send, and an agent wallet audit trail — External audit for your agents — without giving up custody.

Partners

Wallet and runtime partners

Agent Control complements wallets and runtimes (Turnkey, Privy, Coinbase, x402) — it does not replace them. Non-custodial external audit: spend limits, Approval Inbox (hold vs block), and Agent Audit. You keep the keys. Partner page. Adapters: Connect your agent. First-touch links use ?partner= on signup.

For builders · API details

Give the agent its API key. Before every send it should call the check. If must_abort is true, do not send. Pause and denylist still block (never hold). Off-policy or first-time destinations return hold with poll_url — poll until allow or block (10-minute TTL; expired holds are a block).

curl -s https://agent-control.net/api/v1/check \
  -H "Authorization: Bearer YOUR_AGENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to":"<destination>","value_usd":2400}'

Hold response includes poll_url and approval_id. MCP tool get_approval polls the same decision. Same tools on Streamable HTTP POST /api/v1/mcp: check_transfer, get_approval, get_agent_status, plus storefront get_pricing, start_trial, attach_human, create_checkout, get_status.

Machine-readable product brief: /llms.txt.