Coming soon
Developer library · .NET · C# and VB.NET
Bastion Mail Server Sdk
A mail server that lives inside your application.
Embeddable IMAP, POP3 and SMTP servers that run in your process, store mail wherever you already keep data, and answer to your code. No service to install, no configuration files, no second product to license.
3
embeddable servers — IMAP, POP3 and SMTP — one assembly each
1,159
automated tests on .NET Framework 4.8, .NET 8 and .NET 10, every run
3,425
messages a second, held for ten minutes
0
messages lost or duplicated across 22,456,142 delivered in one test campaign
Fifteen lines, and you are serving mail
Add a reference to the library and to Bouncy Castle. Then, in whichever language your team writes:
VB.NET
' Who may sign in.
Dim users = New InMemoryUserAuthenticator()
users.AddUser("alice@example.com", "correct horse battery staple")
' A certificate. This one is made once and reused.
Dim certificate = CertificateFactory.LoadOrCreateSelfSigned("server.pfx", "a password", "mail.example.com")
Dim options = New ImapServerOptions() With {
.ServerName = "mail.example.com",
.Certificate = certificate,
.Authenticator = users,
.MailStore = New DirectoryImapMailStore("C:\Mail")}
options.Endpoints.Add(New ServerEndpoint(IPAddress.Any, 143, ServerEndpointSecurity.StartTls))
options.Endpoints.Add(New ServerEndpoint(IPAddress.Any, 993, ServerEndpointSecurity.ImplicitTls))
Dim server = New ImapServer(options)
server.Start()
C#
// Who may sign in.
var users = new InMemoryUserAuthenticator();
users.AddUser("alice@example.com", "correct horse battery staple");
// A certificate. This one is made once and reused.
var certificate = CertificateFactory.LoadOrCreateSelfSigned("server.pfx", "a password", "mail.example.com");
var options = new ImapServerOptions {
ServerName = "mail.example.com",
Certificate = certificate,
Authenticator = users,
MailStore = new DirectoryImapMailStore(@"C:\Mail")
};
options.Endpoints.Add(new ServerEndpoint(IPAddress.Any, 143, ServerEndpointSecurity.StartTls));
options.Endpoints.Add(new ServerEndpoint(IPAddress.Any, 993, ServerEndpointSecurity.ImplicitTls));
var server = new ImapServer(options);
server.Start();
Any mail client in the world can now sign in. server.Stop() lets sessions finish; server.Dispose() does not wait.
Three servers. No broker between them.
Use one, two or all three — in one process or in three. They share no state, and a message the SMTP server delivers appears in the IMAP inbox and the POP3 maildrop within a second.
Bastion.ImapServer · 143, 993
IMAP4rev1 and IMAP4rev2 with the extensions real clients ask for: IDLE, CONDSTORE, QRESYNC, MOVE, SORT, THREAD, QUOTA, ACL, METADATA, OBJECTID, SAVEDATE, PREVIEW, PARTIAL and COMPRESS.
Bastion.Pop3Server · 110, 995
RFC 1939 in full: all three states, the maildrop lock, CAPA, STLS, SASL, APOP, UTF8, LANG, PIPELINING, EXPIRE and LOGIN-DELAY.
Bastion.SmtpServer · 25, 587, 465
ESMTP and submission with per-port rules, delivery status notifications, and onward delivery through a smart host or straight to the recipient’s MX hosts, with a retry queue and bounces.
Current to the standards most servers have not reached
Fifteen IMAP extensions most mail servers do not have — OBJECTID, SAVEDATE, REPLACE, PREVIEW, PARTIAL, UIDONLY, UIDBATCHES, INPROGRESS, UNAUTHENTICATE, JMAPACCESS and more. Every RFC is named on the standards page; nothing hides behind “and more”.
| Area | RFCs implemented |
|---|---|
| IMAP | 3501, 9051, 2177, 7162, 8474, 8514, 9394, 8970, 8508, 5464, 9590, 4978, 9586, 10022, 9585, 9738, 8437, 8440, 9698, 9208, 4314, 5256, 6855, 9755, 8457 — plus 20 more |
| SMTP and submission | 5321, 6409, 3461/3463/3464 (DSN), 3030 (CHUNKING), 6531 (SMTPUTF8), 8689 (REQUIRETLS), 9422 (LIMITS), 7505 (Null MX), 7672, 1870, 2034, 2920, 3207, 4954, 6152 |
| POP3 | 1939, 2449, 3206, 2595, 5034, 6856 |
| Sign-in | SASL (4422), SCRAM-SHA-256 and SCRAM-SHA-1 (7677, 5802), CRAM-MD5 and PLAIN over TLS only, OAUTHBEARER (7628) and XOAUTH2, SASLprep (4013) |
| TLS posture | Implicit TLS (8314); TLS 1.2 floor, 1.3 preferred (8996, 8997, 9325); 1.0 and 1.1 never offered; SAN-only identity checks when relaying (9525, 7817) |
Your code decides
The libraries write nothing to a log and make no policy of their own. Everything is an event, so the log stays your log and the decisions stay your decisions. A gate that throws refuses temporarily and reports the fault — it never lets a message through by accident.
ConnectionRequested · gate | The remote address, before a byte is read or TLS begins. Refuse a flood for almost nothing. |
SessionStarted | Who connected, on which endpoint, over which TLS version. |
AuthenticationCompleted | Every sign-in attempt, the mechanism used, and whether it worked. |
CommandReceived / ResponseSent | The whole conversation, line by line, with passwords and tokens already replaced by ****. |
ClientIdentified · gate | SMTP: the name the client gave itself. Refuse it and nothing follows. |
MessageStarting · gate | SMTP: sender and recipients, before a single body byte crosses the wire. |
HeadersReceived · gate | SMTP: add, change or remove header fields — or refuse the message now. Your virus, spam, SPF, DKIM and DMARC checks go here. |
MessageDelivered | Accepted and handed to your handler. |
RelayAttempted … RelayFailed | Onward delivery step by step: looking up mail exchangers, connecting, sending. |
SessionError | A fault, with its stack. A normal disconnect is not one. |
Mail lives where your data already lives
In memory or on disk as ordinary .eml files out of the box — or implement one interface and keep mail in SQL Server, PostgreSQL, blob storage, a document system or an ERP.
And so do your users
An in-memory authenticator gets you started. One interface connects the servers to Active Directory, your own user table, or an OAuth token service.
Secure because of the defaults
Clear-text sign-in refused until TLS is up. Connection limits, idle timeouts, failed sign-in limits and delays, size and recipient caps — per port, not just per server.
Proof, not promises
The test programme ships with the product. It drives the servers with MailKit — an independent client — so a matching bug on both sides cannot hide.
46 deliberate faults survived
Torn connections, half-written files and killed processes, injected on purpose by a chaos suite you can run yourself.
700 sessions at once
All three servers in one process. Fifty back-to-back rounds of the whole programme — 58,150 test runs — with threads flat at about 130 and not one message unaccounted for.
Thirty-six sample servers
One per protocol, per language, per runtime, in solutions for Visual Studio 2019, 2022 and 2026. Plus a test host, a load harness and the chaos suite.
It fits where your application already runs
| Frameworks | .NET Framework 4.6.2, 4.7.2 and 4.8 · .NET 6, 8 and 10 — one source, so moving runtimes changes no mail code |
| Languages | C# and VB.NET, with every sample line for line in both |
| Dependencies | One: BouncyCastle.Cryptography. No native code, no service, no registry, no COM |
| Documentation | A CHM reference built from the assemblies, seven cookbook chapters, a standards page naming every RFC, and full, readable source |
How it compares
There is no other commercial embeddable mail server SDK for .NET that we could find. The realistic alternatives are open-source libraries, compared here from their published source and documentation in September 2026. A ? means the capability was not stated either way.
For comparison, a standalone Windows mail server such as SmarterMail is licensed per installation. With the Mail Server Sdk, every copy of your product can carry its own mail server with no further licence fee.
OEM licensing
One licence type, priced for commercial software teams. Every Bastion Mail Server Sdk licence is an OEM licence: build it into your product and ship that product to as many customers as you like, on as many machines as they like.
- Royalty-free redistribution inside your own applications
- Desktop, server, cloud and SaaS deployment — no per-server or per-instance fees
- Perpetual licence with 12 months of updates; renewals at 35% of list
- Every build, .NET Framework to .NET 10, and every sample in C# and VB.NET
- Everything in Developer OEM
- $649 per developer
- Everything in Developer OEM
- No developer count to track as the team grows
- Source-code escrow available, priced on request
Launch prices in US dollars. Final pricing is confirmed at release.
Try it properly first
A thirty-day evaluation of the complete component. Nothing removed and no limits — you evaluate exactly what you would buy.
Because the trial is the whole product, sales are final, and accepting the terms and conditions of sale is part of completing a purchase. The one exception: report a serious defect and, if we cannot fix it and release an update within thirty days, we refund you in full.
Need more than the component? Custom development and integration work built on it is available, remotely or on site — talk to us.
Get notified when Bastion Mail Server Sdk is released
Tell us what you are building. We will let you know the moment the evaluation is available — and answer plainly whether it fits.