Safe Email for TaskWeaver Code Agents

Let TaskWeaver agents generate and execute email code — with MultiMail's API-level oversight catching every send regardless of how the code was written.


TaskWeaver is a code-first agent framework by Microsoft that converts natural language requests into executable Python code. When these generated code snippets include email operations, MultiMail's API-level oversight provides a critical safety layer — catching every send call regardless of how the code was structured.

Unlike tool-based frameworks where you control exactly which functions the agent can call, TaskWeaver generates arbitrary Python code. This means an agent could compose an email send in unexpected ways. MultiMail's oversight is enforced at the API endpoint, not the client side, so all sends are gated even from generated code.

Integration works through TaskWeaver's plugin system. Define a MultiMail plugin that exposes email functions, and TaskWeaver's planner will incorporate email capabilities into its generated code.

Built for TaskWeaver developers

API-Level Safety for Generated Code

TaskWeaver generates arbitrary Python code that may include email operations. MultiMail's oversight is enforced at the API layer, so even unexpected code patterns that call the send endpoint are properly gated.

Plugin-Based Integration

TaskWeaver's plugin system lets you define email functions that the planner can use when generating code. The agent gets structured access to MultiMail's API without needing to construct raw HTTP calls.

Stateful Email Sessions

TaskWeaver maintains stateful Python sessions across interactions. Email context like thread IDs, mailbox state, and draft content persists between code executions, enabling multi-step email workflows.

Prevention of Accidental Mass Emails

Generated code might loop over a dataset and send emails to every row. MultiMail's plan-level rate limits and gated_send mode prevent accidental mass email situations that could arise from code generation errors.


Get started in minutes

TaskWeaver MultiMail Plugin
python
"cm"># plugins/multimail.py — TaskWeaver plugin
import requests
from taskweaver.plugin import Plugin, register_plugin

MULTIMAIL_API = "https://api.multimail.dev/v1"
API_KEY = "mm_live_your_api_key"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

@register_plugin
class MultiMailPlugin(Plugin):
    name = "multimail"
    description = "Email operations via MultiMail API with human oversight"

    def send_email(self, to: str, subject: str, body: str,
                   mailbox_id: str) -> dict:
        """Send an email. In gated_send mode (default), the email
        is queued for human approval before delivery."""
        resp = requests.post(f"{MULTIMAIL_API}/send",
                             headers=HEADERS,
                             json={"mailbox_id": mailbox_id, "to": to,
                                   "subject": subject, "body": body})
        return resp.json()

    def check_inbox(self, mailbox_id: str, limit: int = 10) -> dict:
        """Check inbox for recent messages."""
        resp = requests.get(
            f"{MULTIMAIL_API}/mailboxes/{mailbox_id}/inbox",
            headers=HEADERS, params={"limit": limit})
        return resp.json()

    def reply_email(self, message_id: str, body: str) -> dict:
        """Reply to an email within its thread."""
        resp = requests.post(f"{MULTIMAIL_API}/reply",
                             headers=HEADERS,
                             json={"message_id": message_id,
                                   "body": body})
        return resp.json()

Define a TaskWeaver plugin that exposes MultiMail email functions to the code generation agent.

TaskWeaver Email Workflow
python
"cm"># TaskWeaver converts natural language to code using the plugin
"cm"># User says: "Check my inbox and summarize unread messages"

"cm"># TaskWeaver generates:
from plugins.multimail import MultiMailPlugin

mm = MultiMailPlugin()
inbox = mm.check_inbox(mailbox_id="your_mailbox_id", limit=20)

for msg in inbox.get("messages", []):
    print(f"From: {msg[&"cm">#039;from']}")
    print(f"Subject: {msg[&"cm">#039;subject']}")
    print(f"Preview: {msg.get(&"cm">#039;preview', 'No preview')}")
    print("---")

print(f"Total messages: {len(inbox.get(&"cm">#039;messages', []))}")

Natural language requests that TaskWeaver converts into email code using the MultiMail plugin.

Batch Email Processing with Safety
python
"cm"># User says: "Send a project update to all team leads"
"cm"># TaskWeaver generates code — MultiMail gates each send

from plugins.multimail import MultiMailPlugin

mm = MultiMailPlugin()

team_leads = [
    {"email": "[email protected]", "name": "Alice"},
    {"email": "[email protected]", "name": "Bob"},
    {"email": "[email protected]", "name": "Carol"}
]

results = []
for lead in team_leads:
    result = mm.send_email(
        to=lead["email"],
        subject="Weekly Project Update",
        body=f"Hi {lead[&"cm">#039;name']},\n\nHere is this week's "
             f"project update...\n\nBest regards",
        mailbox_id="your_mailbox_id"
    )
    results.append(result)
    print(f"Queued for {lead[&"cm">#039;name']}: {result.get('status')}")

# All 3 emails are queued in gated_send mode
# Human reviews and approves each one in the MultiMail dashboard
print(f"\n{len(results)} emails queued for approval")

TaskWeaver can generate code for batch email tasks while MultiMail's oversight prevents accidental mass sends.


Step by step

1

Create a MultiMail Account and API Key

Sign up at multimail.dev, create a mailbox, and generate an API key from your dashboard. Your key will start with mm_live_.

2

Install TaskWeaver

Install TaskWeaver and set up your project directory.

bash
pip install taskweaver requests
3

Create the MultiMail Plugin

Add a multimail.py file to your TaskWeaver plugins directory with functions for send_email, check_inbox, and reply_email that call the MultiMail REST API.

4

Test with Natural Language

Start a TaskWeaver session and make email-related requests in natural language. Verify that the generated code correctly uses the MultiMail plugin.

5

Approve Pending Emails

Check the MultiMail dashboard for emails queued by TaskWeaver's generated code. Review and approve before delivery.


Common questions

Can TaskWeaver-generated code bypass MultiMail's oversight?
No. MultiMail's oversight is enforced at the API level, not in the client code. Even if TaskWeaver generates code that calls the API directly (bypassing the plugin), the gated_send mode on the mailbox ensures every email is queued for human approval. The API key's permissions provide an additional boundary.
How do I prevent TaskWeaver from generating bulk email code?
Include constraints in the planner's system prompt that limit batch sizes. Additionally, MultiMail's plan-level rate limits (200-150,000 emails/month depending on tier) provide a hard backstop. The gated_send mode also means every individual email in a batch needs separate approval.
Can TaskWeaver's stateful sessions help with email workflows?
Yes. TaskWeaver maintains Python session state across interactions. Variables like thread IDs, draft content, and inbox results persist between code executions. This enables multi-step workflows: check inbox in one request, draft replies in another, and send in a third.
Does TaskWeaver work with the MultiMail MCP server?
TaskWeaver's plugin system is the recommended integration path. However, you could also have TaskWeaver generate code that calls the MCP server via subprocess. The plugin approach is simpler and provides better type safety for the code generator.

Explore more

The only agent email with a verifiable sender

Email infrastructure built for AI agents. Verifiable identity, graduated oversight, and a 38-tool MCP server. Formally verified in Lean 4.