{
  "markdown": "<div align=\"center\">\n\n![ZeroSMTP — a free SMTP relay that still accepts basic auth. mx.msgwing.com, port 587 STARTTLS or 465 SSL/TLS.](docs/assets/banner.png)\n\n**Everything you need for the Microsoft 365 SMTP AUTH shutdown.**<br>\nFind out what breaks in your tenant, check whether your hardware has a way\nout, and keep it sending — including a free relay for the devices that will\nnever speak OAuth.<br>\nThe relay is free with no paid tier, capped at **200 messages/day**, and sends\nfrom a shared `@msgwing.com` address rather than your own\n([why](docs/FAQ.md#will-emails-be-sent-from-my-own-domain-eg-youyourdomaincom)).\n\n[![mx.msgwing.com status](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/msgwing/ZeroSMTP/status/status.json)](https://github.com/msgwing/ZeroSMTP/actions/workflows/service-healthcheck.yml)\n[![Exchange Online Basic auth countdown](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/msgwing/ZeroSMTP/status/countdown.json)](docs/EXCHANGE-ONLINE-SMTP-AUTH.md)\n[![Lint examples](https://github.com/msgwing/ZeroSMTP/actions/workflows/lint.yml/badge.svg)](https://github.com/msgwing/ZeroSMTP/actions/workflows/lint.yml)\n[![21 ready-to-run examples](https://img.shields.io/badge/examples-21%20ready--to--run-blue)](#code-examples)\n[![GitHub stars](https://img.shields.io/github/stars/msgwing/ZeroSMTP)](https://github.com/msgwing/ZeroSMTP/stargazers)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n\n[![mx.msgwing.com uptime, every check on record](https://raw.githubusercontent.com/msgwing/ZeroSMTP/status/uptime-card.svg)](https://github.com/msgwing/ZeroSMTP/actions/workflows/service-healthcheck.yml)\n\n[![Exchange Online Basic auth (SMTP AUTH) countdown](https://raw.githubusercontent.com/msgwing/ZeroSMTP/status/countdown-card.svg)](docs/EXCHANGE-ONLINE-SMTP-AUTH.md)\n\n[**Get a free account →**](https://msgwing.com) · [**Exchange Online migration →**](docs/EXCHANGE-ONLINE-SMTP-AUTH.md) · [Documentation site](https://docs.msgwing.com/) · [Quickstart](#quickstart) · [Code examples](#code-examples) · [FAQ](docs/FAQ.md) · [Deutsch](README.de.md) · [Polski](README.pl.md)\n\n</div>\n\n<!-- BEGIN GENERATED CONTENTS -->\n<!-- Generated by tools/build-readme-toc.py from this file's own\n     headings. Do not edit by hand - a contents list that drifts is\n     worse than none, because a missing row looks like nothing. -->\n\n## Contents\n\n- [What's in here](#whats-in-here)\n- [Quickstart](#quickstart)\n- [Why ZeroSMTP?](#why-zerosmtp)\n- [⭐ Support ZeroSMTP](#-support-zerosmtp)\n- [How does this compare to other options?](#how-does-this-compare-to-other-options)\n- [GitHub Actions](#github-actions)\n- [Code Examples](#code-examples)\n- [Security & Deliverability](#security--deliverability)\n- [Star History](#star-history)\n\n<!-- END GENERATED CONTENTS -->\n\n> ### Arrived from the GitHub Marketplace?\n>\n> This page is the README of the whole project, which is a free SMTP relay — so\n> the action you came for is below the fold. Here it is:\n>\n> ```yaml\n> - uses: msgwing/ZeroSMTP@v1\n>   with:\n>     host: smtp.office365.com\n>     cert-expiry-days: '14'\n> ```\n>\n> It checks outbound SMTP from the runner — ports, TLS, certificate and the\n> AUTH mechanisms offered — and **fails the job when the mail server's\n> certificate is inside the window you set**. Nobody watches a mail\n> certificate; it expires on a Sunday and the first report is somebody saying\n> scanning stopped working.\n>\n> No install and no npm: the tool has no dependencies, so the action runs the\n> file shipped beside it. Every input, and the scheduled-canary setup that\n> reports without failing, is in [**GitHub Actions**](#github-actions) further\n> down.\n\n## What's in here\n\n| | |\n| --- | --- |\n| **1. Audit your tenant** | [`Find-SmtpAuthExposure.ps1`](Find-SmtpAuthExposure.ps1) — read-only. Reports every mailbox that can still use SMTP AUTH, counting the ones that *inherit* the tenant setting separately, because the usual `-eq $false` one-liner misses those entirely and can report zero on a fully exposed tenant. |\n| **2. Check your hardware** | [Compatibility list](docs/DEVICE-COMPATIBILITY.md) for printers, MFPs, scanners and NAS units — machine-readable, backed by [`data/devices.json`](data/devices.json) and published as data at [docs.msgwing.com/data/devices.json](https://docs.msgwing.com/data/devices.json). Which models have OAuth firmware, and [which ones the vendor has ruled out](docs/NO-OAUTH-FIRMWARE.md), each row linking the vendor's own statement. |\n| **3. Keep it sending** | A free SMTP relay — an outgoing mail gateway that still accepts a username and password — with [21 code examples across 19 languages](#code-examples), [Ansible and Docker Compose recipes](#deployment-recipes), and [scan to email setup by printer brand](docs/PRINTERS.md) for HP, Canon, Ricoh, Xerox, Kyocera, Sharp, Brother and the rest. |\n\nPlus [what every error message actually means](docs/ERROR-MESSAGES.md), and a\n[migration guide](docs/EXCHANGE-ONLINE-SMTP-AUTH.md) that covers Graph API,\nDirect Send and paid relays — not just this one.\n\n**How big is this actually?** Nobody had published a number, so we measure one\nevery week: at least **24,960 public files on GitHub** still contain a\nMicrosoft 365 SMTP hostname. That is a count of files, not of systems that\nwill break, and [the page says exactly what it does and does not\nmean](docs/BLAST-RADIUS.md) — along with the raw data, so you can check it\nrather than trust it.\n\n> **Getting `535 5.7.139 Authentication unsuccessful, basic authentication is disabled`?**\n> That's Microsoft switching off Basic auth for SMTP AUTH — [start\n> here](docs/ERROR-MESSAGES.md). Three of the four causes are still reversible\n> until the end of December 2026.\n>\n> Want to know the day this changes? [Subscribe to the dated timeline](https://github.com/msgwing/ZeroSMTP/issues/305) —\n> one comment per confirmed change, nothing else.\n>\n> ```bash\n> npx zerosmtp-check --explain \"535 5.7.139 Authentication unsuccessful\"\n> ```\n>\n> Paste whatever *your* client printed — a Postfix SASL line, a Python\n> traceback, `1102` off a Kyocera panel, or the `curl: (67) Login denied` that\n> hides the server's answer entirely. They are the same refusal wearing\n> different clothes, and it says which case you are in and whether it can still\n> be switched back on. No install, nothing sent.\n\n---\n\n```bash\ncurl --url \"smtps://mx.msgwing.com:465\" \\\n  --user \"$ZEROSMTP_USERNAME:$ZEROSMTP_PASSWORD\" \\\n  --mail-from \"$ZEROSMTP_FROM\" --mail-rcpt \"$ZEROSMTP_TO\" \\\n  --upload-file <(printf 'Subject: Test\\r\\n\\r\\nHello from ZeroSMTP!') --ssl-reqd\n```\n\nThat's the whole thing — no SDK, no API key, just SMTP credentials that work\nwith anything that already speaks SMTP.\n\n| | |\n| --- | --- |\n| **Server** | `mx.msgwing.com` |\n| **Port** | `587` (STARTTLS) or `465` (SSL/TLS) |\n| **Login** | your randomly generated `@msgwing.com` address |\n| **Cost** | free — up to 200 emails/day ([limits](docs/TROUBLESHOOTING.md#sending-limits-rate-limiting)) |\n| **Catch** | mail is sent *from* `@msgwing.com`, not your own domain ([why](docs/FAQ.md#will-emails-be-sent-from-my-own-domain-eg-youyourdomaincom)) |\n\n## Quickstart\n\n1. **[Register your free account →](https://msgwing.com)** — 30 seconds, no credit card, no trial. You immediately get a random `@msgwing.com` login and password.\n2. Copy [`.env.example`](.env.example) to `.env` and fill in your credentials.\n3. Run the curl snippet above (`export $(grep -v '^#' .env | xargs)` first), or pick your language from the [Code Examples](#code-examples) table — every example reads the same `.env` variables.\n4. Having trouble? Check your network lets SMTP out at all — `Test-NetConnection mx.msgwing.com -Port 587` on Windows, or `openssl s_client -starttls smtp -connect mx.msgwing.com:587` elsewhere. That is what most first-run failures turn out to be. Then see [Error messages](docs/ERROR-MESSAGES.md) · [Troubleshooting](docs/TROUBLESHOOTING.md).\n\n> Prefer not to install anything locally? Every runtime used below (Python, PHP,\n> Node, Ruby, Go, Java, Kotlin/Gradle, .NET, Rust) is preinstalled in the\n> included [Dev Container / Codespace](.devcontainer/devcontainer.json).\n> [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/msgwing/ZeroSMTP)\n\n![Connectivity check against mx.msgwing.com](docs/assets/connection-check.png)\n\n## Why ZeroSMTP?\n\n- **Nothing to run and nothing to pay for.** No mail server, no API key, no\n  credit card, no per-email pricing tier to graduate into.\n- **Works with anything that already speaks SMTP** — apps, scripts, network\n  printers, NAS boxes, IoT hardware. If it has a \"SMTP server\" field, it works.\n- **Plain SMTP AUTH still accepted.** No OAuth2 flow to implement, which is\n  the whole point for old devices that will never get a firmware update.\n- **Managed reputation.** Accounts are randomly generated on a domain that's\n  actively monitored for abuse, so you're not warming up an IP yourself.\n- **21 copy-paste examples** across 19 languages, all reading the same\n  environment variables, plus Ansible and Docker Compose recipes and setup\n  guides for Windows Server, Linux, and printers by brand.\n- **Verifiably up** — the card above is a real check against `mx.msgwing.com`,\n  not a static image: every completed run is drawn, and the spacing printed on\n  it is measured from those runs rather than copied from the schedule. GitHub\n  delays scheduled workflows, so the cron asks for 15 minutes and the median\n  gap is closer to 45.\n- **Auditable handling** — where mail is processed, what is kept and for how\n  long, and the TLS versions the relay actually accepts and refuses, measured\n  rather than claimed: [What happens to mail sent through this\n  relay](https://docs.msgwing.com/PRIVACY.html).\n\nGood for: contact forms · password resets · CI/CD and monitoring alerts ·\nscan-to-email · IoT and device notifications · homelabs.\n\n> ### ⚠️ Losing SMTP AUTH on Exchange Online / Microsoft 365?\n> Microsoft disables Basic authentication for SMTP AUTH by default at the\n> **end of December 2026**. Printers, NAS boxes, backup jobs and monitoring\n> tools that can't do OAuth stop sending — and the alerting ones fail\n> *silently*, so you find out during the incident they should have warned\n> you about.\n>\n> **[Dated timeline →](https://github.com/msgwing/ZeroSMTP/issues/305)** — subscribe and you get an email\n> the day Microsoft changes either date. December 2026 is the default being\n> switched off, not the removal; the final date is announced in H2 2027.\n>\n> **[Migration guide →](docs/EXCHANGE-ONLINE-SMTP-AUTH.md)** covers every\n> option (Graph API, Direct Send, on-prem relay, paid services), not just\n> this one. **[What breaks →](docs/AFFECTED-SYSTEMS.md)** is the audit list,\n> including models whose vendor has said no OAuth firmware is coming.\n>\n> **Run [`Find-SmtpAuthExposure.ps1`](Find-SmtpAuthExposure.ps1)** to get the\n> answer for your own tenant. Read-only, and it counts the mailboxes that\n> inherit the tenant setting — the ones the usual one-liner misses.\n\nSetup guides: [Network printers](docs/PRINTERS.md) · [Popular applications](docs/APPS.md) · [Linux (Debian/Ubuntu/Rocky/Fedora/openSUSE)](docs/LINUX.md) · [System-wide mail relay (Postfix/msmtp/Exim4)](docs/SYSTEM-MTA.md) · [Windows Server](docs/WINDOWS-SERVER.md) · [Exchange Online SMTP AUTH migration](docs/EXCHANGE-ONLINE-SMTP-AUTH.md) · [Monitoring alerts](docs/MONITORING.md) · [OAuth compatibility list](docs/DEVICE-COMPATIBILITY.md) · [No OAuth firmware coming](docs/NO-OAUTH-FIRMWARE.md) · [Device case studies](docs/DEVICE-CASE-STUDIES.md) · [Troubleshooting](docs/TROUBLESHOOTING.md) · [Reliability (retries)](docs/RELIABILITY.md) · [vs. other free relays](docs/ALTERNATIVES.md) · [How much public code breaks](docs/BLAST-RADIUS.md) · [FAQ](docs/FAQ.md)\n\n> **Did this get a specific device sending again?** Tell us which one — a\n> [device report](https://github.com/msgwing/ZeroSMTP/issues/new?template=device_report.yml)\n> takes a couple of minutes. Vendors publish headline model lists; firmware\n> branches, regional names and OEM rebadges drift away from them, so a report\n> from someone holding the hardware is the part of\n> [the compatibility list](docs/DEVICE-COMPATIBILITY.md) nobody else can copy.\n> Confirming a device that *works* is just as useful as reporting one that\n> doesn't.\n\n## ⭐ Support ZeroSMTP\n\nThis project is **free, with no paid tier and no ads** — it exists because\nthe people who found it useful decided to help the next person find it too.\n\n**One star on GitHub is the cheapest way to do that.** GitHub ranks and\nrecommends repositories partly by stars, so it changes whether the next\nsysadmin with a dead printer at 2am finds this — or spends the night\nrebuilding what is already here.\n\n▶️ **[Give ZeroSMTP a star on GitHub](https://github.com/msgwing/ZeroSMTP/stargazers)**\n\nAlready starred? **[Create your free account](https://msgwing.com)** is the\nsecond best thing you can do — it takes 30 seconds and it means the next\nperson who lands here finds a healthy, active service rather than a\nside-project graveyard.\n\nHave a question first? Browse\n[Discussions](https://github.com/msgwing/ZeroSMTP/discussions) — the same\nquestions most people ask before trusting a free relay are already answered\nthere.\n\n## How does this compare to other options?\n\n|  | ZeroSMTP | Gmail SMTP relay | Amazon SES | Mailgun / SendGrid / Brevo (typical free tier) |\n| --- | --- | --- | --- | --- |\n| Cost | Free, no card required | Free (personal Google account) | Pay-per-email (a limited free allowance only applies from AWS EC2, first 12 months) | Free tier, usually capped low and gated behind signup + domain verification |\n| Setup | Register, copy SMTP credentials, done | Needs a Google account; Google's terms discourage automated/bulk sending over it | Needs an AWS account, plus a \"production access\" request before sending to unverified addresses | Signup + domain verification for full features |\n| Custom \"From\" domain | No — always `@msgwing.com` (see [FAQ](docs/FAQ.md#will-emails-be-sent-from-my-own-domain-eg-youyourdomaincom)) | Yes, your Gmail/Workspace address | Yes | Yes, once your domain is verified |\n| Best fit | Contact forms, password resets, notifications, printers/IoT — anywhere the from-address doesn't need to be your own domain | Low-volume personal scripts | Production apps that need it and can handle the AWS setup | Businesses that need branded sending and can handle the setup |\n\nFree-tier terms above change over time — check each provider's current\npricing page before committing to one.\n\n### What about self-hosting my own mail server?\n\nPopular self-hosted options like [docker-mailserver](https://github.com/docker-mailserver/docker-mailserver),\n[Mailu](https://github.com/Mailu/Mailu), or [mailcow](https://github.com/mailcow/mailcow-dockerized)\ngive you a mailbox on your own domain and full control — but you're the one\nrunning Postfix, DKIM/SPF/DMARC, spam filtering, and IP/domain reputation,\nwhich is real ongoing maintenance, not a one-time setup. ZeroSMTP is the\nother end of that trade-off: zero setup and zero maintenance, in exchange\nfor sending from the shared `@msgwing.com` address instead of your own\ndomain. If you already run one of those and it's working, there's no reason\nto switch. If you're not sure the effort is worth it yet for a script,\ncontact form, or side project, ZeroSMTP costs nothing to try first.\n\n## GitHub Actions\n\nTwo actions, and they do opposite things.\n\n**[`msgwing/ZeroSMTP`](https://github.com/marketplace/actions/zerosmtp-check) — check that mail *can* be sent.**\nRuns the connectivity check from the runner and fails the job when the mail\nserver's certificate is inside a window you choose. Nobody watches a mail\ncertificate; it expires on a Sunday and the first report is a user saying\nscanning stopped working. No credentials and no mail sent.\n\n```yaml\n- uses: msgwing/ZeroSMTP@v1\n  with:\n    host: smtp.office365.com\n    cert-expiry-days: '14'\n```\n\n**[`msgwing/send-email-action`](https://github.com/msgwing/send-email-action) — actually send one.**\nFor CI failure alerts, deploy notifications and scheduled reports.\nOn the [GitHub Marketplace](https://github.com/marketplace/actions/zerosmtp-send-email),\nit wraps the setup below into one step:\n\n```yaml\n- uses: msgwing/send-email-action@v1\n  with:\n    username: ${{ secrets.ZEROSMTP_USERNAME }}\n    password: ${{ secrets.ZEROSMTP_PASSWORD }}\n    from: ${{ secrets.ZEROSMTP_USERNAME }}\n    to: you@example.com\n    subject: \"Build failed\"\n    body: \"See the run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\"\n```\n\n## Code Examples\n\nReady-to-run, production-ready examples for `mx.msgwing.com:465` (SSL/TLS) or\n`:587` (STARTTLS), one file per language:\n\n| Language | File |\n| --- | --- |\n| Python | [python-zerosmtp.py](python-zerosmtp.py) |\n| PHP (PHPMailer) | [php-zerosmtp.php](php-zerosmtp.php) |\n| PHP (Symfony Mailer) | [php-symfony-mailer-zerosmtp.php](php-symfony-mailer-zerosmtp.php) |\n| Node.js | [node-zerosmtp.mjs](node-zerosmtp.mjs) |\n| TypeScript | [ts-zerosmtp.ts](ts-zerosmtp.ts) |\n| Bash (curl) | [bash-curl-zerosmtp.sh](bash-curl-zerosmtp.sh) |\n| Bash (swaks) | [bash-swaks-zerosmtp.sh](bash-swaks-zerosmtp.sh) |\n| Java | [java-zerosmtp.java](java-zerosmtp.java) |\n| C# (.NET / MailKit) | [cs-zerosmtp.cs](cs-zerosmtp.cs) |\n| Go | [go-zerosmtp.go](go-zerosmtp.go) |\n| Ruby | [ruby-zerosmtp.rb](ruby-zerosmtp.rb) |\n| Rust | [rust-zerosmtp.rs](rust-zerosmtp.rs) |\n| Kotlin | [kotlin-zerosmtp.kt](kotlin-zerosmtp.kt) |\n| Elixir | [elixir-zerosmtp.exs](elixir-zerosmtp.exs) |\n| Lua | [lua-zerosmtp.lua](lua-zerosmtp.lua) |\n| Perl | [perl-zerosmtp.pl](perl-zerosmtp.pl) |\n| C (libcurl) | [c-zerosmtp.c](c-zerosmtp.c) |\n| Dart | [dart-zerosmtp.dart](dart-zerosmtp.dart) |\n| Zig (libcurl) | [zig-zerosmtp.zig](zig-zerosmtp.zig) |\n| Swift | [swift-zerosmtp.swift](swift-zerosmtp.swift) |\n| PowerShell | [pwsh-zerosmtp.ps1](pwsh-zerosmtp.ps1) |\n\nEach example reads credentials from `ZEROSMTP_*` environment variables\n(`ZEROSMTP_USERNAME`, `ZEROSMTP_PASSWORD`, `ZEROSMTP_FROM`, `ZEROSMTP_TO`,\n`ZEROSMTP_SUBJECT`) — never hardcode real credentials into a script.\n\n### Deployment recipes\n\nNot every migration is a code change. Two of the places SMTP settings\nactually live:\n\n| Recipe | File | What it does |\n| --- | --- | --- |\n| Ansible | [ansible-zerosmtp.yml](ansible-zerosmtp.yml) | Points a fleet's system mailer (cron, unattended-upgrades, `systemd OnFailure=`) at the relay via msmtp. Idempotent; credentials come from `-e` or ansible-vault, never from the file. |\n| Docker Compose | [docker-compose-zerosmtp.yml](docker-compose-zerosmtp.yml) | Runs one send from a container, reading `.env`. Useful for testing the credentials from inside the network the real app runs in. |\n\n### Installing dependencies\n\nEvery example that needs a third-party library has a matching manifest at\nthe repo root, so you can install with each ecosystem's normal command\ninstead of hunting down library names/versions yourself:\n\n| Language(s) | Install with |\n| --- | --- |\n| Node.js / TypeScript | `npm install` |\n| PHP | `composer install` |\n| Rust | `cargo build` (fetches deps automatically) |\n| C# | `dotnet build cs-zerosmtp.csproj` |\n| Java | `mvn compile` |\n| Kotlin | `gradle build` |\n| Swift | `swift build` |\n| Zig | `zig build-exe zig-zerosmtp.zig -lc -lcurl` (needs libcurl headers) |\n| Python, Ruby, Go, Bash, PowerShell | none — standard library only |\n\nEasy Configuration:\n- Login: randomly generated address @msgwing.com\n- SMTP Server: mx.msgwing.com\n- Port: 587 (STARTTLS) or 465 (SSL/TLS)\n- Encryption: SSL/TLS - required\n\nWe respect your privacy - your data is not processed for any marketing or commercial purposes.\n\n## Security & Deliverability\n\n**What we do:**\n- SPF, DKIM and DMARC (`p=reject`) are aligned on `msgwing.com` — check it\n  yourself: `dig txt msgwing.com`, `dig txt _dmarc.msgwing.com`.\n- Accounts that abuse the relay are actively removed (see\n  [FAQ](docs/FAQ.md#why-is-zerosmtp-free-whats-the-catch)).\n- Sending is rate-limited per account to keep the shared domain's reputation\n  good for everyone (see\n  [sending limits](docs/TROUBLESHOOTING.md#sending-limits-rate-limiting)).\n\n**What we don't promise:** a shared domain means shared risk. No single\naccount controls the reputation of the whole pool, unlike your own domain,\nwhere you're the only one who can damage it. If mail must come from your own\ndomain, ZeroSMTP is the wrong tool — see [Alternatives](docs/ALTERNATIVES.md).\n\n**What we don't disclose, and why:** see\n[SECURITY.md](SECURITY.md#infrastructure-and-third-party-integration-inquiries).\n\n### Test it yourself\n\nDon't take our word for it — check with [mail-tester.com](https://mail-tester.com/):\n\n1. Create a free SMTP account at [msgwing.com](https://msgwing.com)\n2. Use our PowerShell test script: [SendEmailTest_mail-tester.com.ps1](SendEmailTest_mail-tester.com.ps1)\n3. Generate a random email at mail-tester.com and send a test message from your @msgwing.com address\n4. Read the score and the detailed analysis\n\n---\n\nIf you have any questions, feel free to contact us: abuse@msgwing.com\n\nRegistration is available at: https://msgwing.com\n\n## Star History\n\n[![GitHub stars](https://img.shields.io/github/stars/msgwing/ZeroSMTP?style=social)](https://star-history.com/#msgwing/ZeroSMTP&Date)\n",
  "bytes": 21434,
  "sha": "b614fa363688b56d115b1ea73c9a279d7a288d7af119edbbb438d51b8eda91d0",
  "repo_slug": "msgwing/zerosmtp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_msgwing_zerosmtp_b4c9bf8f/readme"
}