Yahoo Mail ChatGPT MCP
by karthiknl0
README.md
# Yahoo Mail ChatGPT MCP
A security-first, **read-only** Yahoo Mail MCP server designed for use with ChatGPT and other MCP hosts.
> **Status:** v0.1 foundation. Do not add real Yahoo credentials until CI is green and the deployment has been reviewed.
## Architecture
```text
ChatGPT / MCP host
|
| HTTPS + bearer authentication
v
Remote MCP endpoint: /mcp
|
| read-only tool calls
v
Yahoo Mail reader
|
| IMAPS / TLS 1.2+ / port 993
v
imap.mail.yahoo.com
```
The server uses the current Model Context Protocol TypeScript SDK v2 and Streamable HTTP. The MCP endpoint is `/mcp`.
## Security goals
This project treats mailbox data as high-risk. Yahoo mail may contain OTPs, password-reset links, banking alerts, account identifiers and other authentication material.
The design therefore follows four rules:
1. **Read only.** V1 contains no send, delete, move, archive, flag or mark-read tools.
2. **Fail closed.** The server refuses to start if Yahoo credentials or MCP authentication are missing or invalid.
3. **Minimize output.** Tools return bounded summaries; full raw RFC822 messages are never exposed through MCP.
4. **Sanitize before output.** OTPs, verification codes, sensitive login/reset URLs and long card/account-like numbers are redacted before data is returned to the MCP host.
Email body text is treated as **untrusted data, never instructions**. Every mail-returning tool includes a security notice reminding the caller of this boundary.
## Threat model
The main threats considered are:
- compromise of the remote MCP endpoint;
- accidental public deployment without authentication;
- credential leakage through Git, logs, health checks or error responses;
- prompt injection embedded in email content;
- OTP / reset-link exposure to the model;
- excessive email-body disclosure;
- DNS rebinding / hostile Origin or Host headers;
- brute-force access to the MCP endpoint;
- weak or invalid TLS to Yahoo;
- unsafe mailbox modifications.
Current mitigations include bearer authentication, constant-time token comparison, Host/Origin validation provided by the MCP Express integration, rate limiting, request-size checks, security headers, bounded tool inputs, TLS verification, read-only IMAP mailbox opens, deterministic sanitization and secret-free error responses.
## What ChatGPT can access
V1 exposes only these MCP tools:
### `get_morning_brief_emails`
Returns a small set of recent, sanitized emails prioritized for a morning brief.
Inputs:
- `hours`: 1–168, default 24
- `limit`: bounded by `MAX_EMAILS_PER_REQUEST`
- `unreadOnly`: optional
Output includes safe metadata such as UID, folder, sender, subject, timestamp, unread state, attachment presence, sanitized preview, category and importance score.
### `get_all_accounts_morning_brief`
Returns one bounded, sanitized result containing every configured Yahoo account. Each account is labeled with its email address and reports `ok` or `failed` independently. Scheduled morning and evening briefs should use this tool instead of making separate per-account calls, so a connector can discover one stable all-account action and preserve partial results when an account is unavailable.
Inputs:
- `hours`: 1–168, default 24
- `limit`: bounded by `MAX_EMAILS_PER_REQUEST`, applied per account
- `unreadOnly`: optional
### `list_emails`
Lists sanitized mail summaries from a selected folder.
### `search_emails`
Performs a read-only Yahoo IMAP text search and returns sanitized summaries.
### `read_email`
Reads one email by UID. The text is sanitized and truncated before MCP output.
### `list_folders`
Lists mailbox folder names.
## What ChatGPT cannot access in V1
There are deliberately **no** MCP tools for:
- sending mail;
- deleting mail;
- archiving mail;
- moving mail;
- marking messages read/unread;
- flagging/unflagging;
- changing Yahoo account settings;
- retrieving the Yahoo app password;
- retrieving environment variables;
- retrieving raw unsanitized RFC822 messages.
## Sensitive-content redaction
The sanitizer attempts to redact:
- 4–8 digit OTP / verification / login / security codes when authentication context is present;
- codes separated with spaces, dashes or punctuation;
- password-reset and account-recovery URLs;
- login / magic-link / authentication URLs and token-bearing URLs;
- long card/account-like digit sequences;
- bearer/JWT-like token strings;
- active HTML tags, scripts and styles.
Example:
```text
Your verification code is 492811
```
becomes:
```text
Your verification code is [REDACTED]
```
Redaction reduces risk but is not a mathematical guarantee. The stronger protection is data minimization: use `get_morning_brief_emails` for normal workflows and reserve `read_email` for explicit requests.
## Yahoo authentication
Use a Yahoo **app-specific password**, not your normal Yahoo account password.
Never paste the password into ChatGPT and never commit it to GitHub.
Copy the environment template:
```bash
cp .env.example .env
```
Then provide values locally or, preferably, through your hosting provider's secret manager:
```env
YAHOO_EMAIL=you@example.com
YAHOO_APP_PASSWORD=your-yahoo-app-specific-password
MCP_API_TOKEN=a-long-random-token-at-least-32-characters
```
Generate `MCP_API_TOKEN` using a cryptographically secure password/token generator. Do not reuse another password.
## Local development
Requirements: Node.js 20+.
```bash
npm install
cp .env.example .env
npm run dev
```
The default bind is `127.0.0.1:3000`.
Health check:
```bash
curl http://127.0.0.1:3000/health
```
Expected response:
```json
{"status":"ok"}
```
The health endpoint intentionally contains no email address, Yahoo state, token details, IMAP diagnostics or environment information.
## Testing
```bash
npm run lint
npm run typecheck
npm test
npm run build
```
Tests do not require real Yahoo credentials. CI performs these checks for pushes and pull requests.
## Docker
Build:
```bash
docker build -t yahoo-mail-chatgpt-mcp .
```
Run with secrets supplied at runtime:
```bash
docker run --rm \
-p 127.0.0.1:3000:3000 \
--env-file .env \
yahoo-mail-chatgpt-mcp
```
For a public container deployment set:
```env
HOST=0.0.0.0
ALLOWED_HOSTS=mcp.example.com
```
Terminate TLS at a trusted reverse proxy or managed hosting platform and expose **HTTPS only**.
## Managed deployment
The service can run on Render, Railway, Fly.io or a conventional VPS/container host. It does not depend on any specific existing server.
Production checklist:
- deploy from a reviewed commit;
- configure `YAHOO_EMAIL`, `YAHOO_APP_PASSWORD` and `MCP_API_TOKEN` using the platform's secret storage;
- set `HOST=0.0.0.0` only when required by the platform;
- set `ALLOWED_HOSTS` to the exact public MCP hostname;
- keep HTTPS enabled at all times;
- do not enable request/body logging at the proxy;
- rotate the MCP token and Yahoo app password after any suspected compromise;
- keep V1 read-only.
## Connecting to ChatGPT
ChatGPT custom apps connect to **remote** MCP servers. In ChatGPT developer mode, create a custom app and provide the deployed HTTPS MCP endpoint, for example:
```text
https://mcp.example.com/mcp
```
The exact authentication options offered by ChatGPT can evolve. This repository currently implements a static bearer-token gate suitable for private deployments and MCP clients that can send an `Authorization: Bearer ...` header.
If your ChatGPT custom-app setup requires OAuth rather than a static bearer credential, **do not disable authentication**. Add or place a standards-compliant OAuth/OIDC layer in front of `/mcp` instead. OpenAI recommends refresh-token support when OAuth is used so connectivity can be maintained after access-token expiry.
The server must never be changed to accept unauthenticated `/mcp` traffic merely to make a client connect.
## Credential rotation
### Rotate the MCP bearer token
1. Generate a new random token.
2. Update the hosting secret.
3. Restart/redeploy the service.
4. Update the authorized MCP client/app.
5. Invalidate the old token by ensuring it is no longer present anywhere in deployment configuration.
### Rotate Yahoo access
1. Revoke the Yahoo app-specific password in Yahoo account security.
2. Create a new app-specific password.
3. Replace the hosting secret.
4. Restart/redeploy.
Your normal Yahoo password should not need to change solely because an app-specific password was revoked.
## Incident response
If the server, deployment account or Yahoo app password may have been compromised:
1. Disable or scale down the MCP service immediately.
2. Revoke the Yahoo app-specific password.
3. Rotate `MCP_API_TOKEN`.
4. Review hosting access/audit logs without copying message bodies into tickets or chat.
5. Review Git history for accidentally committed secrets.
6. Re-deploy from a known-good reviewed commit.
7. Reconnect the MCP client only after authentication and sanitization have been revalidated.
## Logging policy
Application logs intentionally contain operational events only. Do not add logging of:
- email bodies or previews;
- subjects or sender addresses;
- Yahoo credentials;
- bearer tokens;
- Authorization headers;
- MCP request bodies;
- parsed environment variables.
## Project layout
```text
src/
config.ts fail-closed environment validation
index.ts HTTPS-facing MCP application entry point
mcp.ts read-only MCP tool definitions
yahoo.ts Yahoo IMAP reader
security/
auth.ts bearer authentication
redact.ts deterministic secret/content sanitization
tests/
redact.test.ts
config-auth.test.ts
.github/workflows/ci.yml
Dockerfile
.env.example
```
## Security note
This repository is public, so assume every committed byte is permanently visible. **Never commit `.env`, credentials, tokens, real email samples, OTPs or Yahoo app passwords.**
See `SECURITY.md` for the security policy.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues