Agent Skills
Email checker agent skills for AI. Verify emails in AI workflows and automation pipelines.
Agent Skills are pre-built capabilities that can be added to AI agents to extend their functionality. EmailVerify provides email verification skills for popular AI agent frameworks, with the crucial advantage of real SMTP verification.
Why SMTP Verification Matters for AI Agents
Most email verification approaches fail because they only check syntax and DNS. This misses 20-40% of invalid emails. SMTP verification is the only reliable method because it:
- Connects directly to the mail server on port 25
- Confirms the specific mailbox exists
- Provides 99.9% accuracy instead of guessing
Why you cannot DIY SMTP verification:
- Cloud providers (AWS, GCP, Azure) block port 25
- Building IP reputation takes months
- Anti-spam systems detect and block verification attempts
- Requires dedicated infrastructure across multiple regions
EmailVerify operates dedicated infrastructure with whitelisted IPs, making real SMTP verification available to AI agents.
What are Agent Skills?
Agent Skills are modular, reusable components that give AI agents specific capabilities:
- Plug-and-play: Add skills to your agent without writing verification logic
- Standardized interface: Works across different agent frameworks
- Best practices built-in: Error handling, rate limiting, and caching included
- Real SMTP verification: Not just syntax checking - actual mailbox confirmation
Supported Agent Frameworks
| Framework | Skill Type | Status |
|---|---|---|
| Claude Agent SDK | Tool | Supported |
| AutoGPT | Plugin | Supported |
| LangChain Agents | Tool | Supported |
| CrewAI | Tool | Supported |
| SuperAGI | Tool | Coming Soon |
Claude Agent SDK
The Claude Agent SDK makes it easy to build custom AI agents. Add email verification as a tool:
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const tools: Anthropic.Tool[] = [
{
name: "verify_email",
description: `Verify if an email address is valid and deliverable.
Returns:
- status: "valid", "invalid", or "unknown"
- deliverable: whether the email can receive messages
- disposable: whether it's a temporary email service
- role: whether it's a role-based address (info@, support@)
- score: confidence score from 0 to 1`,
input_schema: {
type: "object",
properties: {
email: {
type: "string",
description: "The email address to verify",
},
},
required: ["email"],
},
},
];
async function verifyEmail(email: string) {
const response = await fetch("https://api.emailverify.ai/v1/verify", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.EMAILVERIFY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ email }),
});
return response.json();
}
async function processToolCall(
toolName: string,
toolInput: Record<string, string>
) {
if (toolName === "verify_email") {
return await verifyEmail(toolInput.email);
}
throw new Error(`Unknown tool: ${toolName}`);
}
async function agentLoop(userMessage: string) {
const messages: Anthropic.MessageParam[] = [
{ role: "user", content: userMessage },
];
while (true) {
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 4096,
tools,
messages,
});
// Check if we need to process tool calls
if (response.stop_reason === "tool_use") {
const toolUseBlocks = response.content.filter(
(block): block is Anthropic.ToolUseBlock => block.type === "tool_use"
);
const toolResults: Anthropic.ToolResultBlockParam[] = [];
for (const toolUse of toolUseBlocks) {
const result = await processToolCall(
toolUse.name,
toolUse.input as Record<string, string>
);
toolResults.push({
type: "tool_result",
tool_use_id: toolUse.id,
content: JSON.stringify(result),
});
}
messages.push({ role: "assistant", content: response.content });
messages.push({ role: "user", content: toolResults });
} else {
// Agent is done
const textBlock = response.content.find(
(block): block is Anthropic.TextBlock => block.type === "text"
);
return textBlock?.text;
}
}
}
// Usage
const result = await agentLoop(
"I have a list of emails to verify: john@google.com, test@mailinator.com, support@microsoft.com. Check each one and tell me which are safe to use."
);
console.log(result);CrewAI Integration
Add email verification to your CrewAI agents:
from crewai import Agent, Task, Crew
from crewai_tools import tool
import requests
import os
@tool("Email Verification Tool")
def verify_email(email: str) -> str:
"""Verify if an email address is valid and deliverable.
Args:
email: The email address to verify
Returns:
Verification result with status, deliverability, and risk flags
"""
response = requests.post(
'https://api.emailverify.ai/v1/verify',
headers={
'Authorization': f'Bearer {os.environ["EMAILVERIFY_API_KEY"]}',
'Content-Type': 'application/json',
},
json={'email': email}
)
result = response.json()
return f"Email: {email}, Status: {result['status']}, Score: {result['score']}"
# Create an agent with the verification skill
data_quality_agent = Agent(
role='Data Quality Specialist',
goal='Ensure all email addresses in the database are valid and deliverable',
backstory='Expert in data validation and email deliverability',
tools=[verify_email],
verbose=True
)
# Create a task
verification_task = Task(
description='Verify the following email addresses and report which ones are invalid: {emails}',
expected_output='A report of all emails with their verification status',
agent=data_quality_agent
)
# Run the crew
crew = Crew(
agents=[data_quality_agent],
tasks=[verification_task]
)
result = crew.kickoff(inputs={
'emails': 'john@google.com, fake@invalid.xyz, test@mailinator.com'
})
print(result)AutoGPT Plugin
Create an AutoGPT plugin for email verification:
# autogpt_plugins/emailverify/__init__.py
from typing import Any, Dict, List, Optional, Tuple, TypeVar
import requests
import os
PromptGenerator = TypeVar("PromptGenerator")
class EmailVerifyPlugin:
def __init__(self):
self.api_key = os.environ.get("EMAILVERIFY_API_KEY")
@staticmethod
def get_name() -> str:
return "EmailVerify Email Verification"
def can_handle_post_prompt(self) -> bool:
return True
def post_prompt(self, prompt: PromptGenerator) -> PromptGenerator:
prompt.add_command(
"verify_email",
"Verify if an email is valid",
{"email": "<email_address>"},
self.verify_email
)
return prompt
def verify_email(self, email: str) -> str:
response = requests.post(
'https://api.emailverify.ai/v1/verify',
headers={
'Authorization': f'Bearer {self.api_key}',
'Content-Type': 'application/json',
},
json={'email': email}
)
result = response.json()
if result['status'] == 'valid':
return f"✅ {email} is valid (score: {result['score']})"
elif result['status'] == 'invalid':
return f"❌ {email} is invalid"
else:
return f"⚠️ {email} status unknown"Best Practices
1. Skill Description
Write clear descriptions so the agent knows when to use the skill:
description: `Verify if an email address is valid and deliverable.
Use this skill when:
- User asks to check an email address
- Validating contact information before saving
- Cleaning email lists
- Checking if an email is disposable or role-based
Returns: status, deliverability, disposable flag, role flag, confidence score`2. Error Handling
Build robust error handling into your skill:
@tool("Email Verification")
def verify_email(email: str) -> str:
try:
response = requests.post(
'https://api.emailverify.ai/v1/verify',
headers={
'Authorization': f'Bearer {os.environ["EMAILVERIFY_API_KEY"]}',
'Content-Type': 'application/json',
},
json={'email': email},
timeout=30
)
if response.status_code == 429:
return "Rate limit exceeded. Please try again later."
response.raise_for_status()
return response.json()
except requests.exceptions.Timeout:
return "Verification timed out. Please try again."
except Exception as e:
return f"Verification failed: {str(e)}"3. Batch Operations
For multiple emails, use the bulk endpoint:
const verifyBulkSkill = {
name: "verify_emails_bulk",
description: "Verify multiple email addresses at once. More efficient for lists.",
input_schema: {
type: "object",
properties: {
emails: {
type: "array",
items: { type: "string" },
description: "Array of emails to verify (max 100)",
},
},
required: ["emails"],
},
};