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:
co-authored by
Claude Opus 5
parent
428040d964
commit
36b15ddcaf
@@ -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
|
||||
@@ -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),
|
||||
}
|
||||
Reference in New Issue
Block a user