Skip to main content
Glama
DINQ-labs

OpenMailConnect

Official
by DINQ-labs
README.md
# OpenMailConnect

[![Tests](https://github.com/DINQ-labs/openmailconnect/actions/workflows/tests.yml/badge.svg)](https://github.com/DINQ-labs/openmailconnect/actions/workflows/tests.yml)
[![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE)

An independent open-source MCP server for your own mailbox.

- **Gmail:** direct Google OAuth, automatic token refresh, send/reply, read/search,
  threads and drafts.
- **SMTP:** authenticated TLS (465) or STARTTLS (587), sending only.
- No DINQ account, payment system, hosted analytics or third-party OAuth broker.
- Mailbox credentials are entered in a browser, not passed to the agent.

## Install

Python 3.11+ and `uv` are required.

```bash
git clone https://github.com/DINQ-labs/openmailconnect.git
cd openmailconnect
uv sync
cp .env.example .env
uv run openmailconnect
```

The default is MCP stdio, plus a local binding server at `127.0.0.1:8787`.
Configure your MCP client with an absolute checkout path:

```json
{"mcpServers":{"openmailconnect":{"command":"uv","args":["--directory","/absolute/path/openmailconnect","run","openmailconnect"]}}}
```

Client formats differ; adapt this command to the client's configuration.
Do not start multiple instances sharing the same binding port. Use a different
`--port`, data directory and origin for separate owner instances.

## Gmail setup (your Google OAuth application)

Create a Google Cloud OAuth **Web application** client, enable the Gmail API,
and register the exact redirect URI:

```
http://127.0.0.1:8787/oauth/callback
```

Set `GMAIL_CLIENT_ID` and `GMAIL_CLIENT_SECRET` in your local `.env` file. For a
Google OAuth app in testing mode, add your Google account as a test user. Public
Google apps may require verification for Gmail scopes; the project does not
bypass Google's consent or verification requirements.

Ask the agent to call `mail_connect(provider="gmail")`, open the returned link,
authorize your account, then call `mail_accounts`. The Google client secret and
mailbox tokens do not belong in chat. Tokens refresh automatically while the
refresh grant remains valid.

## SMTP setup

Call `mail_connect(provider="smtp")`. Open the returned link and enter your email,
SMTP hostname, port and app-specific password/authorization code. The server
verifies TLS and authentication without sending a test message. Private-network
SMTP addresses and ports other than 465/587 are rejected by default.

SMTP does not provide mailbox reading, search or draft APIs. Use Gmail for those.

## Tools

| Tool | Purpose |
|---|---|
| mail_accounts | List connected mailboxes, without credentials |
| mail_connect | Browser link to connect Gmail or SMTP |
| mail_send | Send or reply, with To/Cc/Bcc, plain text and optional HTML |
| mail_search | Gmail query, paging and message IDs |
| mail_read | Gmail message and MIME parts |
| mail_thread | Gmail conversation |
| mail_create_draft | Create a Gmail draft without sending |
| mail_drafts | List Gmail drafts |

For replies, supply the original Gmail message ID as `reply_to` and explicitly
provide recipients, subject and body. Sending requires the user's authorization.

Use a stable `request_id` for each logical send and reuse it for retries. A request
ID with different content is rejected. States are `submitted`, `partial`, `failed`,
`pending`, and `unknown`. Submitted means the provider accepted the message, not
that it was delivered or opened. Do not re-send an uncertain request under a new
ID; check the mailbox. This prevents automatic duplicate sends but cannot provide
exactly-once delivery across an external mail server and local storage.

## HTTP / Docker

```bash
# Set OPENMAILCONNECT_TOKEN to a long random secret in .env first.
uv run openmailconnect --transport http --host 0.0.0.0
# or
 docker compose up --build -d
```

MCP endpoint: `/mcp`; clients send `Authorization: Bearer <token>`.
Set `OPENMAILCONNECT_ORIGIN` to the HTTPS public origin behind your reverse proxy,
and register `<origin>/oauth/callback` in Google Cloud. Browser binding links are
single-use and expire after ten minutes. The service is single-owner: clients of
one instance share its mailboxes. It is not a hosted multi-user account system.

The SQLite database and encrypted mailbox credentials live under
`OPENMAILCONNECT_DATA_DIR` (default `~/.local/share/openmailconnect`). Keep the
`credentials.key` file with backups; losing it makes stored tokens unreadable.
Protect both files with filesystem permissions. Deleting an account's Google
grant in Google security settings revokes access; SMTP app passwords can be
revoked at the provider. No email body is stored in the send receipt database.

## Develop

```bash
uv run pytest -q
uv build
```

Tests use synthetic mail providers and do not send real email. The provider code
is informed by DINQ Connector's direct Gmail/SMTP implementations. The tool design
references https://github.com/zavora-ai/mcp-email; no source was copied from it.
License: Apache-2.0.

## Contributing and support

Maintained by DINQ Labs as a standalone project. See [CONTRIBUTING.md](CONTRIBUTING.md)
for local checks and pull requests, and [SECURITY.md](SECURITY.md) for the security
model. Report reproducible bugs through [GitHub Issues](https://github.com/DINQ-labs/openmailconnect/issues).
This initial release is intended for self-hosted, single-owner use.

TDQS

A3.8/5.0

Scored across 8 tools

Disambiguation5/5

Each tool targets a distinct resource/action: connection, accounts, sending, draft creation/listing, search, read, and thread retrieval. There is no meaningful overlap between tools, and the descriptions make the boundaries clear.

Naming Consistency5/5

All tools share the mail_ prefix and use consistent snake_case. Action tools use verbs like create_draft, send, search, and read, while resource-listing tools use plural nouns like drafts and accounts, creating a predictable pattern.

Tool Count5/5

With 8 tools, the server is well-scoped for an email integration use case. Each tool earns its place and there is no redundancy or excessive granularity.

Completeness4/5

Core workflows are covered: connect, list accounts, send, read, search, thread, and draft creation/listing. Minor gaps exist around draft lifecycle management, such as updating, deleting, or explicitly sending a draft, but these are not fatal to the primary use case.

Maintenance

ActivityMaintained
ResponsivenessNo issues