azeth_get_registry_entry
Look up participant details in the trust registry using token ID or smart account address to verify registration, capabilities, and reputation scores.
Instructions
Look up a specific participant on the trust registry by token ID or smart account address.
Use this when: You know a specific agent/service address or token ID and want to see their registration details, capabilities, and reputation.
Provide EITHER tokenId OR address (at least one required). If address is provided, it is resolved to a token ID via on-chain lookup.
Returns: Full registry entry including name, description, entity type, capabilities, endpoint, and weighted reputation score.
This is read-only and safe to call at any time.
Example: { "address": "0x1234..." } or { "tokenId": "5" }
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| chain | No | 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"). | |
| tokenId | No | ERC-8004 token ID of the participant to look up. | |
| address | No | Smart account address of the participant. Resolved to tokenId on-chain. |
Implementation Reference
- src/tools/registry.ts:408-595 (handler)The handler for the azeth_get_registry_entry tool, which resolves an address or tokenId to a registry entry, potentially falling back from a server API to on-chain metadata resolution.
// azeth_get_registry_entry // ────────────────────────────────────────────── server.registerTool( 'azeth_get_registry_entry', { description: [ 'Look up a specific participant on the trust registry by token ID or smart account address.', '', 'Use this when: You know a specific agent/service address or token ID and want', 'to see their registration details, capabilities, and reputation.', '', 'Provide EITHER tokenId OR address (at least one required).', 'If address is provided, it is resolved to a token ID via on-chain lookup.', '', 'Returns: Full registry entry including name, description, entity type,', 'capabilities, endpoint, and weighted reputation score.', '', 'This is read-only and safe to call at any time.', '', 'Example: { "address": "0x1234..." } or { "tokenId": "5" }', ].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").'), tokenId: z.string().regex(/^\d+$/).optional().describe('ERC-8004 token ID of the participant to look up.'), address: z.string().optional().describe('Smart account address of the participant. Resolved to tokenId on-chain.'), }), }, async (args) => { try { if (!args.tokenId && !args.address) { return error('INVALID_INPUT', 'Provide at least one of "tokenId" or "address".'); } const chainName = resolveChain(args.chain); const serverUrl = process.env['AZETH_SERVER_URL'] ?? 'https://api.azeth.ai'; // Create a public client for on-chain reads const { createPublicClient, http } = await import('viem'); const viemChain = resolveViemChain(chainName); const rpcUrl = process.env[RPC_ENV_KEYS[chainName]] ?? SUPPORTED_CHAINS[chainName].rpcDefault; const publicClient = createPublicClient({ chain: viemChain, transport: http(rpcUrl) }); // Resolve tokenId from address if needed let tokenId: bigint; let resolvedAddress = args.address as `0x${string}` | undefined; if (args.tokenId) { tokenId = BigInt(args.tokenId); } else { // Validate address format if (!validateAddress(args.address!)) { return error('INVALID_INPUT', `Invalid address: "${args.address}". Expected 0x + 40 hex characters.`); } const addr = args.address!.trim() as `0x${string}`; resolvedAddress = addr; const trustRegAddr = AZETH_CONTRACTS[chainName].trustRegistryModule as `0x${string}`; try { tokenId = await publicClient.readContract({ address: trustRegAddr, abi: TrustRegistryModuleAbi, functionName: 'getTokenId', args: [addr], }) as bigint; } catch { return error('ACCOUNT_NOT_FOUND', `Could not resolve token ID for address ${addr}. The address may not be registered.`); } if (tokenId === 0n) { return error('ACCOUNT_NOT_FOUND', `Address ${addr} is not registered on the trust registry.`); } } // Try server API first let entry: { tokenId: string | number; owner: string; name: string; description: string; entityType: string; capabilities: string[]; endpoint?: string; pricing?: string; catalog?: CatalogEntry[]; active: boolean } | null = null; let source: 'server' | 'on-chain' = 'server'; try { const serverEntry = await getRegistryEntry(serverUrl, tokenId); if (serverEntry) { entry = serverEntry as unknown as typeof entry; } } catch { // Server unavailable — fall back to on-chain } // On-chain fallback via tokenURI if (!entry) { source = 'on-chain'; try { const registryAddr = ERC8004_REGISTRY[chainName] as `0x${string}`; const uri = await publicClient.readContract({ address: registryAddr, abi: ERC8004_TOKEN_URI_ABI, functionName: 'tokenURI', args: [tokenId], }) as string; const meta = parseRegistryDataURI(uri); if (meta) { // If no address was provided (lookup by tokenId), resolve owner via ownerOf let ownerAddress = resolvedAddress ?? ''; if (!ownerAddress) { try { ownerAddress = await publicClient.readContract({ address: registryAddr, abi: ERC721_OWNER_OF_ABI, functionName: 'ownerOf', args: [tokenId], }) as `0x${string}`; } catch { /* owner resolution failed — leave empty */ } } entry = { tokenId: tokenId.toString(), owner: ownerAddress, name: meta.name, description: meta.description, entityType: meta.entityType, capabilities: meta.capabilities, endpoint: meta.endpoint, pricing: meta.pricing, catalog: meta.catalog, active: true, }; } } catch { return error('ACCOUNT_NOT_FOUND', `Token ID ${tokenId} not found on the trust registry.`); } } if (!entry) { return error('ACCOUNT_NOT_FOUND', `No registry entry found for token ID ${tokenId}.`); } // Overlay per-key metadata updates (from setMetadata) onto the base entry. // This ensures fields updated via azeth_update_service are reflected in reads. const registryAddr = ERC8004_REGISTRY[chainName] as `0x${string}`; await overlayMetadataUpdates(publicClient as any, registryAddr, tokenId, entry as Record<string, unknown>); // Optional reputation enrichment let reputation: { weightedValue: string; weightedValueFormatted: string; totalWeight: string; totalWeightFormatted: string; opinionCount: string } = { weightedValue: '0', weightedValueFormatted: '0', totalWeight: '0', totalWeightFormatted: '0', opinionCount: '0' }; try { const repModuleAddr = AZETH_CONTRACTS[chainName].reputationModule; if (repModuleAddr) { const rep = await publicClient.readContract({ address: repModuleAddr, abi: ReputationModuleAbi, functionName: 'getWeightedReputationAll', args: [tokenId], }) as readonly [bigint, bigint, bigint]; const [wv, tw, oc] = rep; // Format weighted value using same heuristic as reputation.ts const absValue = wv < 0n ? -wv : wv; const isHighPrecision = absValue > 10n ** 15n; const weightedValueFormatted = isHighPrecision ? formatTokenAmount(wv, 18, 4) : wv.toString(); // Format totalWeight as USD with adaptive precision const totalWeightFormatted = formatTokenAmount(tw, 12, 2); reputation = { weightedValue: wv.toString(), weightedValueFormatted, totalWeight: tw.toString(), totalWeightFormatted, opinionCount: oc.toString(), }; } } catch { /* reputation not available — default zeros used */ } return success({ tokenId: tokenId.toString(), address: entry.owner || resolvedAddress || null, name: entry.name, description: entry.description, entityType: entry.entityType, capabilities: entry.capabilities, endpoint: entry.endpoint ?? null, pricing: entry.pricing ?? null, catalog: entry.catalog ?? null, active: entry.active, reputation, source, }); } catch (err) { return handleError(err); } }, ); - src/tools/registry.ts:143-144 (registration)Registration of the azeth_get_registry_entry tool within the registry tools module.
/** Register trust registry MCP tools: azeth_publish_service, azeth_discover_services, azeth_get_registry_entry, azeth_update_service */ export function registerRegistryTools(server: McpServer): void {