Your inbox is a time sink. The average professional spends over 2 hours per day reading and responding to emails, and most of those replies follow predictable patterns. What if you could build an AI system that reads every incoming email, classifies it by type and urgency, and drafts a context-aware reply — all running on your own machine with zero API costs?
In this n8n Ollama tutorial, you will build exactly that: a self-hosted AI email automation pipeline that connects your inbox to a locally-running AI model. No OpenAI key. No cloud dependency. No per-request charges. Just your hardware, doing the work.
By the end, you will have a working n8n AI workflow that polls your inbox every 5 minutes, classifies each message (support, sales, spam, personal), rates the urgency, and drafts a reply that you can review and send with one click.
You do not need to be an AI expert. If you have installed software from the terminal before, you can follow this tutorial. Here is what you need:
Time required: approximately 20 minutes for the first setup. After that, the workflow runs unattended.
Before we start building, here is the high-level flow of the local AI email automation system:
Each step is a node in n8n. The entire pipeline runs locally. Your email content never touches a third-party AI provider.
1 Install Ollama
Ollama is a lightweight runtime that lets you run large language models locally. Installation takes about 60 seconds.
# Linux or macOS (one-line install)
curl -fsSL https://ollama.ai/install.sh | sh
# Windows: download the installer from https://ollama.ai/download
2 Pull the llama3:8b model
This is a strong general-purpose model that handles classification and text generation well. The download is approximately 4.7 GB.
ollama pull llama3:8b
If you have limited RAM (8 GB), use mistral:7b instead — it is slightly smaller and still performs well for email tasks.
3 Verify Ollama is running
curl http://localhost:11434/api/tags
You should see a JSON response listing your installed models. If you get a "connection refused" error, start Ollama with ollama serve.
4 Start n8n with Docker
Docker is the easiest way to run n8n. The --add-host flag is critical — it lets n8n inside Docker reach Ollama on your host machine.
docker run -d --name n8n \
-p 5678:5678 \
-v n8n_data:/home/node/.n8n \
--add-host=host.docker.internal:host-gateway \
n8nio/n8n
Open http://localhost:5678 in your browser and create your admin account.
Alternative: if you prefer npm, run npm install n8n -g && n8n start.
5 Test the n8n-to-Ollama connection
Create a new workflow in n8n. Add a Manual Trigger node, then add an HTTP Request node with these settings:
http://host.docker.internal:11434/api/tagsClick "Execute Workflow." If you see your model list in the output, the connection works. If you installed n8n with npm (not Docker), use http://localhost:11434/api/tags instead.
6 Add an IMAP Email trigger
Delete the Manual Trigger and replace it with an IMAP Email node. Configure it with your email credentials:
imap.gmail.com (or your provider's IMAP server)993INBOXThe IMAP node will poll for new emails on whatever schedule you set in the workflow settings (we will set it to every 5 minutes later). Each new email arrives as a JSON object with from, subject, text, and date fields.
This is where the self-hosted AI automation starts. We send the email content to Ollama and ask it to classify the message into structured categories.
7 Add an HTTP Request node after the IMAP trigger
Configure it to POST to Ollama's generate endpoint:
http://host.docker.internal:11434/api/generate120000 (120 seconds — local models can be slow on CPU)Set the JSON body to:
{
"model": "llama3:8b",
"prompt": "You are an email classification assistant. Analyze this email and return a JSON object.\n\nClassify into exactly ONE category: support, sales, partnership, personal, newsletter, spam\nRate urgency: low, medium, high\nDetect sentiment: positive, neutral, negative\nProvide a 1-sentence summary.\n\nEmail from: {{ $json.from }}\nSubject: {{ $json.subject }}\nBody: {{ $json.text }}\n\nReturn ONLY valid JSON, no other text:\n{\"category\": \"...\", \"urgency\": \"...\", \"sentiment\": \"...\", \"summary\": \"...\"}",
"stream": false,
"options": {
"temperature": 0.1
}
}
A few things to note about this prompt:
{{ $json.from }}) are n8n template expressions that inject the email data into the prompt.8 Add a Code node to parse the AI response
Ollama returns the generated text in a response field. We need to extract the JSON from it:
// Extract JSON from the AI response
const aiResponse = $input.first().json.response;
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/);
if (!jsonMatch) {
throw new Error('AI did not return valid JSON. Raw response: ' + aiResponse);
}
const classification = JSON.parse(jsonMatch[0]);
return [{
json: {
...classification,
original_from: $('IMAP Email').first().json.from,
original_subject: $('IMAP Email').first().json.subject,
original_body: $('IMAP Email').first().json.text,
processed_at: new Date().toISOString()
}
}];
The regex /\{[\s\S]*\}/ captures everything between the first { and last }, which handles cases where the model includes extra text around the JSON.
9 Add a Switch node to route by category
Create a Switch node with the routing field set to {{ $json.category }}. Add these outputs:
support → connects to a support reply drafting nodesales → connects to a sales reply drafting nodespam / newsletter → connects to an archive or delete actionThis routing means each email category gets a specialized prompt for reply generation, which produces much better output than a one-size-fits-all approach.
Now we build the reply-drafting nodes. Each category gets its own HTTP Request node calling Ollama, but with a different prompt tailored to that type of email.
10 Support reply node
{
"model": "llama3:8b",
"prompt": "Draft a professional support reply to this email.\n\nFrom: {{ $json.original_from }}\nSubject: {{ $json.original_subject }}\nBody: {{ $json.original_body }}\n\nGuidelines:\n- Be empathetic and acknowledge the issue\n- Provide specific, actionable troubleshooting steps\n- Offer to escalate if the steps don't resolve it\n- Keep it under 150 words\n- Professional but warm tone\n\nWrite ONLY the reply body, no subject line or signature.",
"stream": false,
"options": { "temperature": 0.5 }
}
11 Sales reply node
{
"model": "llama3:8b",
"prompt": "Draft a reply to this sales inquiry.\n\nFrom: {{ $json.original_from }}\nSubject: {{ $json.original_subject }}\nBody: {{ $json.original_body }}\n\nGuidelines:\n- Thank them for their interest\n- Answer their specific question if one was asked\n- Briefly highlight key benefits relevant to their inquiry\n- Include a clear call to action (book a demo, start a trial, etc.)\n- Confident but not pushy\n- Keep it under 150 words\n\nWrite ONLY the reply body.",
"stream": false,
"options": { "temperature": 0.5 }
}
For the generic/default reply, use a neutral prompt that acknowledges the email and says you will follow up shortly. The higher temperature (0.5) gives the replies more natural variation compared to the classification step.
12 Choose your output method
You have several options for what to do with the drafted reply:
13 Set the schedule
Go to your workflow settings and set it to run on a schedule: every 5 minutes is a reasonable starting point. Activate the workflow, and your n8n AI workflow is live.
Once you have verified the workflow handles your emails correctly, here are some improvements for production use:
Wrap the AI classification and reply nodes in n8n's error workflow feature. If Ollama times out or returns garbage, the error handler can log the failure and forward the email to you unprocessed rather than losing it.
Add a filter node before the AI step to skip emails you never want to process: automated notifications from services, calendar invites, delivery receipts. This saves processing time and keeps your logs clean.
Add a Google Sheets or database node at the end of every path to log the email address, classification result, and draft reply. This gives you an audit trail and lets you measure classification accuracy over time.
For email classification specifically, llama3:8b hits the sweet spot of speed and accuracy. If you need faster processing on CPU-only hardware, phi3:mini (3.8B parameters) handles classification well at roughly 3x the speed. For reply drafting where quality matters more, stick with the 8B model or go larger if your hardware allows.
http://host.docker.internal:11434 instead of localhost. If n8n is installed via npm on the same machine, localhost works fine.ollama serve in a terminal. On Linux, you may want to set it up as a systemd service so it starts on boot.mistral:7b or phi3:mini. Even a modest GPU (RTX 3060, 12 GB VRAM) makes a 5-10x speed difference.INBOX is case-sensitive for some providers). Test your credentials with a desktop email client first.You now have a working local AI email automation pipeline. Here are a few ways to extend it:
The email auto-responder is one of 11 production-ready n8n + Ollama workflows in our complete pack. You also get an AI blog writer, social media content generator, lead scoring system, document summarizer, competitor intelligence monitor, and more.
$39 one-time payment — no subscriptions, no API costs
Get the Full Pack →30-day money-back guarantee. Instant download.
Try these open-source workflows to see the quality before buying the pack: