npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@hrmoller/maildrop-mcp

v0.2.0

Published

MCP server for maildrop.cc disposable inboxes: list, read, wait for, extract one-time codes from, and delete test mail via the public GraphQL API.

Readme

maildrop-mcp

An MCP server for maildrop.cc disposable inboxes. It lets an AI agent list a test mailbox, wait for a mail to arrive, pull the one-time code out of it, read a message as plain text, delete it, or fetch the mailbox alias, all through maildrop's public GraphQL API and without a browser.

Built for QA flows where test accounts use [email protected] addresses and the agent needs the verification mail: login OTPs, sign-up confirmations, CRM/marketing-automation test sends.

Why an MCP server

  • Cheap reads. list_inbox returns one line per message and never fetches bodies. get_message strips tags, so a typical notification mail is a few hundred characters instead of the 15–25 KB HTML or raw source. No browser navigation or screenshots.
  • Waiting built in. wait_for_message and get_otp poll server-side at the interval maildrop asks for (10 s) and return once a matching mail lands.
  • Permission-friendly. Tool calls are governed by MCP allow rules in the client, so an agent can be allowed to read a test inbox without a shell-command classifier deciding that "extract digits from an email" looks suspicious.

Install

Requires Node 20 or newer. No API key: maildrop's API is public and unauthenticated.

The package is published to npm as @hrmoller/maildrop-mcp, so clients can run it with npx and nothing needs to be cloned.

Claude Code

claude mcp add --scope user maildrop -- npx -y @hrmoller/maildrop-mcp

Then allow the tools so they run without prompting, either through /permissions or in ~/.claude/settings.json:

{ "permissions": { "allow": ["mcp__maildrop__*"] } }

Start a new session; the tools appear as mcp__maildrop__list_inbox and so on.

Claude Desktop, Cursor, other clients

Add a stdio server entry to the client's MCP config:

{
  "mcpServers": {
    "maildrop": {
      "command": "npx",
      "args": ["-y", "@hrmoller/maildrop-mcp"]
    }
  }
}

From source

git clone https://github.com/hrmoller/maildrop-mcp.git
cd maildrop-mcp
npm install && npm run build
claude mcp add --scope user maildrop -- node "$PWD/dist/index.js"

Tools

| Tool | Arguments | Returns | |---|---|---| | list_inbox | mailbox | One line per message: id \| date \| from \| subject. Max 10 (maildrop's cap). | | get_message | mailbox, id, format = text (default) / html / raw | text: headers + tag-stripped body. html: HTML body. raw: full RFC822 source. | | wait_for_message | mailbox, subject?, from?, after?, timeoutSeconds (default 120, max 240) | The newest matching message as text once it arrives; error on timeout. | | get_otp | same as wait_for_message plus digits? | Only the one-time code (4–8 digits by default, or exactly digits). | | delete_message | mailbox, id | Confirmation. | | get_alias | mailbox | The D-…@maildrop.cc alias that forwards to this mailbox. | | service_status | none | Whether maildrop is operational, plus global counters. |

mailbox accepts name or [email protected]; the suffix is stripped because the API returns an empty inbox when it is present. Names are case-insensitive.

subject and from are case-insensitive regular expressions. from is matched against both the From: header and the envelope sender.

after narrows the search to messages dated after a point in time: an ISO-8601 timestamp, the word now, or a number of seconds ago. Default is 120 seconds ago. Capture a timestamp before triggering the mail and pass it, so two codes requested in quick succession are not confused.

One-time-code extraction

get_otp converts the HTML body to text and looks for a digit run of the requested length (4–8 when unspecified). A run that follows a cue word (code, kode, PIN, verif…, adgangs…, otp) wins; otherwise the first standalone run is used, skipping four-digit values that look like years. If nothing qualifies the tool errors with the message id so the agent can fall back to get_message.

Errors

Tool errors are returned as MCP isError results with a prefix naming the kind: not_found, timeout, no_code, api, network, usage.

API facts

Verified against the live API and docs.maildrop.cc on 2026-09-03.

| Fact | Value | |---|---| | Endpoint | POST https://api.maildrop.cc/graphql with content-type: application/json (400 without it; GET is rejected) | | Auth | None. The docs mention bearer tokens as a possible future measure. | | Rate limit | 50 requests per 10 seconds, burst 25; 429 until you back off; persistent offenders are blocked. Poll a mailbox no more than every 10 s. | | Mailbox | Holds at most 10 messages, oldest evicted. Deleted after 24 hours of inactivity. | | Mailbox name | Local part only, case-insensitive. Any name works without registration. | | Sending | maildrop cannot send mail (SPF -all). | | Greylisting | A first mail from an unknown sending server is deferred; it can take about 15 minutes to arrive. | | Message fields | id ip helo date mailfrom rcptto headerfrom subject data html; data is the raw RFC822 source, html the decoded HTML body. |

Security notes

  • Maildrop inboxes are public. Anyone who guesses a mailbox name can read it. Use it only for test accounts whose mail may be public, never for anything real. Use unguessable names (purpose_<random digits>), and hand out the alias from get_alias when a third party logs recipient addresses.
  • Codes are secrets, briefly. get_otp returns a code so the agent can use it. Do not record codes in tickets, docs, or logs.
  • The server only talks to api.maildrop.cc. It has no other network access, no filesystem access, and no configuration.

Releasing

Merging to main publishes the package when package.json carries a version that is not on the registry yet; a merge that does not bump the version runs the tests and stops. The workflow is .github/workflows/release.yml:

  1. Tests run on Node 20, 22 and 24.
  2. If they pass and the version is new, npm publish runs and the commit is tagged vX.Y.Z with a GitHub release.

So a release is: bump version in package.json, add a CHANGELOG.md entry, merge to main.

Publishing authenticates with npm trusted publishing over GitHub Actions OIDC, so no npm token is stored in the repository, and npm attaches provenance to each published version automatically. The trusted publisher configured on npmjs.com must name the workflow file release.yml.

Development

npm run typecheck   # tsc --noEmit
npm test            # build + node:test unit tests
npm run smoke       # build, then drive dist/index.js over stdio: initialize, tools/list, two tool calls
npm run smoke -- some_mailbox

Layout: src/maildrop.ts holds the API client and pure helpers (HTML-to-text, code extraction, filters); src/index.ts registers the tools and carries the server instructions that clients load at session start. Tests live next to the code and run against the compiled dist/.

License

MIT.