{"id":49336235,"url":"https://github.com/datanoisetv/smartmail","last_synced_at":"2026-04-27T01:01:58.470Z","repository":{"id":353654314,"uuid":"1219411605","full_name":"DatanoiseTV/smartmail","owner":"DatanoiseTV","description":"A local/remote LLM powered smart E-Mail manager/sorter and smart Spam Filter.","archived":false,"fork":false,"pushed_at":"2026-04-24T20:36:14.000Z","size":38,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-24T22:29:41.913Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DatanoiseTV.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-23T21:11:05.000Z","updated_at":"2026-04-24T20:22:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/DatanoiseTV/smartmail","commit_stats":null,"previous_names":["datanoisetv/smartmail"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/DatanoiseTV/smartmail","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DatanoiseTV%2Fsmartmail","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DatanoiseTV%2Fsmartmail/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DatanoiseTV%2Fsmartmail/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DatanoiseTV%2Fsmartmail/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DatanoiseTV","download_url":"https://codeload.github.com/DatanoiseTV/smartmail/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DatanoiseTV%2Fsmartmail/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32318417,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"ssl_error","status_checked_at":"2026-04-26T23:26:25.802Z","response_time":129,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-27T01:01:57.687Z","updated_at":"2026-04-27T01:01:58.445Z","avatar_url":"https://github.com/DatanoiseTV.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# smartmail\n\nLLM-powered IMAP inbox organizer. A single Go binary that connects to any mail\nserver, classifies incoming messages with an LLM using proper tool-calling,\nand organizes them into category folders — without ever deleting anything, so\nyou always have a safe path back.\n\nWorks with Gmail, iCloud, Fastmail, Outlook, Yahoo, Proton Bridge, or any\nself-hosted IMAP server. Uses OpenAI or any OpenAI-compatible endpoint\n(LMStudio, Ollama with `--openai`, vLLM, llama.cpp server, …) so you can run\nfully local if you prefer.\n\n## Highlights\n\n- **Single static binary.** No Docker, no Python, no Node. Just `go build`.\n- **Real IMAP, real tool calls.** Uses three well-typed tools — `file_email`,\n  `mark_spam`, `keep_in_inbox` — with JSON Schema parameters. Not prompt-hacked\n  regex parsing.\n- **Non-destructive.** Everything is a move. An append-only audit log records\n  every action with reasoning, and `smartmail undo` rolls back the last N.\n- **Smart folder layout.** The model sees your existing mailboxes and prefers\n  to reuse them instead of creating `Newsletters-1/Newsletters-2/…`.\n- **Confidence gate.** Low-confidence decisions fall back to leaving the\n  message in the inbox — you set the threshold.\n- **IMAP keywords as tags.** Cross-folder semantic search (prefix `sm-`).\n- **Pre-filters.** Trusted / blocked sender rules skip the LLM to save tokens.\n- **Real-time watch mode.** IMAP IDLE + periodic rescan as a safety net.\n- **Daemon mode.** `smartmail watch -d` forks into the background with a\n  pidfile and logfile.\n- **Web UI.** Login-protected dashboard (HTTP basic auth) to trigger runs,\n  browse the audit log, view folders, and edit the config.\n- **Privacy.** Nothing leaves your machine if you point it at a local\n  LMStudio/Ollama endpoint.\n\n## Install\n\nRequires Go 1.22+.\n\n```sh\ngit clone https://github.com/DatanoiseTV/smartmail.git\ncd smartmail\ngo build -o smartmail .\n# optional:\nsudo mv smartmail /usr/local/bin/\n```\n\n## Quick start\n\n```sh\nsmartmail init     # interactive setup wizard; writes smartmail.yaml\nsmartmail run --dry-run --limit 20 --verbose\nsmartmail run      # when you're happy with the dry-run output\nsmartmail watch    # stay connected and process in real time\n```\n\n### Gmail\n\nEnable 2FA and create an [App Password](https://myaccount.google.com/apppasswords).\nUse `imap.gmail.com:993` with TLS. For the archive root, `[Gmail]/All Mail`\nworks but top-level labels are usually friendlier — Gmail treats folders as\nlabels, so whatever you pick will show up in the Gmail web UI.\n\n### Local LLM via LMStudio\n\n1. Launch LMStudio, load a model that supports tool calls (Llama 3.1 8B+,\n   Qwen2.5 7B+, Mistral Small 3, etc.), and start the local server.\n2. In `smartmail init` pick \"LMStudio\" and confirm `http://localhost:1234/v1`.\n3. That's it — everything works offline from here.\n\n## Commands\n\n```\nsmartmail init                   Interactive setup wizard\nsmartmail run [flags]            One pass over unseen mail, then exit\nsmartmail watch [flags]          Long-running: IMAP IDLE + periodic rescan\nsmartmail watch -d               Daemonize (background, pidfile, logfile)\nsmartmail folders                List mailboxes on the server\nsmartmail undo --last N          Roll back the last N actions\nsmartmail stats                  Summarize the audit log\nsmartmail webui --pass XXX       Serve the web UI on 127.0.0.1:8787\n```\n\n### Common flags\n\n| flag | meaning |\n|------|---------|\n| `--config PATH` | override config discovery |\n| `--dry-run` | print decisions without touching mailboxes |\n| `--limit N` | process at most N messages this run |\n| `--since DAYS` | only look at messages newer than N days |\n| `--verbose` | show full LLM reasoning |\n\n## How it decides\n\nFor each unseen message the classifier:\n\n1. Checks **deterministic rules** first (trusted / blocked sender lists) to\n   avoid spending tokens on things with obvious answers.\n2. Builds a compact prompt: headers, `List-Id`, `List-Unsubscribe`,\n   truncated body (HTML stripped), plus the list of **existing mailboxes** on\n   the server so the model can reuse them.\n3. Forces the model to call **exactly one** of three tools:\n   - `file_email(category, subfolder?, tags[], priority, should_star, confidence, reasoning)`\n   - `mark_spam(indicators[], confidence, reasoning)`\n   - `keep_in_inbox(priority, should_flag, tags[], reasoning)`\n4. If the returned confidence is below the configured threshold, the\n   decision is downgraded to `keep_in_inbox`.\n5. Applies IMAP operations (create folder if missing, add keywords / `\\Flagged`,\n   then `MOVE` — with automatic fallback to `COPY + STORE + EXPUNGE` on older\n   servers).\n6. Appends a JSONL entry to the audit log.\n\n## Configuration\n\nA minimal `smartmail.yaml`:\n\n```yaml\nimap:\n  host: imap.gmail.com\n  port: 993\n  username: you@example.com\n  password: env:SMARTMAIL_IMAP_PASSWORD\n  tls: true\n  inbox: INBOX\n  archive_root: \"\"          # leave empty for top-level folders\n\nllm:\n  provider: openai          # or \"lmstudio\"\n  base_url: https://api.openai.com/v1\n  api_key: env:OPENAI_API_KEY\n  model: gpt-4o-mini\n  temperature: 0\n  max_tokens: 800\n  timeout_sec: 60\n\npolicy:\n  min_confidence: 0.65      # below this, keep in inbox\n  max_body_chars: 4000\n  mark_seen: false\n  concurrency: 3\n\nrules:\n  trusted_senders:\n    - boss@example.com\n    - \"@partner-company.com\"\n  blocked_senders:\n    - \"@obvious-spammer.biz\"\n  pinned_folders:\n    - Personal\n    - Work\n    - Finance\n    - Receipts\n    - Shopping\n    - Travel\n    - Newsletters\n    - Marketing\n    - Social\n    - Notifications\n    - Updates\n```\n\nAny secret field can be replaced with `env:VAR_NAME` to read it from the\nenvironment instead of storing it in the file.\n\n## Web UI\n\n```sh\nexport SMARTMAIL_WEB_PASS='choose-a-strong-one'\nsmartmail webui --addr 127.0.0.1:8787\n```\n\nThen browse to `http://127.0.0.1:8787`, log in (default user: `admin`), and\nyou get a dashboard with status, audit log, folder list, editable config,\nand an on-demand \"Run now\" button.\n\nServe it behind a reverse proxy if you want to expose it beyond localhost.\n\n## Daemonizing\n\n```sh\nsmartmail watch -d \\\n  --pidfile /var/run/smartmail.pid \\\n  --logfile /var/log/smartmail.log\n```\n\nDefault paths are `smartmail.pid` and `smartmail.log` next to your config\nfile. To stop:\n\n```sh\nkill $(cat /var/run/smartmail.pid)\n```\n\nsystemd unit (example):\n\n```ini\n[Unit]\nDescription=smartmail inbox organizer\nAfter=network-online.target\n\n[Service]\nType=simple\nExecStart=/usr/local/bin/smartmail watch --config /etc/smartmail/config.yaml\nRestart=on-failure\nUser=smartmail\nEnvironmentFile=/etc/smartmail/env\n\n[Install]\nWantedBy=default.target\n```\n\n## Undo / safety\n\nEvery action is a single-line JSON entry in `smartmail.audit.log`. The state\nfile `smartmail.state.json` prevents reprocessing the same UID twice.\n\n```sh\nsmartmail undo --last 5           # roll back the most recent five moves\nsmartmail undo --last 5 --dry-run # preview first\n```\n\n## Roadmap\n\n- OAuth2 (XOAUTH2) for Gmail / Outlook — today only basic auth + app\n  passwords are supported.\n- Learning loop: feed the user's manual moves back as few-shot examples.\n- Per-mailbox rules (e.g. different policy for a shared team inbox).\n- Encrypted password-at-rest via OS keyring.\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatanoisetv%2Fsmartmail","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatanoisetv%2Fsmartmail","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatanoisetv%2Fsmartmail/lists"}