Repository navigation
Echo
Echo answers one question: is my site still saying what it should? It captures every email, SMS, webhook and API call a site sends, seals staging so none of it reaches real people and compares what each form, order or sign-up sends before and after a change. This page explains where Echo fits, what it catches and how it works.
rhythm echo up # start Echo: staging is sealed
rhythm echo install wordpress /var/www/staging # connect the site
rhythm echo snapshot --name before-update # what each action sends now
# …update plugins, deploy…
rhythm echo compare # what changedEcho ships as its own binary (rhythm-echo) and as a container image (ghcr.io/rhythmshahriar/echo). You normally run it through rhythm echo (or the short alias rhythm e): rhythm echo and rhythm-echo are the same command. The installer sets it up along with Tuner and Soundcheck; if you see rhythm: echo isn't installed, run rhythm install echo (rhythm v0.5.0 or later). See Install. Run rhythm echo on its own in a terminal and it asks what to do: start Echo, connect a site, snapshot, compare.
Important
Use Echo on sites you own or are authorized to test. Captured messages hold personal data: they stay on your machine, with credentials masked. Their content isn't masked. Echo seals by default; observe mode really sends. See Responsible use.
| Tool | Asks | Looks at |
|---|---|---|
| Tuner | Is my site safe? | what an attacker can find |
| Soundcheck | Did my change break anything? | what visitors see and do |
| Echo | Is my site still saying what it should? | everything the site sends |
The three work on the same change. Tuner tells you a plugin has a known vulnerability, so you update it. Soundcheck tells you the update broke the menu on 34 pages. Echo tells you the contact form still says "sent" while the office no longer gets the email. Soundcheck and Echo also work together: rhythm soundcheck compare --echo submits the real forms and compares what each one sent. See With Soundcheck.
| What | Page | |
|---|---|---|
| 📭 Lost messages | The admin notification that stopped, the autoresponder an update removed, the SMS a gateway change broke, the Slack alert, the GA4 purchase event, the webhook Zapier no longer receives, the queued mail stuck in a job, the PDF invoice no longer attached. | Actions and compare |
| ✍️ Wrong content | Unfilled placeholders ({first_name}, *|FNAME|*, [your-name]), PHP warnings printed into emails, links to localhost, garbled encoding, emails Gmail clips, CSS Outlook drops, SMS that cost several parts, payloads that lost fields or changed values, text you said should never appear (an old phone number). |
Messages and checks |
| 🔒 Staging that talks to real people | Sealed by default: email, SMS, WhatsApp, chat, webhooks, analytics and push are answered by Echo instead. Live-mode calls to Stripe, PayPal, Adyen, Braintree, Square, Authorize.net, Mollie and Razorpay get the gateway's own refusal in every mode. In observe mode, real recipients outside your allowlist are flagged. | Sealing staging |
| 📬 Deliverability | SPF (with the 10-lookup limit), DKIM keys, DMARC policy and alignment for the service you actually send through, MX, MTA-STS, TLS-RPT and BIMI, plus what a received email's headers say. Never sends anything. | Deliverability |
Echo recognizes 53 services out of the box, from SendGrid, Mailgun, Postmark, Resend, SES and the Gmail and Microsoft Graph APIs to Twilio, Vonage, WhatsApp Cloud, Slack, Teams, GA4, Segment, Meta, FCM, APNs, Stripe, HubSpot, Klaviyo and Zapier. rhythm echo providers lists them. Anything else is recorded as a generic webhook or request. The full list is in Messages and checks.
-
On every staging site, all the time.
rhythm echo upwith the connector installed means a staging copy of production can't email customers, text them, or post orders to the live CRM. Echo Inbox shows everything it caught. - In place of Mailpit. The image drops in where Mailpit runs (Docker Compose, DDEV, Lando and Sail) and answers Mailpit's API. See Docker and DDEV.
- Before and after a change. Plugin and theme updates, a new SMTP plugin, a PHP upgrade, a deploy. Snapshot what each action sends, make the change, compare.
-
In end-to-end tests.
code=$(rhythm echo latest --to ann@shop.test --code)gives a test the sign-in code just sent; Playwright and Cypress have helpers. A coding agent gets the same through Echo's MCP server. -
For inbound webhooks.
rhythm echo replay payment_intent.succeededsends a signed Stripe test event to staging and shows the order email and SMS it triggers. See Replay. -
For deliverability.
rhythm echo check yoursite.comchecks the DNS records for the sender you use, on production too, since it only reads DNS. - In CI. Fail a pull request when a message stops being sent. See CI.
- Across an agency's client sites. One hub for every staging site, update windows that snapshot, update and compare each site, plus a branded report for each client.
Echo isn't a mail client renderer or a general API mocking tool. It doesn't send to real phones. Its job is what your site sends and whether that changed.
flowchart LR
subgraph site ["Your site (staging)"]
C["Connector<br/>WordPress plugin,<br/>Laravel, Node"]
M["SMTP or sendmail"]
P["SDKs with their<br/>own HTTP"]
end
C -- "capture API :8025" --> E
M -- "SMTP sink :1025" --> E
P -. "HTTPS proxy :8026<br/>(optional)" .-> E
E["rhythm echo up<br/>recognize · seal · check · record"] --> I["Echo Inbox<br/>:8025"]
E --> A["Actions<br/>snapshot, compare, run"]
A --> S[(".echo/<br/>snapshots, runs")]
S --> R["Compare and report<br/>terminal, HTML, MD,<br/>JSON, JUnit"]
-
Connectors observe. A connector lives inside the site: a WordPress mu-plugin (or the Echo Staging Seal plugin), a Laravel package, an npm package for Next.js and Node. It hooks the mailer and the HTTP client, so it sees each message in plain text before it leaves and reports it to Echo. For anything else, Echo has an SMTP sink, a
sendmailstand-in and an HTTPS proxy. See Connectors. -
The catcher decides.
rhythm echo upruns the capture API, Echo Inbox, the SMTP sink and, when asked, the proxy. Each HTTP request is recognized (a Twilio SMS, a Slack alert, a GA4 event…) and, while sealed, answered with a response shaped like the provider's, so the site carries on as if it had been sent. Emails are recorded and never delivered. Every message is checked as it arrives. - An egress seal guarantees. A connector can only see what goes through the hooks it patches. For a seal nothing can get around, run the site on an internal Docker network or behind a firewall, with Echo as its only way out. See Sealing staging.
-
Actions make the site send.
.echo/config.yamllists actions: HTTP requests (a form post), commands (wp eval,php artisan), or signed webhook replays. Each one is tagged with anX-Echo-RunID, which the connector copies into every capture, so Echo knows which messages each action caused, even from queued jobs. Soundcheck can be the action runner too, submitting real forms. -
Compare. A snapshot records what each action sent.
compareruns the actions again and matches messages by who they go to and where, with test data, dates and order numbers normalized away. Missing messages are BROKE, new ones NEW, different recipients, subjects, text, payloads or attachments CHANGED and problems that went away FIXED. See Actions and compare.
The catcher keeps captured messages in memory (up to the newest 10,000) and forgets them when it stops; --store <dir> keeps them across restarts (see Echo Inbox). Snapshots, runs and reports go to the .echo/ folder next to your .echo/config.yaml, which every command finds from any subfolder of the project. Inside a git repository, .echo/snapshots/ and .echo/runs/ are added to .git/info/exclude, so captured personal data is never committed by accident, while config.yaml stays visible for your team. Reports and runs are written readable by you only. The HTTPS proxy's certificate authority lives in your config folder (~/.config/rhythm/echo/ca on Linux). See Configuration.
| You want to… | Read |
|---|---|
| Seal a site and check a change, step by step | Your first run |
| Connect WordPress, Laravel, Next.js or anything else | Connectors |
| Know what's caught, faked and refused | Sealing staging |
| Browse, search and share what the site sent | Echo Inbox |
| Add a check of your own, or turn one off | Checks and rules |
| Write actions and read a comparison | Actions and compare |
| Check real forms and flows | With Soundcheck |
| Swap Mailpit for Echo in Docker, DDEV, Lando or Sail | Docker and DDEV |
| Watch many client sites from one Echo | Agency hub and reports |
| Let a coding agent read what the site sent | MCP server |
| Wire it into CI | CI |
| Look up a flag | CLI reference |
| Fix a problem | FAQ and troubleshooting |
← Benchmark · Home · Your first run →
rhythm · Useful ideas. Working systems. · Check only sites you own or have permission to test. Keep staging sealed (responsible use) · This wiki is published from wiki/ in the rhythm repository; suggest changes there with a pull request.
Get started
rhythm in depth
Tuner
- Overview
- Your first scan
- Reading results
- Choosing checks
- Requests and politeness
- Output and reports
- Batch scans
- Local scans
- Integrity and malware
- Changes and notifications
Tuner in depth
- Known vulnerabilities
- PHP advisories
- CI and code scanning
- GitHub Action
- Config file
- Watch and serve
- Writing checks
- Check packs
- Finding reference
- CLI reference
- Coming from Wordfence CLI or WPScan
- FAQ and troubleshooting
Soundcheck
- Overview
- Your first check
- Reading results
- Review and accept
- Discovery
- Page health
- Visual changes
- Interactions
- Forms and flows
- Cache
- Speed
- Accessibility and SEO
Soundcheck in depth
- CI
- CI baselines and PR comments
- Configuration
- Error rules and exec
- WordPress updates
- Fleet and client reports
- History
- Import from BackstopJS and Lost Pixel
- Firefox and WebKit
- CLI reference
- FAQ and troubleshooting
- Benchmark
Echo
- Overview
- Your first run
- Connectors
- Sealing staging
- Echo Inbox
- Messages and checks
- Checks and rules
- Attachments
- Actions and compare
- With Soundcheck
- Replay
- Deliverability
Echo in depth
- Docker and DDEV
- Agency hub and reports
- Schedule
- MCP server
- Conformance kit
- CI
- Configuration
- API
- CLI reference
- FAQ and troubleshooting
- Benchmark
Project