Skip to main content
Glama

duplicate_email_as_draft

Create a draft email by copying an existing message while preserving its complete formatting and structure.

Instructions

Duplicate existing email as draft (preserving complete format)

Input Schema

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

Implementation Reference

  • The core handler function that duplicates an existing email as a new draft in Outlook. It uses PowerShell to invoke Outlook COM API, finds the source email by ID, creates a ReplyAll copy to preserve formatting, updates subject and recipients if provided, and saves it as a 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';
    }
  • Input schema definition for the duplicate_email_as_draft tool, specifying parameters like source_email_id (required), store_id, new_subject, and new_recipients.
    name: "duplicate_email_as_draft",
    description: "Duplicate existing email as draft (preserving complete format)",
    inputSchema: {
      type: "object",
      properties: {
        source_email_id: {
          type: "string",
          description: "Original email ID to duplicate"
        },
        store_id: {
          type: "string",
          description: "Store ID for the original email (optional but recommended)"
        },
        new_subject: {
          type: "string",
          description: "New email subject (optional)"
        },
        new_recipients: {
          type: "array",
          items: { type: "string" },
          description: "New recipient list (optional)"
        }
      },
      required: ["source_email_id"]
    }
  • src/index.ts:659-683 (registration)
    Tool registration in the CallToolRequestSchema handler switch statement. Extracts arguments, validates source_email_id, calls the OutlookManager.duplicateEmailAsDraft method, and formats the response.
    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(', ')}` : ''}`,
          },
        ],
      };
    }
  • src/index.js:175-196 (registration)
    Alternative registration and schema in the JavaScript version of index.js for list tools.
        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"]
        }
    }

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