Quick start & writing rules
Quick start
- Open Settings and paste your Gemini API key. Get one free at aistudio.google.com/app/apikey.
- (Optional) Configure SMS — pick a provider and add named SMS recipients in Settings.
- (Optional) Add Google Chat spaces or MCP servers in Settings if you want to route alerts there.
- Open Rules and click + New rule, or click Starter rules on the home card to create 5 pre-built rules (urgent emails, invoices, shipping updates, security alerts, subscription renewals). Starter rules are created disabled — edit each to tick channels, then tap On back on the Rules card.
- On the home card, pick a scan interval from the Scan email every dropdown, then click Start scheduled scans. A time-driven trigger runs in the background even when Gmail is closed; the interval you pick is also saved into Settings.
Writing a rule
Rules are plain English. Be specific about senders, subjects, attachments, or body keywords. Examples:
- "Any email from @example.com with a PDF that looks like an invoice."
- "Subject contains URGENT or CRITICAL."
- "Email from boss@example.com asking for a status update."
Each rule has an Alert message content field — plain-English instructions that tell Gemini how to format the alert. The default includes date, sender, subject, summary, and action items. Click Help me write the rule text or Help me write the alert text in the rule editor to have Gemini draft a starting point.
Labels
Gmail uses labels rather than folders. Use INBOX for the inbox, or any label name as shown in Gmail. Multiple labels: comma-separated.
Rule examples by channel
SMS — urgent, time-sensitive
- Server down: "Automated email about a server outage or critical alert." → SMS to on-call
- Wire transfer: "Email from the bank confirming a wire transfer over $10,000." → SMS to CFO
Google Chat — team-visible
- Sales lead: "Email from a new contact mentioning pricing or demo." → Chat "Sales Leads"
- Support escalation: "Subject contains ESCALATION or P1." → Chat "Escalations"
Calendar — time-based follow-ups
- Meeting request: "Any email asking to schedule a meeting." → Calendar event
- Deadline: "Email mentioning a deadline or due date." → Calendar event
Sheets — audit trails
- Compliance log: "Email from a regulatory body or auditor." → Sheets row
- Expense tracking: "Emails with receipts or payment confirmations." → Sheets log
Tasks — to-do items
- Action items: "Email explicitly asking me to do, review, or approve something." → Task
- Follow-up: "Email saying 'let me know' or 'awaiting your response'." → Task
Docs — narrative log
- Weekly digest: "Newsletter from a key vendor or industry source." → Docs entry (build a running reading log)
- Customer-feedback log: "Email containing testimonial, NPS comment, or review excerpt." → Docs entry (one document grows with all feedback)
External integrations — route to external tools
- Sales lead → Teams: "Email mentioning pricing or demo from a new contact." → Microsoft Teams MCP
- Support ticket → Asana: "Customer email tagged P1 or ESCALATION." → Asana task
- Custom downstream → Cloudflare Worker: any rule → Custom MCP server you host yourself
- Slack channel via webhook: any rule → Custom webhook with a Slack incoming-webhook URL (no MCP server needed)
Combining channels
- Critical vendor issue: SMS + Chat + Calendar + Sheets
- New hire onboarding: Task + Sheets + Chat
Alert channel setup
SMS
Any provider you want. Six quick-start presets built in (see SMS setup guide in the add-on); the Generic webhook handles anything else.
- Textbelt — easiest: 1 free SMS/day with key "textbelt", no sign-up
- ClickSend — free trial, username + API key, no phone number
- Vonage — free trial credits, no credit card
- Telnyx — cheapest per SMS at scale; needs a rented phone number
- Plivo — $10 free credit; needs a rented phone number
- Twilio — most popular and best docs; $15 free credit; needs a rented phone number
- Generic webhook — POST to any HTTPS endpoint; use this for any provider without a built-in preset
Current per-SMS and phone-number prices are shown in the SMS setup card and on each provider's site. Prices change — verify before committing.
After picking a provider, add named SMS recipients (e.g. "On-call", "CFO") in the SMS recipients section of Settings. Rules pick recipients by name via checkboxes. Click Send test SMS to verify.
Google Chat
Requires a Google Workspace paid account.
- Go to chat.google.com and create a Space
- Click the space name in the header ▸ Apps & integrations ▸ Webhooks
- Add a webhook, copy the URL, paste into Settings
- Select the space name in each rule
Calendar
Creates a 15-minute event with alert details. Phone notifications fire if calendar notifications are on.
Sheets
Appends a row to a spreadsheet (auto-created on first alert). Great for audit trails.
Tasks
Creates a task in Google Tasks. Shows in Gmail sidebar and the Tasks app.
Docs
Appends a structured entry to a Google Doc (auto-created on first alert as "emAIl Sentinel — Alert Log" in your Drive). Each entry has a HEADING3 line with the timestamp and rule name, then plain paragraphs for From, Subject, Received, and the Gemini-formatted alert message. Useful for a narrative/audit log that reads top-to-bottom rather than as a spreadsheet — e.g. weekly newsletter digests, a running customer-feedback log, or a chronological record of any alert category you want to skim later. Per-rule override is supported in the rule editor (paste a different Doc URL or ID); blank uses the global Settings value.
External integrations
Route alerts to Microsoft Teams, Asana (REST or MCP V2), a custom MCP server you host yourself, or any HTTPS webhook (Slack incoming webhooks, Discord, n8n / Zapier / Make scenarios, custom internal APIs). Configure in Settings ▸ External integrations, then tick them per rule.
Custom — Cloudflare Worker MCP server (recommended starting point)
This is the simplest reproducible MCP example. You deploy a 40-line JavaScript Worker on Cloudflare's free tier; the Worker speaks MCP JSON-RPC, accepts a bearer token you choose, and logs every alert to its console. No Slack workspace, no Asana account, no OAuth flow, no expiring tokens. Total setup: about 15 minutes one-time.
- Create a Cloudflare account. Sign up free at cloudflare.com if you do not already have one.
- Create a Worker. From the dashboard sidebar pick Workers & Pages → Create application → Start with Hello World!. Name it
es-demo-mcp(or anything). Click Deploy to accept the default Hello World template. - Replace the template with the MCP code. After deploy, click Edit code. Delete the template and paste this:
Change theconst SECRET = "es-demo-token-change-me"; export default { async fetch(request) { if (request.method !== "POST") { return new Response("e-mail Sentinel MCP demo. POST with Bearer auth.", { status: 200 }); } if (request.headers.get("Authorization") !== `Bearer ${SECRET}`) { return new Response("Unauthorized", { status: 401 }); } const req = await request.json(); const { method, params = {}, id } = req; if (method === "notifications/initialized") return new Response(null, { status: 204 }); let result, error; if (method === "initialize") { result = { protocolVersion: "2024-11-05", capabilities: { tools: {} }, serverInfo: { name: "es-demo", version: "1.0.0" } }; } else if (method === "tools/list") { result = { tools: [{ name: "log_alert", description: "Logs an alert to the Worker console.", inputSchema: { type: "object", properties: { message: { type: "string" } }, required: ["message"] } }] }; } else if (method === "tools/call") { const message = params.arguments?.message || "(empty)"; console.log("[ALERT RECEIVED]", message); result = { content: [{ type: "text", text: `Logged: ${message}` }] }; } else { error = { code: -32601, message: `Method not found: ${method}` }; } const body = { jsonrpc: "2.0", id }; if (error) body.error = error; else body.result = result; return new Response(JSON.stringify(body), { headers: { "Content-Type": "application/json" } }); } };SECRETstring to any value you like — that becomes your bearer token. Click Deploy. - Copy the Worker URL. After deploy, the URL appears at the top of the page (looks like
https://es-demo-mcp.<your-subdomain>.workers.dev). Save it. - Configure in emAIl Sentinel. Settings → + Add external integration. Server name: anything. Type: pick Custom MCP, click Load defaults. Endpoint URL: paste the Worker URL from step 4. Authorization header value: paste
Bearerfollowed by the value ofSECRETfrom your Worker code (full field reads likeBearer es-demo-token-change-me). Tool name:log_alert. Tool arguments (JSON):{"message":"{{message}}"}. Save. - Test it. Wire the new server onto a rule, send yourself a matching email, click Scan email now. In the Cloudflare dashboard, open the Worker → Observability tab → click Live. The line
[ALERT RECEIVED] <your alert text>appears in real time. Done.
Authorization header format (all integration types)
The Authorization header value field accepts the full header value, not just the token. For most types, paste literally Bearer <token> — capital B, single space, then the token. The dispatcher sends this string verbatim as the Authorization HTTP header. Some webhook destinations don't use bearer auth: Slack incoming webhooks have the secret embedded in the URL itself (leave Authorization blank), Discord webhooks are similar, and some custom endpoints expect ApiKey <key> or just <key>. Omit any required prefix and the server will reject with HTTP 401.
Custom webhook setup (Slack / Discord / n8n / Zapier / custom)
Use this for any HTTPS endpoint that accepts a JSON POST. Not MCP — no JSON-RPC envelope, no tool name. The request body you configure is sent verbatim with placeholders substituted.
- Get the webhook URL.
- Slack: api.slack.com/messaging/webhooks → create an app → enable incoming webhooks → install to a workspace → copy the URL. The URL contains the secret; no Authorization header needed.
- Discord: server settings → Integrations → Webhooks → New webhook → copy URL.
- n8n / Zapier / Make: create a webhook trigger node, copy its URL.
- Custom internal API: whatever your server exposes; HTTPS only.
- Configure in emAIl Sentinel. Settings → + Add external integration. Type: Custom webhook (HTTPS POST). Endpoint URL: paste your webhook URL. Authorization header value: blank for Slack/Discord (the URL is the secret); for others use
Bearer <token>or whatever your endpoint expects. - Request body (JSON): a JSON object that gets POSTed verbatim with placeholders substituted. Defaults to
{"text":"{{message}}"}which is the Slack incoming-webhook format. Discord uses{"content":"{{message}}"}. Available placeholders:{{message}},{{subject}},{{from}},{{rule}}. Click Suggest request body to have Gemini draft a starting point for your endpoint type. - Test it. Tick the integration on a rule, send yourself a matching email, click Scan email now. The request body lands at your endpoint as a plain HTTPS POST.
Asana setup — REST API path (recommended)
Use this unless you specifically need MCP-protocol semantics.
- Get a Personal Access Token (PAT). Open app.asana.com/0/my-apps. Under Personal access tokens, click Create new token, name it (e.g. "emAIl Sentinel"), agree to the API terms, and copy the token immediately — Asana shows it only once.
- Get a project GID. Open the Asana project where new tasks should land. The URL looks like
https://app.asana.com/1/<workspace>/project/1214322995210370/board/<view>on current Asana. The project GID is the number directly after/project/— not the workspace GID after/1/and not the board view ID after/board/. Copy just the project GID. - Configure in emAIl Sentinel. Settings → + Add external integration. Type: pick Asana (REST API — easier), click Load defaults. The endpoint auto-fills to
https://app.asana.com/api/1.0/tasks. Authorization header value: pasteBearerfollowed by your PAT. Tool args template: pre-filled — replace the literal textPROJECT_IDwith your project GID; leave{{subject}}and{{message}}placeholders as they are. Save.
Asana setup — MCP V2 path (advanced, OAuth required)
This is the true MCP-protocol path but requires an OAuth-issued access token. PATs do not work. Asana access tokens expire (typically 1 hour) and emAIl Sentinel does not currently refresh them automatically — for long-running setups, the REST API path above is more practical.
- Register an OAuth app in Asana. Open app.asana.com/0/my-apps. Switch to the Apps tab and click + New app. Fill in the app name, redirect URI (a localhost URL is fine for personal use, e.g.
http://localhost:8080/callback), and accept the API terms. Asana issues a client ID and client secret — save both. - Perform an OAuth 2.0 authorization-code flow. The simplest tool is Postman. New request → Authorization tab → Type OAuth 2.0 → Get New Access Token. Auth URL
https://app.asana.com/-/oauth_authorize, Token URLhttps://app.asana.com/-/oauth_token, Client ID and Secret from step 1, Scopedefault, Redirect URI matching what you registered. Click Get New Access Token; Postman opens an Asana authorization page; approve. Postman captures the access token. - Get a project GID exactly as in step 2 of the REST walkthrough above.
- Configure in emAIl Sentinel. Settings → + Add external integration. Type: Asana (MCP V2 — requires OAuth), click Load defaults. Endpoint auto-fills to
https://mcp.asana.com/v2/mcp. Authorization header value:Bearerfollowed by the OAuth access token from Postman. Tool args template auto-fills — replacePROJECT_IDwith your GID. Save. - When the access token expires (about an hour after issue), Asana V2 will start returning HTTP 401. Repeat step 2 to mint a fresh token, then edit the integration in Settings and replace the Authorization header value. To skip this loop, switch to the REST API path above.
Gemini pricing & models
emAIl Sentinel calls Gemini twice per email per rule: once to evaluate, once to format the alert.
Models (select in Settings)
- 2.5 Flash (default) — fast, highly capable, best for most users
- 2.5 Flash Lite — ultra-low-cost, slightly less capable
- 2.5 Pro — highest accuracy for complex rules, higher cost
- 2.0 Flash 001 — stable previous-generation Flash, reliable fallback
Free tier
Get a key at aistudio.google.com/app/apikey. Free quota resets daily; at the limit Gemini returns 429 and calls resume next day.
Estimate your usage
new emails/day × active rules × 2 = daily API calls
- 20 emails × 1 rule = 40 calls — well within free
- 50 emails × 3 rules = 300 calls — well within free
- 100 emails × 5 rules = 1,000 calls — approaching limit
Paid rates (verify at ai.google.dev/pricing)
- Flash: ~$0.075/M input, ~$0.30/M output
- Flash Lite: ~$0.04/M input, ~$0.15/M output
- Pro: ~$1.25/M input, ~$5.00/M output
50 emails/day, 3 rules ≈ under $1/month.
Tips to minimize usage
- Enable Business hours — skips scans outside your window
- Lower Max email age (Settings ▸ Scan schedule) — skips older messages entirely
- Watch specific labels instead of INBOX
- Combine related conditions into one rule
- Keep alert format prompts concise
Settings & troubleshooting
Business hours
Restrict scans to a daily window. Outside hours, the trigger fires but skips the scan — no Gemini quota used.
Scan schedule
Background scans: Free = every 3 hours minimum; Pro = every 1 hour minimum. The 1-hour hard floor is a Google Workspace add-on platform limit. We could scan faster by running our own backend that stores your Gmail tokens and reads your email on our servers — but we deliberately do not. The add-on runs entirely inside your own Google account; your email content never reaches our infrastructure. The scan-interval floor is the price of that privacy posture. Click Scan email now any time for an immediate on-demand scan. The first run baselines existing messages so you do not get a flood of alerts.
Max email age
Controls how far back the Service looks when scanning a label. Default is 30 days. Emails older than this are ignored even if they are unread — useful for skipping long-dormant threads and cutting Gemini usage on busy labels.
Reset baseline
The first time the Service checks a watched label, it records every existing message ID as a "seen" baseline so you do not get a flood of alerts on install — alerts only fire for mail that arrives after that point. Clicking Reset baseline in Settings deletes that stored set. On the next run, every label is treated as brand-new: existing messages are silently absorbed into a fresh baseline, and alerting resumes for mail that arrives after. Use it if alerts start firing for old mail (e.g. after changing labels or reinstalling), or any time you want a clean slate.
Time zone for alerts
All dates rendered in alerts — the Sheets row Timestamp / Received columns, the Calendar event description, the Tasks notes, and any timestamp Gemini includes in the alert message — are formatted in your local time zone (taken from your primary Google Calendar). The format is yyyy-MM-dd h:mm:ss AM/PM TZ, e.g. 2026-04-27 5:29:58 PM CDT. Underlying milliseconds are preserved internally for sorting; only the user-visible string is localized.
Privacy
Settings, rules, seen messages, and the activity log are stored in UserProperties — private to your Google account. Email content goes only to Gemini and your configured alert channels.
Troubleshooting
- "No Gemini API key configured" — open Settings, paste a key, click Test Gemini
- "Label '...' fetch failed" — verify the label exists in Gmail (case-insensitive)
- SMS not delivered — check Activity Log for the provider's error
- Alerts for old mail — open Settings, click Reset baseline
- MCP target (Asana / Teams / Custom) not populated, no error in Activity Log — push the latest version. The MCP dispatcher now parses Streamable-HTTP
text/event-streamresponses (Asana V2 returns this) and surfaces tool-level errors asMCP alert to "<name>" FAILED: MCP "<name>" tool error: <detail>. Common details: Project not found (badproject_id), Forbidden (PAT lacks workspace access), Required field missing. All MCP types expect the auth header literalBearer <token>— capital B, single space, then the token. - Activity log times or alert dates look off by several hours — dates use your primary Google Calendar's timezone. Fix at calendar.google.com ▸ Time zone, then re-run.
- Lost edits in the rule or settings editor — always click Save before tapping the back arrow. Google's add-on framework gives no event when the system back arrow is pressed, so the editor cannot prompt to save unsaved changes. Each editor card shows an amber notice at the top as a reminder.
- Still stuck? Two ways to get help:
- Community discussions — ask other users, share rule recipes, browse setup tips for SMS / Chat / MCP. Best for usage questions.
- Open a GitHub issue — best for bugs and feature requests; tracked, searchable, get the fastest response from the developer.
Contact
- Support: support@jjjjjenterprises.com
- Legal / privacy: legal@jjjjjenterprises.com
- Billing: billing@jjjjjenterprises.com
Google, Gmail, Google Workspace, Google Chat, Google Calendar, Google Sheets, Google Tasks, and Gemini are trademarks of Google LLC. Microsoft and Teams are trademarks of Microsoft Corporation. Asana is a trademark of Asana, Inc. Not affiliated with or endorsed by any of these companies.