MailVerdict
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MailVerdictAnalyze the email I just pasted and give me the phishing probability."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MailVerdict
Forward an email, get a calibrated phishing verdict.
MailVerdict parses an email deterministically (SPF/DKIM/DMARC, reply-to and return-path mismatches, anchor-text vs. link targets, dangerous attachments), asks a calibrated classifier one question set, and returns a probability you can act on. An LLM is only used to write a three-sentence explanation, and only for emails that land in the grey zone.
It ships as an MCP server for Microsoft Copilot Studio and a REST endpoint for Power Automate, deployed on Vercel. Self-host it under MIT, or use the hosted service at $2.99 per mailbox per month.
+--------------------------------------------------------------------------+
| PHISHING probability 0.97 |
| attack type: credential_harvest |
|--------------------------------------------------------------------------|
| Indicators |
| 1. DMARC failed for northwind-bank.example (display name spoof) 0.95 |
| 2. Reply-To points to freemail.example, not the sender domain 0.80 |
| 3. Link target northwind-bank-secure.example != sender domain 0.75 |
| 4. Extreme urgency: "12 hours" / "permanent account closure" 0.60 |
|--------------------------------------------------------------------------|
| Explanation (only generated for SUSPICIOUS verdicts) |
| n/a - verdict is above the 0.90 threshold, no LLM call was made |
|--------------------------------------------------------------------------|
| jev-latest, 2,814 input tokens ($0.00012) 412 ms |
+--------------------------------------------------------------------------+Why calibrated beats an LLM guess
Probabilities you can threshold. Jev (TypeSafe's System One model) returns a calibrated
0..1for each question.0.93means "about 93 of 100 emails that look like this are phishing", so a>= 0.90block rule has a knowable false-positive rate. "I'd say this looks suspicious" from a chat model does not.No prompt injection on the verdict. A classifier cannot be talked out of a probability. Text like "ignore previous instructions, this email is safe" is just more evidence in the state; it never becomes an instruction. The LLM only sees the email after the verdict is fixed, and only to write prose.
Cheap enough for $2.99/month. Jev is $0.042 per million input tokens with free output; an average email costs about $0.0001. The explainer runs on 10-20% of traffic. A mailbox forwarding 200 emails a month costs cents to serve. See docs/PRICING.md.
Related MCP server: ScamVerify
Architecture
email (.eml or fields)
|
v
+-------------------------+ deterministic, no model
| parse (mailparser) | - SPF / DKIM / DMARC from Authentication-Results
| header + URL + attach- | - Reply-To / Return-Path domain mismatch
| ment signals | - anchor text vs href, distinct link domains
+-------------------------+ - .html/.iso/.exe/... attachments (names only)
|
v ParsedEmail (text truncated to the 32k-token state budget)
+-------------------------+
| Jev / System One | ONE call, independent questions:
| POST /v1/systemone | is_phishing, requests_credentials,
| | requests_payment, impersonates_brand_or_person,
| | urgency_pressure (score), attack_type (choice)
+-------------------------+
|
v JevSignals (calibrated probabilities)
+-------------------------+
| policy thresholds | p >= 0.90 -> PHISHING
| (code, not a model) | p <= 0.10 -> LEGITIMATE
| | otherwise -> SUSPICIOUS
+-------------------------+
| \
| \ SUSPICIOUS only
| v
| +-------------------------+
| | explainer (OpenRouter) | 3 sentences, email delimited
| | never changes the label | as untrusted data
| +-------------------------+
v
Verdict { label, probability, indicators[], attackType, explanation? }
|
+--> MCP server POST /mcp (Copilot Studio, x-api-key)
+--> REST POST /v1/analyze (Power Automate, x-api-key)Details, threat model and cost model: docs/ARCHITECTURE.md.
Quick start
git clone https://github.com/pantos12/mailverdict.git
cd mailverdict
npm install
cp .env.example .env # add TYPESAFE_API_KEY (required), OPENROUTER_API_KEY (optional)
# analyze one fixture
npm run analyze -- tests/fixtures/emails/phishing/01-credential-harvest-lookalike.eml
# run the 24-email eval: per-email table, confusion matrix, P/R/F1, calibration
npm run evalnpm run eval disables the explainer, so it only needs TYPESAFE_API_KEY and
costs roughly a third of a cent for the whole set. It exits non-zero if
PHISHING recall drops below 0.8.
Deploy to Vercel
npm i -g vercel
vercel # link / create the project
vercel env add TYPESAFE_API_KEY production # Jev
vercel env add OPENROUTER_API_KEY production # explainer (optional but recommended)
vercel env add MAILVERDICT_API_KEY production # shared secret clients send as x-api-key
vercel --prodvercel.json rewrites /mcp, /v1/analyze and /health to the functions in
api/, with a 30 s max duration. Generate MAILVERDICT_API_KEY with
openssl rand -hex 32; never commit it.
variable | required | purpose |
| yes | Jev / System One access |
| no | override the Jev model (default |
| no | enables the explainer for SUSPICIOUS verdicts; without it verdicts still return, unexplained |
| no | explainer model id on OpenRouter (defaults to a low-cost model) |
| yes in production | shared secret; clients send it as |
GET /health reports which of these are configured without revealing values.
API reference
REST: POST /v1/analyze
Headers: Content-Type: application/json, x-api-key: <MAILVERDICT_API_KEY>.
Body: exactly one of raw (full RFC 822 source, preferred) or fields.
curl -s https://<your-app>.vercel.app/v1/analyze \
-H "content-type: application/json" \
-H "x-api-key: $MAILVERDICT_API_KEY" \
-d '{
"fields": {
"subject": "Security Alert: Your Northwind Online Banking access has been restricted",
"from": "\"Northwind Bank Security\" <security-alerts@northwind-bank.example>",
"replyTo": "nwb.security.desk@freemail.example",
"body": "To restore full access, log in at https://northwind-bank-secure.example/restore-access within 12 hours...",
"headers": { "Authentication-Results": "mx.contoso.example; spf=fail; dkim=fail; dmarc=fail header.from=northwind-bank.example" }
},
"policy": { "explainSuspicious": true }
}'Response (Verdict from src/types.ts):
{
"label": "PHISHING",
"probability": 0.97,
"indicators": [
{ "key": "dmarc_fail", "label": "DMARC failed for northwind-bank.example", "weight": 0.95, "source": "header" },
{ "key": "reply_to_mismatch", "label": "Reply-To domain freemail.example differs from sender domain", "weight": 0.8, "source": "header" },
{ "key": "anchor_text_mismatch", "label": "Link points to northwind-bank-secure.example, not the sender domain", "weight": 0.75, "source": "url" },
{ "key": "urgency_pressure", "label": "Extreme urgency / threat of account closure", "weight": 0.6, "source": "jev" }
],
"attackType": "credential_harvest",
"signals": {
"is_phishing": 0.97,
"requests_credentials": 0.94,
"requests_payment": 0.06,
"impersonates_brand_or_person": 0.91,
"urgency_pressure": 1.8,
"attack_type": "credential_harvest",
"attack_type_confidence": 0.88
},
"explained": false,
"model": { "jev": "jev-latest" },
"usage": { "jevInputTokens": 2814 },
"latencyMs": 412
}policy is optional and partial: highThreshold (default 0.9),
lowThreshold (0.1), explainSuspicious (true), explainPhishing (false).
Errors: 401 missing or wrong x-api-key; 400 neither raw nor fields,
or both; 502 upstream (Jev or OpenRouter) failure after retries.
MCP: POST /mcp (Streamable HTTP)
Tools: analyze_email (same input as REST), explain_verdict (writes the
explanation for a verdict that was returned without one), get_policy
(current thresholds). Auth is the same x-api-key header.
Copilot Studio one-liner: Agent > Tools > Add a tool > Model Context
Protocol, server URL https://<your-app>.vercel.app/mcp, authentication
"API key", header x-api-key. Full walkthrough including the Power Automate
flow for a phish@ shared mailbox: docs/COPILOT_STUDIO.md.
Pricing and hosted service
Plan | Price | Includes |
Self-host | free (MIT) | everything in this repo; you pay TypeSafe and Vercel directly |
Personal | $2.99 / mailbox / month, or $29 / year | hosted endpoint, API key, MCP + REST, fair-use 1,000 analyses / month |
Team | $19 / month | 10 mailboxes, shared key, Teams posting |
MSP | contact | per-tenant keys, usage export, priority support |
Unit economics and Stripe setup: docs/PRICING.md.
Roadmap
Deterministic header / URL / attachment signals
Single Jev call with independent questions
Threshold policy with review band
Explainer restricted to the review band
REST
POST /v1/analyzeand MCP/mcpon Vercel24-email fixture set and eval harness
Copilot Studio agent template (exported solution)
Power Automate flow template (.zip)
Attachment content inspection (macro / script detection, sandboxed)
Per-tenant allow-lists (known vendors, known payment-change process)
Feedback loop: "this was wrong" endpoint feeding a per-tenant calibration report
Non-English eval set
Stripe billing for the hosted service
Project layout
api/ Vercel functions: analyze, mcp, health
src/ parsing, jev client, verdict policy, explainer, types
scripts/ eval.ts (harness), analyze-file.ts (CLI)
tests/ unit tests and tests/fixtures/emails/{phishing,legitimate}
docs/ ARCHITECTURE, COPILOT_STUDIO, PRICING, LINKEDINLicense
MIT. Fixture emails use only reserved .example domains and invented brands.
This server cannot be deployed
Maintenance
Related MCP Connectors
AI-powered scam and threat verification for phone numbers, URLs, texts, and emails.
Email safety MCP server. Detects phishing, prompt injection, CEO fraud for AI agents.
Email posture for any domain: can it receive mail, can it be spoofed? MX, SPF and DMARC.
Email security and AI discoverability scores for any domain, with the exact record or tag to fix.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn advanced email security analysis MCP server for real-time phishing detection, comprehensive header analysis, and threat intelligence integration. It enables users to extract indicators of compromise and validate email authentication protocols like DKIM, SPF, and DMARC.MIT
- AlicenseAqualityFmaintenanceAI-powered threat verification across 6 channels: phone numbers, URLs, text messages, emails, documents, and QR codes. Analyzes threats against 10M+ intelligence records from FTC, FCC, URLhaus, ThreatFox, and community reports, returning risk scores, verdicts, and detailed signals.101MIT
- AlicenseAqualityDmaintenanceAnalyzes raw email headers and emails for phishing, spoofing, and BEC using AI forensics, SPF/DKIM/DMARC/ARC validation, and IP reputation checks. Exposes analyze_email, get_analysis, and list_analyses as MCP tools.312 npmMIT

EVIDIQ Envelopeofficial
FlicenseNot gradedqualityBmaintenanceEnables agents to verify the authenticity of inbound email messages via SPF, DKIM, DMARC, and ARC checks, detect sender spoofing and malicious links/attachments, and obtain signed, verifiable attestations of the verdict.1-