parse-dmarc

mcp
Security Audit
Fail
Health Pass
  • License — License: Apache-2.0
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 201 GitHub stars
Code Fail
  • rm -rf — Recursive force deletion command in .goreleaser.yml
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

DMARC aggregate report parser with a built-in dashboard. One Go binary, IMAP in, SQLite, Prometheus metrics, MCP server. Apache-2.0.

README.md

Parse DMARC

CI
Release
License
Stars
Docker pulls
Image size
Go Report Card
Scope

Read your DMARC aggregate reports in one dashboard. One Go binary, SQLite, no Elasticsearch.

Parse DMARC is built and maintained by the team behind DMARCguard, a hosted DMARC monitoring service. The two do not share code, and this repository stays Apache-2.0 in full.

Parse DMARC dashboard showing pass rate, message volume and top sending sources

What it does

When your DMARC record carries a rua= address, mail receivers such as Google, Microsoft and Yahoo send you aggregate reports: gzip or zip XML attachments, at the interval your record asks for and daily by default, listing every IP that sent mail as your domain and whether SPF and DKIM passed (RFC 7489 section 7.2, carried forward by RFC 9990). Nobody reads those by hand. Parse DMARC does:

  • Fetches reports over IMAP from any mailbox. Reports that Exchange or Outlook forward as message/rfc822 attachments are unwrapped too.
  • Parses gzip, zip and raw XML, with a 16 MB decompression cap per report.
  • Stores everything in one SQLite file. No database server, no JVM.
  • Shows pass rate, message volume and top sending sources, and opens any report down to its raw records.
  • Generates your _dmarc TXT record from a form.
  • Exposes 28 Prometheus metrics and ships a Grafana dashboard.
  • Serves an MCP server, so an AI assistant can query your reports.
  • Dark mode. One static binary. The Docker image is built FROM scratch.

It reads aggregate (RUA) reports only. Failure reports (RUF), TLS-RPT, alerting, login and multi-mailbox intake are not built; see Roadmap and contributing.

Run it

Docker, with a named volume for the database:

docker run -d --name parse-dmarc -p 8080:8080 \
  -e IMAP_HOST=imap.gmail.com \
  -e IMAP_PORT=993 \
  -e [email protected] \
  -e IMAP_PASSWORD='your-app-password' \
  -v parse-dmarc:/data \
  ghcr.io/dmarcguardhq/parse-dmarc:latest

Homebrew on macOS or Linux:

brew tap meysam81/tap
brew install parse-dmarc
parse-dmarc --gen-config          # writes a config.json template
parse-dmarc --config config.json

Or download a release archive, parse-dmarc_<os>_<arch>.tar.gz, from the releases page.

Open http://localhost:8080. Gmail needs an App Password, not the account password. The same image is on Docker Hub as meysam81/parse-dmarc; both names track the same builds, and tags such as v1 or v1.6.0 pin a release.

Get reports flowing

Receivers only send reports if your DMARC record asks for them. Publish this TXT record at _dmarc.example.com, with your own domain and mailbox:

v=DMARC1; p=none; rua=mailto:[email protected]
  • p=none asks receivers to deliver as usual and only report. Move to p=quarantine, then p=reject, once every legitimate sender in the reports passes (RFC 9989 section 5.1).
  • rua= is the mailbox Parse DMARC reads. It has to exist and accept mail before the first report arrives.
  • Check the record with dig +short TXT _dmarc.example.com. Reports typically start within 24 to 48 hours.

Cloudflare, Route 53 and every other DNS host take the same three fields: name _dmarc, type TXT, value as above. SPF and DKIM do not have to be set up first; the reports are how you find out what they are doing.

Deploy anywhere

One click on a platform, or a template for the self-hosted PaaS you already run. Every option needs the IMAP settings from Configuration.

Platform as a Service (PaaS)

Provider Deploy Notes
Railway Deploy on Railway Recommended for beginners
Render Deploy to Render Free tier available
Koyeb Deploy to Koyeb Global edge deployment. Manually mount /data as volume.
Zeabur Deploy on Zeabur Asia-Pacific optimized
Northflank Deploy to Northflank Developer-focused

Self-hosted PaaS

Provider Deploy Notes
CapRover Deploy to CapRover Self-hosted PaaS
Coolify Deploy to Coolify Open-source Heroku alternative
Dokploy Deploy to Dokploy Self-hosted deployment platform
Docker Docker Run anywhere

Infrastructure

Provider Deploy Notes
DigitalOcean Droplet Deploy to DigitalOcean VM with Packer image

Configuration

Every setting is an environment variable or a key in config.json. Environment is read first and the file overrides it.

