Skip to main content
Glama
gabeosx

Yahoo Mail MCP

by gabeosx
README.md
# Yahoo Mail MCP

A self-hosted MCP server for one Yahoo Mail account. Search and read messages, save drafts, send plain-text email, change read flags, and deliver signed new-mail webhooks.

Runs on **Linux, Windows, and macOS** with Node.js 22.13 or newer. No Python, Homebrew, Keychain, or Bitwarden installation is required. CI runs synthetic tests on all three operating systems with Node.js 22 and 24.

## Quick start

Install [Node.js](https://nodejs.org/en/download) and Git. Generate a Yahoo **app password** for this connector in your Yahoo account settings; use that password rather than your normal account password. See [Yahoo's app-password instructions](https://help.yahoo.com/kb/technical-support/generate-password-access-yahoo-mail-sln15241.html).

Run these commands in Terminal, a Linux shell, PowerShell, or Command Prompt:

~~~sh
git clone https://github.com/gabeosx/yahoo-mail-mcp.git
cd yahoo-mail-mcp
npm ci --ignore-scripts
npm run configure
~~~

Open the generated `.env` in a text editor and fill in:

~~~dotenv
YAHOO_EMAIL=your-address@yahoo.com
YAHOO_APP_PW=your-yahoo-app-password
~~~

The configure command creates separate random authentication and encryption keys. Keep both values, and keep `.env` private. It refuses to overwrite an existing configuration.

~~~sh
npm start
~~~

The server listens at `http://127.0.0.1:8935/mcp`. An MCP client must send `X-Yahoo-Connector-Token` with the value of `YAHOO_CONNECTOR_TOKEN`. Use a client that supports Streamable HTTP with custom headers, or connect through the optional [OpenAI tunnel](docs/tunnel.md).

To expose the draft, send, and mark-read tools, set `YAHOO_READ_ONLY=false` and restart. New installations expose three read tools and the new-mail event. Use Ctrl+C to stop.

## Tools

| Tool | Behavior | Available in read-only mode |
| --- | --- | --- |
| `yahoo_status` | Verify IMAP/SMTP authentication and list mailbox paths. | Yes |
| `yahoo_list_messages` | Search metadata by mailbox, unread status, sender, subject, body, and date. | Yes |
| `yahoo_read_message` | Read text and attachment metadata without marking the message read. | Yes |
| `yahoo_save_draft` | Save a plain-text draft in the Drafts mailbox. | No |
| `yahoo_send_email` | Send plain-text mail from the configured account. | No |
| `yahoo_mark_read` | Set or clear a message's read flag. | No |

Message operations use a UID and `uidValidity` returned by a list result, so a rebuilt mailbox cannot silently redirect an operation to another message. Reading is limited to 5 MiB messages and 30,000 text characters. Sending attachments and downloading attachments are not implemented.

Draft and send operations require a UUID `requestId`. Retrying identical content with the same ID returns the original confirmed result. An interrupted or failed write blocks reuse of that ID; inspect Yahoo before choosing a new one. This avoids blindly resending after a timeout. SMTP acceptance means Yahoo accepted the recipients, not that final delivery succeeded.

## New-mail events

`yahoo.message.created` supports mailbox, sender, and subject filters. The server polls Yahoo every 60 seconds while subscriptions exist, persists subscriptions and pending deliveries in SQLite, and signs callbacks using Standard Webhooks. See [the event contract and delivery limits](docs/events.md).

A subscription starts at the current mailbox position and lasts at most 24 hours. This is a new-mail monitor, without a protocol replay cursor. Expiration or a mailbox UID reset establishes a fresh baseline. Event availability depends on the client's event support; ordinary MCP clients can still use the mail tools.

## Configuration

| Variable | Required | Default |
| --- | --- | --- |
| `YAHOO_EMAIL` | Yes | Your Yahoo address |
| `YAHOO_APP_PW` | Yes | Your Yahoo app password |
| `YAHOO_CONNECTOR_TOKEN` | Yes | Generated by configure; 32–128 URL-safe characters |
| `YAHOO_STATE_KEY` | Yes | Generated by configure; 32 random bytes encoded as unpadded base64url |
| `YAHOO_READ_ONLY` | No | `true` |
| `YAHOO_PORT` | No | `8935`; loopback only |
| `YAHOO_POLL_INTERVAL_MS` | No | `60000`; supported range 1000–3600000 |
| `YAHOO_STATE_PATH` | No | `runtime/state.sqlite` under the repository |

Relative data paths resolve from the repository directory, independent of the process's working directory. Absolute paths are supported, including Windows drive paths on Windows. Store credentials outside source control. Existing environment variables take precedence over the local env file.

For a secret manager or background service that supplies environment variables directly, start with:

~~~sh
node /absolute/path/to/yahoo-mail-mcp/src/server.mjs
~~~

On Windows, use a path such as `C:\Apps\yahoo-mail-mcp\src\server.mjs`. See [background operation on each platform](docs/operations.md). Bitwarden, Keychain, or another secret manager can supply the same environment variables; no provider-specific identifiers are embedded in the server.

## Storage and access

This is a single-account server. Anyone holding its connector token can use the exposed tools and create event subscriptions for that account. Tool descriptions ask clients to follow user authorization, but they do not replace the client's own action permissions. Treat email subjects, senders, and bodies as untrusted input.

The listener binds only to IPv4 loopback. The custom token header is checked on every request. The server validates Host and Origin headers and limits request sizes and concurrent requests. OAuth, multi-user hosting, stdio transport, and a public hosted endpoint are outside this release's scope.

Subscription secrets, queued event payloads, and saved write results use AES-256-GCM encryption. Database identifiers, hashes, statuses, and timing metadata are not encrypted. Keep the encryption key with your backup: losing or changing it makes stored payloads unreadable. Keep the same database across restarts to retain send deduplication.

Unix configuration/database files are created with owner-only permissions. Windows uses the directory's inherited ACLs; store the checkout and data in an account-restricted location. The ignored `.env` contains credentials in plaintext. Encryption at rest does not protect against another process running as your OS user.

## Development

~~~sh
npm ci --ignore-scripts
npm run check
npm test
~~~

Tests use synthetic mail, fake webhook receivers, temporary databases, and local HTTP listeners. They do not access Yahoo or send real email. CI covers Linux, Windows, and macOS with Node.js 22 and 24. Yahoo read access was checked in the originating private deployment; live sending and end-to-end event delivery are not claimed as verified by this public test suite.

See [CONTRIBUTING.md](CONTRIBUTING.md). MIT licensed. This is an independent project, not affiliated with Yahoo or OpenAI.