joeyhbuilds · external setup guide
It sorts your incoming email as it arrives, quietly marks the noise as read, and pings you only when something actually needs you. And it gets smarter every time you correct it.
01 Overview
A busy inbox mixes two very different things: mail you simply haven't opened yet, and mail that genuinely needs you to do something. The Inbox Triage Agent separates them. Every minute it checks for new mail, reads each message, and asks Claude to sort it against a growing table of your own past decisions, so it reasons from real examples instead of a rigid rule set. Noise gets marked as read automatically, so it never adds to your unread pile. Anything important triggers an instant alert on your phone. And when the AI is unsure, it asks: it sends an alert with two buttons, Suppress or Surface, and your tap is saved as a new example so it keeps getting better.
If a full inbox quietly stresses you out, if you feel that pull to check every notification just in case this one matters, this is built for exactly that. It takes the deciding off your plate. The noise gets marked read and left alone, and you only get pinged for the things that genuinely need you.
You don't need to be technical. It's a little more involved than a five minute setup, about an hour, with a few command and credential steps, but every one is spelled out and any unfamiliar word has a plain explanation you can hover or tap. If you can follow steps and copy and paste, you can do this. You'll make a couple of keys and a bot along the way, and the guide walks you through each.
One honest note: it never replies to your email for you. It sorts and alerts, and every actual reply still goes through you, on purpose.
What "done" looks like
02 At a glance
03 What you'll need
Some tools may be new, that's fine. Any word with a dotted underline like this one has a plain explanation: hover or tap it, or find them all in the word list at the end.
Download the main workflow Download the tap to train handler
04 Cost & security
Building it is free. The only ongoing cost is the Claude API, and it stays small because the workflow reuses (caches) the big block of example decisions on every call, so repeat calls are billed at a fraction of the first.
| One time, to build | Free |
| Ongoing, pay as you go | Estimated $1 to $4 a month for a typical personal inbox, about half a cent per email classified (based on observed token usage, not a guarantee). Only genuinely new mail triggers a Claude call, and caching keeps each one cheap. |
05 Setup, four steps
▸ about 20 minutes
Install Docker. In an empty folder, save the Dockerfile, docker-compose.yml, and an env file below (with your real Gmail and Telegram values). Then run source ./env && docker compose up -d. Open http://localhost:5678 and create your account.
Dockerfile (this builds a version of n8n that can read email):
FROM docker.n8n.io/n8nio/n8n
USER root
RUN npm install -g imapflow mailparser
USER nodedocker-compose.yml (this tells Docker how to run n8n):
services:
n8n:
build: .
container_name: n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
- NODE_FUNCTION_ALLOW_EXTERNAL=imapflow,mailparser
- NODE_FUNCTION_ALLOW_BUILTIN=fs
- N8N_BLOCK_ENV_ACCESS_IN_NODE=false
- N8N_EDITOR_BASE_URL=http://localhost:5678
- GMAIL_ADDRESS=${GMAIL_ADDRESS}
- GMAIL_APP_PASSWORD=${GMAIL_APP_PASSWORD}
- WEBHOOK_URL=${WEBHOOK_URL}
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:env that holds your Gmail secrets as environment settings (you'll fill in the Gmail values in Step 2, the WEBHOOK_URL in Step 4). Your Anthropic key and Telegram bot token do not go here, they become n8n credentials in Step 3:
export GMAIL_ADDRESS=you@gmail.com
export GMAIL_APP_PASSWORD=your16charapppassword
export WEBHOOK_URL=http://localhost:5678/source ./env && docker compose up -d. Docker builds the image and starts n8n in its own container.http://localhost:5678 in your web browser. That localhost address is simply your own computer, and it is the same for everyone. Create your local account there.The restart: unless-stopped line matters. Without it n8n won't come back after a reboot, and real time triage depends on it always being up. Also run source ./env before docker compose up each time, so your secrets get read in.
http://localhost:5678 opens n8n in your web browser and the container shows as running in Docker Desktop. If not, make sure Docker is fully started and you ran the command from inside the folder with the three files.
▸ about 20 minutes
Create a Gmail App Password, an Anthropic API key, and a Telegram bot (via BotFather) plus your chat ID. Put the Gmail address and App Password into the env file from Step 1. Keep the Anthropic key and Telegram token handy, they become n8n credentials in Step 3.
/newbot, and follow the prompts. It gives you a bot token. Then get your chat ID (message @userinfobot, it replies with your number). You need both.env file from Step 1 and fill in your Gmail address and App Password. Save it, then run source ./env && docker compose up -d again so n8n picks them up. Your Anthropic key and Telegram bot token become credentials inside n8n in Step 3.The App Password option only shows up after 2 Step Verification is on. Turn that on first.
You have four things saved: your Gmail App Password, your Anthropic key, your Telegram bot token, and your Telegram chat ID. If BotFather didn't give a token, send /newbot again and pick a different bot name.
▸ about 15 minutes
Import both files. Create an Anthropic credential and a Telegram credential in n8n, then select them on the HTTP Request box and the Telegram boxes. Set your Telegram chat ID in the alert boxes. Create the three Data Tables with the exact columns below, starting known_examples empty. Leave both workflows Inactive.
HTTP Request (the one that calls Claude) and, under Credential, pick the one you just made.YOUR_TELEGRAM_CHAT_ID so alerts reach you.known_examples: sender (String), subject (String), ai_guess (String), final_decision (String), reasoning (String), date (Date). This is the table it learns from. Start it empty and let it fill from your own taps over the first week, so it learns your inbox, not someone else's.processed_emails: message_id (String), processed_at (Date).pending_review: message_id (String), sender (String), subject (String), ai_classification (String), ai_confidence (String), ai_reasoning (String), created_at (Date).Both workflows import, your Anthropic and Telegram credentials are selected on their boxes, your chat ID is set, and the three Data Tables exist with the right columns. If a Data Table box shows red, re-open it and pick the matching table by name.
▸ about 15 minutes
Install Tailscale and enable Funnel for just the one Telegram webhook address. Point WEBHOOK_URL at your Tailscale address, then restart n8n so the webhook registers.
The Suppress and Surface buttons need Telegram to reach your machine at a public web address. Tailscale Funnel gives you one safely, scoped to only the single webhook path, so nothing else is exposed.
/webhook. That address (its "webhook path") is the one thing Telegram needs to reach your machine, it is unique to your workflow. Copy the whole thing.<YOUR_WEBHOOK_PATH>, paste the path part of your address, that is everything from /webhook onward, not the whole https://... part. It goes in both spots:
tailscale funnel --bg --yes --set-path <YOUR_WEBHOOK_PATH> http://localhost:5678<YOUR_WEBHOOK_PATH>
Tailscale prints your public address, something like https://your-machine.your-tailnet.ts.net.env file as WEBHOOK_URL (with a trailing slash), then restart n8n with source ./env && docker compose up -d. The restart is what actually registers the webhook so taps get delivered.Just activating the workflow isn't enough. The restart after setting WEBHOOK_URL is what registers the public webhook.
Tapping a button on a Review alert clears the little spinner and replies "Marked as suppress" or "Marked as surface", and a new row appears in your known_examples table. If nothing happens, re-check that Funnel is on for the exact path ending in /webhook and that you restarted n8n.
06 Testing & going live
Prove each path before you trust it:
For the first few days, glance at the alerts and correct any it gets wrong with the buttons. That's how it tunes to your inbox.
07 What's next
joeyhbuilds · the newsletter
You just set up one of the automations from joeyhbuilds, systems that do the work so you don't have to.
Subscribe and each new build reaches you the moment it's finished, the working automation, plus a guide exactly like this one.
Subscribe at joeyhbuilds.com →08 Rollback & limitations
It sorts and alerts, it does not reply to email for you (by design, every reply goes through you). It runs on your own machine, so it only triages while your computer and Docker are running. It judges each email fresh using your examples as reference, so a brand new sender it hasn't seen may need a correction or two before it's confident. And it works on one inbox at a time.
09 FAQ
10 Troubleshooting
No mail is being picked up. This build reads mail with a dedicated connector rather than n8n's built in email trigger, which had a known connection bug. Make sure you're using the provided workflow and that your Gmail App Password and address are in the env file and read in.
The workflow can't read my credentials. The Code steps read your saved settings through n8n's secure accessor, which only works with N8N_BLOCK_ENV_ACCESS_IN_NODE=false in place (Step 1). Confirm that line is in your compose file, and that you ran source ./env before starting.
An important email was sorted but no Telegram message came. Make sure the chat ID is set on every Telegram box, and that you imported the provided workflow unchanged. Rewiring the alert boxes by hand can drop fields they need.
Button taps do nothing. Re-check Step 4. Funnel must be on for the exact webhook path (ending in /webhook), Tailscale must be running, and n8n must have been restarted after you set WEBHOOK_URL.
Claude returns a billing or credit error. Add credit under Billing in the Anthropic console.
Email support@joeyhbuilds.com and describe exactly what you see: which step, which box, and any red error text. The more specific, the faster the fix.
11 Every word, explained
New terms in one place, no need to know these before you start.