Rewrite as a Rust, Apache-2.0 workspace

Supersedes the Go + embed-Mox design. The Go tree is removed; its
architecture doc is preserved at docs/archive/ARCHITECTURE-go-embed-mox.md
because its competitive analysis and data model still hold.

Five decisions recorded as ADRs:

  0001  Rust, not Go — accepting ~5,500 lines of protocol code that Mox
        would have given us free, to get the first permissively licensed
        Rust mail server. Costs stated plainly.
  0002  Apache-2.0, not MIT or AGPL — patent grant, trademark, CLA-free
        contribution. Public on GitHub; Gitea stays as the private fallback.
  0003  Stalwart's primitive crates (Apache-2.0/MIT) yes; its AGPL server
        crates never. DANE and MTA-STS sit on the AGPL side of that line,
        which is why we write our own.
  0004  Milestones, reordered: embedded inbound is required at launch.
  0005  Oracle Cloud blocks outbound :25, so direct-to-MX is impossible on
        the launch host. Split delivery is mandatory, not an on-ramp.

Twelve crates in three tiers. Tier 1 (mail-dane, mail-mta-sts, mail-dsn)
is standalone and publishable — no `dane` or `mta-sts` crate exists on
crates.io at all today.

openmail-relay ships the provider table as data, with SES and Oracle from
the start. Oracle's and Resend's SPF includes are deliberately None: a
guessed include turns the DNS check green against a mechanism the provider
does not honour, and mail still fails SPF silently.

cargo check/test/clippy/fmt all green; unsafe_code is forbidden workspace
wide; cargo-deny enforces the licence policy in CI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JkyvfNJGTshJNE9FtwPLk7
This commit is contained in:
Karti Tripathi
2026-09-02 13:08:05 -07:00
co-authored by Claude Opus 5
parent 428040d964
commit 36b15ddcaf
59 changed files with 5540 additions and 1762 deletions
+21
View File
@@ -0,0 +1,21 @@
[package]
name = "openmail-mcp"
description = "MCP server: an agent owns and operates its own mailbox as tools."
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
authors.workspace = true
[lints]
workspace = true
[dependencies]
openmail-core.workspace = true
openmail-store.workspace = true
serde.workspace = true
serde_json.workspace = true
tokio.workspace = true
thiserror.workspace = true
+30
View File
@@ -0,0 +1,30 @@
//! MCP server — the thing nobody else has.
//!
//! A thin front-end over [`openmail_core`] that lets an agent own and operate
//! its own mailbox as tools: `create_inbox`, `list_messages`, `get_thread`,
//! `send_message`, `reply`, `search`.
//!
//! # The rule that keeps this safe
//!
//! Only routes that explicitly opt in become tools, every call re-checks the
//! caller's scopes, and credential or key-management routes can **never** be
//! exposed as tools regardless of opt-in. An agent may read and send its own
//! mail; it may not mint itself a wider key.
/// Marker for a route's MCP exposure. Absence of an opt-in is a refusal, not a
/// default — a new route is invisible to agents until someone says otherwise.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Exposure {
Tool,
Hidden,
/// Credential-bearing. Never exposable; the type makes it unrepresentable.
NeverExposable,
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("tool not found: {0}")]
UnknownTool(String),
#[error("scope denied: {0}")]
ScopeDenied(String),
}