MCP server · Audited from source
mailcheap MCP server
by marclou/mailcheapAGPL-3.0 licenceAudited 23 Oct 2026 · source f74cb8e1d2fe
Is it safe? With care — CAUTION, grade B (81/100). It exposes 2 tools: 2 read, 0 write and 0 destructive. The audit recorded 26 findings (0 critical, 1 high, 1 medium, 24 low). Maintainer's description: Newsletters where you pay for the emails you send, not for dormant subscribers, at a fraction of the price of beehiiv and the like. Open source: self-host it, or use mailcheap.ai.
Cite
Cite this page
ModelsAtlas. “mailcheap MCP server (marclou/mailcheap)”. Retrieved 23 Oct 2026. https://modelsatlas.com/mcp/marclou/mailcheap
Trust audit
Audit 0.4.1 · full source read 23 Oct 2026
26 findings, listed below with the file and line each was found on. Grade A needs a sandboxed behavioural run too; this audit read the source only.
What the source does
- FilesystemNone observedNothing seen in the source
- NetworkDeclared6 observations
- ShellNone observedNothing seen in the source
- DependenciesNot pinnedSome ranges float
- SecretsNone foundNo keys in source
“Declared” means the server says it does this and the source agrees. Browser, file and shell access are expected of some kinds of server.
Five audit layers
| Layer | What we check | Result |
|---|---|---|
L0 Provenance | Repo owner, licence, archive status, activity | PASS |
L1 Static source | Secrets, path traversal, supply chain | FAIL 17 findings |
L2 Instructions | Prompt injection and authority framing in docs and tool descriptions | PASS 8 findings |
L3 Inventory | Declared tools match the source | PASS |
L4 Sandbox | Run in isolation and watch behaviour | SKIPPED |
Provenance & runtime
Who published it, and what the audit could and could not run
Provenance
- Repository owner
marclouUser accountAccount type recorded when we read the repository. - PackagePublished on npm
mailcheapat version 1.0.0 - LicenceAGPL-3.0From the repository, as read at the audited commit.
- Last pushTodayActivity of the repository when we read it.
- Source commit readf74cb8e1d2feThe audit covers exactly this commit, read on 23 Oct 2026.
Runtime
- Sandbox runNot run yetThis audit read the source only; it did not execute the server.
- Tool inventory2 declaredRead from the source and classed read, write or destructive.
Every value here is read from the record's own repository and audit.Suggest a correction
Findings (26)
Sorted by severity · the 25 most severe of 26 are listed
HIGHNetwork egressnet.tls_off · lib/email-provider/postshiba.js:220
async function readDomain({ account, domain, verify = false }) {- Why
- certificate verification is disabled
- Fix
- leave verification on
MEDIUMNetwork egressnet.beacon_words · lib/thumbnail.js:1
const SKIPPED_URL_PATTERN = /(pixel|tracking|spacer|beacon|1x1|favicon|emoji)/i;
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWFilesystem / pathfs.traversal · tests/helpers/app-pages.mjs:4
const APP = fileURLToPath(new URL("../../app", import.meta.url));- Why
- No further detail recorded for this rule.
- Fix
- —
LOWFilesystem / pathfs.traversal · tests/helpers/app.mjs:71
const { getPlan, getPrice, parseLookupKey } = await import("../../lib/plans.js");- Why
- No further detail recorded for this rule.
- Fix
- —
LOWFilesystem / pathfs.traversal · tests/helpers/app.mjs:117
const { connectDb } = await import("../../lib/db.js");- Why
- No further detail recorded for this rule.
- Fix
- —
LOWFilesystem / pathfs.traversal · tests/helpers/app.mjs:177
const { sendSigninCode, verifySigninCode } = await import("../../app/signin/actions.js");- Why
- No further detail recorded for this rule.
- Fix
- —
LOWFilesystem / pathfs.traversal · tests/helpers/app.mjs:185
const Account = (await import("../../models/Account.js")).default;- Why
- No further detail recorded for this rule.
- Fix
- —
LOWNetwork egressnet.metadata_ip · tests/image-files.test.mjs:34
"169.254.169.254",
- Why
- cloud metadata endpoint: the classic SSRF credential grab
- Fix
- —
LOWNetwork egressnet.metadata_ip · tests/image-files.test.mjs:44
"::ffff:169.254.169.254",
- Why
- cloud metadata endpoint: the classic SSRF credential grab
- Fix
- —
LOWNetwork egressnet.metadata_ip · tests/image-files.test.mjs:55
for (const link of ["https://127.0.0.1/a.png", "https://169.254.169.254/latest/meta-data", "https://[::1]/a.png", "https://10.0.0.5/a.png"]) {- Why
- cloud metadata endpoint: the classic SSRF credential grab
- Fix
- —
LOWNetwork egressnet.metadata_ip · tests/og-image.test.mjs:33
for (const url of ["https://169.254.169.254/latest/meta-data", "https://127.0.0.1/logo.png", "https://10.0.0.5/logo.png"]) {- Why
- cloud metadata endpoint: the classic SSRF credential grab
- Fix
- —
LOWNetwork egressnet.raw_ip · tests/image-files.test.mjs:55
for (const link of ["https://127.0.0.1/a.png", "https://169.254.169.254/latest/meta-data", "https://[::1]/a.png", "https://10.0.0.5/a.png"]) {- Why
- No further detail recorded for this rule.
- Fix
- —
LOWNetwork egressnet.raw_ip · tests/oauth-rules.test.mjs:51
assert.deepEqual(describeClient(null, "http://127.0.0.1:3118/callback"), { name: "127.0.0.1:3118", host: "127.0.0.1:3118" });- Why
- No further detail recorded for this rule.
- Fix
- —
LOWNetwork egressnet.raw_ip · tests/oauth-rules.test.mjs:68
for (const uri of ["http://localhost:3118/callback", "http://127.0.0.1/callback", "http://[::1]:8080/cb"]) assert.equal(isLoopbackRedirect(uri), true, uri);
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWNetwork egressnet.raw_ip · tests/oauth.test.mjs:72
redirect_uris: ["http://localhost/callback", "http://127.0.0.1/callback"],
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWNetwork egressnet.raw_ip · tests/oauth.test.mjs:574
[CLAUDE_CODE_DOCUMENT, "http://127.0.0.1:41893/callback"],
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWSupply chainsupply.unpinned · package.json
@aws-sdk/client-cloudfront, @aws-sdk/client-s3, @aws-sdk/client-sesv2, @better-auth/cimd, @better-auth/mcp, @better-auth/oauth-provider, @floating-ui/dom, @modelcontextprotocol/server
- Why
- 43 dependency range(s) float
- Fix
- pin exact versions or ship a lockfile
LOWPrompt injectionprompt.authority_framing · README.md:187
1. **Team and key.** In API keys, create a full access key: `POSTSHIBA_API_KEY`, with the team id as `POSTSHIBA_TEAM_ID`. Add a payment method (clusters need one).
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWPrompt injectionprompt.authority_framing · README.md:291
Create a key on the **API keys** page and send it as `Authorization: Bearer <key>`. A full access key can do everything the dashboard can; a signups only key can only add contacts, for keys that sit i
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWPrompt injectionprompt.authority_framing · README.md:302
**MCP**: connect Claude Code with a full access key. Every action is a tool.
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWPrompt injectionprompt.authority_framing · README.md:309
ChatGPT, Claude and Grok Bot add `https://<your-app>/mcp` as a connector or custom MCP server and sign in with OAuth: you sign in to MailCheap and allow the app on a consent page, and it gets full acc
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWPrompt injectionprompt.authority_framing · SECURITY.md:19
- Two levels: full access, and signups only, which can only add contacts. Keys made before levels count as signups only. Only a full access key can create keys, and an account has up to 20 active ones
- Why
- No further detail recorded for this rule.
- Fix
- —
LOWPrompt injectionprompt.credential_read · README.md:114
2. **Database Access**: add a user with a password and the "Read and write to any database" role.
- Why
- asks the agent to read credentials
- Fix
- —
LOWPrompt injectionprompt.transfer_instruction · README.md:121
2. Fill in `MONGODB_URI`, `BETTER_AUTH_SECRET` (at least 32 characters; generate it with `openssl rand -base64 48`), `SUPPRESSION_HASH_KEY` (generated the same way, another value), `ADMIN_EMAILS` (you
- Why
- an instruction to move sensitive data to an outside destination
- Fix
- remove; a skill never needs the user's secrets off the machine
LOWPrompt injectionprompt.transfer_instruction · README.md:330
- QStash can't reach `localhost`. To try a full send locally, run the QStash dev server (`npx @upstash/qstash-cli dev`) and use the URL, token and signing keys it prints.
- Why
- an instruction to move sensitive data to an outside destination
- Fix
- remove; a skill never needs the user's secrets off the machine
Tools it exposes
2 declared in source · 0 destructive
| Tool | Risk | What it does |
|---|---|---|
Get-thing | read | No description in the source |
get_thing | read | Gets a thing. |
Install
Package version 1.0.0 · audited commit f74cb8e
Read the findings first. The most severe is Network egress (high) at lib/email-provider/postshiba.js.
One-click links open your editor with the config below filled in, exactly as the snippets show it, pinned to version 1.0.0. The audit covers commit f74cb8e only.
claude mcp add mailcheap --env AWS_SHARED_CREDENTIALS_FILE=${AWS_SHARED_CREDENTIALS_FILE} --env BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET} --env CRON_SECRET=${CRON_SECRET} --env GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} -- npx -y [email protected]{
"mcpServers": {
"mailcheap": {
"command": "npx",
"args": [
"-y",
"[email protected]"
],
"env": {
"AWS_SHARED_CREDENTIALS_FILE": "${AWS_SHARED_CREDENTIALS_FILE}",
"BETTER_AUTH_SECRET": "${BETTER_AUTH_SECRET}",
"CRON_SECRET": "${CRON_SECRET}",
"GOOGLE_CLIENT_SECRET": "${GOOGLE_CLIENT_SECRET}"
}
}
}
}The command pins the package version recorded in the source (1.0.0); the audit covers commit f74cb8e1d2fe. Transport: streamable-http. Reads these environment variables: AWS_SHARED_CREDENTIALS_FILE, BETTER_AUTH_SECRET, CRON_SECRET, GOOGLE_CLIENT_SECRET, IMAGES_S3_ACCESS_KEY_ID, IMAGES_S3_SECRET_ACCESS_KEY, POSTSHIBA_WEBHOOK_SECRET, QSTASH_CURRENT_SIGNING_KEY and 4 more. Give it the narrowest token it needs.
Audit history
- !CAUTION B 81 / 100
First audit ·
f74cb8e1d2fe
README badge
For maintainers · updates on every re-audit
[](https://modelsatlas.com/mcp/marclou/mailcheap/)
The badge always shows the latest audit; a maintainer cannot pin an old verdict.
Other ratings
Cited, never blended into our score
No third-party security ratings are recorded for this server yet. When they exist they appear here with their source and date, beside, not inside, our grade.
Questions about mailcheap MCP server
What is the mailcheap MCP server?
What tools does mailcheap expose?
Is mailcheap safe to connect to an agent?
What credentials does mailcheap need?
How does mailcheap run?
How current is this page?
Sources
- marclou/mailcheap on GitHub — the source we read, its licence, stars and activityObserved · 23 Oct 2026
- ModelsAtlas trust audit — CAUTION verdict for commit f74cb8e1d2feObserved · 23 Oct 2026
Spotted something wrong? Report a correction · Methodology
Keep going in your AI
Opens with this page as the source. We add nothing else to the prompt.
- What is the mailcheap MCP server?
- What tools does mailcheap expose?
- Is mailcheap safe to connect to an agent?