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

carlyemail

v0.6.0

Published

Real email inboxes your agent can send, receive and reply from. SDK and CLI.

Readme

carlyemail

Real email inboxes your agent can send, receive and reply from. One package, two things: a typed client and a command line.

The client

npm install carlyemail
import { CarlyEmail } from "carlyemail";

const carly = new CarlyEmail();          // reads CARLYEMAIL_API_KEY

const inbox = await carly.inboxes.create({ username: "hello" });

await carly.messages.send(inbox.email, {
  to: ["[email protected]"],
  subject: "Hello",
  text: "From an agent.",
});

Generated from the OpenAPI spec, so it cannot describe an endpoint the API does not serve. One fetch call per method and no dependencies, so it runs in Node, the browser, a worker and on the edge with no build step. Types ship with it.

Errors carry the message, the fix and a documentation link:

import { CarlyEmailError } from "carlyemail";

try {
  await carly.inboxes.create({ username: "hello" });
} catch (error) {
  if (error instanceof CarlyEmailError) {
    console.log(error.status, error.code, error.fix, error.docs);
  }
}

There is a Python client too: pip install carlyemail.

The command line

npx carlyemail signup

It asks for your email, offers an inbox name, and writes the key to ~/.carlyemail/config.json. Confirm the emailed code and it can send:

npx carlyemail verify 123456
npx carlyemail send \
  --from [email protected] \
  --to [email protected] \
  --subject "Hello" \
  --text "Sent by an agent with its own address."

Load the saved key and its first inbox into the current shell before starting LangChain, the Claude Agent SDK, Eve, Mastra, or another framework:

eval "$(npx carlyemail env)"

Install it if you use it often:

npm install -g carlyemail

Commands

| | | |---|---| | signup --human-email <e> --username <u> | Create an account and an inbox | | verify <code> | Confirm the owner email | | whoami | Identity and scope of the current key | | env | Print CARLYEMAIL_API_KEY and CARLYEMAIL_INBOX shell exports | | inboxes | List inboxes | | create --username <u> | Create an inbox | | delete <inbox> --yes | Delete an inbox and its mail | | send --from <i> --to <a> --subject <s> --text <t> | Send an email | | messages <inbox> | List messages | | read <inbox> <id> | Read one message in full | | search <inbox> <text> | Search messages | | threads <inbox> | List conversations | | reply <inbox> <id> --text <t> | Reply to the sender (--all to copy everyone) | | drafts <inbox> | List drafts | | draft <inbox> --to <a> --text <t> | Write a draft without sending | | send-draft <inbox> <id> | Send a draft written earlier | | webhooks | List webhook endpoints | | domains | List custom domains, with their DNS records | | plan | Current plan, with usage against every limit | | upgrade <plan> | A Stripe checkout link | | billing | Invoices, card changes, cancellation | | mcp | The MCP endpoint, for Claude and other clients |

Scripting

--json prints the API response untouched — the same shape the API reference documents, not a reshaped subset:

carlyemail inboxes --json | jq -r '.inboxes[].email'
carlyemail plan --json | jq '.organization.storage_bytes'

Failures still exit 1 under --json, and the error is still printed, so set -e behaves.

Configuration

The key is saved to ~/.carlyemail/config.json, written 0600 — it can read and send your mail, so it is not left group-readable.

Two environment variables override it, and the environment always wins:

| | | |---|---| | CARLYEMAIL_API_KEY | Use this key instead of the saved one | | CARLYEMAIL_API_URL | Point at a different deployment |

That ordering is what makes CI and containers work without touching the saved state, and it means running one command as a different account is a prefix rather than a login.

Notes

An owner email is not a login. Running sign-up again for an existing address returns account_exists and leaves every key untouched. Recover access with an emailed code at https://console.carlyemail.com; use create from an authenticated CLI session to add another inbox.

delete requires --yes. It removes the inbox and every message in it, and there is no undo.

Exit codes are meaningful. 0 on success, 1 on any failure, so carlyemail send … || handle-it behaves in a script.

Errors carry their fix. The API answers with a message, the thing that clears it, and a documentation link; all three are printed.

✗ Inbox limit reached (3 on the free plan).
  Upgrade the plan, or delete an inbox you no longer need.
  https://docs.carlyemail.com/inboxes

Requirements

Node 18 or newer. No dependencies — this is one file that uses Node's built-in fetch, so npx never resolves a tree and never fails for a reason unrelated to the thing you asked for.

Inbound email in a Worker

The dependency-free webhook helper uses Web Crypto, so the same verified onEmail callback runs in Cloudflare Workers, Node, and other edge runtimes:

import { createEmailHandler } from "carlyemail/webhooks";

const handleEmail = createEmailHandler({
  secret: env.CARLYEMAIL_WEBHOOK_SECRET,
  async onEmail(event) {
    console.log(event.message);
  },
});

Licence

MIT — see LICENSE. That covers this CLI only. The CarlyEmail service it talks to is a separate, proprietary product; a permissive licence on an HTTP client grants nothing over the API behind it.

Links