Custom Tools
Email Triggers
Email triggers let any code tool receive and process inbound email. Forward a receipt, send a report, or pipe alerts — the tool processes the email body and attachments automatically.
Enable Email for a Tool
tool(action="email_enable", tool_id="tool_abc123")
This gives the tool a unique email address like [email protected]. Any email sent to this address will trigger the tool.
How It Works
- Email arrives at the tool's address
- Kyew parses the email (sender, subject, body, attachments)
- Your code tool's
fetchhandler receives the parsed email as JSON input - The tool processes it and returns a result
Input Format
Your code tool receives:
{
"from": "[email protected]",
"to": "[email protected]",
"subject": "March expense report",
"text": "Plain text body",
"html": "<p>HTML body</p>",
"attachments": [
{
"filename": "report.csv",
"content_type": "text/csv",
"size": 1234,
"content_base64": "..."
}
]
}
Sender Allowlists
By default, only the tool owner's email is allowed. Add trusted senders:
tool(action="email_allowlist_add", tool_id="tool_abc123", email="[email protected]")
Manage the Allowlist
tool(action="email_allowlist_list", tool_id="tool_abc123")
tool(action="email_allowlist_remove", tool_id="tool_abc123", email="[email protected]")
Allow All Org Members
For team tools, allow anyone in your organization:
tool(action="email_allow_org", tool_id="tool_abc123", allow_org_members=true)
View Email History
See recent emails processed by a tool:
tool(action="email_history", tool_id="tool_abc123")
Check Email Config
See a tool's email address and current settings:
tool(action="email_config", tool_id="tool_abc123")
Disable Email
tool(action="email_disable", tool_id="tool_abc123")
Example: Expense Tracker
A tool that processes forwarded receipts:
tool(action="create",
name="receipt_processor",
description="Process forwarded receipt emails and log expenses",
tool_type="code",
input_schema={
type: "object",
properties: {
from: { type: "string" },
subject: { type: "string" },
text: { type: "string" }
}
},
code_config={
code: `
import { exec, query } from "./db.mjs";
export default {
async fetch(request) {
const { from, subject, text } = await request.json();
await exec(\`
CREATE TABLE IF NOT EXISTS expenses (
id INTEGER PRIMARY KEY AUTOINCREMENT,
sender TEXT, subject TEXT, body TEXT,
created_at TEXT DEFAULT (datetime('now'))
)
\`);
await exec(
"INSERT INTO expenses (sender, subject, body) VALUES (?, ?, ?)",
from, subject, text
);
const count = await query("SELECT COUNT(*) as total FROM expenses");
return Response.json({
logged: true,
total_expenses: count.rows[0].total
});
}
}`,
runtime: "javascript",
allowed_domains: []
})
Then enable email:
tool(action="email_enable", tool_id="tool_abc123")
tool(action="email_allowlist_add", tool_id="tool_abc123", email="[email protected]")
Combining with Scheduling
Email triggers and scheduling work together. A tool can receive emails throughout the day and send a daily digest on a schedule. See Scheduling.