Skip to main content
Glama

hyperd.bundle

Reduce costs for 3+ paid GET calls by bundling them into one x402 settlement. Fixed $0.20 USDC fee, parallel execution of up to 10 sub-calls.

Instructions

Bundle multiple paid GET calls into one x402 settlement. Up to 10 sub-calls executed in parallel (concurrency cap 4), per-call results returned in a structured envelope. Fixed $0.20 USDC — typically cheaper than à la carte for any combination summing > $0.24 individually. Best-effort execution: failed sub-calls don't refund in v1.0 (credit ledger planned for v1.1). Use this when you need 3+ paid calls and want to save on facilitator round-trips.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
callsYes1-10 sub-calls. Each must target a bundleable paid GET endpoint.

Implementation Reference

  • src/server.ts:425-444 (registration)
    Registration of the 'hyperd.bundle' tool via server.tool(). Defines name, description, input schema (array of 1-10 sub-calls with id, method, path, query), and delegates to paidWithBody for execution.
    // hyperd.bundle — multi-call settlement ($0.20 fixed)
    server.tool(
      "hyperd.bundle",
      "Bundle multiple paid GET calls into one x402 settlement. Up to 10 sub-calls executed in parallel (concurrency cap 4), per-call results returned in a structured envelope. Fixed $0.20 USDC — typically cheaper than à la carte for any combination summing > $0.24 individually. Best-effort execution: failed sub-calls don't refund in v1.0 (credit ledger planned for v1.1). Use this when you need 3+ paid calls and want to save on facilitator round-trips.",
      {
        calls: z
          .array(
            z.object({
              id: z.string().optional().describe("Caller-supplied id; echoed in result."),
              method: z.literal("GET").describe("Only GET sub-calls supported in v1.0."),
              path: z.string().describe("Endpoint path (e.g. /api/balance)."),
              query: z.record(z.unknown()).optional().describe("Query params for the sub-call."),
            }),
          )
          .min(1)
          .max(10)
          .describe("1-10 sub-calls. Each must target a bundleable paid GET endpoint."),
      },
      async (args) => asText(await paidWithBody("POST", "/api/bundle", args)),
    );
  • paidWithBody — the actual handler invoked by hyperd.bundle. Sends a POST request to /api/bundle with the calls payload, performing the x402 payment dance (402 -> payment payload -> retry with payment headers).
    async function paidWithBody(
      method: "POST" | "DELETE",
      path: string,
      body: unknown,
      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(method, url, body);
    }
  • Input schema for hyperd.bundle: an array of 1-10 objects, each with optional id, method (literal 'GET'), path (string), and optional query (record). Defined via Zod.
    {
      calls: z
        .array(
          z.object({
            id: z.string().optional().describe("Caller-supplied id; echoed in result."),
            method: z.literal("GET").describe("Only GET sub-calls supported in v1.0."),
            path: z.string().describe("Endpoint path (e.g. /api/balance)."),
            query: z.record(z.unknown()).optional().describe("Query params for the sub-call."),
          }),
        )
        .min(1)
        .max(10)
        .describe("1-10 sub-calls. Each must target a bundleable paid GET endpoint."),
  • asText — helper that wraps JSON responses into the MCP text content format used by the handler.
    function asText(data: unknown) {
      return { content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }] };
    }
  • paidRequest — core x402 payment flow used by paidWithBody. Handles the 402 Payment Required, creating payment payload, and retrying with payment signature headers.
    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?

With no annotations, the description fully bears the burden. It discloses parallelism (up to 10 sub-calls, concurrency cap 4), pricing ($0.20 USDC), best-effort execution, and refund policy (no refunds in v1.0). These traits go well beyond the schema.

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?

The description is 4 clear, front-loaded sentences. No extraneous content; every sentence adds critical information about purpose, behavior, pricing, and usage.

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

Completeness3/5

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

While the description covers usage and behavioral details well, it omits the structure of the return envelope. Since there is no output schema, the agent lacks information about what the response will look like, which is a notable gap.

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 value by explaining how parameters are used in practice (parallelism, pricing, error handling), but does not introduce new parameter constraints 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 states that the tool bundles multiple paid GET calls into one x402 settlement. This is a specific verb+resource combination and clearly distinguishes it from sibling tools like hyperd.balance.get or hyperd.wallet.balance which are individual calls.

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

Usage Guidelines5/5

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

It explicitly advises using this tool when needing 3+ paid calls, and provides a cost comparison (fixed $0.20 vs. à la carte total > $0.24). This gives clear when-to-use guidance, though it does not explicitly state when not to use it.

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