Skip to content

MarcelRoozekrans/MailPeek

Repository files navigation

MailPeek

GitHub Sponsors

A NuGet package that provides an in-memory fake SMTP server with a real-time web dashboard for ASP.NET Core applications. Think Hangfire, but for emails.

Perfect for local development and testing — capture emails your app sends without configuring a real mail server.

Dashboard Desktop

Features

  • Fake SMTP server — Receives emails on a configurable port, no external mail server needed
  • Real-time dashboard — Messages appear instantly via SignalR
  • Full MIME support — HTML/text bodies, attachments, CC/BCC, headers (powered by MimeKit)
  • Read/unread tracking — Unread indicator dot, auto-marks as read on open
  • Message tagging — Add/remove tags per message, filter inbox by tag
  • Link checking — Automatic validation of URLs in message bodies
  • Bulk operations — Select multiple messages with checkboxes, bulk delete via floating action bar
  • Sortable columns — Click column headers to sort by From, Subject, or Date
  • Browser notifications — Desktop notifications for new messages (with permission prompt)
  • Webhook support — POST to a configurable URL when new messages arrive
  • Message preview snippets — See the first few lines of each message in the inbox
  • Keyboard shortcuts — j/k navigate, Enter open, Delete remove, Esc back, ? help
  • HTML compatibility scoring — Check email HTML against common client rendering rules
  • Spam score analysis — Built-in heuristic scorer with optional SpamAssassin integration
  • Responsive UI — Works on desktop, tablet, and mobile
  • Dark/light theme — Respects your OS prefers-color-scheme setting
  • Hangfire-style DX — Two lines of code to set up
  • Extensible auth — Plug in your own authorization filter (OAuth, Azure AD, cookie auth, etc.)
  • Testable — Inject IMessageStore in your tests to assert emails were sent
  • Zero frontend toolchain — All assets embedded in the DLL

Quick Start

1. Install the package

dotnet add package MailPeek

2. Register services

using MailPeek.Extensions;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddMailPeek(options =>
{
    options.Port = 2525;           // SMTP port to listen on
    options.MaxMessages = 1000;    // Max stored messages (FIFO eviction)
});

var app = builder.Build();

app.UseMailPeek(options =>
{
    options.PathPrefix = "/mailpeek";  // Dashboard URL (configurable)
    options.Title = "MailPeek";        // Custom page title
});

app.Run();

3. Point your app's SMTP settings to localhost:2525

{
  "Smtp": {
    "Host": "localhost",
    "Port": 2525
  }
}

4. Open the dashboard

Navigate to http://localhost:5000/mailpeek to see received emails in real-time.

Configuration

MailPeekSmtpOptions

Property Default Description
Port 2525 SMTP listen port
Hostname "localhost" SMTP server hostname
MaxMessages 1000 Max messages in memory (oldest evicted first)
MaxMessageSize 10000000 Max message size in bytes (10 MB)

MailPeekDashboardOptions

Property Default Description
PathPrefix "/mailpeek" Dashboard URL prefix
Authorization [] Array of IMailPeekAuthorizationFilter
Title "MailPeek" Page title

Authorization

The dashboard supports extensible authorization via IMailPeekAuthorizationFilter:

using MailPeek.Authorization;

public class MyAuthFilter : IMailPeekAuthorizationFilter
{
    public bool Authorize(MailPeekAuthContext context)
    {
        // Check claims, roles, policies — whatever your auth stack provides
        return context.HttpContext.User.Identity?.IsAuthenticated == true;
    }
}

// Register it
app.UseMailPeek(options =>
{
    options.Authorization = [new MyAuthFilter()];
});

Works naturally with OAuth, Azure AD, cookie auth, or any ASP.NET Core authentication middleware.

Testing

Inject IMessageStore in your tests to assert that emails were sent:

using MailPeek.Storage;

var store = serviceProvider.GetRequiredService<IMessageStore>();

// Send an email through your app's email service...

var messages = store.GetAll();
Assert.Single(messages);
Assert.Equal("user@example.com", messages[0].To.First());
Assert.Equal("Welcome!", messages[0].Subject);

Aspire Integration

MailPeek integrates with .NET Aspire for service discovery.

AppHost

Install the hosting package in your AppHost project:

dotnet add package MailPeek.Hosting.Aspire
var mailpeek = builder.AddMailPeek("mailpeek", smtpPort: 2525);

builder.AddProject<Projects.WebApp>("webapp")
    .WithReference(mailpeek);

Consuming Service

In the web project that hosts the MailPeek dashboard:

builder.Services.AddMailPeek("mailpeek"); // reads SMTP config from Aspire
app.UseMailPeek();

Other services can read the SMTP connection string directly:

var smtp = builder.Configuration.GetConnectionString("mailpeek");
// -> "smtp://localhost:2525"

Dashboard Pages

Page Description
/mailpeek Inbox — searchable message list with real-time updates
/mailpeek (detail) Message detail — HTML preview, plain text, headers, attachment downloads

REST API

The dashboard exposes a REST API under {prefix}/api/:

Method Path Description
GET /mailpeek/api/messages List messages (paged: ?page=0&size=25&search=&tag=&sortBy=date&sortDesc=true)
GET /mailpeek/api/messages/{id} Message detail
GET /mailpeek/api/messages/{id}/html HTML body (for iframe)
GET /mailpeek/api/messages/{id}/attachments/{index} Download attachment
GET /mailpeek/api/messages/{id}/links Link check results (202 while checking, 200 when complete)
GET /mailpeek/api/messages/{id}/compatibility HTML compatibility score and issues
GET /mailpeek/api/messages/{id}/spam Spam score analysis
PUT /mailpeek/api/messages/{id}/read Mark message as read
PUT /mailpeek/api/messages/{id}/tags Set message tags (JSON array body)
DELETE /mailpeek/api/messages/{id} Delete message
DELETE /mailpeek/api/messages/bulk Bulk delete (JSON body: {"ids": [...]})
DELETE /mailpeek/api/messages Clear all messages

Tech Stack

  • SmtpServer — SMTP protocol handling
  • MimeKit — MIME message parsing
  • ASP.NET Core SignalR — Real-time dashboard updates
  • Embedded HTML/JS/CSS — No frontend build toolchain required

Requirements

  • .NET 8.0 or .NET 9.0

License

MIT

About

In-memory fake SMTP server with a real-time web dashboard for ASP.NET Core. Capture emails during development and testing.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors