Skip to main content
Glama

duplicate_email_as_draft

Recreate emails as drafts in Outlook by duplicating an existing email, preserving its format, and allowing customization of subject and recipients. Simplifies drafting emails with existing templates.

Instructions

Duplicate existing email as draft (preserving complete format)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
new_recipientsNoNew recipient list (optional)
new_subjectNoNew email subject (optional)
source_email_idYesOriginal email ID to duplicate
store_idNoStore ID for the original email (optional but recommended)

Implementation Reference

  • The core implementation of the duplicate_email_as_draft tool. Fetches the source email content using getEmailById and creates a new draft email using createDraft, optionally updating subject and recipients.
    async duplicateEmailAsDraft(sourceEmailId, newSubject, newRecipients) { // まず元のメールの内容を取得 const originalEmail = await this.getEmailById(sourceEmailId); // 新しい件名を設定(指定されていない場合は元の件名を使用) const finalSubject = newSubject || originalEmail.subject; // 新しい宛先を設定(指定されていない場合は空にする) const finalRecipients = newRecipients || []; // createDraftを使用して新しい下書きを作成 const draftData = { to: finalRecipients, subject: finalSubject, body: originalEmail.body }; return await this.createDraft(draftData); }
  • Input schema definition for the duplicate_email_as_draft tool, defining parameters source_email_id (required), new_subject, and new_recipients.
    { name: "duplicate_email_as_draft", description: "复制已有邮件为草稿(保持完整格式)", inputSchema: { type: "object", properties: { source_email_id: { type: "string", description: "要复制的原始邮件ID" }, new_subject: { type: "string", description: "新邮件主题(可选)" }, new_recipients: { type: "array", items: { type: "string" }, description: "新收件人列表(可选)" } }, required: ["source_email_id"] } }
  • src/index.js:342-358 (registration)
    Registration of the tool handler in the CallToolRequestSchema switch statement, which validates arguments and delegates to OutlookManager.duplicateEmailAsDraft.
    case 'duplicate_email_as_draft': { const sourceEmailId = args?.source_email_id; const newSubject = args?.new_subject; const newRecipients = args?.new_recipients; if (!sourceEmailId) { throw new Error('Source email ID is required'); } const result = await outlookManager.duplicateEmailAsDraft(sourceEmailId, newSubject, newRecipients); return { content: [ { type: 'text', text: `✅ **邮件复制成功**\n\n**结果:** ${result}${newSubject ? `\n**新主题:** ${newSubject}` : ''}${newRecipients ? `\n**新收件人:** ${newRecipients.join(', ')}` : ''}`, }, ], }; }
  • TypeScript version of the handler using Outlook's ReplyAll method to better preserve email formatting, tables, and styles when duplicating to draft.
    async duplicateEmailAsDraft(sourceEmailId: string, newSubject?: string, newRecipients?: string[], storeId?: string): Promise<string> { const script = ` try { Add-Type -AssemblyName "Microsoft.Office.Interop.Outlook" -ErrorAction Stop $outlook = New-Object -ComObject Outlook.Application -ErrorAction Stop $namespace = $outlook.GetNamespace("MAPI") # Find the original email using EntryID and StoreID $item = $null $sourceEntryID = "${sourceEmailId.replace(/"/g, '""')}" $sourceStoreID = "${(storeId || '').replace(/"/g, '""')}" # Try GetItemFromID with StoreID first, then fallback methods try { if ($sourceStoreID -and $sourceStoreID.Length -gt 0) { $item = $namespace.GetItemFromID($sourceEntryID, $sourceStoreID) } else { $item = $namespace.GetItemFromID($sourceEntryID) } } catch { # Fallback: search through folders $folders = @( $namespace.GetDefaultFolder(6), # Inbox $namespace.GetDefaultFolder(5), # Sent Items $namespace.GetDefaultFolder(16) # Drafts ) foreach ($folder in $folders) { try { foreach ($email in $folder.Items) { if ($email.EntryID -eq $sourceEntryID) { $item = $email break } } if ($item) { break } } catch { continue } } } if (-not $item) { throw "Original email not found with EntryID: $sourceEntryID" } # Use ReplyAll to preserve all formatting, then modify $draft = $item.ReplyAll() # Update subject if provided $subjectToUse = "${(newSubject || '').replace(/"/g, '""')}" if ($subjectToUse.Length -gt 0) { $draft.Subject = $subjectToUse } # Clear and set recipients if provided if ("${(newRecipients || []).join(',')}" -ne "") { $draft.Recipients.RemoveAll() $newRecipientsList = @("${(newRecipients || []).join('","')}") foreach ($recipient in $newRecipientsList) { if ($recipient.Trim().Length -gt 0) { $draft.Recipients.Add($recipient.Trim()) | Out-Null } } } # Resolve recipients and save try { $draft.Recipients.ResolveAll() | Out-Null } catch { } $draft.Save() Write-Output "success" } catch { Write-Output "error: $($_.Exception.Message)" } `; const result = await this.executePowerShell(script); if (result.startsWith('error:')) { throw new Error(result.substring(7)); } return 'Draft created successfully using ReplyAll method'; }
  • src/index.ts:659-683 (registration)
    TypeScript handler registration supporting optional store_id parameter.
    case 'duplicate_email_as_draft': { const sourceEmailId = (args as any)?.source_email_id; const newSubject = (args as any)?.new_subject; const newRecipients = (args as any)?.new_recipients; const storeId = (args as any)?.store_id; if (!sourceEmailId) { throw new Error('Source email ID is required'); } const result = await outlookManager.duplicateEmailAsDraft( sourceEmailId, newSubject, newRecipients, storeId ); return { content: [ { type: 'text', text: `✅ **Email duplicated successfully**\n\n**Result:** ${result}${newSubject ? `\n**New Subject:** ${newSubject}` : ''}${newRecipients ? `\n**New Recipients:** ${newRecipients.join(', ')}` : ''}`, }, ], }; }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cqyefeng119/windows-outlook-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server