Send Mail and Trace
Send test emails through the mail infrastructure and trace their complete delivery path.
Prerequisites
- •mailtrace MCP server running with valid config
- •Network access: Client IP must be authorized by mail server relay policy, OR valid SMTP credentials in
data-generator/.env
Workflow
digraph send_mail_trace {
rankdir=TB;
"Send email with unique subject" [shape=box];
"Sending failed?" [shape=diamond];
"Wait 10-30 seconds" [shape=box];
"Query logs by recipient email" [shape=box];
"Found mail IDs?" [shape=diamond];
"Trace mail by ID" [shape=box];
"Report delivery status" [shape=box];
"Extend time range and retry" [shape=box];
"Trace existing mail instead" [shape=box];
"Send email with unique subject" -> "Sending failed?";
"Sending failed?" -> "Trace existing mail instead" [label="yes - access denied"];
"Sending failed?" -> "Wait 10-30 seconds" [label="no"];
"Wait 10-30 seconds" -> "Query logs by recipient email";
"Trace existing mail instead" -> "Query logs by recipient email";
"Query logs by recipient email" -> "Found mail IDs?";
"Found mail IDs?" -> "Trace mail by ID" [label="yes"];
"Found mail IDs?" -> "Extend time range and retry" [label="no"];
"Extend time range and retry" -> "Query logs by recipient email";
"Trace mail by ID" -> "Report delivery status";
}
Step 1: Send Test Email
Use the wrapper script in this skill directory:
/home/efficacy38/.claude/skills/send-mail/scripts/send-mail \
--config config.yaml \
--ssl-mode starttls \
--no-ssl-verify \
--rate 1 \
--duration 1 \
--mail-subject "Test $(date +%Y-%m-%d_%H:%M:%S) - Mailtrace Verification" \
--export-records /tmp/sent_emails.json
The wrapper script automatically:
- •Changes to the data-generator directory
- •Loads credentials from
.env - •Runs the traffic generator via
uvx
SSL Mode Options
| Mode | Port | Description | Command |
|---|---|---|---|
none | 25 | No encryption (plain SMTP) | --ssl-mode none |
starttls | 587/25 | Upgrade to TLS after connecting | --ssl-mode starttls |
smtps | 465 | SSL/TLS from connection start | --ssl-mode smtps --server-port 465 |
Common Flags
| Flag | Purpose |
|---|---|
--ssl-mode <mode> | SSL/TLS mode (none, starttls, smtps) |
--no-ssl-verify | Skip SSL certificate verification (for self-signed certs) |
--rate 1 --duration 1 | Send single email |
--mail-subject | Include timestamp for traceability |
--export-records | Save email metadata (message-id, queue-id) for tracing |
--no-auth | Disable authentication |
--server-host <host> | Override SMTP server from config |
--server-port <port> | Override SMTP port |
Exported records format (/tmp/sent_emails.json):
[
{
"timestamp": "2026-01-27T15:00:00.123456+00:00",
"message_id": "<uuid@traffic-generator.local>",
"queue_id": "ABC123DEF",
"subject": "Test 2026-01-27_15:00:00 - Mailtrace Verification",
"from": "sender@example.com",
"to": "recipient@example.com",
"success": true,
"status_code": 250
}
]
Use queue_id from this file to directly trace with mailtrace_trace_mail.
Step 2: Wait for Delivery
sleep 15
Mail typically takes 5-30 seconds to traverse relay chain.
Step 3: Query Logs
Use mailtrace MCP tool with email address or domain (not status phrases):
mailtrace_query_logs(
host="csmail1.test.cc.cs.nctu.edu.tw",
keywords=["recipient@domain.com"],
time="2026-01-27 15:00:00", # current time, server timezone (+08:00)
time_range="1h"
)
Valid keywords: Email addresses (user@example.com), domains (example.com)
Invalid keywords: Status phrases like status=sent won't match - these are log field values, not searchable text.
Step 4: Trace Mail
Use returned mail_id to trace complete path:
mailtrace_trace_mail(
host="csmail1.test.cc.cs.nctu.edu.tw",
mail_id="ABC123DEF",
time="2026-01-27 15:00:00",
time_range="1h"
)
Step 5: Verify Delivery
Check trace results for:
- •
status=sentwithdsn=2.0.0= successful delivery - •
status=deferred= temporary failure, will retry - •
status=bounced= permanent failure
Quick Reference
| Task | Command/Tool |
|---|---|
| Send email (STARTTLS) | send-mail --config config.yaml --ssl-mode starttls --no-ssl-verify --rate 1 --duration 1 |
| Send to different host | send-mail --config config.yaml --server-host <hostname> ... |
| Query logs | mailtrace_query_logs with recipient email |
| Trace path | mailtrace_trace_mail with mail_id |
| Check config | data-generator/config.yaml for SMTP settings |
| Credentials | data-generator/.env (username/password) |
Troubleshooting
| Error | Solution |
|---|---|
530 5.7.0 Must issue STARTTLS | Use --ssl-mode starttls |
SSL: WRONG_VERSION_NUMBER | Port/mode mismatch: use starttls for port 25/587, smtps for port 465 |
SSL: CERTIFICATE_VERIFY_FAILED | Add --no-ssl-verify for self-signed certificates |
554 5.7.1 Client host rejected | Check .env credentials or network access |
554 no valid recipients | Server requires auth - ensure .env has credentials |
535 Authentication failed | Check credentials in .env or use --no-auth to skip auth |
| No mail IDs found | Extend time_range to 2h or check keyword spelling |
| Empty trace graph | Mail delivered locally without relay hops |
Mail Server Clusters
- •
smtp-cluster: csmail1, csmail2 (outgoing relay) - start here for sent mail - •
mx-cluster: csmx1, csmx2 (incoming mail) - •
mailer-cluster: mailer4 (application mail) - •
maillist-cluster: maillist1, maillist2 (mailing lists)