Skip to main content
Glama

azeth_receive_messages

Read encrypted XMTP messages from other agents or services. Check specific conversations or get an inbox overview of latest messages.

Instructions

Read incoming encrypted messages from the XMTP messaging network.

Use this when: You want to check for messages from other agents or services. This is the "inbox" view — it lets you read what others have sent you.

Two modes:

  1. With "from": Read messages from a specific sender (up to "limit" messages)

  2. Without "from": Read the latest message from each conversation (inbox overview)

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

Returns: Array of messages with sender address, content, timestamp, and conversation ID.

Note: XMTP messages are end-to-end encrypted. The account reading messages is determined by the AZETH_PRIVATE_KEY environment variable. First call may be slow due to XMTP initialization.

Example: { "from": "Alice", "limit": 10 } or { } (all conversations)

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").
fromNoRead messages from a specific sender. Accepts: address, name, "me", "#N". Omit for inbox overview.
limitNoMaximum messages to return. Defaults to 20. Max 100.

Implementation Reference

  • The handler implementation for azeth_receive_messages. It supports two modes: retrieving messages from a specific sender or providing an inbox overview with the latest message per conversation.
      async (args) => {
        let client;
        try {
          client = await createClient(args.chain);
          const limit = args.limit ?? 20;
    
          if (args.from) {
            // Mode 1: Messages from specific sender
            let fromResolved;
            try {
              fromResolved = await resolveAddress(args.from, client);
            } catch (resolveErr) {
              return handleError(resolveErr);
            }
    
            const messages = await client.getMessages(fromResolved.address, limit);
    
            return success({
              from: fromResolved.address,
              ...(fromResolved.resolvedFrom ? { resolvedFrom: `"${fromResolved.resolvedFrom}" → ${fromResolved.address}` } : {}),
              messageCount: messages.length,
              messages: messages.map(msg => ({
                sender: msg.sender,
                content: msg.content,
                timestamp: new Date(msg.timestamp).toISOString(),
                conversationId: msg.conversationId,
              })),
            });
          } else {
            // Mode 2: Inbox overview — latest message per conversation
            const conversations = await client.getConversations();
    
            // For each conversation, get the latest message
            const inbox = [];
            for (const conv of conversations.slice(0, limit)) {
              try {
                const messages = await client.getMessages(conv.peerAddress, 1);
                inbox.push({
                  conversationId: conv.id,
                  peerAddress: conv.peerAddress,
                  createdAt: new Date(conv.createdAt).toISOString(),
                  latestMessage: messages.length > 0 ? {
                    content: messages[0]!.content,
                    sender: messages[0]!.sender,
                    timestamp: new Date(messages[0]!.timestamp).toISOString(),
                  } : null,
                });
              } catch {
                // Skip conversations that fail to load
                inbox.push({
                  conversationId: conv.id,
                  peerAddress: conv.peerAddress,
                  createdAt: new Date(conv.createdAt).toISOString(),
                  latestMessage: null,
                });
              }
            }
    
            return success({
              conversationCount: conversations.length,
              showing: inbox.length,
              inbox,
            });
          }
        } catch (err) {
          return handleError(err);
        } finally {
          try { await client?.destroy(); } catch { /* M-10: prevent destroy from masking the original error */ }
        }
      },
    );
  • The input schema validation for azeth_receive_messages using Zod.
      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").'),
        from: z.string().optional().describe('Read messages from a specific sender. Accepts: address, name, "me", "#N". Omit for inbox overview.'),
        limit: z.coerce.number().int().min(1).max(100).optional().describe('Maximum messages to return. Defaults to 20. Max 100.'),
      }),
    },
  • Registration of the azeth_receive_messages tool within the MCP server.
    server.registerTool(
      'azeth_receive_messages',

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