Skip to main content
Glama

insumer_attest

Verify on-chain conditions (token balances, NFT ownership, EAS attestations, Farcaster identity) across 33 chains. Returns ECDSA-signed boolean results preserving privacy. Supports EVM, Solana, XRPL, Bitcoin.

Instructions

Create on-chain verification (attestation). Verify 1-10 conditions (token balances, NFT ownership, EAS attestations, Farcaster identity) across 33 chains. Returns ECDSA-signed boolean results with a kid field identifying the signing key (fetch public key via insumer_jwks). Never exposes actual balances. Each result includes evaluatedCondition (exact logic checked), conditionHash (SHA-256 for tamper-evidence), and blockNumber/blockTimestamp for RPC chains (freshness). XRPL results include ledgerIndex and ledgerHash (validated ledger hash) instead of blockNumber/blockTimestamp; trust line token results also include trustLineState: { frozen: boolean } (frozen trust lines cause met: false). Standard mode costs 1 credit. Pass proof: 'merkle' for EIP-1186 Merkle storage proofs (2 credits). For EAS attestations, use a compliance template (Coinbase Verifications, Gitcoin Passport) or raw schemaId. For Farcaster, use type 'farcaster_id' (checks IdRegistry on Optimism). Use insumer_compliance_templates to list available templates.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
walletNoEVM wallet address (0x...)
solanaWalletNoSolana wallet address (base58)
xrplWalletNoXRPL wallet address (r-address). For verifying XRP, trust line tokens (RLUSD, USDC), or NFTs on XRP Ledger.
bitcoinWalletNoBitcoin address (P2PKH, P2SH, bech32, or Taproot). For verifying native BTC balance. Use chainId 'bitcoin' with contractAddress 'native'.
proofNoSet to 'merkle' for EIP-1186 Merkle storage proofs (2 credits). Proofs available for token_balance on RPC chains only.
formatNoSet to 'jwt' to include a Wallet Auth by InsumerAPI token (ES256-signed JWT) in the response. Verifiable by any standard JWT library using JWKS at /.well-known/jwks.json.
conditionsYes1-10 on-chain conditions to verify

