Skip to main content
Glama

hyperd.budget.guardian

Check recent USDC spend from your wallet before initiating a paid x402 call. Returns total spend, destination breakdown, projected rate, and optional cap compliance.

Instructions

Agent spend visibility: aggregates recent outbound USDC transfers from a wallet over a configurable window (1h/24h/7d/30d). Returns total spend, by-destination breakdown, projected-24h rate, and an optional under_cap flag if cap_usd is provided. Use this BEFORE initiating the next paid x402 call to enforce a self-imposed budget. Bridged USDC.e variants are NOT counted. Costs $0.01 in USDC.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
addressYes0x EVM wallet address
chainNoChain to compute spend on. Default 'base'.
windowNoLookback window. Default '24h'.
cap_usdNoOptional self-imposed USDC cap. When provided, response includes under_cap, remainingUsd, and anyTxExceedsTenthOfCap.

Implementation Reference

  • src/server.ts:406-423 (registration)
    Registration of the 'hyperd.budget.guardian' tool using server.tool() with its name, description, schema, and handler.
    // hyperd.budget.guardian — agent spend visibility ($0.01)
    server.tool(
      "hyperd.budget.guardian",
      "Agent spend visibility: aggregates recent outbound USDC transfers from a wallet over a configurable window (1h/24h/7d/30d). Returns total spend, by-destination breakdown, projected-24h rate, and an optional under_cap flag if cap_usd is provided. Use this BEFORE initiating the next paid x402 call to enforce a self-imposed budget. Bridged USDC.e variants are NOT counted. Costs $0.01 in USDC.",
      {
        address: z.string().describe("0x EVM wallet address"),
        chain: z
          .enum(["base", "ethereum", "polygon", "arbitrum", "optimism", "avalanche", "bnb"])
          .optional()
          .describe("Chain to compute spend on. Default 'base'."),
        window: z
          .enum(["1h", "24h", "7d", "30d"])
          .optional()
          .describe("Lookback window. Default '24h'."),
        cap_usd: z.number().positive().optional().describe("Optional self-imposed USDC cap. When provided, response includes under_cap, remainingUsd, and anyTxExceedsTenthOfCap."),
      },
      async (args) => asText(await paidGet("/api/budget/guardian", args)),
    );
  • Zod schema defining the tool's input parameters: address (required string), chain (optional enum), window (optional enum), and cap_usd (optional positive number).
    {
      address: z.string().describe("0x EVM wallet address"),
      chain: z
        .enum(["base", "ethereum", "polygon", "arbitrum", "optimism", "avalanche", "bnb"])
        .optional()
        .describe("Chain to compute spend on. Default 'base'."),
      window: z
        .enum(["1h", "24h", "7d", "30d"])
        .optional()
        .describe("Lookback window. Default '24h'."),
      cap_usd: z.number().positive().optional().describe("Optional self-imposed USDC cap. When provided, response includes under_cap, remainingUsd, and anyTxExceedsTenthOfCap."),
    },
  • The handler function: calls paidGet() to the remote API endpoint '/api/budget/guardian' and wraps the response via asText().
    async (args) => asText(await paidGet("/api/budget/guardian", args)),
  • Helper function 'paidGet' that constructs a URL with query parameters and delegates to paidRequest() for the x402 payment flow.
    async function paidGet(
      path: string,
      query: Record<string, string | number | boolean | undefined>,
    ): Promise<unknown> {
      if (!httpClient) {
        throw new Error(WALLET_NOT_CONFIGURED_MSG);
      }
    
      const url = new URL(`${API_BASE}${path}`);
      for (const [k, v] of Object.entries(query)) {
        if (v !== undefined && v !== "" && v !== null) url.searchParams.set(k, String(v));
      }
      return paidRequest("GET", url, undefined);
    }
  • Helper function 'paidRequest' implementing the x402 payment flow: first attempt, then if 402 is returned, creates and sends a payment payload, retries the request.
    async function paidRequest(
      method: "GET" | "POST" | "DELETE",
      url: URL,
      body: unknown,
    ): Promise<unknown> {
      const requestInit = (extraHeaders: Record<string, string> = {}): RequestInit => {
        const headers: Record<string, string> = { ...extraHeaders };
        let payload: string | undefined;
        if (body !== undefined && method !== "GET") {
          headers["Content-Type"] = "application/json";
          payload = JSON.stringify(body);
        }
        return { method, headers, body: payload };
      };
    
      const first = await fetch(url, requestInit());
      if (first.status === 200 || first.status === 201) return first.json();
      if (first.status !== 402) {
        throw new Error(`HTTP ${first.status} on initial ${method} request: ${await first.text()}`);
      }
    
      const paymentRequired = httpClient!.getPaymentRequiredResponse(
        (name) => first.headers.get(name),
        undefined,
      );
      const paymentPayload = await httpClient!.createPaymentPayload(paymentRequired);
      const paymentHeaders = httpClient!.encodePaymentSignatureHeader(paymentPayload);
    
      const second = await fetch(url, requestInit(paymentHeaders));
      if (!second.ok) {
        throw new Error(`HTTP ${second.status} on payment retry: ${await second.text()}`);
      }
      return second.json();
    }
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses aggregation behavior, configurable window, return fields, exclusion of bridged USDC.e, and cost ($0.01 USDC) – all beyond what the input schema provides.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise sentences, each adding unique value: function, usage guidance, and exclusions/cost. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite no output schema, the description fully explains return data (total spend, breakdown, projected rate, under_cap flags) and cost. Covers all important aspects for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds context for cap_usd, explaining what response fields are included when it's provided, which adds meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it aggregates USDC transfers for agent spend visibility, with a specific use case for budget enforcement before x402 calls. It distinguishes from sibling tools like balance.get or wallet.pnl.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says 'Use this BEFORE initiating the next paid x402 call' and notes what it does not count (bridged USDC.e). However, no explicit alternatives or when-not-to-use are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hyperd-ai/hyperd-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server