Agent Spend Guard — owner-set purchasing guardrails

Free spend guardrails for AI agents: approve/deny/ask_user, caps, dupes.

Should I use this

Quality & Safety

B
Description quality
100%
Schema completeness
73%
Naming quality
80%
Poisoning risk
20%
Permission match
100%
Protocol compliance
100%

Findings (5)

  • HIGHTool poisoning patterns detected
  • MEDIUMTool description contains URL to non-standard domainin spend_guard_check_purchase
  • MEDIUMTool description contains URL to non-standard domainin spend_guard_record_purchase
  • MEDIUMTool description contains URL to non-standard domainin spend_guard_set_rules
  • MEDIUMTool description contains URL to non-standard domainin spend_guard_report

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~2,169Tokens (tool definitions)
~3.5 KBTypical response size
Moderate attention impact (1.69% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

{
  "mcpServers": {
    "agent-spend-guard": {
      "url": "https://a2awire.com/mcp/connectors/spend-guard/http"
    }
  }
}

Remote endpoints

https://a2awire.com/mcp/connectors/spend-guard/httpstreamable-http

What it can do

Tool inventory

Tools (4)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟡spend_guard_check_purchase(merchant, amount_usd, currency, category, description, ...)

Humans: sign up with your email at https://a2awire.com/api-key and create an API key, then hand it to your agent (it sends Authorization: Bearer <key> or X-API-Key with every call). Agents without an account: a reviewable bootstrap script is served at https://a2awire.com/api/v1/connectors/spend-guard/bootstrap.sh (download it, read it, then run it to mint a key). Call BEFORE checkout. Evaluate a proposed purchase (merchant, amount_usd) against the owner's spend rules and recent ledger. Returns a decision (approve, deny, or ask_user), a plain-English reason, the remaining monthly budget when a cap is set, and a check_id. deny means denylisted merchant or over the monthly cap; ask_user means above the per-purchase threshold or a possible duplicate of a purchase in the last 10 minutes. Optional tx_ref is your idempotency key for this purchase; pass the same value to spend_guard_record_purchase afterwards. Appends a check event; checks never consume budget. USD only (the currency argument is kept for forward compatibility; any other value is rejected). Not guest-callable. REST: POST /api/v1/spend-guard/check.

Input Schema

{
  "type": "object",
  "properties": {
    "merchant": {
      "maxLength": 200,
      "minLength": 1,
      "title": "Merchant",
      "type": "string"
    },
    "amount_usd": {
      "anyOf": [
        {
          "exclusiveMinimum": 0,
          "maximum": 100000,
          "type": "number"
        },
        {
          "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
          "type": "string"
        }
      ],
      "title": "Amount Usd"
    },
    "currency": {
      "default": "USD",
      "description": "USD only. Kept for forward compatibility; any other value is rejected.",
      "maxLength": 8,
      "title": "Currency",
      "type": "string"
    },
    "category": {
      "anyOf": [
        {
          "maxLength": 100,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Category"
    },
    "description": {
      "anyOf": [
        {
          "maxLength": 500,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Description"
    },
    "tx_ref": {
      "anyOf": [
        {
          "maxLength": 200,
          "minLength": 1,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Optional idempotency key for this purchase; pass the same value to the record call afterwards. Checks are exempt from the uniqueness constraint that applies to recorded purchases.",
      "title": "Tx Ref"
    }
  },
  "required": [
    "merchant",
    "amount_usd"
  ],
  "additionalProperties": false,
  "description": "Arguments for ``spend_guard_check_purchase`` (call BEFORE checkout).\n\nThe owner is derived from the authenticated principal, never from the\narguments. ``tx_ref`` is optional here; reuse the same value on\n``spend_guard_record_purchase`` so the check and its record share one\nidempotency key. ``currency`` is USD only; the field is kept for forward\ncompatibility and any other value is rejected.",
  "title": "SpendGuardCheckPurchaseInput"
}
🟡spend_guard_record_purchase(merchant, amount_usd, currency, category, description, ...)

Humans: sign up with your email at https://a2awire.com/api-key and create an API key, then hand it to your agent (it sends Authorization: Bearer <key> or X-API-Key with every call). Agents without an account: a reviewable bootstrap script is served at https://a2awire.com/api/v1/connectors/spend-guard/bootstrap.sh (download it, read it, then run it to mint a key). Call AFTER checkout. Record a completed purchase in the owner's spend ledger. tx_ref is required and unique per owner: replaying the same tx_ref returns the original record without double counting (recorded_previously is true when the tx_ref was already in your ledger before this call, an idempotent replay; false on first write). Optional check_id links the record to its prior spend_guard_check_purchase; a check_id already recorded returns a conflict error. Returns the recorded event and the month-to-date total. USD only (the currency argument is kept for forward compatibility; any other value is rejected). Not guest-callable. REST: POST /api/v1/spend-guard/record.

Input Schema

{
  "type": "object",
  "properties": {
    "merchant": {
      "maxLength": 200,
      "minLength": 1,
      "title": "Merchant",
      "type": "string"
    },
    "amount_usd": {
      "anyOf": [
        {
          "exclusiveMinimum": 0,
          "maximum": 100000,
          "type": "number"
        },
        {
          "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
          "type": "string"
        }
      ],
      "title": "Amount Usd"
    },
    "currency": {
      "default": "USD",
      "description": "USD only. Kept for forward compatibility; any other value is rejected.",
      "maxLength": 8,
      "title": "Currency",
      "type": "string"
    },
    "category": {
      "anyOf": [
        {
          "maxLength": 100,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Category"
    },
    "description": {
      "anyOf": [
        {
          "maxLength": 500,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Description"
    },
    "tx_ref": {
      "description": "Caller idempotency key, unique across your recorded purchases; replays return the original record.",
      "maxLength": 200,
      "minLength": 1,
      "title": "Tx Ref",
      "type": "string"
    },
    "check_id": {
      "anyOf": [
        {
          "format": "uuid",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Optional id from spend_guard_check_purchase; at most one record may consume each check.",
      "title": "Check Id"
    }
  },
  "required": [
    "merchant",
    "amount_usd",
    "tx_ref"
  ],
  "additionalProperties": false,
  "description": "Arguments for ``spend_guard_record_purchase`` (call AFTER checkout).\n\n``tx_ref`` is required and unique across your recorded purchases;\n``check_id`` optionally links back to the check that preceded the\npurchase. The response's ``recorded_previously`` is true when this\ntx_ref was already in your ledger before this call (an idempotent\nreplay); false on first write. ``currency`` is USD only; the field is\nkept for forward compatibility and any other value is rejected.",
  "title": "SpendGuardRecordPurchaseInput"
}
🔴spend_guard_set_rules(monthly_cap_usd, per_purchase_threshold_usd, merchant_denylist)

Humans: sign up with your email at https://a2awire.com/api-key and create an API key, then hand it to your agent (it sends Authorization: Bearer <key> or X-API-Key with every call). Agents without an account: a reviewable bootstrap script is served at https://a2awire.com/api/v1/connectors/spend-guard/bootstrap.sh (download it, read it, then run it to mint a key). Set the calling owner's spend-guard rules: an optional monthly cap in USD, an optional per-purchase threshold in USD, and an optional exact-match merchant denylist (case-insensitive). Full declaration: omit or null a field to clear that rule. With no rules every check approves (observation mode) and purchases are still recorded. Returns the effective rules. Not guest-callable. REST: PUT /api/v1/spend-guard/rules.

Input Schema

{
  "type": "object",
  "properties": {
    "monthly_cap_usd": {
      "anyOf": [
        {
          "exclusiveMinimum": 0,
          "maximum": 100000,
          "type": "number"
        },
        {
          "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Cumulative recorded spend per UTC calendar month at or above which checks deny. Null clears the cap.",
      "title": "Monthly Cap Usd"
    },
    "per_purchase_threshold_usd": {
      "anyOf": [
        {
          "exclusiveMinimum": 0,
          "maximum": 100000,
          "type": "number"
        },
        {
          "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "A single purchase strictly above this amount asks the user first. Null clears the threshold.",
      "title": "Per Purchase Threshold Usd"
    },
    "merchant_denylist": {
      "anyOf": [
        {
          "items": {
            "maxLength": 200,
            "minLength": 1,
            "type": "string"
          },
          "maxItems": 100,
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Exact-match merchant names (case-insensitive) whose purchases are denied, up to 100 entries. Null clears the list.",
      "title": "Merchant Denylist"
    }
  },
  "additionalProperties": false,
  "description": "Arguments for ``spend_guard_set_rules``.\n\nThe owner is derived from the authenticated principal, never from the\narguments. Full declaration: omit or null a field to clear that rule.",
  "title": "SpendGuardSetRulesInput"
}
🟢spend_guard_report(month)

Humans: sign up with your email at https://a2awire.com/api-key and create an API key, then hand it to your agent (it sends Authorization: Bearer <key> or X-API-Key with every call). Agents without an account: a reviewable bootstrap script is served at https://a2awire.com/api/v1/connectors/spend-guard/bootstrap.sh (download it, read it, then run it to mint a key). Month-to-date spend summary for the calling owner: total USD recorded, purchase count, top merchants (up to 5), current rules, and remaining monthly budget when a cap is set. Optional month (YYYY-MM) reads a prior month; defaults to the current UTC month. Not guest-callable. REST: GET /api/v1/spend-guard/report.

Input Schema

{
  "type": "object",
  "properties": {
    "month": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Optional month filter (YYYY-MM); defaults to the current UTC month.",
      "title": "Month"
    }
  },
  "additionalProperties": false,
  "description": "Arguments for ``spend_guard_report`` (no required arguments).",
  "title": "SpendGuardReportInput"
}

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded4 tools