wangamail-rs
Send email on behalf of a Microsoft tenant using Microsoft Graph API and app registration credentials (OAuth2 client credentials flow). Suitable for daemon apps and backend services. Part of the WangaMail family: wangamail-rs (Rust), wangamail-js (JavaScript), wangamail-py (Python), wangamail-net (.NET).
Documentation
- API docs: docs.rs/wangamail-rs (after publishing)
- Build locally:
cargo doc --openin this crate
Requirements
- Rust 2021 edition
- An async runtime (e.g.
tokiowithfullorrt-multi-thread+macros) in your binary when calling the async API
Azure setup
- In Azure Portal, go to Microsoft Entra ID → App registrations → New registration.
- Create a client secret under Certificates & secrets.
- Under API permissions, add Microsoft Graph → Application permissions → Mail.Send, then Grant admin consent.
- To send as a specific user, use that user’s Object (ID) or User principal name (e.g.
user@yourtenant.onmicrosoft.com) asfrom_user. The app will send mail from that user’s mailbox (Exchange Online).
Usage
Add to Cargo.toml:
[]
= "0.1"
= { = "1", = ["full"] }
Example:
use ;
async
Sovereign clouds
Override the token and Graph endpoints when using national clouds:
let client = builder
.tenant_id
.client_id
.client_secret
.token_url
.graph_base
.build?;
MCP (Model Context Protocol)
With the mcp feature, the crate exposes an MCP server so AI assistants (Cursor, Claude Desktop, etc.) can send email via the send_email tool.
Enable the feature
[]
= { = "0.1", = ["mcp"] }
Run the MCP server (stdio)
Set AZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_CLIENT_SECRET, then:
The process speaks JSON-RPC over stdin/stdout. Configure your AI client to run this command as an MCP server (e.g. in Cursor MCP settings or Claude Desktop claude_desktop_config.json).
Tool: send_email
- from_user – User id or userPrincipalName to send as (e.g.
user@tenant.onmicrosoft.com). - to – List of recipient email addresses.
- subject – Subject line.
- body – Plain text or HTML body.
- body_type –
"text"or"html"(default"text"). - cc, bcc – Optional lists of addresses.
Use from code
use WangaMailMcpServer;
// From env (AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET)
let server = from_env?;
// Or with an existing client
let server = new;
// Run over stdio (for subprocess use)
server.run_stdio.await?;
CI/CD
- Pull requests: Format (
cargo fmt --check), lint (clippy), check, test. - Push to
main: Bump patch version, build, publish to crates.io, create a GitHub release.
To enable publish to crates.io, add a repository secret:
CARGO_REGISTRY_TOKEN– crates.io API token with publish scope (crates.io/settings/tokens).
License
MIT OR Apache-2.0