Implementation Reference

  • src/index.ts:226-261 (registration)
    Registration of the 'insumer_attest' tool on the MCP server. This is where the tool is defined with name, description, input schema (using Zod), and handler.
    server.tool(
      "insumer_attest",
      "Create on-chain verification (attestation). Verify 1-10 conditions (token balances, NFT ownership, EAS attestations, Farcaster identity) across 33 chains. Returns ECDSA-signed boolean results with a kid field identifying the signing key (fetch public key via insumer_jwks). Never exposes actual balances. Each result includes evaluatedCondition (exact logic checked), conditionHash (SHA-256 for tamper-evidence), and blockNumber/blockTimestamp for RPC chains (freshness). XRPL results include ledgerIndex and ledgerHash (validated ledger hash) instead of blockNumber/blockTimestamp; trust line token results also include trustLineState: { frozen: boolean } (frozen trust lines cause met: false). Standard mode costs 1 credit. Pass proof: 'merkle' for EIP-1186 Merkle storage proofs (2 credits). For EAS attestations, use a compliance template (Coinbase Verifications, Gitcoin Passport) or raw schemaId. For Farcaster, use type 'farcaster_id' (checks IdRegistry on Optimism). Use insumer_compliance_templates to list available templates.",
      {
        wallet: z.string().optional().describe("EVM wallet address (0x...)"),
        solanaWallet: z.string().optional().describe("Solana wallet address (base58)"),
        xrplWallet: z.string().optional().describe("XRPL wallet address (r-address). For verifying XRP, trust line tokens (RLUSD, USDC), or NFTs on XRP Ledger."),
        bitcoinWallet: z.string().optional().describe("Bitcoin address (P2PKH, P2SH, bech32, or Taproot). For verifying native BTC balance. Use chainId 'bitcoin' with contractAddress 'native'."),
        proof: z.enum(["merkle"]).optional().describe("Set to 'merkle' for EIP-1186 Merkle storage proofs (2 credits). Proofs available for token_balance on RPC chains only."),
        format: z.enum(["jwt"]).optional().describe("Set to 'jwt' to include a Wallet Auth by InsumerAPI token (ES256-signed JWT) in the response. Verifiable by any standard JWT library using JWKS at /.well-known/jwks.json."),
        conditions: z
          .array(
            z.object({
              type: z.enum(["token_balance", "nft_ownership", "eas_attestation", "farcaster_id"]).describe("Condition type: token_balance, nft_ownership, eas_attestation, or farcaster_id (Farcaster IdRegistry on Optimism)"),
              contractAddress: z.string().optional().describe("Token or NFT contract address (required for token_balance and nft_ownership)"),
              chainId: ChainId.optional(),
              threshold: z.number().optional().describe("Minimum balance required (for token_balance). Must be > 0 when proof is merkle."),
              decimals: z.number().int().min(0).max(77).optional().describe("Token decimals (default 18)"),
              label: z.string().max(100).optional().describe("Human-readable label"),
              schemaId: z.string().optional().describe("EAS schema ID (bytes32 hex). Required for eas_attestation unless template is provided."),
              attester: z.string().optional().describe("Expected attester address (optional, for eas_attestation)"),
              indexer: z.string().optional().describe("EAS indexer contract address (optional, for eas_attestation)"),
              template: z.enum(["coinbase_verified_account", "coinbase_verified_country", "coinbase_one", "gitcoin_passport_score", "gitcoin_passport_active"]).optional().describe("Compliance template name. Use instead of raw schemaId/attester/indexer for eas_attestation. Gitcoin Passport templates check Sybil resistance on Optimism."),
              currency: z.string().optional().describe("XRPL trust line currency code (e.g. 'RLUSD', 'USDC'). Required for XRPL trust line tokens, ignored for other chains."),
              taxon: z.number().int().optional().describe("XRPL NFToken taxon filter (optional, for nft_ownership on XRPL only). Filters NFTs by issuer + taxon."),
            })
          )
          .min(1)
          .max(10)
          .describe("1-10 on-chain conditions to verify"),
      },
      async (args) => {
        const result = await apiCall("POST", "/attest", args);
        return formatResult(result);
      }
    );
  • Input schema for insumer_attest: accepts wallet addresses (EVM, Solana, XRPL, Bitcoin), optional proof/format flags, and 1-10 conditions of type token_balance, nft_ownership, eas_attestation, or farcaster_id.
    {
      wallet: z.string().optional().describe("EVM wallet address (0x...)"),
      solanaWallet: z.string().optional().describe("Solana wallet address (base58)"),
      xrplWallet: z.string().optional().describe("XRPL wallet address (r-address). For verifying XRP, trust line tokens (RLUSD, USDC), or NFTs on XRP Ledger."),
      bitcoinWallet: z.string().optional().describe("Bitcoin address (P2PKH, P2SH, bech32, or Taproot). For verifying native BTC balance. Use chainId 'bitcoin' with contractAddress 'native'."),
      proof: z.enum(["merkle"]).optional().describe("Set to 'merkle' for EIP-1186 Merkle storage proofs (2 credits). Proofs available for token_balance on RPC chains only."),
      format: z.enum(["jwt"]).optional().describe("Set to 'jwt' to include a Wallet Auth by InsumerAPI token (ES256-signed JWT) in the response. Verifiable by any standard JWT library using JWKS at /.well-known/jwks.json."),
      conditions: z
        .array(
          z.object({
            type: z.enum(["token_balance", "nft_ownership", "eas_attestation", "farcaster_id"]).describe("Condition type: token_balance, nft_ownership, eas_attestation, or farcaster_id (Farcaster IdRegistry on Optimism)"),
            contractAddress: z.string().optional().describe("Token or NFT contract address (required for token_balance and nft_ownership)"),
            chainId: ChainId.optional(),
            threshold: z.number().optional().describe("Minimum balance required (for token_balance). Must be > 0 when proof is merkle."),
            decimals: z.number().int().min(0).max(77).optional().describe("Token decimals (default 18)"),
            label: z.string().max(100).optional().describe("Human-readable label"),
            schemaId: z.string().optional().describe("EAS schema ID (bytes32 hex). Required for eas_attestation unless template is provided."),
            attester: z.string().optional().describe("Expected attester address (optional, for eas_attestation)"),
            indexer: z.string().optional().describe("EAS indexer contract address (optional, for eas_attestation)"),
            template: z.enum(["coinbase_verified_account", "coinbase_verified_country", "coinbase_one", "gitcoin_passport_score", "gitcoin_passport_active"]).optional().describe("Compliance template name. Use instead of raw schemaId/attester/indexer for eas_attestation. Gitcoin Passport templates check Sybil resistance on Optimism."),
            currency: z.string().optional().describe("XRPL trust line currency code (e.g. 'RLUSD', 'USDC'). Required for XRPL trust line tokens, ignored for other chains."),
            taxon: z.number().int().optional().describe("XRPL NFToken taxon filter (optional, for nft_ownership on XRPL only). Filters NFTs by issuer + taxon."),
          })
        )
        .min(1)
        .max(10)
        .describe("1-10 on-chain conditions to verify"),
    },
  • Handler function for insumer_attest. Makes an apiCall POST to /attest with the provided arguments and formats the result.
    async (args) => {
      const result = await apiCall("POST", "/attest", args);
      return formatResult(result);
    }
  • The apiCall helper used by insumer_attest's handler. Sends authenticated requests to the InsumerAPI backend.
    async function apiCall(
      method: string,
      path: string,
      body?: Record<string, unknown>
    ): Promise<{ ok: boolean; data?: unknown; error?: unknown; meta?: unknown }> {
      if (!apiKey) {
        return { ok: false, error: "INSUMER_API_KEY is not set. Call the insumer_setup tool to generate a free API key instantly, then add it to your MCP config as INSUMER_API_KEY and restart." };
      }
      const url = `${API_BASE}${path}`;
      const res = await fetch(url, {
        method,
        headers: {
          "Content-Type": "application/json",
          "X-API-Key": apiKey,
        },
        body: body ? JSON.stringify(body) : undefined,
      });
      return res.json() as Promise<{
        ok: boolean;
        data?: unknown;
        error?: unknown;
        meta?: unknown;
      }>;
    }
  • The formatResult helper used by insumer_attest's handler. Wraps API responses into MCP content blocks.
    function formatResult(result: {
      ok: boolean;
      data?: unknown;
      error?: unknown;
      meta?: unknown;
    }) {
      if (result.ok) {
        return {
          content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
        };
      }
      return {
        content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
        isError: true,
      };
    }
