Automate email workflows, templates, and campaigns with Gmail MCP integration
Overall
score
18%
Does it follow best practices?
If you maintain this skill, you can automatically optimize it using the tessl CLI to improve its score:
npx tessl skill review --optimize ./path/to/skillValidation for skill structure
Automate email workflows, create templates, and manage campaigns using Gmail and MCP integrations.
{
"mcpServers": {
"gmail-mcp": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-gmail"],
"env": {
"GOOGLE_CLIENT_ID": "${GOOGLE_CLIENT_ID}",
"GOOGLE_CLIENT_SECRET": "${GOOGLE_CLIENT_SECRET}",
"GOOGLE_REDIRECT_URI": "http://localhost:3000/oauth/callback"
}
}
}
}{
"mcpServers": {
"nineteen-blocks": {
"command": "npx",
"args": ["-y", "@nineteen-blocks/mcp-server"],
"env": {
"NINETEEN_BLOCKS_API_KEY": "${NINETEEN_BLOCKS_API_KEY}"
}
}
}
}| Tool | Capabilities |
|---|---|
Bash(gmail:*) | Execute Gmail CLI commands |
MCP(gmail-mcp:*) | Gmail API: send, read, label, draft |
MCP(nineteen-blocks:*) | Streak CRM, Sheets, Drive integration |
Create Google Cloud Project
Get OAuth Credentials
credentials.jsonConfigure Environment
export GOOGLE_CLIENT_ID="your-client-id"
export GOOGLE_CLIENT_SECRET="your-client-secret"
export NINETEEN_BLOCKS_API_KEY="your-api-key"First Run (OAuth)
gmail authVerify Connection
gmail me// 1. Load recipient data from sheet
const leads = await sheet.load("Q1_Prospects", "A:D");
// 2. For each lead, send personalized email
for (const lead of leads) {
const email = {
to: lead.email,
subject: `Exclusive Offer for ${lead.company_name}`,
body: `Hi ${lead.first_name}, ...`
};
await gmail.send(email);
// Respect rate limits (100 emails/day)
await delay(60000);
}// Watch inbox for new emails
gmail.watch({
labelIds: ["INBOX"],
callback: async (email) => {
if (email.subject.toLowerCase().includes("urgent")) {
await gmail.send({
to: email.from,
subject: `Re: ${email.subject}`,
body: "Thank you for reaching out..."
});
}
}
});const recipients = await sheet.load("Campaign_Q1", "A:C");
const results = [];
for (const recipient of recipients) {
const result = await gmail.send({
to: recipient.email,
subject: `Hi ${recipient.name}`,
body: "..."
});
results.push({ email: recipient.email, status: result.success });
await delay(1000);
}| Command | Description |
|---|---|
gmail auth | Start OAuth authentication |
gmail send --to user@email.com --subject "Subject" --body "Body" | Send email |
gmail list --label INBOX --max 10 | List recent emails |
gmail read <message-id> | Read specific email |
gmail draft --to user@email.com --subject "Subject" | Create draft |
gmail label create "Label Name" | Create new label |
| Error Code | Meaning | Recovery |
|---|---|---|
AUTH_001 | Invalid credentials | Run gmail auth |
AUTH_002 | Token expired | Re-authenticate |
RATE_001 | Daily limit (100/day) | Wait 24 hours |
SEND_001 | Invalid recipient | Check email format |
async function sendBatch(emails: Email[], delayMs = 60000) {
const results = [];
for (const email of emails) {
try {
const result = await gmail.send(email);
results.push({ ...email, success: true, id: result.messageId });
} catch (error) {
results.push({ ...email, success: false, error: error.message });
}
await delay(delayMs);
}
return results;
}# Dry run
gmail send --to test@example.com --subject "Test" --body "Test" --dry-runproductivity/google-workspace - Google Drive, Sheets integrationsales/sales-strategy - Sales email sequencesSkill v2.0 - Email Automation with MCP
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.