View blogs | Login

Creating an AI-Powered Agent Integrated With an Email System

AI-powered solutions are the future, and many organizations are racing to develop them. A powerful solution typically combines resources from multiple external systems and provides a unified interface to the end user. For example, an AI-powered accounting system may integrate with several relational databases, banking systems, and email servers to collect the information needed to build the final solution. This document focuses on the steps necessary to build an AI-powered solution, including collecting information and communicating with an email system.

Use Cases

Fetching email status: Consider an example where your accounting system includes a chatbot that lets customers check their order status. The order status screen also displays email correspondence with the clients. In such cases, the interface will need to check the status of emails sent to and from the client, which is then presented to the client.

Sending emails: In many instances, it may be necessary to generate new emails to send to end users, to different employees within the organization, or to notify other subsystems.

Reading emails from an Inbox: Email delivery is asynchronous by design, requiring external systems to connect to the system via an email-fetching protocol such as IMAP or POP3. Using these protocols, external processes can pull emails from a user's inbox. Once an expected email is found, the system can take further action. For example, when a user is required to send documents as part of their workflow. Using these protocols, the AI-Powered system can pull newly arrived emails.

Data validation: It is common for users to mistype their email addresses. Validating the entered values is essential and should not be restricted to just a syntax check. In other words, a good email validator must ensure that the entire address, including the user part and the domain name, exists. AI Agents can use such validators to ensure that no mistakes are made when data is entered.

AI Tools

AI tools are software applications that use artificial intelligence to perform specific tasks, automate processes, and help with decision-making. They can also be defined as optional capabilities that an AI agent can use to access external information or execute actions, such as sending emails or checking the status of previously sent emails. These tools play an essential role by injecting recent, relevant information into AI prompts, enabling LLMs to generate up-to-date responses.

How AI Agent Tools Work

  • A typical AI Agent may have several tools. Each tool announces its purpose and how to use it. For example, a tool to check the email status may expose itself with a description like: Checks the status of a previously sent email when the recipient and sender's email addresses are available.
  • Once the available tools are exposed, the LLM can decide to call one or more of them.
  • The tool performs the action and returns the results to the AI agent, which then synthesizes the information and provides a response to the user.

Tools can be implemented as native functions in the applications that call the LLM or work in a client-server model using the Model Context Protocol (MCP)

How Xeams Facilitates Integration with AI Agents

Xeams offers several features that help organizations build intelligent AI-powered agents, making Xeams the perfect companion when building an AI-powered agent for your organization.

These tools include:

  • MCP Server
  • RESTful APIs
  • Webhooks

MCP Server:

The Xeams MCP server allows any MCP client to connect and fetch information. These MCP clients can exist in an AI front-end interface, such as Claude Desktop or Cursor AI, or as backend applications, as when building your own AI tool. In either case, you can pull useful information from MCP servers. For the Xeams MCP server, you can use it to validate email addresses and check the status of previously sent messages. The Xeams MCP server is an open-source tool available for download from GitHub - click here.

RESTful APIs:

Xeams publishes standard APIs that can be called from any HTTP client, allowing AI agents to retrieve information and send emails through Xeams. These APIs adhere to the OpenAPI standards, enabling easy implementation on the client's end. For more details, please click here. The following benefits are offered through this API.

  • Validating Email Address (username as well as the domain)
  • Check the status of previously sent emails
  • Sending new emails
  • Adding, modifying, and removing domains
  • Adding, modifying, and removing users
  • Managing distribution lists

Webhooks

Webhooks are an excellent mechanism for notifying an external system when specific events occur. For example, when an email results in a non-deliverable report (NDR), Xeams can notify another system in your organization that can take further steps to handle the workflow. Refer to This  link for additional details regarding this feature.

Implementation Example

Now, let's implement a couple of examples demonstrating the methods mentioned above. In production, you would write these methods either inside an MCP server or as a tool attached to your AI agent. For demonstration purposes, the code is written as a stand-alone script.

Prerequisite

You must take the following steps before running the code:

  • Download and install Xeams
  • Create an API key and secret:
  • Click Home > Plugins, and click the Manage button for Xeams API
  • Click Add API Key
  • Assign a Friendly Name, and select the "Allow Sending Emails" for Permissions.
  • Assign the generated API key, secret, and the URL for Xeams to the following environment variables:
  • XEAMS_URL=https://your.xeams.url
  • XEAMS_AUTH_KEY=ReplaceYourKey
  • XEAMS_SECRET=YourSecret

Now, you're ready to run the code.

Email Validation

