pin_email
Pin an email to keep it prominent, or unpin it to remove the flag. Provide the email ID and set pinned to true or false.
Instructions
Pin or unpin an email
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| emailId | Yes | ID of the email to pin/unpin | |
| pinned | No | true to pin, false to unpin |
Implementation Reference
- src/index.ts:1424-1439 (handler)Handler case for the 'pin_email' tool. Extracts emailId and pinned args, calls JmapClient.pinEmail(), and returns success message.
case 'pin_email': { const { emailId, pinned = true } = args as any; if (!emailId) { throw new McpError(ErrorCode.InvalidParams, 'emailId is required'); } const client = initializeClient(); await client.pinEmail(emailId, pinned); return { content: [ { type: 'text', text: `Email ${pinned ? 'pinned' : 'unpinned'} successfully`, }, ], }; } - src/index.ts:629-647 (schema)Input schema registration for the 'pin_email' tool, defining emailId (required string) and pinned (optional boolean, default true).
{ name: 'pin_email', description: 'Pin or unpin an email', inputSchema: { type: 'object', properties: { emailId: { type: 'string', description: 'ID of the email to pin/unpin', }, pinned: { type: 'boolean', description: 'true to pin, false to unpin', default: true, }, }, required: ['emailId'], }, }, - src/jmap-client.ts:776-800 (handler)Core JMAP implementation of pinEmail. Uses Email/set to toggle the $flagged keyword (true to pin, null to unpin).
async pinEmail(emailId: string, pinned: boolean = true): Promise<void> { const session = await this.getSession(); const update: Record<string, any> = {}; update[emailId] = pinned ? { 'keywords/$flagged': true } : { 'keywords/$flagged': null }; const request: JmapRequest = { using: ['urn:ietf:params:jmap:core', 'urn:ietf:params:jmap:mail'], methodCalls: [ ['Email/set', { accountId: session.accountId, update }, 'pinEmail'] ] }; const response = await this.makeRequest(request); const result = this.getMethodResult(response, 0); if (result.notUpdated && result.notUpdated[emailId]) { throw new Error(`Failed to ${pinned ? 'pin' : 'unpin'} email.`); } } - src/index.ts:629-990 (registration)Tool registration within the ListToolsRequestSchema handler (lines 629-647 for pin_email definition).
{ name: 'pin_email', description: 'Pin or unpin an email', inputSchema: { type: 'object', properties: { emailId: { type: 'string', description: 'ID of the email to pin/unpin', }, pinned: { type: 'boolean', description: 'true to pin, false to unpin', default: true, }, }, required: ['emailId'], }, }, { name: 'delete_email', description: 'Delete an email (move to trash)', inputSchema: { type: 'object', properties: { emailId: { type: 'string', description: 'ID of the email to delete', }, }, required: ['emailId'], }, }, { name: 'move_email', description: 'Move an email to a different mailbox', inputSchema: { type: 'object', properties: { emailId: { type: 'string', description: 'ID of the email to move', }, targetMailboxId: { type: 'string', description: 'ID of the target mailbox', }, }, required: ['emailId', 'targetMailboxId'], }, }, { name: 'add_labels', description: 'Add labels (mailboxes) to an email without removing existing ones', inputSchema: { type: 'object', properties: { emailId: { type: 'string', description: 'ID of the email to add labels to', }, mailboxIds: { type: 'array', items: { type: 'string' }, description: 'Array of mailbox IDs to add as labels', }, }, required: ['emailId', 'mailboxIds'], }, }, { name: 'remove_labels', description: 'Remove specific labels (mailboxes) from an email', inputSchema: { type: 'object', properties: { emailId: { type: 'string', description: 'ID of the email to remove labels from', }, mailboxIds: { type: 'array', items: { type: 'string' }, description: 'Array of mailbox IDs to remove as labels', }, }, required: ['emailId', 'mailboxIds'], }, }, { name: 'get_email_attachments', description: 'Get list of attachments for an email', inputSchema: { type: 'object', properties: { emailId: { type: 'string', description: 'ID of the email', }, }, required: ['emailId'], }, }, { name: 'download_attachment', description: 'Download an email attachment. If savePath is provided, saves the file to disk and returns the file path and size. Otherwise returns a download URL.', inputSchema: { type: 'object', properties: { emailId: { type: 'string', description: 'ID of the email', }, attachmentId: { type: 'string', description: 'ID of the attachment', }, savePath: { type: 'string', description: `File path to save the attachment to. Paths are restricted to ${getDownloadDir() || '~/Downloads/fastmail-mcp/'} (configurable via FASTMAIL_DOWNLOAD_DIR). Path traversal outside this directory is rejected for security. Parent directories will be created automatically.`, }, }, required: ['emailId', 'attachmentId'], }, }, { name: 'advanced_search', description: 'Advanced email search with multiple criteria', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Text to search for in subject/body', }, from: { type: 'string', description: 'Filter by sender email', }, to: { type: 'string', description: 'Filter by recipient email', }, subject: { type: 'string', description: 'Filter by subject', }, hasAttachment: { type: 'boolean', description: 'Filter emails with attachments', }, isUnread: { type: 'boolean', description: 'Filter unread emails', }, isPinned: { type: 'boolean', description: 'Filter pinned emails', }, mailboxId: { type: 'string', description: 'Search within specific mailbox', }, after: { type: 'string', description: 'Emails after this date (ISO 8601)', }, before: { type: 'string', description: 'Emails before this date (ISO 8601)', }, limit: { type: ['number', 'string'], description: 'Maximum results (default: 50)', default: 50, }, ascending: { type: 'boolean', description: 'Sort oldest first instead of newest first (default: false)', }, }, }, }, { name: 'get_thread', description: 'Get all emails in a conversation thread', inputSchema: { type: 'object', properties: { threadId: { type: 'string', description: 'ID of the thread/conversation', }, }, required: ['threadId'], }, }, { name: 'get_mailbox_stats', description: 'Get statistics for a mailbox (unread count, total emails, etc.)', inputSchema: { type: 'object', properties: { mailboxId: { type: 'string', description: 'ID of the mailbox (optional, defaults to all mailboxes)', }, }, }, }, { name: 'get_account_summary', description: 'Get overall account summary with statistics', inputSchema: { type: 'object', properties: {}, }, }, { name: 'bulk_mark_read', description: 'Mark multiple emails as read/unread', inputSchema: { type: 'object', properties: { emailIds: { type: 'array', items: { type: 'string' }, description: 'Array of email IDs to mark', }, read: { type: 'boolean', description: 'true to mark as read, false as unread', default: true, }, }, required: ['emailIds'], }, }, { name: 'bulk_pin', description: 'Pin or unpin multiple emails', inputSchema: { type: 'object', properties: { emailIds: { type: 'array', items: { type: 'string' }, description: 'Array of email IDs to pin/unpin', }, pinned: { type: 'boolean', description: 'true to pin, false to unpin', default: true, }, }, required: ['emailIds'], }, }, { name: 'bulk_move', description: 'Move multiple emails to a mailbox', inputSchema: { type: 'object', properties: { emailIds: { type: 'array', items: { type: 'string' }, description: 'Array of email IDs to move', }, targetMailboxId: { type: 'string', description: 'ID of target mailbox', }, }, required: ['emailIds', 'targetMailboxId'], }, }, { name: 'bulk_delete', description: 'Delete multiple emails (move to trash)', inputSchema: { type: 'object', properties: { emailIds: { type: 'array', items: { type: 'string' }, description: 'Array of email IDs to delete', }, }, required: ['emailIds'], }, }, { name: 'bulk_add_labels', description: 'Add labels to multiple emails simultaneously', inputSchema: { type: 'object', properties: { emailIds: { type: 'array', items: { type: 'string' }, description: 'Array of email IDs to add labels to', }, mailboxIds: { type: 'array', items: { type: 'string' }, description: 'Array of mailbox IDs to add as labels', }, }, required: ['emailIds', 'mailboxIds'], }, }, { name: 'bulk_remove_labels', description: 'Remove labels from multiple emails simultaneously', inputSchema: { type: 'object', properties: { emailIds: { type: 'array', items: { type: 'string' }, description: 'Array of email IDs to remove labels from', }, mailboxIds: { type: 'array', items: { type: 'string' }, description: 'Array of mailbox IDs to remove as labels', }, }, required: ['emailIds', 'mailboxIds'], }, }, { name: 'check_function_availability', description: 'Check which MCP functions are available based on account permissions', inputSchema: { type: 'object', properties: {}, }, }, { name: 'test_bulk_operations', description: 'Test bulk operations by finding recent emails and performing safe operations (mark read/unread)', inputSchema: { type: 'object', properties: { dryRun: { type: 'boolean', description: 'If true, only shows what would be done without making changes (default: true)', default: true, }, limit: { type: 'number', description: 'Number of emails to test with (default: 3, max: 10)', default: 3, }, }, }, }, ], }; });