Behavior5/5

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

With no annotations, the description details behavioral traits: returns ECDSA-signed boolean results with kid, never exposes balances, includes evaluatedCondition, conditionHash, blockNumber/blockTimestamp for RPC chains, XRPL specifics, trust line state, credit costs, and proof mode. This fully compensates for missing annotations.

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 a single paragraph but is information-dense. Key information is front-loaded. Every sentence adds value, though a structured bullet list could improve readability. It is still concise for the complexity covered.

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?

No output schema is present, but the description thoroughly explains return values, including per-condition fields and chain-specific differences. It covers all mode variations (standard, proof, JWT format) and condition types. The description is complete given the tool's complexity.

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

Parameters5/5

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

Schema coverage is 100%, but the description adds critical context: e.g., for bitcoinWallet use chainId 'bitcoin' with contractAddress 'native', for XRPL trust lines use currency, for Farcaster type 'farcaster_id', and template names for EAS. It explains the JWT format parameter. This goes well 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 'Create on-chain verification (attestation)' and specifies the scope: verifying 1-10 conditions across 33 chains. It distinguishes from sibling tools like insumer_compliance_templates by referencing it for listing templates, and insumer_verify is a different operation. The verb 'verify' and resource 'attestation' are specific.

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?

The description explains when to use the tool (to create attestations) and provides guidance on modes, credits, and template usage. It explicitly advises using insumer_compliance_templates to list available templates, indicating a decision point. However, it does not contrast with other sibling tools like insumer_verify or 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/douglasborthwick-crypto/mcp-server-insumer'

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