The code below accepts three inputs:

  1. Recipient's email address - this will be validated
  2. Sender's email address - many email systems may also check the sender's address before accepting emails, and therefore, the validation routine requires this value.
  3. Deep: This is a boolean parameter that enables in-depth validation and confirms whether the user exists on the remote system. When this is false, the validation routine will only confirm whether an MX record exists for the recipient's email address.

Validate Results

The API returns an integer in response to the validation code, which has one of the following values:

  1. Email is valid
  2. The email address has a syntax error
  3. Domain name is invalid.
  4. The user is invalid. In other words, the domain name is correct, but the receiving server rejected the user.
  5. Inconclusive. This code is returned when Xeams cannot determine the results. For example, if the MX record points to a valid host, but a network issue prevents a connection. In such cases, results are inconclusive.

Example Code

	
#!/usr/bin/env python3
"""
Email validation script using Xeams API
Validates an email address using the /email/validate endpoint
"""

import os
import sys
import requests


def validate_email():
    # Read configuration from environment variables
    api_url = os.getenv('XEAMS_URL')
    auth_key = os.getenv('XEAMS_AUTH_KEY')
    secret = os.getenv('XEAMS_SECRET')
    
    # Validate environment variables
    if not api_url:
        print("Error: XEAMS_URL environment variable is not set")
        sys.exit(1)
    if not auth_key:
        print("Error: XEAMS_AUTH_KEY environment variable is not set")
        sys.exit(1)
    if not secret:
        print("Error: XEAMS_SECRET environment variable is not set")
        sys.exit(1)
    
    # Prompt user for recipient's email address
    recipient_email = input("Enter recipient's email address (re): ").strip()
    if not recipient_email:
        print("Error: Recipient's email address cannot be empty")
        sys.exit(1)
    
    # Prompt for sender's email address (required by API)
    sender_email = input("Enter sender's email address (se): ").strip()
    if not sender_email:
        print("Error: Sender's email address cannot be empty")
        sys.exit(1)
    
    # Optional: prompt for deep check
    deep_check = input("Perform deep check? (y/n, default: y): ").strip().lower()
    deep = True if deep_check != 'n' else False
    
    # Construct the API endpoint URL
    endpoint = f"{api_url.rstrip('/')}/email/validate"
    
    # Prepare query parameters
    params = {
        'auth-key': auth_key,
        'secret': secret,
        're': recipient_email,
        'se': sender_email,
        'deep': str(deep).lower()
    }
    
    try:
        # Make the API request
        print(f"\nValidating email: {recipient_email}...")
        response = requests.get(endpoint, params=params)
        
        # Parse response
        if response.status_code == 200:
            data = response.json()
            code = data.get('code', 0)
            description = data.get('description', 'No description')
            
            print(f"\nValidation Result:")
            print(f"  Code: {code}")
            print(f"  Description: {description}")
            
            # Interpret the code
            if code == 1:
                print("  Status: ? Email is valid")
            elif code == 2:
                print("  Status: ? Email address is invalid")
            elif code == 3:
                print("  Status: ? Domain is invalid")
            elif code == 4:
                print("  Status: ? User does not exist")
            elif code == 5:
                print("  Status: ? Inconclusive (server not listening or greylisted)")
            else:
                print(f"  Status: Unknown code")
                
        elif response.status_code == 400:
            print(f"Error: Bad request - {response.json().get('description', 'Invalid input')}")
            sys.exit(1)
        elif response.status_code == 401:
            print("Error: Invalid auth-key or secret")
            sys.exit(1)
        else:
            print(f"Error: Unexpected response (HTTP {response.status_code})")
            print(response.text)
            sys.exit(1)
            
    except requests.exceptions.RequestException as e:
        print(f"Error: Failed to connect to API - {e}")
        sys.exit(1)
    except Exception as e:
        print(f"Error: {e}")
        sys.exit(1)


if __name__ == "__main__":
    validate_email()
	
	
	
#!/usr/bin/env node
/**
 * Email validation script using Xeams API
 * Validates an email address using the /email/validate endpoint
 */

import * as readline from 'readline';

interface ValidationResponse {
  code: number;
  description: string;
}

async function prompt(question: string): Promise {
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });

  return new Promise((resolve) => {
    rl.question(question, (answer) => {
      rl.close();
      resolve(answer.trim());
    });
  });
}

