Communication Tools (Email + WhatsApp)
Optional, side-effecting tools for real-world agent workflows: send, list, and read email/WhatsApp messages.
Safety first
- These tools can send real messages. Keep them behind an approval boundary / allowlist.
- Secrets are resolved from env vars at execution time (tool args carry env var names, not secrets).
- Default toolsets in AbstractRuntime only expose these tools when explicitly enabled.
What exists today
Email tools (SMTP/IMAP)
list_email_accountssend_emaillist_emailsread_email
WhatsApp tools (v1 provider: Twilio)
send_whatsapp_messagelist_whatsapp_messagesread_whatsapp_message
Importing the tools
from abstractcore.tools.comms_tools import (
list_email_accounts,
send_email,
list_emails,
read_email,
send_whatsapp_message,
list_whatsapp_messages,
read_whatsapp_message,
)
Execution boundaries (recommended)
Communication tools have real-world side effects. Keep them behind an allowlist / approval boundary in your host/runtime
(even if you use execute_tools=True).
from abstractcore.tools import ToolCall, ToolRegistry
from abstractcore.tools.comms_tools import send_email, send_whatsapp_message
dangerous_tools = {"send_email", "send_whatsapp_message"}
registry = ToolRegistry()
registry.register(send_email)
registry.register(send_whatsapp_message)
# In your agent loop:
for call in response.tool_calls or []:
name = call.get("name")
if name in dangerous_tools:
# gate via UI approval / allowlist / policy engine
continue
registry.execute_tool(ToolCall(name=name, arguments=call.get("arguments") or {}))
See Tool Calling System for a complete host/runtime execution flow.
Email (SMTP + IMAP)
Email tools are operator-configured: tool arguments cannot override SMTP/IMAP hosts, usernames, or secrets.
Configure one or more accounts first, then use tools like send_email / list_emails.
1) Configure accounts
Recommended: point AbstractCore to an accounts YAML file (supports multiple accounts + per-account allowlists).
The AbstractCore repo includes a template at configs/emails.yaml.
# Point to your accounts config file
export ABSTRACT_EMAIL_ACCOUNTS_CONFIG="$PWD/emails.yaml"
# Secrets stay in env vars
export EMAIL_PASSWORD="xxxx xxxx xxxx xxxx" # e.g. Gmail App Password
# Gmail example (values referenced by the YAML via ${ENV_VAR})
export ABSTRACT_EMAIL_IMAP_HOST="imap.gmail.com"
export ABSTRACT_EMAIL_IMAP_USERNAME="you@gmail.com"
export ABSTRACT_EMAIL_IMAP_PASSWORD_ENV_VAR="EMAIL_PASSWORD"
export ABSTRACT_EMAIL_SMTP_HOST="smtp.gmail.com"
export ABSTRACT_EMAIL_SMTP_PORT=587
export ABSTRACT_EMAIL_SMTP_USERNAME="you@gmail.com"
export ABSTRACT_EMAIL_SMTP_PASSWORD_ENV_VAR="EMAIL_PASSWORD"
export ABSTRACT_EMAIL_SMTP_STARTTLS=1
export ABSTRACT_EMAIL_FROM="you@gmail.com"
Prefer env vars for secrets. The config stores a reference (password_env_var), not the secret itself.
2) Discover available accounts
from abstractcore.tools.comms_tools import list_email_accounts
print(list_email_accounts()) # shows can_read/can_send + default account
3) Send an email
{
"name": "send_email",
"arguments": {
"to": "you@example.com",
"subject": "Daily report",
"body_text": "Hello! Here is the report..."
}
}
If you configured multiple accounts, pass account to select one. Otherwise, the default account is used.
4) List and read emails
{
"name": "list_emails",
"arguments": {
"since": "1d",
"status": "unread",
"limit": 20
}
}
{
"name": "read_email",
"arguments": {
"uid": "12345"
}
}
WhatsApp (Twilio example)
WhatsApp automation typically uses a provider (v1 uses Twilio). Credentials are read from env vars by default.
export TWILIO_ACCOUNT_SID="AC..."
export TWILIO_AUTH_TOKEN="..."
Send a WhatsApp message
{
"name": "send_whatsapp_message",
"arguments": {
"provider": "twilio",
"to": "+3306XXXXXXXX",
"from_number": "+14155238886",
"body": "Hello from AbstractCore",
"account_sid_env_var": "TWILIO_ACCOUNT_SID",
"auth_token_env_var": "TWILIO_AUTH_TOKEN"
}
}