Skip to main content
Glama
jahfer
by jahfer

get_email_content

Fetch email content by providing the email ID using the JMAP MCP Server tool for efficient email data retrieval.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
inputSchemaYes

Implementation Reference

  • The handler function for 'get_email_content' tool. It fetches the email details using JMAP Email.get, downloads the body content (prioritizing text over HTML), handles errors, and formats a readable output with subject, from, to, date, and body.
    async ({ emailId }) => { const session = await jam.session; const accountId = session.primaryAccounts["urn:ietf:params:jmap:mail"]; const [emails] = await jam.api.Email.get({ accountId, ids: [emailId], properties: ["id", "textBody", "htmlBody", "subject", "from", "to", "cc", "bcc", "sentAt", "receivedAt"] }); if (!emails || emails.list.length === 0) { return { content: [{ type: "text", text: `Error: Email with ID ${emailId} not found.` }], isError: true }; } const email = emails.list[0]; let bodyContent = 'No body content found.'; const downloadBodyPartContent = async (bodyPart) => { if (!bodyPart || !bodyPart.blobId) { return null; } try { const response = await jam.downloadBlob({ accountId, blobId: bodyPart.blobId, mimeType: bodyPart.type || 'application/octet-stream', // Use part type or a default fileName: bodyPart.name || 'body_part' // Use part name or a default }); if (response.ok) { return response.text(); // Read the response body as text } else { console.error(`Failed to download blob ${bodyPart.blobId}: ${response.status} ${response.statusText}`); return null; } } catch (error) { console.error(`Error downloading blob ${bodyPart.blobId}:`, error); return null; } }; // Prioritize text body, then HTML body if (email.textBody && email.textBody.length > 0) { // Assuming we only need the content of the first text part for simplicity const firstTextPart = email.textBody[0]; const downloadedText = await downloadBodyPartContent(firstTextPart); if (downloadedText !== null) { bodyContent = downloadedText; } } else if (email.htmlBody && email.htmlBody.length > 0) { // Assuming we only need the content of the first html part for simplicity const firstHtmlPart = email.htmlBody[0]; const downloadedHtml = await downloadBodyPartContent(firstHtmlPart); // Note: For HTML body, you might want to strip HTML tags for a text representation if (downloadedHtml !== null) { bodyContent = `[HTML Body - may contain tags]\n${downloadedHtml}`; // Indicate it's HTML } } return { content: [{ type: "text", text: `Subject: ${email.subject || '(No Subject)'}\nFrom: ${email.from ? email.from.map(f => f.name ? `${f.name} <${f.email}>` : f.email).join(', ') : '(Unknown Sender)'}\nTo: ${email.to ? email.to.map(t => t.name ? `${t.name} <${t.email}>` : t.email).join(', ') : '(Unknown Recipient)'}\nDate: ${email.receivedAt || email.sentAt || '(Unknown Date)'}\n\n---\n\n${bodyContent}` }] }; }
  • Input schema for the 'get_email_content' tool, requiring an 'emailId' string.
    inputSchema: z.object({ emailId: z.string().describe("The ID of the email to fetch.") })
  • index.js:229-308 (registration)
    Registration of the 'get_email_content' tool using server.tool, including name, description, input schema, and handler reference.
    server.tool( "get_email_content", { description: "Retrieves the full content of an email by its ID, including subject, sender, recipients, date, and body (text or HTML).", inputSchema: z.object({ emailId: z.string().describe("The ID of the email to fetch.") }) }, async ({ emailId }) => { const session = await jam.session; const accountId = session.primaryAccounts["urn:ietf:params:jmap:mail"]; const [emails] = await jam.api.Email.get({ accountId, ids: [emailId], properties: ["id", "textBody", "htmlBody", "subject", "from", "to", "cc", "bcc", "sentAt", "receivedAt"] }); if (!emails || emails.list.length === 0) { return { content: [{ type: "text", text: `Error: Email with ID ${emailId} not found.` }], isError: true }; } const email = emails.list[0]; let bodyContent = 'No body content found.'; const downloadBodyPartContent = async (bodyPart) => { if (!bodyPart || !bodyPart.blobId) { return null; } try { const response = await jam.downloadBlob({ accountId, blobId: bodyPart.blobId, mimeType: bodyPart.type || 'application/octet-stream', // Use part type or a default fileName: bodyPart.name || 'body_part' // Use part name or a default }); if (response.ok) { return response.text(); // Read the response body as text } else { console.error(`Failed to download blob ${bodyPart.blobId}: ${response.status} ${response.statusText}`); return null; } } catch (error) { console.error(`Error downloading blob ${bodyPart.blobId}:`, error); return null; } }; // Prioritize text body, then HTML body if (email.textBody && email.textBody.length > 0) { // Assuming we only need the content of the first text part for simplicity const firstTextPart = email.textBody[0]; const downloadedText = await downloadBodyPartContent(firstTextPart); if (downloadedText !== null) { bodyContent = downloadedText; } } else if (email.htmlBody && email.htmlBody.length > 0) { // Assuming we only need the content of the first html part for simplicity const firstHtmlPart = email.htmlBody[0]; const downloadedHtml = await downloadBodyPartContent(firstHtmlPart); // Note: For HTML body, you might want to strip HTML tags for a text representation if (downloadedHtml !== null) { bodyContent = `[HTML Body - may contain tags]\n${downloadedHtml}`; // Indicate it's HTML } } return { content: [{ type: "text", text: `Subject: ${email.subject || '(No Subject)'}\nFrom: ${email.from ? email.from.map(f => f.name ? `${f.name} <${f.email}>` : f.email).join(', ') : '(Unknown Sender)'}\nTo: ${email.to ? email.to.map(t => t.name ? `${t.name} <${t.email}>` : t.email).join(', ') : '(Unknown Recipient)'}\nDate: ${email.receivedAt || email.sentAt || '(Unknown Date)'}\n\n---\n\n${bodyContent}` }] }; } );
  • Helper function inside the handler to download blob content for email body parts using jam.downloadBlob.
    const downloadBodyPartContent = async (bodyPart) => { if (!bodyPart || !bodyPart.blobId) { return null; } try { const response = await jam.downloadBlob({ accountId, blobId: bodyPart.blobId, mimeType: bodyPart.type || 'application/octet-stream', // Use part type or a default fileName: bodyPart.name || 'body_part' // Use part name or a default }); if (response.ok) { return response.text(); // Read the response body as text } else { console.error(`Failed to download blob ${bodyPart.blobId}: ${response.status} ${response.statusText}`); return null; } } catch (error) { console.error(`Error downloading blob ${bodyPart.blobId}:`, error); return null; } };

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/jahfer/jmap-mcp-server'

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