Skip to main content
Glama

azeth_get_weighted_reputation

Check an agent's on-chain reputation using USD-weighted ratings to assess trustworthiness before interactions. Returns weighted average based on rater payments.

Instructions

Get USD-weighted reputation for an agent from the on-chain ReputationModule.

Use this when: You want to check the reputation of an agent or service before interacting. Returns a weighted average where each rater's influence is proportional to their USD payment to the agent.

Returns: Weighted reputation with weightedValue (int256), totalWeight, and opinionCount.

Note: This is a read-only on-chain query. No private key or gas is required. Leave raters empty to aggregate across all raters who have submitted opinions.

Example: { "agentId": "1024" } or { "agentId": "1024", "raters": ["0x1234...abcd"] }

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
chainNoTarget chain. Defaults to AZETH_CHAIN env var or "baseSepolia". Accepts "base", "baseSepolia", "ethereumSepolia", "ethereum" (and aliases like "base-sepolia", "eth-sepolia", "sepolia", "eth", "mainnet").
agentIdYesTarget agent's ERC-8004 token ID (numeric string).
ratersNoSpecific rater addresses to include (optional). Empty = all raters.

Implementation Reference

  • The asynchronous handler function that executes the azeth_get_weighted_reputation tool, interacting with the ReputationModule contract via viem.
      async (args) => {
        const agentIdCheck = validateUint256(args.agentId, 'agentId');
        if (!agentIdCheck.valid) {
          return error('INVALID_INPUT', `${agentIdCheck.fieldName} exceeds maximum uint256 value`);
        }
    
        try {
          const { createPublicClient, http } = await import('viem');
    
          const resolved = resolveChain(args.chain);
          const chain = resolveViemChain(resolved);
          const rpcUrl = process.env[RPC_ENV_KEYS[resolved]] ?? SUPPORTED_CHAINS[resolved].rpcDefault;
    
          const publicClient = createPublicClient({
            chain,
            transport: http(rpcUrl),
          });
    
          const moduleAddress = AZETH_CONTRACTS[resolved].reputationModule;
          if (!moduleAddress || moduleAddress === ('' as `0x${string}`)) {
            return error('NETWORK_ERROR', `ReputationModule not deployed on ${resolved}.`, 'Deploy the ReputationModule first or switch to baseSepolia.');
          }
    
          // Check if the token ID exists on the trust registry before querying reputation
          const trustRegistryAddr = AZETH_CONTRACTS[resolved].trustRegistryModule;
          if (trustRegistryAddr && trustRegistryAddr !== ('' as `0x${string}`)) {
            try {
              const accountAddr = await publicClient.readContract({
                address: trustRegistryAddr,
                abi: TrustRegistryModuleAbi,
                functionName: 'getAccountByTokenId',
                args: [agentIdCheck.bigint],
              });
              if (accountAddr === '0x0000000000000000000000000000000000000000') {
                return success({
                  agentId: args.agentId,
                  weightedValue: '0',
                  totalWeight: '0',
                  opinionCount: '0',
                  warning: `No agent registered with token ID ${args.agentId}. The returned zeros indicate no registration, not a zero reputation.`,
                });
              }
            } catch {
              // getAccountByTokenId may not exist on older deployments — proceed with query
            }
          }
    
          const raterAddrs = args.raters
            .filter((a): a is `0x${string}` => /^0x[0-9a-fA-F]{40}$/.test(a));
    
          let result: readonly [bigint, bigint, bigint];
    
          if (raterAddrs.length > 0) {
            result = await publicClient.readContract({
              address: moduleAddress,
              abi: ReputationModuleAbi,
              functionName: 'getWeightedReputation',
              args: [agentIdCheck.bigint, raterAddrs],
            }) as readonly [bigint, bigint, bigint];
          } else {
            result = await publicClient.readContract({
              address: moduleAddress,
              abi: ReputationModuleAbi,
              functionName: 'getWeightedReputationAll',
              args: [agentIdCheck.bigint],
            }) as readonly [bigint, bigint, bigint];
          }
    
          const [weightedValue, totalWeight, opinionCount] = result;
    
          // Format weighted value: the contract returns values in the same decimal precision
          // as the submitted opinions. For the default MCP submission (valueDecimals=0), this
          // is an integer. For SDK submissions with 18 decimals, format accordingly.
          // Heuristic: if |value| > 10^15, it's likely 18-decimal; otherwise treat as integer.
          const absValue = weightedValue < 0n ? -weightedValue : weightedValue;
          const isHighPrecision = absValue > 10n ** 15n;
          const weightedValueFormatted = isHighPrecision
            ? formatTokenAmount(weightedValue, 18, 4)
            : weightedValue.toString();
    
          // totalWeight is a dampened dimensionless value: sum of pow2over3(netPaidUSD) across raters.
          // It is NOT USD — do not format as currency. Display as a plain number.
          const totalWeightFormatted = formatTokenAmount(totalWeight, 12, 2);
    
          return success({
            agentId: args.agentId,
            weightedValue: weightedValue.toString(),
            weightedValueFormatted,
            totalWeight: totalWeight.toString(),
            totalWeightFormatted,
            totalWeightDescription: 'Aggregate economic skin-in-the-game (higher = more payments behind opinions)',
            opinionCount: opinionCount.toString(),
            ratersFilter: raterAddrs.length > 0 ? raterAddrs : '(all raters)',
          });
        } catch (err) {
          return handleError(err);
        }
      },
    );
  • Input validation schema for azeth_get_weighted_reputation tool.
      inputSchema: z.object({
        chain: z.string().optional().describe('Target chain. Defaults to AZETH_CHAIN env var or "baseSepolia". Accepts "base", "baseSepolia", "ethereumSepolia", "ethereum" (and aliases like "base-sepolia", "eth-sepolia", "sepolia", "eth", "mainnet").'),
        agentId: z.string().regex(/^\d+$/, 'Must be a non-negative integer string').describe('Target agent\'s ERC-8004 token ID (numeric string).'),
        raters: z.preprocess(
          (val) => typeof val === 'string' ? JSON.parse(val) : val,
          z.array(
            z.string().regex(/^0x[0-9a-fA-F]{40}$/, 'Each rater must be a valid Ethereum address'),
          ).default([]),
        ).describe('Specific rater addresses to include (optional). Empty = all raters.'),
      }),
    },
  • Registration of the azeth_get_weighted_reputation tool with the server.
    server.registerTool(
      'azeth_get_weighted_reputation',
      {
        description: [
          'Get USD-weighted reputation for an agent from the on-chain ReputationModule.',
          '',
          'Use this when: You want to check the reputation of an agent or service before interacting.',
          'Returns a weighted average where each rater\'s influence is proportional to their USD payment to the agent.',
          '',
          'Returns: Weighted reputation with weightedValue (int256), totalWeight, and opinionCount.',
          '',
          'Note: This is a read-only on-chain query. No private key or gas is required.',
          'Leave raters empty to aggregate across all raters who have submitted opinions.',
          '',
          'Example: { "agentId": "1024" } or { "agentId": "1024", "raters": ["0x1234...abcd"] }',
        ].join('\n'),
        inputSchema: z.object({
          chain: z.string().optional().describe('Target chain. Defaults to AZETH_CHAIN env var or "baseSepolia". Accepts "base", "baseSepolia", "ethereumSepolia", "ethereum" (and aliases like "base-sepolia", "eth-sepolia", "sepolia", "eth", "mainnet").'),
          agentId: z.string().regex(/^\d+$/, 'Must be a non-negative integer string').describe('Target agent\'s ERC-8004 token ID (numeric string).'),
          raters: z.preprocess(
            (val) => typeof val === 'string' ? JSON.parse(val) : val,
            z.array(
              z.string().regex(/^0x[0-9a-fA-F]{40}$/, 'Each rater must be a valid Ethereum address'),
            ).default([]),
          ).describe('Specific rater addresses to include (optional). Empty = all raters.'),
        }),
      },

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/azeth-protocol/mcp-azeth'

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