Setting Environment variable Default
IMAP host and port IMAP_HOST, IMAP_PORT required, 993
IMAP username and password IMAP_USERNAME, IMAP_PASSWORD required
Mailbox to read IMAP_MAILBOX INBOX
Implicit TLS IMAP_USE_TLS true
STARTTLS on a plaintext port IMAP_STARTTLS false
Internal CA bundle, PEM IMAP_TLS_CA_FILE unset
Skip certificate verification IMAP_TLS_SKIP_VERIFY false
Mark fetched mail as seen IMAP_MARK_AS_SEEN true
Move processed mail to IMAP_PROCESSED_MAILBOX unset
Database file DATABASE_PATH ~/.parse-dmarc/db.sqlite, /data/parse-dmarc.db in Docker
HTTP listen SERVER_HOST, SERVER_PORT all interfaces, 8080
Seconds between fetches FETCH_INTERVAL 300
Log level LOG_LEVEL info

Providers: Gmail is imap.gmail.com on 993 with an App Password. Microsoft 365 is outlook.office365.com on 993. Anything else is port 993 with TLS unless its documentation says otherwise.

An IMAP server whose certificate comes from your own CA fails with x509: certificate signed by unknown authority. Mount the CA bundle and point IMAP_TLS_CA_FILE at it; verification stays on. IMAP_TLS_SKIP_VERIFY=true also connects and is the last resort, because the session can then be intercepted. IMAP_STARTTLS=true dials plaintext, usually port 143, and upgrades; it takes precedence over IMAP_USE_TLS. Turning TLS off entirely is plaintext IMAP, and most servers refuse LOGIN on it.

Flag What it does
--fetch-once Fetch, parse, store, exit. For cron.
--serve-only Serve the dashboard without fetching.
--fetch-interval 600 Seconds between fetch cycles.
--metrics=false Turn off /metrics.
--gen-config Write a config.json template and exit.
--mcp, --mcp-http :8081 Run the MCP server over stdio or HTTP instead of the fetcher. See docs/MCP.md.

Metrics, Grafana and MCP

/metrics is on by default: 28 metrics covering fetch cycles, IMAP connections, parse and store errors, compliance rate overall and per domain, SPF and DKIM result counts, and HTTP latency. grafana/dashboard.json is a ready dashboard for them. The full list, a Prometheus Operator ServiceMonitor, alert rules and a compose stack with Prometheus and Grafana are in docs/METRICS.md.

parse-dmarc --mcp exposes the same data to an AI assistant over the Model Context Protocol: nine tools, from get_statistics to parse_dmarc_report, over stdio or HTTP with optional OAuth2. Setup and the tool list are in docs/MCP.md.

The HTTP API behind the dashboard is four GET routes: /api/statistics, /api/reports, /api/reports/{id} and /api/top-sources. None of them has authentication, so keep the port behind your reverse proxy or VPN.

Parse DMARC or DMARCguard?

Two products, one maker, separate codebases. Parse DMARC is the whole of this repository: no enterprise directory, nothing to unlock. DMARCguard is a hosted, proprietary service that reads the reports for you and tells you what to change.

Parse DMARC DMARCguard
Who runs it You: a binary or container, a mailbox, a volume We do
What it reads DMARC aggregate reports DMARC aggregate reports, TLS-RPT reports, failure reports on Pro, and DNS checks for 9 protocols: DMARC, SPF, DKIM, BIMI, MTA-STS, TLS-RPT, ARC, DANE, ARF (7 on Free)
Sending sources IP addresses 170 named senders, Mailchimp or SendGrid rather than an IP, each with the DNS change that fixes it
Alerts Prometheus rules you write Email on Free; Slack, Teams, Discord and webhooks on Pro
Retention Whatever your disk holds 30 days on Free, 1 year on Pro
Access control None; keep it behind your proxy Accounts and 2FA; SAML SSO on Pro
Support GitHub issues Email
Price $0, Apache-2.0 Free for 2 domains, no credit card. Pro is $29/month including 2 domains

Run Parse DMARC when you want the data on your own disk and one mailbox to watch. Use DMARCguard when you want the reports read for you, or you have more domains than evenings.

I built Parse DMARC first, in late 2025. DMARCguard came out of what people asked for next: a sender's name instead of its IP, and the exact record to change on every alert. Paying for DMARCguard is what funds the hours that go into this repository, and it stays Apache-2.0.

Meysam

Start free on 2 domains, no credit card

Roadmap and contributing

The three most-asked additions, in the order people ask: TLS-RPT reports (#154), a Maildir or directory intake for people without IMAP (#169), and whois on sending sources (#143). ROADMAP.md has the rest. CONTRIBUTING.md covers the toolchain: just build, just dev, and docker compose up for a local Dovecot seeded with a sample report.

License

Apache-2.0, for everything in this repository. There is no ee/ directory and no feature that needs a key.


If Parse DMARC did the job, a star helps the next person find it. If you would rather have the reports read for you, DMARCguard is the hosted product from the same team.

Reviews (0)

No results found