async function validateEmail(): Promise {
  // Read configuration from environment variables
  const apiUrl = process.env.XEAMS_URL;
  const authKey = process.env.XEAMS_AUTH_KEY;
  const secret = process.env.XEAMS_SECRET;

  // Validate environment variables
  if (!apiUrl) {
    console.error('Error: XEAMS_URL environment variable is not set');
    process.exit(1);
  }
  if (!authKey) {
    console.error('Error: XEAMS_AUTH_KEY environment variable is not set');
    process.exit(1);
  }
  if (!secret) {
    console.error('Error: XEAMS_SECRET environment variable is not set');
    process.exit(1);
  }

  // Prompt user for recipient's email address
  const recipientEmail = await prompt("Enter recipient's email address (re): ");
  if (!recipientEmail) {
    console.error("Error: Recipient's email address cannot be empty");
    process.exit(1);
  }

  // Prompt for sender's email address (required by API)
  const senderEmail = await prompt("Enter sender's email address (se): ");
  if (!senderEmail) {
    console.error("Error: Sender's email address cannot be empty");
    process.exit(1);
  }

  // Optional: prompt for deep check
  const deepCheckInput = await prompt('Perform deep check? (y/n, default: y): ');
  const deep = deepCheckInput.toLowerCase() !== 'n';

  // Construct the API endpoint URL
  const endpoint = `${apiUrl.replace(/\/$/, '')}/email/validate`;

  // Prepare query parameters
  const params = new URLSearchParams({
    'auth-key': authKey,
    'secret': secret,
    're': recipientEmail,
    'se': senderEmail,
    'deep': String(deep)
  });

  try {
    // Make the API request
    console.log(`\nValidating email: ${recipientEmail}...`);
    const response = await fetch(`${endpoint}?${params.toString()}`);

    // Parse response
    if (response.status === 200) {
      const data: ValidationResponse = await response.json();
      const code = data.code || 0;
      const description = data.description || 'No description';

      console.log('\nValidation Result:');
      console.log(`  Code: ${code}`);
      console.log(`  Description: ${description}`);

      // Interpret the code
      switch (code) {
        case 1:
          console.log('  Status: ? Email is valid');
          break;
        case 2:
          console.log('  Status: ? Email address is invalid');
          break;
        case 3:
          console.log('  Status: ? Domain is invalid');
          break;
        case 4:
          console.log('  Status: ? User does not exist');
          break;
        case 5:
          console.log('  Status: ? Inconclusive (server not listening or greylisted)');
          break;
        default:
          console.log('  Status: Unknown code');
      }
    } else if (response.status === 400) {
      const data: ValidationResponse = await response.json();
      console.error(`Error: Bad request - ${data.description || 'Invalid input'}`);
      process.exit(1);
    } else if (response.status === 401) {
      console.error('Error: Invalid auth-key or secret');
      process.exit(1);
    } else {
      console.error(`Error: Unexpected response (HTTP ${response.status})`);
      console.error(await response.text());
      process.exit(1);
    }
  } catch (error) {
    if (error instanceof Error) {
      console.error(`Error: Failed to connect to API - ${error.message}`);
    } else {
      console.error(`Error: ${error}`);
    }
    process.exit(1);
  }
}

// Run the script
validateEmail();
	
	
	
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

/**
 * Email validation script using Xeams API
 * Validates an email address using the /email/validate endpoint
 * Compatible with JRE 21
 */
public class validate {
    
    private static final HttpClient httpClient = HttpClient.newHttpClient();
    
    public static void main(String[] args) {
        try {
            validateEmail();
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
            System.exit(1);
        }
    }
    
