This workflow corresponds to n8n.io template #16922 — we link there as the canonical source.
This workflow follows the Gmail Tool → Google Sheets Tool recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "vYeFCfAOxQGp4IfP",
"name": "send-personalized-cold-emails-from-google-sheets-via-claude-mcp",
"tags": [],
"nodes": [
{
"id": "24c297f2-7ec7-46df-bb44-ef2d7f0d9dc0",
"name": "MCP Server Trigger",
"type": "@n8n/n8n-nodes-langchain.mcpTrigger",
"position": [
-144,
-160
],
"parameters": {
"path": "claude-email-machine"
},
"typeVersion": 1
},
{
"id": "5528e24c-2154-48fb-b6b8-3fb4ca449d5b",
"name": "send_from_account_1",
"type": "n8n-nodes-base.gmailTool",
"onError": "continueRegularOutput",
"position": [
-192,
224
],
"parameters": {
"sendTo": "={{ $fromAI('to_email', 'Recipient email address') }}",
"message": "={{ $fromAI('body', 'Full plain text email body') }}",
"options": {},
"subject": "={{ $fromAI('subject', 'Email subject line') }}",
"descriptionType": "manual",
"toolDescription": "SEND an email immediately from Gmail ACCOUNT 1. Inputs: to_email, subject, body. Only use when Mohsin has approved direct sending."
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "eb068fad-b36f-467a-8e00-1546b3574939",
"name": "send_from_account_2",
"type": "n8n-nodes-base.gmailTool",
"onError": "continueRegularOutput",
"position": [
0,
224
],
"parameters": {
"sendTo": "={{ $fromAI('to_email', 'Recipient email address') }}",
"message": "={{ $fromAI('body', 'Full plain text email body') }}",
"options": {},
"subject": "={{ $fromAI('subject', 'Email subject line') }}",
"descriptionType": "manual",
"toolDescription": "SEND an email immediately from Gmail ACCOUNT 2. Inputs: to_email, subject, body. Only use when Mohsin has approved direct sending."
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "0dad3d53-5eee-4200-b6c2-52aad8878bd1",
"name": "send_from_account_3",
"type": "n8n-nodes-base.gmailTool",
"onError": "continueRegularOutput",
"position": [
208,
224
],
"parameters": {
"sendTo": "={{ $fromAI('to_email', 'Recipient email address') }}",
"message": "={{ $fromAI('body', 'Full plain text email body') }}",
"options": {},
"subject": "={{ $fromAI('subject', 'Email subject line') }}",
"descriptionType": "manual",
"toolDescription": "SEND an email immediately from Gmail ACCOUNT 3. Inputs: to_email, subject, body. Only use when Mohsin has approved direct sending."
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "248e74f8-7523-4059-b796-311d29dcc96e",
"name": "get_leads",
"type": "n8n-nodes-base.googleSheetsTool",
"onError": "continueRegularOutput",
"position": [
416,
224
],
"parameters": {
"sheetName": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultUrl": "",
"cachedResultName": ""
},
"documentId": {
"__rl": true,
"mode": "id",
"value": ""
},
"descriptionType": "manual",
"toolDescription": "Read ALL rows from the Leads sheet. Columns: Name, Clinic, Email, Subject, Body, Status, Assigned_Account, Sent_Date, Error_Note, row_number. Always call this FIRST before drafting or sending, to find Status 'Queued' rows, avoid duplicates, and count today's per-account volume from Sent_Date + Assigned_Account."
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "f1d1298e-01ec-4d34-a6b9-af410b90462e",
"name": "update_lead",
"type": "n8n-nodes-base.googleSheetsTool",
"onError": "continueRegularOutput",
"position": [
624,
224
],
"parameters": {
"columns": {
"value": {
"Status": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Status', ``, 'string') }}",
"Subject": "={{ $fromAI('Subject', ``, 'string') }}",
"Sent_Date": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Sent_Date', ``, 'string') }}",
"Error_Note": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Error_Note', ``, 'string') }}",
"row_number": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('row_number', ``, 'string') }}",
"Assigned_Account": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Assigned_Account', ``, 'string') }}"
},
"schema": [
{
"id": "row_number",
"type": "string",
"display": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Name",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Clinic",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Clinic",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Email",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Phone",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Phone",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Website",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Website",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Notes",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Notes",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Subject",
"type": "string",
"display": true,
"required": false,
"displayName": "Subject",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Body",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Body",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Assigned_Account",
"type": "string",
"display": true,
"required": false,
"displayName": "Assigned_Account",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Sent_Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Sent_Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Error_Note",
"type": "string",
"display": true,
"required": false,
"displayName": "Error_Note",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 437177982,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit#gid=437177982",
"cachedResultName": "Leads"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": ""
},
"descriptionType": "manual",
"toolDescription": "Update one lead row after every draft or send attempt. Inputs: row_number, status (Drafted / Sent / Error), account (acc1-acc4), sent_date (YYYY-MM-DD), error_note ('' if success). ALWAYS call this immediately after each draft or send so the sheet stays the single source of truth."
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "2162a536-08aa-4447-bfd3-5c056abeb7ab",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
112,
-272
],
"parameters": {
"color": "#E1D4A8",
"width": 480,
"height": 224,
"content": "## MCP Server Trigger\n\nExposes your workflow as tools an AI assistant like Claude GPT and gemini can call directly.\nPublishes a secure URL with Bearer token authentication.\nNo polling or webhooks needed the AI connects and calls tools on demand."
},
"typeVersion": 1
},
{
"id": "4d3d2a72-2b75-48f6-9674-8c2cf499316f",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-608,
432
],
"parameters": {
"color": "#E1D4A8",
"width": 720,
"height": 192,
"content": "## Gmail Draft/Send Tools (x4 accounts)\n\nEach tool lets the AI create a Gmail draft or send an email from a specific account.\nInputs: recipient, subject, body, supplied by the AI based on context.\nDraft mode is default so a human reviews before anything sends."
},
"typeVersion": 1
},
{
"id": "5917ba7c-fbf9-496f-a8d3-bdf1dfbd7006",
"name": "draft_account_2",
"type": "n8n-nodes-base.gmailTool",
"onError": "continueRegularOutput",
"position": [
-512,
240
],
"parameters": {
"message": "={{ $fromAI('body', 'Full plain text email body') }}",
"options": {
"sendTo": "={{ $fromAI('to_email', 'Recipient email address') }}"
},
"subject": "={{ $fromAI('subject', 'Email subject line') }}",
"resource": "draft",
"descriptionType": "manual",
"toolDescription": "Create a DRAFT (does not send) in Gmail ACCOUNT 2. Inputs: to_email, subject, body. Use drafts by default for review before sending."
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "d76cf198-4d7c-43df-bd0c-2f2de1a039ae",
"name": "draft_account_3",
"type": "n8n-nodes-base.gmailTool",
"onError": "continueRegularOutput",
"position": [
-368,
240
],
"parameters": {
"message": "={{ $fromAI('body', 'Full plain text email body') }}",
"options": {
"sendTo": "={{ $fromAI('to_email', 'Recipient email address') }}"
},
"subject": "={{ $fromAI('subject', 'Email subject line') }}",
"resource": "draft",
"descriptionType": "manual",
"toolDescription": "Create a DRAFT (does not send) in Gmail ACCOUNT 3. Inputs: to_email, subject, body. Use drafts by default for review before sending."
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "3045b3d8-9758-4ca4-b68e-f0e46deacf42",
"name": "draft _account_1",
"type": "n8n-nodes-base.gmailTool",
"onError": "continueRegularOutput",
"position": [
-688,
240
],
"parameters": {
"message": "={{ $fromAI('body', 'Full plain text email body') }}",
"options": {
"sendTo": "={{ $fromAI('to_email', 'Recipient email address') }}"
},
"subject": "={{ $fromAI('subject', 'Email subject line') }}",
"resource": "draft",
"descriptionType": "manual",
"toolDescription": "Create a DRAFT (does not send) in Gmail ACCOUNT 1. Inputs: to_email, subject, body. Use drafts by default for review before sending."
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "181e6b21-7d6a-42cf-8de6-e350bc7d9a4f",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
304,
432
],
"parameters": {
"color": "#E1D4A8",
"width": 608,
"height": 176,
"content": "### Google Sheets Tools (get_leads / update_lead)\n\nReads lead data (name, email, status) so the AI knows who's been contacted.\nWrites back status, account used, and date after every send.\nKeeps the sheet as the single source of truth, preventing duplicate outreach."
},
"typeVersion": 1
},
{
"id": "6651802f-9a5f-47e4-b402-4357a8235a20",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-480,
-288
],
"parameters": {
"color": "#E1D4A8",
"width": 560,
"height": 112,
"content": "## Send personalized cold emails from Google Sheets leads via Claude MCP"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "0df7662f-e18e-469b-b693-b6acdda54958",
"nodeGroups": [],
"connections": {
"get_leads": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"update_lead": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"draft_account_2": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"draft_account_3": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"draft _account_1": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"send_from_account_1": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"send_from_account_2": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"send_from_account_3": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googleSheetsOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This template turns a Google Sheet of leads into an outreach engine controlled by any MCP-compatible AI assistant, including Claude, ChatGPT,and others. Instead of manually drafting emails, you instruct the assistant to draft or send them through rotating Gmail accounts, while…
Source: https://n8n.io/workflows/16922/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Gmail MCP Server. Uses gmailTool, stickyNote, mcpTrigger. Event-driven trigger; 27 nodes.
Gmail MCP Server. Uses gmailTool, mcpTrigger. Event-driven trigger; 27 nodes.
Gmail MCP Server Expose Gmail’s full API as a single SSE “tool server” endpoint for your AI agents.
MCP Email. Uses gmailTool, mcpTrigger. Event-driven trigger; 27 nodes.
Gmail_MCP_Server___Your_All_in_One_AI_Email_Toolkit. Uses gmailTool, mcpTrigger. Event-driven trigger; 27 nodes.