create_email_draft
Generate and save an email draft in Outlook, including subject, body, recipient details, and optional file attachments, using file paths specified for attachments.
Instructions
Create an email draft with file path(s) as attachments
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| account_id | Yes | ||
| attachments | No | ||
| body | Yes | ||
| cc | No | ||
| subject | Yes | ||
| to | Yes |
Implementation Reference
- src/microsoft_mcp/tools.py:212-285 (handler)The handler function decorated with @mcp.tool that implements the create_email_draft tool. It constructs the email message, handles small and large attachments differently, creates the draft via Microsoft Graph API, and uploads large attachments.@mcp.tool def create_email_draft( account_id: str, to: str | list[str], subject: str, body: str, cc: str | list[str] | None = None, attachments: str | list[str] | None = None, ) -> dict[str, Any]: """Create an email draft with file path(s) as attachments""" to_list = [to] if isinstance(to, str) else to message = { "subject": subject, "body": {"contentType": "Text", "content": body}, "toRecipients": [{"emailAddress": {"address": addr}} for addr in to_list], } if cc: cc_list = [cc] if isinstance(cc, str) else cc message["ccRecipients"] = [ {"emailAddress": {"address": addr}} for addr in cc_list ] small_attachments = [] large_attachments = [] if attachments: # Convert single path to list attachment_paths = ( [attachments] if isinstance(attachments, str) else attachments ) for file_path in attachment_paths: path = pl.Path(file_path).expanduser().resolve() content_bytes = path.read_bytes() att_size = len(content_bytes) att_name = path.name if att_size < 3 * 1024 * 1024: small_attachments.append( { "@odata.type": "#microsoft.graph.fileAttachment", "name": att_name, "contentBytes": base64.b64encode(content_bytes).decode("utf-8"), } ) else: large_attachments.append( { "name": att_name, "content_bytes": content_bytes, "content_type": "application/octet-stream", } ) if small_attachments: message["attachments"] = small_attachments result = graph.request("POST", "/me/messages", account_id, json=message) if not result: raise ValueError("Failed to create email draft") message_id = result["id"] for att in large_attachments: graph.upload_large_mail_attachment( message_id, att["name"], att["content_bytes"], account_id, att.get("content_type", "application/octet-stream"), ) return result