    private static void validateEmail() throws IOException, InterruptedException {
        // Read configuration from environment variables
        String apiUrl = System.getenv("XEAMS_URL");
        String authKey = System.getenv("XEAMS_AUTH_KEY");
        String secret = System.getenv("XEAMS_SECRET");
        
        // Validate environment variables
        if (apiUrl == null || apiUrl.isEmpty()) {
            System.err.println("Error: XEAMS_URL environment variable is not set");
            System.exit(1);
        }
        if (authKey == null || authKey.isEmpty()) {
            System.err.println("Error: XEAMS_AUTH_KEY environment variable is not set");
            System.exit(1);
        }
        if (secret == null || secret.isEmpty()) {
            System.err.println("Error: XEAMS_SECRET environment variable is not set");
            System.exit(1);
        }
        
        Scanner scanner = new Scanner(System.in);
        
        // Prompt user for recipient's email address
        System.out.print("Enter recipient's email address (re): ");
        String recipientEmail = scanner.nextLine().trim();
        if (recipientEmail.isEmpty()) {
            System.err.println("Error: Recipient's email address cannot be empty");
            System.exit(1);
        }
        
        // Prompt for sender's email address (required by API)
        System.out.print("Enter sender's email address (se): ");
        String senderEmail = scanner.nextLine().trim();
        if (senderEmail.isEmpty()) {
            System.err.println("Error: Sender's email address cannot be empty");
            System.exit(1);
        }
        
        // Optional: prompt for deep check
        System.out.print("Perform deep check? (y/n, default: y): ");
        String deepCheckInput = scanner.nextLine().trim().toLowerCase();
        boolean deep = !deepCheckInput.equals("n");
        
        scanner.close();
        
        // Construct the API endpoint URL
        String endpoint = apiUrl.replaceAll("/$", "") + "/email/validate";
        
        // Build query parameters
        String queryParams = String.format(
            "auth-key=%s&secret=%s&re=%s&se=%s&deep=%s",
            URLEncoder.encode(authKey, StandardCharsets.UTF_8),
            URLEncoder.encode(secret, StandardCharsets.UTF_8),
            URLEncoder.encode(recipientEmail, StandardCharsets.UTF_8),
            URLEncoder.encode(senderEmail, StandardCharsets.UTF_8),
            String.valueOf(deep)
        );
        
        String fullUrl = endpoint + "?" + queryParams;
        
        // Create HTTP request
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(fullUrl))
            .GET()
            .build();
        
        try {
            // Make the API request
            System.out.println("\nValidating email: " + recipientEmail + "...");
            HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            
            // Parse response
            int statusCode = response.statusCode();
            String responseBody = response.body();
            
            if (statusCode == 200) {
                ValidationResponse data = parseResponse(responseBody);
                int code = data.code;
                String description = data.description;
                
                System.out.println("\nValidation Result:");
                System.out.println("  Code: " + code);
                System.out.println("  Description: " + description);
                
                // Interpret the code
                switch (code) {
                    case 1:
                        System.out.println("  Status: ? Email is valid");
                        break;
                    case 2:
                        System.out.println("  Status: ? Email address is invalid");
                        break;
                    case 3:
                        System.out.println("  Status: ? Domain is invalid");
                        break;
                    case 4:
                        System.out.println("  Status: ? User does not exist");
                        break;
                    case 5:
                        System.out.println("  Status: ? Inconclusive (server not listening or greylisted)");
                        break;
                    default:
                        System.out.println("  Status: Unknown code");
                }
            } else if (statusCode == 400) {
                ValidationResponse data = parseResponse(responseBody);
                System.err.println("Error: Bad request - " + data.description);
                System.exit(1);
            } else if (statusCode == 401) {
                System.err.println("Error: Invalid auth-key or secret");
                System.exit(1);
            } else {
                System.err.println("Error: Unexpected response (HTTP " + statusCode + ")");
                System.err.println(responseBody);
                System.exit(1);
            }
        } catch (IOException | InterruptedException e) {
            System.err.println("Error: Failed to connect to API - " + e.getMessage());
            System.exit(1);
        }
    }
    
    private static ValidationResponse parseResponse(String json) {
        // Simple JSON parsing for code and description
        ValidationResponse response = new ValidationResponse();
        
        // Extract code
        int codeIndex = json.indexOf("\"code\"");
        if (codeIndex != -1) {
            int colonIndex = json.indexOf(":", codeIndex);
            int commaIndex = json.indexOf(",", colonIndex);
            if (commaIndex == -1) {
                commaIndex = json.indexOf("}", colonIndex);
            }
            String codeStr = json.substring(colonIndex + 1, commaIndex).trim();
            response.code = Integer.parseInt(codeStr);
        }
        
        // Extract description
        int descIndex = json.indexOf("\"description\"");
        if (descIndex != -1) {
            int colonIndex = json.indexOf(":", descIndex);
            int quoteStart = json.indexOf("\"", colonIndex);
            int quoteEnd = json.indexOf("\"", quoteStart + 1);
            response.description = json.substring(quoteStart + 1, quoteEnd);
        } else {
            response.description = "No description";
        }
        
        return response;
    }
    
    private static class ValidationResponse {
        int code = 0;
        String description = "No description";
    }
}
	
	

Summary

AI-powered agents need to fetch relevant, up-to-date information and inject it into the user's prompt to achieve better results. The combination of MCP Server, RESTful APIs, and Webhooks makes Xeams an indispensable tool when integrating AI-powered agents with an email system.


Created on: Nov 25, 2025
Last updated on: Nov 26, 2025

LEAVE A COMMENT

Your email address will not be published.