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
Findings (5)
- HIGH
- MEDIUMin spend_guard_check_purchase
- MEDIUMin spend_guard_record_purchase
- MEDIUMin spend_guard_set_rules
- MEDIUMin spend_guard_report
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
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-httpWhat it can do
Tool inventory
Tools (4)
🟡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
Evidence