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
| 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"). | |
| agentAddress | Yes | Target agent: Ethereum address, participant name, "me", or "#N" (account index). | |
| timeoutMs | No | Timeout in milliseconds to wait for response. Defaults to 15000 (15 seconds). Max 60000. |
Implementation Reference
- src/tools/messaging.ts:300-369 (handler)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 */ } } }, ); - src/tools/messaging.ts:294-298 (schema)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.'), }), - src/tools/messaging.ts:275-299 (registration)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.'), }), },