5.4 KiB
Email MCP Design
Goal
Build a local Linux MCP server as a single Go binary with two modes:
setup: prompt for IMAP host, username, and password, then store them in KDE Wallet if availablemcp: start an MCP server over stdio and expose read-only mail tools backed by IMAP
The V1 target is KDE Wallet only for secret storage, with internal interfaces designed so other secret stores can be added later without rewriting the IMAP or MCP layers.
Scope
Included in V1:
- Go project from scratch
- Single binary named
email-mcp - Interactive
setupcommand - Detection of KDE Wallet availability over D-Bus
- Storage and retrieval of one default IMAP account in KDE Wallet
- Read-only IMAP access
- MCP server with a minimal tool surface
Out of scope for V1:
- OAuth2
- Multiple mail accounts
- Sending mail
- Message mutation operations such as delete, move, mark read, or flag
- Non-KDE secret stores
- Integration tests against a real KDE Wallet instance
Why Go
Go is the best fit for this version because the primary deliverable is a local distributable binary rather than a fast prototype. It gives a simple deployment model, good network I/O behavior for IMAP, and a clean way to define internal interfaces for future expansion. KDE Wallet integration over D-Bus is a little lower-level than Python, but still straightforward enough for the V1 scope.
Architecture
The binary is split into two entry paths:
email-mcp setupemail-mcp mcp
Internally, the code is organized behind narrow interfaces:
SecretStore: save and load account credentialsIMAPClient: connect to IMAP and expose read-only mailbox/message operationsMCPServer: register tools and route requests to the IMAP layer
This keeps KDE Wallet isolated to one package and avoids coupling the MCP server to secret storage details.
Data Model
V1 stores a single logical account under a fixed profile key, default.
Stored credential fields:
hostusernamepassword
The credential value is stored in KDE Wallet as a serialized blob owned by the application namespace email-mcp. The application will not hash the IMAP password because the password must be recoverable in order to authenticate to the IMAP server. Security relies on KDE Wallet protecting the secret at rest.
KDE Wallet Behavior
The setup flow must:
- Check whether the KDE Wallet D-Bus service is reachable.
- Open or create an application folder for
email-mcp. - Prompt the user for
host,username, andpassword. - Save those values under the
defaultaccount key.
If KDE Wallet is not available, setup exits with a clear error and stores nothing anywhere else.
The MCP mode must:
- Open KDE Wallet over D-Bus.
- Read the
defaultaccount credential. - Fail with a clear message if no credential is present.
MCP Surface
The V1 MCP server exposes three read-only tools:
list_mailboxeslist_messagesget_message
Behavior:
list_mailboxesreturns mailbox names visible to the account.list_messagestakes a mailbox and returns a small list of messages with lightweight metadata.get_messagereturns one message with headers and body content suitable for MCP clients.
The initial protocol transport is stdio. Logging must not corrupt stdio protocol traffic, so operational logs should go to stderr or be disabled by default.
IMAP Behavior
The IMAP layer connects to the configured host using TLS on the standard secure IMAP path. The first version is read-only by design and should avoid any mutation APIs. The connection setup should return actionable errors for authentication failure, TLS failure, or network failure without leaking secrets.
The message listing behavior should be intentionally conservative in V1:
- modest result limits
- explicit mailbox selection
- stable lightweight metadata for summaries
This keeps the first protocol surface predictable and reduces unnecessary mailbox scanning.
Error Handling
Expected user-facing failures:
- KDE Wallet service unavailable
- KDE Wallet locked or inaccessible
- credentials not configured
- IMAP authentication failure
- mailbox not found
- message not found
Errors should be mapped to concise messages. The process must never print stored secrets, entered passwords, or raw serialized credential payloads.
File Layout
Planned layout:
cmd/email-mcp/main.gointernal/cliinternal/secretstoreinternal/secretstore/kwalletinternal/imapclientinternal/mcpserver
Tests will live next to their packages where idiomatic for Go.
Testing Strategy
V1 tests focus on unit boundaries:
- credential validation and serialization
- KDE Wallet store interface behavior with mocks or fakes
- IMAP service behavior against mocked client boundaries
- MCP tool handler behavior
- error mapping and missing-credential flows
V1 does not require a live KDE Wallet integration test. The D-Bus integration should be kept behind a narrow adapter to make this practical.
Security Notes
This design is acceptable for a local tool if the user already trusts KDE Wallet as the host secret manager. It is materially safer than inventing a custom local encryption scheme with a locally stored key, because the operating environment already provides secret storage controls and user-session integration.
The main limitation of V1 is that it stores a recoverable IMAP password. That is necessary for password-based IMAP auth. A future version should prefer OAuth2 for providers that support it.