Skip to main content
Glama
SpasticPalate

Proton MCP Server

proton_read_email

Read full email content from Proton Mail, including headers, body, and attachments, by specifying folder and email UID.

Instructions

Read the complete content of an email, including headers, body, and attachments. Specify folder and email UID.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
folderNoINBOX
uidYes

Implementation Reference

  • The async callback function containing the implementation logic for the 'proton_read_email' tool, which fetches and formats email data.
      async (params: z.infer<typeof ReadEmailSchema>) => {
        try {
          const message = await fetchMessage(params.folder, params.uid);
    
          // Format email content
          let result = `**From:** ${message.from.name || message.from.email} <${message.from.email}>\n`;
          
          if (message.to && message.to.length > 0) {
            const toList = message.to
              .map(t => `${t.name || t.email} <${t.email}>`)
              .join(', ');
            result += `**To:** ${toList}\n`;
          }
    
          if (message.cc && message.cc.length > 0) {
            const ccList = message.cc
              .map(c => `${c.name || c.email} <${c.email}>`)
              .join(', ');
            result += `**CC:** ${ccList}\n`;
          }
    
          result += `**Subject:** ${message.subject}\n`;
          result += `**Date:** ${message.date.toISOString()}\n`;
    
          if (message.messageId) {
            result += `**Message-ID:** ${message.messageId}\n`;
          }
    
          if (message.inReplyTo) {
            result += `**In-Reply-To:** ${message.inReplyTo}\n`;
          }
    
          result += '\n---\n\n';
    
          // Add body
          if (message.textBody) {
            result += message.textBody;
          } else if (message.htmlBody) {
            result += `[HTML Body]\n${message.htmlBody}`;
          } else {
            result += '[No message body]';
          }
    
          // Add attachments section
          if (message.attachments && message.attachments.length > 0) {
            result += '\n\n---\n\n**Attachments:**\n';
            for (const attachment of message.attachments) {
              const size = formatBytes(attachment.size);
              result += `- ${attachment.filename} (${attachment.contentType}, ${size})\n`;
            }
          }
    
          return {
            content: [
              {
                type: 'text',
                text: result,
              },
            ],
          };
        } catch (error) {
          return {
            content: [
              {
                type: 'text',
                text: `Error reading email: ${error instanceof Error ? error.message : String(error)}`,
              },
            ],
          };
        }
      }
    );
  • Registration function that registers the 'proton_read_email' tool with the MCP server.
    export function registerReadEmailTool(server: McpServer) {
      server.registerTool(
        'proton_read_email',
        {
          title: 'Read Full Email',
          description: 'Read the complete content of an email, including headers, body, and attachments. Specify folder and email UID.',
          inputSchema: ReadEmailSchema,
          annotations: {
            readOnlyHint: true,
            destructiveHint: false,
            idempotentHint: true,
            openWorldHint: false,
          },
        },
        async (params: z.infer<typeof ReadEmailSchema>) => {
          try {
            const message = await fetchMessage(params.folder, params.uid);
    
            // Format email content
            let result = `**From:** ${message.from.name || message.from.email} <${message.from.email}>\n`;
            
            if (message.to && message.to.length > 0) {
              const toList = message.to
                .map(t => `${t.name || t.email} <${t.email}>`)
                .join(', ');
              result += `**To:** ${toList}\n`;
            }
    
            if (message.cc && message.cc.length > 0) {
              const ccList = message.cc
                .map(c => `${c.name || c.email} <${c.email}>`)
                .join(', ');
              result += `**CC:** ${ccList}\n`;
            }
    
            result += `**Subject:** ${message.subject}\n`;
            result += `**Date:** ${message.date.toISOString()}\n`;
    
            if (message.messageId) {
              result += `**Message-ID:** ${message.messageId}\n`;
            }
    
            if (message.inReplyTo) {
              result += `**In-Reply-To:** ${message.inReplyTo}\n`;
            }
    
            result += '\n---\n\n';
    
            // Add body
            if (message.textBody) {
              result += message.textBody;
            } else if (message.htmlBody) {
              result += `[HTML Body]\n${message.htmlBody}`;
            } else {
              result += '[No message body]';
            }
    
            // Add attachments section
            if (message.attachments && message.attachments.length > 0) {
              result += '\n\n---\n\n**Attachments:**\n';
              for (const attachment of message.attachments) {
                const size = formatBytes(attachment.size);
                result += `- ${attachment.filename} (${attachment.contentType}, ${size})\n`;
              }
            }
    
            return {
              content: [
                {
                  type: 'text',
                  text: result,
                },
              ],
            };
          } catch (error) {
            return {
              content: [
                {
                  type: 'text',
                  text: `Error reading email: ${error instanceof Error ? error.message : String(error)}`,
                },
              ],
            };
          }
        }
      );
    }

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/SpasticPalate/proton-mcp-server'

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