DEV Community

Adam
Adam

Posted on Edited on AI-assisted

Building an AI Email Assistant with n8n & Ollama: Part 1

Exploring how a locally hosted AI model can identify actionable emails, distinguish between responsibilities and produce structured data for automation.

The problem

Managing a busy inbox isn't just about the volume of emails. It's about identifying which messages actually require your attention.

In an operational environment, emails contain requests, updates, questions, confirmations and ongoing conversations. Some require immediate action, some need following up, and others are simply informational.

What interests me is whether AI can help distinguish between them.

I'm building a prototype that analyses emails, identifies potential tasks and determines whether those tasks are actually the recipient's responsibility.

The longer-term ambition is to turn those decisions into an organised task register, with the ability to correct the AI's mistakes and improve its assessments over time.

The technology

I've chosen three technologies for the initial prototype:

  • n8n: A workflow automation platform that connects applications and controls how data moves between them.
  • Ollama: Software that allows language models to run locally, without relying on an external AI service for inference.
  • Qwen3 8B: The language model responsible for analysing the email content.

I'm running the prototype on an Apple Silicon Mac with 24 GB of memory.

Running the model locally was an intentional choice. I wanted to explore how much AI-powered processing could be performed without sending email content to an external model provider.

For now, the system uses entirely fictional emails. It isn't connected to a live mailbox.

Building the first workflow

The initial n8n workflow is straightforward:

Manual Trigger → Edit Fields → Basic LLM Chain

n8n workflow showing Manual Trigger, Edit Fields and Basic LLM Chain, connected to Ollama Chat Model and Structured Output Parser.

Figure 1: The initial n8n workflow, connecting a sample email input to the locally running Qwen3 8B model through Ollama, with structured output parsing.

The Manual Trigger starts the automation.

Edit Fields supplies a fictional email containing a sender, subject and message body.

Basic LLM Chain passes that information to Qwen3 through the Ollama Chat Model.

I also added a Structured Output Parser so the AI returns consistent, machine-readable information rather than an ordinary paragraph.

Each assessment contains four properties:

  • action_required: YES, NO or UNCERTAIN
  • task: A description of the action required
  • reason: The explanation behind the decision
  • priority: HIGH, MEDIUM or LOW

This is important because I eventually want the results to populate a database automatically.

For example, the extracted task could become a record title, while its priority determines how prominently it appears in a dashboard.

Getting the data flowing

One of the first challenges was ensuring that the AI actually received the information from the preceding node.

Initially, Qwen3 returned a perfectly formatted response explaining that it couldn't determine whether action was required because no email information had been supplied.

The problem wasn't the model itself. It was how I'd configured the prompt in n8n.

The solution was to use dynamic expressions to reference the preceding node's data:

  • {{ $json.sender }}
  • {{ $json.subject }}
  • {{ $json.body }}

Once these expressions were configured correctly, the AI could analyse the supplied email rather than a hardcoded example.

It was a useful introduction to the distinction between an AI model working correctly and an automation successfully supplying it with the right information.

The first successful test

I initially tested the workflow using a fictional email from a distributor confirming that a revised programme master had been delivered.

The sender asked the recipient to confirm receipt and report any issues.

The model returned:

Action required: YES

Task: Confirm receipt of the revised master and check for issues.

Priority: MEDIUM

The response was sensible, and the structured output worked as intended.

At this point, I had a functioning workflow that could accept email information and return a structured assessment.

However, the next test revealed a more interesting problem.

Identifying tasks isn't the same as identifying responsibility

I created another fictional email, this time addressed to a Scheduling department.

The message requested that Scheduling update a programme's transmission date. It also explicitly stated that Programme Delivery was copied for visibility only and wasn't required to take action.

I expected the AI to return NO ACTION REQUIRED.

Instead, it returned:

Action required: YES

Task: Update the transmission date for Episode 3 to Wednesday.

Interestingly, the model hadn't misunderstood the email's content. It correctly identified the requested task.

What it failed to recognise was that the task belonged to somebody else.

The AI was effectively answering:

Does this email contain an action?

But the question I needed answered was:

Does this email contain an action that I'm personally responsible for?

That distinction is fundamental to the usefulness of the system.

In a busy operational environment, an email might contain several requests, but only some will be relevant to a particular recipient.

I've since revised the prompt to distinguish more explicitly between personal responsibilities, actions assigned to others and situations where responsibility is uncertain.

The next step is to test whether those revised instructions produce more reliable classifications.

What comes next?

The prototype has demonstrated that n8n can communicate with a locally running language model and return structured assessments of sample emails.

But it's still an early experiment.

My next objectives are to:

  • Improve the accuracy of responsibility classification.
  • Build a persistent feedback mechanism that remembers corrections.
  • Develop a database and dashboard for managing identified tasks.
  • Explore how the system could reliably track unresolved actions across email conversations.

The plan is to use Airtable as a task management interface, with each identified action recorded alongside the sender's name, organisation, email address, date received, a summary of the request, priority and task status. This would provide a centralised, actionable overview of outstanding responsibilities rather than simply a list of flagged emails.

Any eventual integration with a real organisational mailbox would also require appropriate access permissions and security controls.

For now, I'm concentrating on the classification problem.

The goal isn't simply to build an AI that identifies tasks in emails. It's to build a personal assistant that automatically turns my busy inbox into an organised, prioritised list of things I need to do.

Top comments (0)