Skip to main content
Glama

Prepare HTTP Purchase

prepare_verify_evidence_purchase
Idempotent

Prepare an HTTP purchase request for deterministic JSON verification after a successful free precheck; a prior quote tool call is optional. After a successful free precheck at POST /validate-request, supply the unchanged intent and its precheck_receipt.receipt_digest. Creates or reuses a persisted quote and records observability events; no payment, signing or paid verification is performed. The bound quote ties request/evidence digests, precheck digest, spend policy, quoted amount, network, asset, recipient and expiry together. Server availability, fresh cost basis and conservative contribution-margin thresholds must pass. Returns JSON text and structuredContent containing quote, request (POST /verify-evidence, content-type and X-Quote-ID headers, unchanged intent body), expected_first_status=402 and expected_payment_header=PAYMENT-REQUIRED. It does not send this request. Application failures return isError=true with JSON error.code, message, retryable and optional details (for example PRECHECK_STALE, PRICE_CAP_EXCEEDED, IDEMPOTENCY_KEY_CONFLICT, IDEMPOTENCY_KEY_EXPIRED or UNPROFITABLE_TRANSACTION); invalid argument shapes are rejected by MCP schema validation. Re-run precheck after request/policy changes; do not pay on refusal. Next send the returned request to obtain a challenge, check binding, amount, network, asset, payTo and expiry against local policy, then authorize payment separately. Use quote_verify_evidence when only quote terms are needed.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
intentYesRequired prechecked purchase intent: request, spend_policy and precheck_receipt_digest are all required, with no defaults or optional fields. Preserve the request and policy used in the successful free POST /validate-request.
idempotency_keyYesRequired 16-128 characters from A-Z, a-z, 0-9, underscore or hyphen. Reuse with the unchanged intent to reuse an unexpired quote; changed bindings return IDEMPOTENCY_KEY_CONFLICT. An expired key returns IDEMPOTENCY_KEY_EXPIRED; use a new key.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed16 schema fields changed
    • addedInput schema / properties / idempotency_key / description
      Added value: +"Required 16-128 characters from A-Z, a-z, 0-9, underscore or hyphen. Reuse with the unchanged intent to reuse an unexpired quote; changed bindings return IDEMPOTENCY_KEY_CONFLICT. An expired key returns IDEMPOTENCY_KEY_EXPIRED; use a new key."
    • addedInput schema / properties / intent / description
      Added value: +"Required prechecked purchase intent: request, spend_policy and precheck_receipt_digest are all required, with no defaults or optional fields. Preserve the request and policy used in the successful free POST /validate-request."
    • addedInput schema / properties / intent / properties / precheck_receipt_digest / description
      Added value: +"Required sha256: followed by 64 lowercase hex characters, copied from precheck_receipt.receipt_digest of the successful free precheck. Recomputed against request, policy and current discovery contract; mismatches return PRECHECK_STALE."
    • addedInput schema / properties / intent / properties / request / description
      Added value: +"Required complete bounded verification request, unchanged from precheck; no optional fields or defaults."
    • addedInput schema / properties / intent / properties / request / properties / assertions / description
      Added value: +"Required 1-16 deterministic assertions. Each operation accepts only its documented fields. Precheck validates input, not assertion truth."
    • changedInput schema / properties / intent / properties / request / properties / assertions / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "expected_hex": {
      -        "pattern": "^[a-f0-9]{64}$",
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "sha256_equals",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "expected_hex"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "json_pointer_exists",
      -        "type": "string"
      -      },
      -      "path": {
      -        "maxLength": 512,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "path"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "expected": {},
      -      "op": {
      -        "const": "json_pointer_equals",
      -        "type": "string"
      -      },
      -      "path": {
      -        "maxLength": 512,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "path",
      -      "expected"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "expected_type": {
      -        "enum": [
      -          "null",
      -          "boolean",
      -          "number",
      -          "string",
      -          "array",
      -          "object"
      -        ],
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "json_type_is",
      -        "type": "string"
      -      },
      -      "path": {
      -        "maxLength": 512,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "path",
      -      "expected_type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "expected_hex": {
      +        "description": "Required expected digest as exactly 64 lowercase hex characters, without sha256: prefix.",
      +        "pattern": "^[a-f0-9]{64}$",
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "sha256_equals",
      +        "description": "Compare SHA-256 of the raw decoded evidence bytes.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "expected_hex"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "json_pointer_exists",
      +        "description": "Check whether the JSON Pointer resolves.",
      +        "type": "string"
      +      },
      +      "path": {
      +        "description": "Required RFC 6901 JSON Pointer, at most 512 characters; empty string selects the document root. Escape tilde as ~0 and slash as ~1.",
      +        "maxLength": 512,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "path"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "expected": {
      +        "description": "Required expected JSON value, including null; JSON depth/key/value and safe-integer limits apply."
      +      },
      +      "op": {
      +        "const": "json_pointer_equals",
      +        "description": "Compare the selected JSON value with expected.",
      +        "type": "string"
      +      },
      +      "path": {
      +        "description": "Required RFC 6901 JSON Pointer, at most 512 characters; empty string selects the document root. Escape tilde as ~0 and slash as ~1.",
      +        "maxLength": 512,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "path",
      +      "expected"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "expected_type": {
      +        "description": "Required JSON type: null, boolean, number, string, array or object.",
      +        "enum": [
      +          "null",
      +          "boolean",
      +          "number",
      +          "string",
      +          "array",
      +          "object"
      +        ],
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "json_type_is",
      +        "description": "Check the selected JSON value type.",
      +        "type": "string"
      +      },
      +      "path": {
      +        "description": "Required RFC 6901 JSON Pointer, at most 512 characters; empty string selects the document root. Escape tilde as ~0 and slash as ~1.",
      +        "maxLength": 512,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "path",
      +      "expected_type"
      +    ],
      +    "type": "object"
      +  }
      +]
    • addedInput schema / properties / intent / properties / request / properties / client_request_id / description
      Added value: +"Required caller request identifier, 1-64 characters from A-Z, a-z, 0-9, dot, underscore, colon or hyphen; included in the request hash."
    • addedInput schema / properties / intent / properties / request / properties / evidence / description
      Added value: +"Required caller-supplied JSON bytes; no remote evidence is fetched."
    • addedInput schema / properties / intent / properties / request / properties / evidence / properties / content_base64 / description
      Added value: +"Required strict standard Base64 of UTF-8 JSON; 4-87384 encoded characters and at most 65536 decoded bytes. JSON limits: depth 32, object keys 2048, values 8192; integers must be JavaScript safe integers."
    • addedInput schema / properties / intent / properties / request / properties / evidence / properties / media_type / description
      Added value: +"Required literal application/json."
    • addedInput schema / properties / intent / properties / spend_policy / description
      Added value: +"Required caller spending limits and allowed terms; preserve from precheck. All five fields required; no defaults."
    • addedInput schema / properties / intent / properties / spend_policy / properties / asset / description
      Added value: +"Required USDC contract address, 0x plus 40 hex characters; must match current advertised asset."
    • addedInput schema / properties / intent / properties / spend_policy / properties / max_amount_atomic / description
      Added value: +"Required positive decimal integer string in atomic USDC units (1000000 = 1 USDC), at most 16 digits and within JavaScript safe-integer range. No leading zero; must cover the current quoted price."
    • addedInput schema / properties / intent / properties / spend_policy / properties / network / description
      Added value: +"Required eip155:8453 (Base) or eip155:84532 (Base Sepolia); must match current advertised terms."
    • addedInput schema / properties / intent / properties / spend_policy / properties / pay_to / description
      Added value: +"Required allowed payment recipient, 0x plus 40 hex characters; must match current advertised payTo."
    • addedInput schema / properties / intent / properties / spend_policy / properties / policy_version / description
      Added value: +"Required literal agent-economy/precheck-policy/2.0."
  2. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations cover readOnlyHint=false, idempotentHint=true, destructiveHint=false, openWorldHint=false, so the safety profile is clear. The description adds crucial context beyond annotations: no payment/signing occurs, creates or reuses a persisted quote, records observability events, server availability and margin thresholds must pass, application failures return isError=true with specific error codes, and it explains the next steps.

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

Conciseness4/5

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

The description is dense and front-loads the key purpose. While long, every sentence earns its place by conveying necessary behavioral and procedural details. However, it could be slightly more structured with bullet points or shorter sentences for readability.

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?

Given the complexity (nested objects, 2 required params, no output schema), the description covers all essential aspects: inputs needed, what the tool does, what it returns (including expected_first_status and expected_payment_header), error behaviors, and next steps. It's complete for an agent to call it correctly.

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 description coverage is 100%, so the schema already documents parameters thoroughly. The description adds meaning by explaining that the precheck_receipt_digest ties to the successful precheck, that the intent must be unchanged, and that idempotency_key reuse with unchanged intent reuses an unexpired quote, which goes beyond the schema's parameter descriptions.

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?

States a specific verb+resource: prepares an HTTP purchase request for deterministic JSON verification. Clearly distinguishes from siblings by explicitly naming quote_verify_evidence as the alternative when only quote terms are needed, and distinguishes from verify_evidence by stating it does not send the request.

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?

Explicitly describes when to use: after a successful free precheck, with a prior quote tool call being optional. Names the alternative (quote_verify_evidence) and the condition that selects it. Instructs to re-run precheck after changes and not to pay on refusal.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources