get_draft_emails
Retrieve draft emails from Microsoft Outlook to review, edit, or send pending messages.
Instructions
Get draft emails list
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Number of draft emails to retrieve |
Implementation Reference
- src/index.ts:623-637 (handler)MCP server request handler case for 'get_draft_emails': parses input count, fetches drafts via OutlookManager, and returns formatted markdown list of draft emails.case 'get_draft_emails': { const count = (args as any)?.count || 10; const drafts = await outlookManager.getDraftEmails(count); return { content: [ { type: 'text', text: `š **Draft Email Overview**\nTotal: ${drafts.length} drafts\n\nš **Draft Email List:**\n` + drafts.map((draft, index) => `${index + 1}. **${draft.subject}**\n From: ${draft.sender}\n Time: ${draft.receivedTime}\n EntryID: ${draft.id}\n StoreID: ${draft.storeId || 'N/A'}\n Preview: ${draft.body?.substring(0, 100)}...\n` ).join('\n') }, ], }; }
- src/outlook-manager.ts:224-226 (handler)Core handler method getDraftEmails that retrieves draft emails from Outlook Drafts folder (folder type 16) using the shared getEmailsFromFolder helper.async getDraftEmails(count: number = 10): Promise<EmailMessage[]> { return this.getEmailsFromFolder(16, count, "[LastModificationTime]"); // 16 = Drafts }
- src/outlook-manager.ts:87-191 (helper)Shared helper function getEmailsFromFolder executes PowerShell script using Outlook COM interop to fetch, parse, and return EmailMessage[] from any specified folder (Inbox=6, Sent=5, Drafts=16), with sorting, limiting, cleaning, and fallback handling.private async getEmailsFromFolder(folderType: number, count: number = 10, sortBy: string = "[ReceivedTime]"): Promise<EmailMessage[]> { const script = ` try { Add-Type -AssemblyName "Microsoft.Office.Interop.Outlook" -ErrorAction Stop $outlook = New-Object -ComObject Outlook.Application -ErrorAction Stop $namespace = $outlook.GetNamespace("MAPI") $folder = $namespace.GetDefaultFolder(${folderType}) if ($folder.Items.Count -eq 0) { Write-Output "[]" exit 0 } $items = $folder.Items $items.Sort("${sortBy}", $true) $emails = @() $counter = 0 foreach ($item in $items) { if ($counter -ge ${count}) { break } try { $subject = if ($item.Subject) { $item.Subject.ToString() -replace '[\\x00-\\x1F\\x7F]', '' } else { "No Subject" } $sender = if ($item.SenderEmailAddress) { $item.SenderEmailAddress.ToString() -replace '[\\x00-\\x1F\\x7F]', '' } else { "Unknown" } $body = if ($item.Body) { $bodyStr = $item.Body.ToString() -replace '[\\x00-\\x1F\\x7F]', '' if ($bodyStr.Length -gt 150) { $bodyStr.Substring(0, 150) + "..." } else { $bodyStr } } else { "" } $timeStamp = if ($item.SentOn -and ${folderType} -eq 5) { $item.SentOn.ToString("yyyy-MM-dd HH:mm:ss") } elseif ($item.ReceivedTime) { $item.ReceivedTime.ToString("yyyy-MM-dd HH:mm:ss") } else { (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") } $emails += [PSCustomObject]@{ Id = if ($item.EntryID) { $item.EntryID.ToString() } else { "no-id-$counter" } StoreID = if ($item.Session -and $item.Session.DefaultStore -and $item.Session.DefaultStore.StoreID) { $item.Session.DefaultStore.StoreID.ToString() } elseif ($item.Parent -and $item.Parent.StoreID) { $item.Parent.StoreID.ToString() } else { try { $namespace.DefaultStore.StoreID.ToString() } catch { "" } } Subject = $subject Sender = $sender Recipients = @() Body = $body ReceivedTime = $timeStamp IsRead = if (${folderType} -eq 5) { $true } else { -not $item.UnRead } HasAttachments = $item.Attachments.Count -gt 0 } $counter++ } catch { $counter++; continue } } if ($emails.Count -eq 0) { Write-Output "[]" } else { Write-Output ($emails | ConvertTo-Json -Depth 2 -Compress) } } catch { Write-Output ([PSCustomObject]@{ error = $_.Exception.Message; type = "OutlookConnectionError" } | ConvertTo-Json -Compress) } `; try { const result = await this.executePowerShell(script); if (!result || result.trim() === '') return []; const cleanResult = result.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/g, '').trim(); const parsed = JSON.parse(cleanResult); if (parsed.error) throw new Error(`Outlook Error: ${parsed.error}`); const emailArray = Array.isArray(parsed) ? parsed : [parsed]; return emailArray.map((item: any) => ({ id: this.cleanText(item.Id || ''), storeId: this.cleanText(item.StoreID || ''), subject: this.cleanText(item.Subject || 'No Subject'), sender: this.cleanText(item.Sender || 'Unknown'), recipients: [], body: this.cleanText(item.Body || ''), receivedTime: new Date(item.ReceivedTime), isRead: Boolean(item.IsRead), hasAttachments: Boolean(item.HasAttachments) })); } catch (error) { console.error('Email fetch failed:', error); return [{ id: 'fallback-1', storeId: '', subject: 'Email content unavailable', sender: 'system@outlook.com', recipients: [], body: 'Unable to retrieve email content.', receivedTime: new Date(), isRead: true, hasAttachments: false }]; } }
- src/index.ts:184-197 (registration)Tool registration in ListToolsRequestSchema handler: defines name, description, and inputSchema for get_draft_emails.{ name: "get_draft_emails", description: "Get draft emails list", inputSchema: { type: "object", properties: { count: { type: "number", description: "Number of draft emails to retrieve", default: 10 } } } },
- src/outlook-manager.ts:3-13 (schema)TypeScript interface EmailMessage defining the structure of email objects returned by getDraftEmails and other email fetching methods.export interface EmailMessage { id: string; storeId?: string; subject: string; sender: string; recipients: string[]; body: string; receivedTime: Date; isRead: boolean; hasAttachments: boolean; }