send_email
Send emails through Gmail for revenue tracking and business management. Get user approval before sending messages to recipients.
Instructions
Send an email via Gmail. ALWAYS get user approval before calling this.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient email address | |
| subject | Yes | Email subject line | |
| body | Yes | Email body content |
Implementation Reference
- index.js:366-377 (registration)Registration of the send_email tool in the ListTools response, including name, description, and input schema.name: "send_email", description: "Send an email via Gmail. ALWAYS get user approval before calling this.", inputSchema: { type: "object", properties: { to: { type: "string", description: "Recipient email address" }, subject: { type: "string", description: "Email subject line" }, body: { type: "string", description: "Email body content" } }, required: ["to", "subject", "body"] } },
- index.js:686-688 (handler)Handler implementation for the send_email tool, which calls the callAPI helper with action 'sendEmail' and tool arguments.case "send_email": result = await callAPI("sendEmail", args); break;
- index.js:368-376 (schema)Input schema definition for the send_email tool, specifying required parameters: to, subject, body.inputSchema: { type: "object", properties: { to: { type: "string", description: "Recipient email address" }, subject: { type: "string", description: "Email subject line" }, body: { type: "string", description: "Email body content" } }, required: ["to", "subject", "body"] }
- index.js:74-131 (helper)The callAPI helper function that proxies tool calls to the external Google Apps Script API, handling form-encoded POST requests, logging, and error handling. This is where send_email logic is ultimately executed via action='sendEmail'.async function callAPI(action, data = {}) { debugLog('=== API CALL START ==='); debugLog(`Action: ${action}`); debugLog(`Data: ${JSON.stringify(data)}`); try { // Build form-encoded body for POST const formData = new URLSearchParams(); formData.append('action', action); // Add all data fields to form for (const [key, value] of Object.entries(data)) { if (value !== undefined && value !== null) { formData.append(key, value.toString()); } } const formString = formData.toString(); debugLog(`FormData: ${formString}`); debugLog(`API_URL: ${API_URL}`); // Use POST with proper content type const response = await fetch(API_URL, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: formString }); debugLog(`Response status: ${response.status}`); debugLog(`Response ok: ${response.ok}`); if (!response.ok) { debugLog(`Response not OK: ${response.status} ${response.statusText}`); throw new Error(`API request failed: ${response.status} ${response.statusText}`); } const text = await response.text(); debugLog(`Response text length: ${text.length}`); debugLog(`Response text: ${text}`); if (!text) { debugLog('ERROR: Empty response from API'); throw new Error('Empty response from API'); } const parsed = JSON.parse(text); debugLog(`Parsed successfully: ${JSON.stringify(parsed)}`); debugLog('=== API CALL END ==='); return parsed; } catch (error) { debugLog(`ERROR in callAPI: ${error.message}`); debugLog(`ERROR stack: ${error.stack}`); throw error; } }