add_run_note
ChatGPTAdds a line of your own to a run, such as a step you took ("Submitted the sign-up form") or a failure of your own; failed: true fails the run.
check_delivery
ChatGPTExplains an address's mail without waiting: how many emails have arrived and when the last one did, any messages Proxy Mail QA refused for it (too large, or over a limit), mail Cloudflare's mail servers turned away before it arrived (blocked: rejected for failing SPF, DKIM or DMARC, dropped, or not delivered), and a hint such as the app's email provider only sending to verified addresses. Use it when a wait finds nothing, and tell the person what it says.
check_email
ChatGPTChecks the newest matching email at the address (or email_id, from count_emails): SPF, DKIM and DMARC, links to localhost or plain http, where its sign-in, verify, reset or invite link goes (expect_host), whether it says when its sign-in code or link expires and when a coupon ends, a plain-text part, its size against Gmail's 102 KB limit, image-only emails, whether it fits a phone (fixed widths, alt text, tiny text), and, when asked, whether it contains given phrases (expect_text), is in a given language (expect_language) arrived soon enough after since (expect_within, such as 5m) and has the attachments expected (expect_attachment, such as .pdf). A marketing email also gets list_unsubscribe (a List-Unsubscribe header with an https address), one_click_unsubscribe (List-Unsubscribe-Post, covered by a DKIM signature that verified), unsubscribe_link (one in the email), preheader (preview text) and after_unsubscribe (it came after the address unsubscribed from its sender, see mark_unsubscribed); other emails skip them. A coupon also gets offer_reuse: it fails when the sender already sent a coupon to another version of the address (name+promo1@…, capitals); and coupon_result, once record_coupon_result has said what checkout did with it. Marketing email is also judged by the rules where the persona lives (see record_consent): marketing_consent, prechecked_consent, double_opt_in, unsubscribe_deadline, postal_address, sender_identity, minor_marketing, misleading_subject (a fake Re: or a deadline the email contradicts) and ad_label (Singapore's <ADV>). Every email also gets harmful_attachment (a file type Gmail blocks, such as .exe or a program named like a .pdf, fails; macros, HTML pages and archives warn) and spam_risk, a spam score out of 10 (score, with the markers that add up to it) of whether inboxes would reject it or file it as spam (5 or more fails), might (1.5 or more warns) or wouldn't (pass). Each check passes, fails, warns or is skipped, with a one-line reason. Verdicts only: never the email's text or links. Wait for the email first. The marketing and coupon checks need Marketing and offer emails, and harmful_attachment and spam_risk need Spam score and attachment checks, switched on in Account settings → Labs; checks of a feature that's off are left out.
check_offers
ChatGPTFor each sender, its coupons at this address and which version of the address each went to: plain, capitals, or a +tag (name+promo1@…). Mail to all of them reaches one inbox, so a one-time or welcome offer that reached two or more has been given to one person twice: reused is true, and with run_id that fails the run. same_code says whether it was one shared code (whether it works twice is then up to checkout). Use get_address_variants for versions to sign up with. Gmail’s dot trick can’t be tested here. In Labs: works once the person who connected you switches on Marketing and offer emails in Account settings → Labs; until then it answers with an error that says so.
check_out_account
ChatGPTBorrows a test account in a known state from the project (an address someone already signed up with in the app under test, tagged with its state): one matching every filter given (tags for its state, such as verified or premium; country; age; a saved password; text) that no other test has checked out, the least recently used first. It is yours for minutes (default 10, at most 60); return it with return_account and its checkout token. If every match is checked out, the error says when the first comes free.
check_sequence
ChatGPTChecks a welcome series or drip campaign: each step is an email to expect, in order, after since (the sign-up, say). A step can name a phrase from its subject, its category (auth, transactional or marketing), whether it has a code or a link, after (when it should come, such as 1d, from since) and within (how far off still passes; default a tenth of after, at least 10 minutes). Each step answers pass, early, late, missing or waiting (not due yet), with when it came; done is false while any step is waiting, so call again later. Subjects are matched here and never returned. In Labs: works once the person who connected you switches on Marketing and offer emails in Account settings → Labs; until then it answers with an error that says so.
check_unsubscribe
ChatGPTFor each sender the address unsubscribed from (mark_unsubscribed), the marketing emails that came after, by id and how long after, never their content. passed is false when any came, and with run_id that fails the run. Receipts, password resets and sign-in emails never count against it. In Labs: works once the person who connected you switches on Marketing and offer emails in Account settings → Labs; until then it answers with an error that says so.
count_emails
ChatGPTCounts the emails that reached the address, for checks such as "exactly one verification email". Doesn't wait: call it after the wait for the first email has returned, so a duplicate has had time to arrive. Each email is summarised by when it came, its sender and the kind of its code or link, never its content.
create_address
ChatGPTCreates a disposable email address in the project "Wholesome Project" for signing up to the app under test. It's on @enable.li unless you choose another domain. By default it also returns a fictional persona (first name, last name, username) to fill in sign-up forms; with age, the persona also gets a date of birth in that range, and with country, where it lives, for forms that ask. With password: true it also returns a strong password for the form, saved on the address; this is the only time it is shown here. It doesn't register anything in the app: sign up there yourself, or, if you can't open the app, give the person the address (and password) to sign up with. Then call wait_for_code or wait_for_link and pass on the code or link.
delete_address
ChatGPTDeletes the address and all its mail. Its name is never issued again.
expect_no_email
ChatGPTWatches the address for up to 30 seconds and passes if no matching email arrives, for checks such as "an unsubscribed user gets nothing" or "a second reset request is rate-limited". Answers as soon as one does arrive, saying when and from whom (passed: false), never what it says. Pass since as the time the action happened. For longer, pass until (up to 60 minutes after since) and call again with the same since and until while done is false.
extend_checkout
ChatGPTKeeps an account from check_out_account held for longer: minutes from now (default 10, at most 60), with the checkout.token it gave. For a test that runs past the hold; give it back with return_account when done.
finish_run
ChatGPTFinishes a run and returns its report in Markdown, ready for a pull request comment or a reply. It passes unless an email never came, one came when none should have, a check failed, a note failed it, or failed: true says your test failed. Show the person the report.
form_values
ChatGPTGives what to type or pick in each field of a sign-up form, from a new test address made for it (or one made earlier: address). Send what the page says about each field: its type, name, label, placeholder, autocomplete, rules (pattern, min_length, max_length) and a drop-down's options. The answer has a value for each field id: the email, names, a username and a password that fit the field's rules, the date of birth in the field's format (or day, month and year), and a country its drop-down offers; null with a note for anything else, such as a terms checkbox. A marketing consent checkbox (kind marketing_consent) is yours to tick or not; record_consent records what you chose and whether it started ticked (checked). A new address's password is saved on it and shown only here. Proxy Mail QA doesn't fill in or submit the form: you do, with your browser tools.
get_address_variants
ChatGPTLists versions of a test address for checking that the app under test accepts valid but unusual email addresses and rejects invalid ones: delivered (capitals, plus tags with apostrophes and other special characters, the longest name allowed; their mail arrives in this address's inbox), undeliverable (valid, but refused before they arrive) and invalid. Sign up with a delivered one, then wait on that same variant.
get_name_variants
ChatGPTLists values for testing what the app under test does with a name field, as get_address_variants does for the email field: accept (a real person's name the app should take as typed: O'Brien, Smith-Jones, José, Straße, 李, Мария, محمد, สมชาย, one letter, exactly the maximum), reject (over the maximum, empty, only spaces), store_as_text (HTML, a script tag, a SQL injection, a template expression: the app should store and show them exactly as typed, never run them) and decide (digits, symbols, an emoji, spaces around, a zero-width space, composed and decomposed accents, and 64, 128 and 255 characters when no maximum is given: apps differ, so note what the app did). Type each into the field yourself and report what the app did: accepted, rejected, or changed it (trimmed, escaped, cut short).
get_password_variants
ChatGPTLists passwords for testing what the app under test does with its password field, within the field's rules (min_length, max_length, symbols): accept (exactly the minimum and the maximum, each symbol class including quotes, a backslash and a space, non-ASCII letters: the app should take them, and sign the account in with them afterwards), reject (one under the minimum, one over the maximum, a symbol where none are allowed) and decide (only digits, only lower case, a space at the start or end, an emoji, composed and decomposed accents, and when the maximum is over 72 a pair sharing their first 72 bytes, which bcrypt stops at: apps differ, so note what the app did). Each call makes fresh passwords. Set one with the form, then check signing in with it works; for the composed and decomposed pair, set one and sign in with the other.
get_project
ChatGPTThe project this connection works in: its name, website, default mail domain and the other domains available, the email prefix new addresses start with, how long addresses can last, how many new addresses it can still make (Free: 500 in total, up to 50 a day; Team: no limit), and what it tests (areas: signup, offers, marketing, receipts).
list_addresses
ChatGPTLists addresses in the project, newest first, each with its persona, tags and newest code or link. Filters find a test account made earlier instead of creating another, such as an under-18 in GB with a saved password (country: "GB", max_age: 17, has_password: true); every filter given must match.
mark_dev_host
ChatGPTMarks a host as a dev environment of this project, as in Project settings: links to it in emails (an app running on localhost:3000, say) then pass check_email's local-links check instead of failing it. Use it when testing an app that runs on your machine; links to an unmarked localhost still fail, which catches a staging or live app that sends them by mistake.
mark_resubscribed
ChatGPTEnds an unsubscribe watch when the address has subscribed again (in the app’s email settings, say): marketing email from then on no longer fails. With only one sender watched, no sender is needed; otherwise pass email_id or service. In Labs: works once the person who connected you switches on Marketing and offer emails in Account settings → Labs; until then it answers with an error that says so.
mark_unsubscribed
ChatGPTRecords that the address unsubscribed from a sender, after you did it in your own browser or in the app (Proxy Mail QA never opens unsubscribe links). From then on, any marketing email from that sender fails after_unsubscribe in check_email and shows in check_unsubscribe, however long after. Name the sender with email_id (the email you unsubscribed from, from count_emails) or service (a name or domain, such as acme.com); with neither, the newest marketing email decides. Pass at for an unsubscribe that happened earlier. Marking twice is harmless. In Labs: works once the person who connected you switches on Marketing and offer emails in Account settings → Labs; until then it answers with an error that says so.
record_consent
ChatGPTRecords what the address agreed to at sign-up, after you filled in the form: marketing (opted_in or declined), prechecked (whether the consent box was already ticked when the page loaded) and double_opt_in (confirmed or pending, when the app asks to confirm the subscription by email; it confirms itself when the verify link is used). check_email then judges marketing email by the rules where the persona lives (create_address with country): marketing_consent, prechecked_consent, double_opt_in, unsubscribe_deadline, postal_address, sender_identity, minor_marketing, misleading_subject and ad_label, for the EU and EEA, UK, US, Canada, Australia, New Zealand, Switzerland, Japan, South Korea, Singapore and Hong Kong, each naming its official source. A test aid, not legal advice. Give only what changed; answers with the consent as recorded. In Labs: works once the person who connected you switches on Marketing and offer emails in Account settings → Labs; until then it answers with an error that says so.
record_coupon_result
ChatGPTAfter applying a coupon at checkout with your own browser tools (on staging with test payments only, never real card details: Proxy Mail QA never checks out), records whether the app accepted it, refused it (rejected) or failed with an error, with the app’s own message. Answers with every result for that coupon and the coupon_result verdict: it fails a coupon accepted after its end date, accepted for an offer already given to another version of the address (check_offers), or accepted twice when one_time is true; it warns on an error or a refusal with no reason. With run_id, a failed verdict fails the run. The coupon: code (default: the newest coupon at the address) or email_id. In Labs: works once the person who connected you switches on Marketing and offer emails in Account settings → Labs; until then it answers with an error that says so.
return_account
ChatGPTGives a checked-out account back for the next test, with the token from check_out_account. add_tags and remove_tags record the state your test left it in (for example add cancelled, remove premium), so the pool stays accurate.
search_docs
ChatGPTSearches Proxy Mail QA's docs and guides for how to do something: connect this MCP server in another client; use the REST API, the npm client or the Python helper; wait for a code or link in Playwright, Cypress, pytest, CI or a mobile app test; why a test email may not arrive (an email provider in sandbox mode, or Supabase, Clerk, Auth0 or Firebase sending limits); plans and limits. Returns the best-matching passages, each with its page's title and address. For this project's own settings and limits, use get_project.
set_password
ChatGPTSaves the password a test account uses now, replacing the one saved on the address before: after testing a password change or reset in the app under test, or when a sign-up form needed a different one. Leave password out to generate a strong one (16 characters), returned once in this result. Only for the test account's password in the app under test, never a real person's.
start_run
ChatGPTStarts a run: a record of one test session. Pass its run_id to create_address, the waits, count_emails, expect_no_email, check_email and check_out_account, and each adds what it saw: addresses, which emails arrived and how long after since, the code or the link's site (never its query), checks, and emails that never came. finish_run gives the report in Markdown for a pull request; the run is also in the app for the project's people.
update_address
ChatGPTChanges a test account's details: its first name, last name, username, date of birth or country (for example to match what the app under test accepted), or what it was used for: its label, notes (up to 2,000 characters, for test details) or tags. Send only the fields to change; an empty string clears one. To change its password, use set_password.
update_project
ChatGPTChanges this project's name, website, environments, email prefix or default mail domain, as in Project settings. Only the fields given change. It needs the project's lead (or an organisation owner or admin), the same as in the app, and every change is in the project's activity log. Archiving or deleting a project, and keeping whole emails, stay in the app. Returns the project as get_project does.
wait_for_code
ChatGPTWaits up to 30 seconds for a verification or login code to arrive at the address, and returns it with the sending service and when it expires. Returns at once if one arrived in the last 15 minutes. kind: coupon waits for a coupon or promo code instead (after signing up for an offer, say), with its discount and the date it is valid until when the email states them. With since, after_seconds says how long after it the email arrived; offers often come minutes later, so call again if nothing has come yet.
wait_for_link
ChatGPTWaits up to 30 seconds for a verify, magic sign-in, invite or password-reset link to arrive at the address, and returns the link with the sending service. The link has not been opened.