Skip to main content
Glama

azeth_discover_agent_capabilities

Discover services, pricing, and usage instructions from other agents by sending a capabilities request over XMTP before making service requests or payments.

Instructions

Discover what services an agent offers by sending them a capabilities request over XMTP.

Use this when: You want to find out what services another agent provides, their pricing, and how to use them — before making a service request or payment.

Sends a JSON capabilities request to the target agent and waits for their response. The target agent must be online and have a MessageRouter configured to respond.

The "agentAddress" field accepts: an Ethereum address, a participant name, "me", or "#N" (account index).

Returns: The agent's capabilities including services, pricing, and usage instructions. If no response within the timeout, returns an error indicating the agent may be offline.

Example: { "agentAddress": "0x1234567890abcdef1234567890abcdef12345678" }

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").
agentAddressYesTarget agent: Ethereum address, participant name, "me", or "#N" (account index).
timeoutMsNoTimeout in milliseconds to wait for response. Defaults to 15000 (15 seconds). Max 60000.

Implementation Reference

  • The handler logic for 'azeth_discover_agent_capabilities' which sends a capability request via XMTP and polls for a response.
      async (args) => {
        let client;
        try {
          client = await createClient(args.chain);
          const timeoutMs = args.timeoutMs ?? 15_000;
    
          // Resolve target address
          let resolved;
          try {
            resolved = await resolveAddress(args.agentAddress, client);
          } catch (resolveErr) {
            return handleError(resolveErr);
          }
    
          // Send capabilities request
          const capabilitiesRequest = JSON.stringify({ type: 'capabilities' });
          await client.sendMessage({
            to: resolved.address,
            content: capabilitiesRequest,
          });
    
          // Poll for response within timeout
          const startTime = Date.now();
          const pollIntervalMs = 2_000;
    
          while (Date.now() - startTime < timeoutMs) {
            // Wait before polling
            await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
    
            const messages = await client.getMessages(resolved.address, 5);
            if (messages.length > 0) {
              // Look for a capabilities response among recent messages
              for (const msg of messages) {
                // Skip messages older than our request
                if (msg.timestamp < startTime) continue;
    
                try {
                  const parsed: unknown = JSON.parse(msg.content);
                  if (
                    typeof parsed === 'object' &&
                    parsed !== null &&
                    'type' in parsed &&
                    (parsed as { type: string }).type === 'capabilities'
                  ) {
                    return success({
                      agentAddress: resolved.address,
                      ...(resolved.resolvedFrom ? { resolvedFrom: `"${resolved.resolvedFrom}" → ${resolved.address}` } : {}),
                      capabilities: parsed,
                    });
                  }
                } catch {
                  // Not valid JSON — skip
                }
              }
            }
          }
    
          // Timeout — no response received
          return error(
            'NETWORK_ERROR',
            `No capabilities response received from ${resolved.address} within ${timeoutMs}ms. ` +
            'The agent may be offline or does not have a MessageRouter configured.',
          );
        } catch (err) {
          return handleError(err);
        } finally {
          try { await client?.destroy(); } catch { /* M-10: prevent destroy from masking the original error */ }
        }
      },
    );
  • Zod schema defining the input for 'azeth_discover_agent_capabilities'.
    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").'),
      agentAddress: z.string().describe('Target agent: Ethereum address, participant name, "me", or "#N" (account index).'),
      timeoutMs: z.coerce.number().int().min(1000).max(60_000).optional().describe('Timeout in milliseconds to wait for response. Defaults to 15000 (15 seconds). Max 60000.'),
    }),
  • Registration of the 'azeth_discover_agent_capabilities' tool within the MCP server.
    server.registerTool(
      'azeth_discover_agent_capabilities',
      {
        description: [
          'Discover what services an agent offers by sending them a capabilities request over XMTP.',
          '',
          'Use this when: You want to find out what services another agent provides, their pricing,',
          'and how to use them — before making a service request or payment.',
          '',
          'Sends a JSON capabilities request to the target agent and waits for their response.',
          'The target agent must be online and have a MessageRouter configured to respond.',
          '',
          'The "agentAddress" field accepts: an Ethereum address, a participant name, "me", or "#N" (account index).',
          '',
          'Returns: The agent\'s capabilities including services, pricing, and usage instructions.',
          'If no response within the timeout, returns an error indicating the agent may be offline.',
          '',
          'Example: { "agentAddress": "0x1234567890abcdef1234567890abcdef12345678" }',
        ].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").'),
          agentAddress: z.string().describe('Target agent: Ethereum address, participant name, "me", or "#N" (account index).'),
          timeoutMs: z.coerce.number().int().min(1000).max(60_000).optional().describe('Timeout in milliseconds to wait for response. Defaults to 15000 (15 seconds). Max 60000.'),
        }),
      },

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