yahoo-mail-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@yahoo-mail-mcp-serverlist my unread emails"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Yahoo Mail MCP Server
A Model Context Protocol (MCP) server that provides full email management for Yahoo Mail via IMAP. This server supports both local stdio transport (for Claude Desktop) and HTTP/SSE transport (for remote access via Claude.ai).
Features
Secure OAuth 2.0 Authentication: Protect your remote MCP server with OAuth 2.0 authorization code flow with PKCE
UID-Based Operations: Uses permanent IMAP UIDs that don't change when emails are deleted (v3.0.0+)
Full Email Management: Complete email operations with batch processing support
Eleven Powerful Tools:
list_emails: List recent emails with enriched metadata (size, flags, attachments) and paginationread_email: Read the full content of emails (batch support)search_emails: Advanced search with filters (date ranges, sender, unread status)list_folders: Discover all available IMAP foldersdelete_emails: Move emails to Trash (soft delete, recoverable)archive_emails: Archive emails for long-term storagemark_as_read: Mark emails as readmark_as_unread: Mark emails as unreadflag_emails: Flag emails as important/starredunflag_emails: Remove flag from emailsmove_emails: Move emails to any folder
Enriched Metadata: All emails include UID, size, flags, hasAttachments, and folder information
Advanced Search: Filter by date range, sender, unread status, and search across any folder
Batch Operations: All management operations support processing multiple emails at once with accurate success/failure tracking
Dual Transport Modes:
stdio: For local Claude Desktop integrationsse: For remote access via HTTP/Server-Sent Events (required for Render.com)
Cross-Platform: Works on both Windows and Linux development environments
Docker Support: Containerized deployment with Docker and Docker Compose
Cloud Ready: Configured for easy deployment to Render.com with OAuth security
Related MCP server: Yahoo Mail MCP Server
Prerequisites
For Local Development
Node.js: Version 18.0.0 or higher
Yahoo Mail Account: With app-specific password enabled
Git: For version control
For Docker Development/Deployment
Docker: Latest version
Docker Compose: Latest version (included with Docker Desktop on Windows/Mac)
For Render.com Deployment
GitHub Account: To host your repository
Render.com Account: Free tier available at https://render.com
Quick Start
1. Clone and Setup
# Clone the repository
git clone <your-repo-url>
cd yahoo-mail-mcp-server
# Copy environment template
cp .env.example .env2. Get Yahoo Mail App Password
Click "Generate app password" or "Manage app passwords"
Select "Other App" and enter "MCP Server"
Copy the generated 16-character password
3. Configure Environment
Edit .env file with your credentials:
YAHOO_EMAIL=your.email@yahoo.com
YAHOO_APP_PASSWORD=your16charpassword
TRANSPORT_MODE=stdio # or 'sse' for HTTP mode
PORT=30004. Install Dependencies
Windows (PowerShell):
npm installLinux/macOS (Bash):
npm install5. Run Locally
stdio mode (for Claude Desktop):
npm run start:stdioSSE mode (for testing HTTP endpoint):
npm run start:sseDevelopment mode (with auto-reload):
npm run devDocker Usage
Build and Run with Docker
Windows (PowerShell):
# Build the image
npm run docker:build
# Run the container
npm run docker:run
# Or use Docker Compose (recommended)
npm run docker:compose:up
# View logs
npm run docker:compose:logs
# Stop containers
npm run docker:compose:downLinux/macOS (Bash):
# Build the image
npm run docker:build
# Run the container
npm run docker:run
# Or use Docker Compose (recommended)
npm run docker:compose:up
# View logs
npm run docker:compose:logs
# Stop containers
npm run docker:compose:downManual Docker Commands
Windows (PowerShell):
# Build
docker build -t yahoo-mail-mcp .
# Run
docker run -p 3000:3000 `
-e YAHOO_EMAIL=your.email@yahoo.com `
-e YAHOO_APP_PASSWORD=yourpassword `
-e TRANSPORT_MODE=sse `
yahoo-mail-mcp
# Or with Docker Compose
docker-compose up -dLinux/macOS (Bash):
# Build
docker build -t yahoo-mail-mcp .
# Run
docker run -p 3000:3000 \
-e YAHOO_EMAIL=your.email@yahoo.com \
-e YAHOO_APP_PASSWORD=yourpassword \
-e TRANSPORT_MODE=sse \
yahoo-mail-mcp
# Or with Docker Compose
docker-compose up -dTesting the Server
Test Health Endpoint
Windows (PowerShell):
# Using npm script
npm run test:health
# Using curl (if installed)
curl http://localhost:3000/health
# Using PowerShell
Invoke-WebRequest -Uri http://localhost:3000/health | Select-Object -Expand ContentLinux/macOS (Bash):
# Using npm script
npm run test:health
# Using curl
curl http://localhost:3000/healthTest SSE Endpoint
Windows (PowerShell):
# Using npm script
npm run test:sse
# Using curl
curl http://localhost:3000/mcp/sse
# Using PowerShell
Invoke-WebRequest -Uri http://localhost:3000/mcp/sseLinux/macOS (Bash):
# Using npm script
npm run test:sse
# Using curl
curl http://localhost:3000/mcp/sseDeploying to Render.com
Step 1: Prepare Your Repository
Windows (PowerShell):
# Initialize git (if not already done)
git init
# Add all files
git add .
# Commit
git commit -m "Initial commit: Yahoo Mail MCP Server"
# Create GitHub repository at https://github.com/new
# Then push to GitHub
git remote add origin https://github.com/yourusername/yahoo-mail-mcp-server.git
git branch -M main
git push -u origin mainLinux/macOS (Bash):
# Initialize git (if not already done)
git init
# Add all files
git add .
# Commit
git commit -m "Initial commit: Yahoo Mail MCP Server"
# Create GitHub repository at https://github.com/new
# Then push to GitHub
git remote add origin https://github.com/yourusername/yahoo-mail-mcp-server.git
git branch -M main
git push -u origin mainStep 2: Deploy to Render
Sign up/Login to Render.com
Go to https://render.com
Click "Get Started for Free" or "Login"
Connect GitHub Repository
Click "New +" button in top right
Select "Web Service"
Click "Connect GitHub" and authorize Render
Select your
yahoo-mail-mcp-serverrepository
Configure the Service
Name:
yahoo-mail-mcp-server(or your preferred name)Runtime: Docker
Region: Choose closest to you (Oregon, Frankfurt, Singapore, Ohio)
Branch:
mainPlan: Free (or Starter for production)
Set Environment Variables
In the "Environment" section, click "Add Environment Variable" and add:
Key
Value
How to Generate
NODE_ENVproduction-
TRANSPORT_MODEsse-
YAHOO_EMAILyour.email@yahoo.comYour Yahoo email address
YAHOO_APP_PASSWORDyour16charpasswordSee "Get Yahoo Mail App Password" section
OAUTH_CLIENT_ID32-char-hex-stringRun:
openssl rand -hex 16OAUTH_CLIENT_SECRET64-char-hex-stringRun:
openssl rand -hex 32Important:
Mark
YAHOO_EMAIL,YAHOO_APP_PASSWORD,OAUTH_CLIENT_ID, andOAUTH_CLIENT_SECRETas "Secret"PORTis automatically set by Render, don't add it manuallySave the OAuth credentials - you'll need them to configure Claude Desktop
Deploy
Click "Create Web Service"
Render will automatically build and deploy your Docker container
Wait for deployment to complete (first build takes 5-10 minutes)
Get Your Service URL
Once deployed, you'll get a URL like:
https://yahoo-mail-mcp-server.onrender.comTest it by visiting:
https://yahoo-mail-mcp-server.onrender.com/health
Step 3: Connect to Claude Desktop
Note: Remote MCP servers require a Claude Pro, Max, Team, or Enterprise plan.
Open Claude Desktop
Launch the Claude Desktop app on your computer
Add MCP Connector
Click on your profile icon or menu
Select "Settings"
Navigate to "Connectors" section
Click "Add Custom Connector"
Configure the Connector
Name:
Yahoo MailURL:
https://your-service-name.onrender.com/mcp/sse
Example:
https://yahoo-mail-mcp-server.onrender.com/mcp/sseConfigure OAuth Authentication
Click "Advanced Settings" ⚙️
Enter the OAuth credentials from Step 4:
OAuth Client ID: The value from
OAUTH_CLIENT_IDenvironment variableOAuth Client Secret: The value from
OAUTH_CLIENT_SECRETenvironment variable
Save and Test
Click "Add" or "Save"
Claude Desktop will authenticate using OAuth 2.0
If successful, you'll see the connector active
You can now use Yahoo Mail tools in your conversations!
Step 4: Using the MCP Server in Claude.ai
Once connected, you can use these tools in your conversations:
Can you list my recent emails?
Can you read email number 5?
Can you search for emails from john@example.com?Troubleshooting
Common Issues
1. "Authentication failed" error
Solution: Verify your app-specific password
Make sure you're using an app-specific password, not your regular Yahoo password
Generate a new app-specific password at https://login.yahoo.com/account/security
Check for typos in your
.envfile or Render environment variables
2. Docker build fails on Windows
Solution: Check Docker Desktop settings
Ensure Docker Desktop is running
Check that WSL2 is enabled (Settings > General > Use WSL2 based engine)
Verify file sharing is enabled (Settings > Resources > File Sharing)
3. Port 3000 already in use
Solution: Change the port
Windows (PowerShell):
$env:PORT=3001; npm run start:sseLinux/macOS (Bash):
PORT=3001 npm run start:sseOr edit .env:
PORT=30014. Render deployment fails
Solution: Check the logs
Go to your Render dashboard
Click on your service
Click "Logs" tab
Look for error messages
Common issues:
Missing environment variables
Incorrect Dockerfile path
Build timeout (increase build timeout in settings)
5. SSE connection drops
Solution: Render free tier limitations
Free tier services sleep after 15 minutes of inactivity
First request after sleep takes 30-60 seconds to wake up
Upgrade to Starter plan ($7/month) for always-on service
6. IMAP connection timeout
Solution: Check Yahoo Mail IMAP settings
Ensure IMAP is enabled in Yahoo Mail settings
Go to Yahoo Mail > Settings > More Settings > Mailboxes
Verify IMAP access is allowed
Check firewall settings aren't blocking port 993
Windows-Specific Issues
Line Ending Problems
If you see errors about line endings:
PowerShell:
# Configure git to handle line endings correctly
git config --global core.autocrlf input
# Re-clone the repository
git clone <your-repo-url>npm Scripts Not Working
If cross-platform scripts fail:
PowerShell:
# Install cross-env globally
npm install -g cross-env
# Or run scripts directly
node server.jsLinux-Specific Issues
Permission Errors with Docker
Bash:
# Add user to docker group
sudo usermod -aG docker $USER
# Logout and login again, or run:
newgrp docker
# Test
docker psEnvironment Variables Reference
Variable | Required | Default | Description |
| Yes | - | Your Yahoo Mail email address |
| Yes | - | 16-character app-specific password from Yahoo |
| Yes (Remote) | - | OAuth 2.0 client ID for MCP server authentication (generate with |
| Yes (Remote) | - | OAuth 2.0 client secret for MCP server authentication (generate with |
| No |
| Transport mode: |
| No |
| Port for SSE mode (auto-set by Render) |
| No |
| Environment: |
Note: OAUTH_CLIENT_ID and OAUTH_CLIENT_SECRET are only required for remote deployments (Render.com). Local stdio mode doesn't require OAuth.
Available npm Scripts
Script | Description | Cross-Platform |
| Start server (stdio mode) | ✅ |
| Start in stdio mode | ✅ |
| Start in SSE mode | ✅ |
| Development mode with auto-reload | ✅ |
| Build Docker image | ✅ |
| Run Docker container | ✅ |
| Start with Docker Compose | ✅ |
| Stop Docker Compose | ✅ |
| View Docker Compose logs | ✅ |
| Test health endpoint | ✅ |
| Test SSE endpoint | ✅ |
Project Structure
yahoo-mail-mcp-server/
├── server.js # Main server code
├── package.json # Node.js dependencies and scripts
├── Dockerfile # Docker build configuration
├── docker-compose.yml # Docker Compose configuration
├── render.yaml # Render.com deployment config
├── .env.example # Environment variable template
├── .env # Your local environment variables (gitignored)
├── .dockerignore # Files to exclude from Docker build
├── .gitignore # Files to exclude from git
├── .gitattributes # Git line ending configuration
└── README.md # This fileSecurity Best Practices
OAuth 2.0 Protection (Remote Deployments)
Server requires OAuth 2.0 authentication for all MCP requests
Uses authorization code flow with PKCE (Proof Key for Code Exchange)
Only clients with correct credentials can access your emails
Generate strong random credentials:
openssl rand -hex 16andopenssl rand -hex 32Store credentials securely in Render dashboard (marked as "Secret")
Never commit credentials
.envfile is gitignoredAlways use
.env.exampleas templateSet sensitive values in Render dashboard
Never share OAuth credentials publicly
Use app-specific passwords
Never use your main Yahoo password
Generate new passwords for each service
Revoke unused passwords regularly
App passwords can be revoked without changing your main password
Email management operations
All modification operations are reversible (soft delete, not permanent)
Deleted emails are moved to Trash folder (recoverable within 7 days for free accounts)
Archive, flag, and read status changes are non-destructive
Move operations preserve email content and metadata
No send operations - server cannot send emails on your behalf
HTTPS in production
Render.com provides free SSL certificates
All traffic is encrypted (TLS/SSL)
IMAP connection uses TLS
OAuth tokens transmitted securely
Development Workflow
Making Changes
Windows (PowerShell):
# 1. Make your changes to server.js
# 2. Test locally
npm run dev
# 3. Test with Docker
npm run docker:compose:up
# 4. Commit and push
git add .
git commit -m "Description of changes"
git push origin main
# 5. Render automatically deploys the changesLinux/macOS (Bash):
# 1. Make your changes to server.js
# 2. Test locally
npm run dev
# 3. Test with Docker
npm run docker:compose:up
# 4. Commit and push
git add .
git commit -m "Description of changes"
git push origin main
# 5. Render automatically deploys the changesViewing Logs
Local Development:
# The server logs to stderr
npm run start:sseDocker:
npm run docker:compose:logsRender.com:
Go to your service dashboard
Click "Logs" tab
Real-time logs appear here
API Endpoints
When running in SSE mode, the server exposes these endpoints:
Endpoint | Method | Description |
| GET | API information and available tools |
| GET | Health check (returns status, version, timestamp) |
| GET | Server-Sent Events endpoint for MCP (requires OAuth token) |
| POST | Message endpoint for MCP communication (requires OAuth token) |
| GET | OAuth 2.0 server metadata (RFC 8414) |
| GET | OpenID Connect discovery endpoint |
| GET | OAuth 2.0 authorization endpoint |
| POST | OAuth 2.0 token endpoint |
Example Health Check Response
{
"status": "ok",
"service": "yahoo-mail-mcp",
"version": "1.0.0",
"timestamp": "2025-01-11T12:34:56.789Z"
}Breaking Changes & Migration Guide
⚠️ v3.0.0 Breaking Changes
Version 3.0.0 introduces UID-based operations which fundamentally changes how you interact with emails. This is a breaking change that requires updating your code.
What Changed
1. Parameter Rename: sequenceNumbers → uids
All email management tools now use uids (permanent identifiers) instead of sequenceNumbers (temporary positions):
// ❌ v2.x (OLD - sequence numbers)
read_email({ sequenceNumbers: [1, 2, 3] })
delete_emails({ sequenceNumbers: [5] })
// ✅ v3.0.0 (NEW - UIDs)
read_email({ uids: [510867, 510866, 510862] })
delete_emails({ uids: [510867] })2. Response Format: Plain Text → JSON
All tools now return structured JSON instead of plain text:
// ❌ v2.x response
"Email 1 of 10..."
// ✅ v3.0.0 response
{
"emails": [...],
"totalCount": 10,
"returned": 10
}3. New Required Workflow
You must now get UIDs from list_emails or search_emails before performing operations:
// Step 1: Get UIDs
const result = list_emails({ count: 10 });
// Returns: { emails: [{ uid: 510867, ... }, { uid: 510866, ... }] }
// Step 2: Use UIDs for operations
const uidsToDelete = [510867, 510866];
delete_emails({ uids: uidsToDelete });Why UIDs Are Better
Sequence Numbers (v2.x):
❌ Change when emails are deleted
❌ Position-based (email #1, #2, #3)
❌ Can become invalid between operations
❌ Cause confusion and errors
UIDs (v3.0.0):
✅ Permanent identifiers assigned by IMAP server
✅ Never change, even when other emails are deleted
✅ Always valid until email is permanently deleted
✅ Reliable for batch operations
Migration Checklist
Update all tool calls to use
uidsparameter instead ofsequenceNumbersUpdate code to get UIDs from
list_emailsorsearch_emailsfirstUpdate code to handle JSON responses instead of plain text
Test batch operations to ensure all UIDs are processed (v3.0.0 fixes critical batch bug)
Review new features: pagination, enriched metadata, advanced search, folder support
New Features in v3.0.0
Enriched Metadata: All emails include
uid,size,flags,hasAttachmentsPagination:
list_emailssupportsoffsetandlimitparametersAdvanced Search:
search_emailssupports date ranges, sender filter, unread-onlyFolder Support: All tools support
folderparameter (default: INBOX)list_folders: New tool to discover available IMAP folders
Accurate Batch Operations: Fixed critical bug where only first UID was processed
Enhanced Error Handling: Better timeout and connection error messages
MCP Tools
list_emails
List recent emails with enriched metadata (UID, size, flags, attachments) and pagination support.
Parameters:
count(optional): Number of emails to retrieve (default: 10, max: 50)folder(optional): Folder to list from (default: 'INBOX'). Uselist_foldersto see available foldersoffset(optional): Number of emails to skip for pagination (default: 0)
Response: JSON with emails array containing enriched metadata for each email:
uid: Permanent IMAP UID (use this for all operations)sequenceNumber: Position in folder (for reference only, don't use for operations)from: Sender addresssubject: Email subjectdate: Date in RFC 2822 formatsize: Email size in bytesflags: Array of IMAP flags (e.g.,['\\Seen'],['\\Flagged'])hasAttachments: Boolean indicating if email has attachments
Examples:
// List 20 most recent emails
list_emails({ count: 20 })
// List emails with pagination (skip first 10)
list_emails({ count: 10, offset: 10 })
// List emails from Sent folder
list_emails({ count: 15, folder: "Sent" })read_email
Read the full content of emails using UIDs (supports batch reading).
Parameters:
uids(required): Array of UIDs to read (get UIDs fromlist_emailsorsearch_emails)folder(optional): Folder containing the emails (default: 'INBOX')
Response: JSON with enriched email data including body content
Examples:
// Read a single email
read_email({ uids: [510867] })
// Read multiple emails
read_email({ uids: [510867, 510866, 510862] })
// Read email from Sent folder
read_email({ uids: [510867], folder: "Sent" })search_emails
Advanced search with filters for date ranges, sender, and unread status.
Parameters:
query(optional): Search term for subject or sender (can be empty for date-only searches)count(optional): Number of results to return (default: 10, max: 50)dateFrom(optional): Filter emails from this date onwards (ISO 8601 or RFC 2822 format)dateTo(optional): Filter emails up to this date (ISO 8601 or RFC 2822 format)sender(optional): Filter by specific sender email address or nameunreadOnly(optional): Only return unread emails (default: false)folder(optional): Folder to search in (default: 'INBOX')
Response: JSON with emails array, totalMatches, returned, query, filters, and folder
Examples:
// Basic search
search_emails({ query: "invoice", count: 15 })
// Search unread emails only
search_emails({ query: "meeting", unreadOnly: true })
// Search by date range
search_emails({ dateFrom: "2025-01-01", dateTo: "2025-01-31" })
// Search by sender
search_emails({ sender: "boss@company.com" })
// Combined filters
search_emails({
query: "report",
sender: "team@company.com",
dateFrom: "2025-01-15",
unreadOnly: true
})list_folders
Discover all available IMAP folders in your Yahoo Mail account.
Parameters: None
Response: JSON with array of folder objects containing name, path, delimiter, and children
Example:
// List all folders
list_folders()
// Example response:
// {
// "folders": [
// { "name": "INBOX", "path": "INBOX" },
// { "name": "Sent", "path": "Sent" },
// { "name": "Trash", "path": "Trash" },
// { "name": "Archive", "path": "Archive" }
// ]
// }delete_emails
Move emails to Trash folder using UIDs (soft delete - emails can be recovered).
Parameters:
uids(required): Array of UIDs to delete (get UIDs fromlist_emailsorsearch_emails)folder(optional): Source folder (default: 'INBOX')
Response: Success/failure message with accurate count of processed emails
Examples:
// Delete a single email
delete_emails({ uids: [510867] })
// Delete multiple emails
delete_emails({ uids: [510867, 510866, 510862, 510856] })
// Delete from Sent folder
delete_emails({ uids: [510867], folder: "Sent" })archive_emails
Move emails to Archive folder using UIDs for long-term storage.
Parameters:
uids(required): Array of UIDs to archivefolder(optional): Source folder (default: 'INBOX')
Response: Success/failure message with accurate count of processed emails
Examples:
// Archive a single email
archive_emails({ uids: [510867] })
// Archive multiple emails
archive_emails({ uids: [510867, 510866, 510862, 510851] })mark_as_read
Mark emails as read using UIDs by adding the Seen flag.
Parameters:
uids(required): Array of UIDs to mark as readfolder(optional): Folder containing the emails (default: 'INBOX')
Response: Success/failure message with accurate count of processed emails
Examples:
// Mark a single email as read
mark_as_read({ uids: [510867] })
// Mark multiple emails as read
mark_as_read({ uids: [510867, 510866, 510862, 510851, 510865] })mark_as_unread
Mark emails as unread using UIDs by removing the Seen flag.
Parameters:
uids(required): Array of UIDs to mark as unreadfolder(optional): Folder containing the emails (default: 'INBOX')
Response: Success/failure message with accurate count of processed emails
Examples:
// Mark a single email as unread
mark_as_unread({ uids: [510867] })
// Mark multiple emails as unread
mark_as_unread({ uids: [510869, 510867, 510866] })flag_emails
Flag emails as important/starred using UIDs by adding the Flagged flag.
Parameters:
uids(required): Array of UIDs to flagfolder(optional): Folder containing the emails (default: 'INBOX')
Response: Success/failure message with accurate count of processed emails
Examples:
// Flag a single email
flag_emails({ uids: [510867] })
// Flag multiple emails
flag_emails({ uids: [510851, 510865, 510864] })unflag_emails
Remove flag/star from emails using UIDs by removing the Flagged flag.
Parameters:
uids(required): Array of UIDs to unflagfolder(optional): Folder containing the emails (default: 'INBOX')
Response: Success/failure message with accurate count of processed emails
Examples:
// Unflag a single email
unflag_emails({ uids: [510867] })
// Unflag multiple emails
unflag_emails({ uids: [510867, 510866, 510862] })move_emails
Move emails to a specified folder using UIDs.
Parameters:
uids(required): Array of UIDs to movefolderName(required): Name of the destination folder (e.g., "Work", "Personal", "Archive")sourceFolder(optional): Source folder (default: 'INBOX')
Response: Success/failure message with accurate count of processed emails
Examples:
// Move a single email to Work folder
move_emails({ uids: [510867], folderName: "Work" })
// Move multiple emails to Personal folder
move_emails({ uids: [510867, 510866, 510862], folderName: "Personal" })
// Move from Sent to Archive
move_emails({ uids: [510867], folderName: "Archive", sourceFolder: "Sent" })Performance Considerations
Render.com Free Tier
Sleep after inactivity: Services sleep after 15 minutes of no requests
Wake-up time: First request takes 30-60 seconds
Monthly hours: 750 hours/month (enough for moderate use)
Upgrade: $7/month for Starter plan (always-on)
IMAP Performance
Connection pooling: Each request creates a new IMAP connection
Timeout: 30 seconds for connection and auth
Rate limiting: Yahoo may throttle excessive requests
Recommendation: Cache results on client side when possible
Cross-Platform Compatibility
This project is designed to work seamlessly on:
Windows 10/11 with PowerShell or Command Prompt
Linux (Ubuntu, Debian, Fedora, etc.)
macOS (Intel and Apple Silicon)
Docker Desktop (Windows, Mac, Linux)
WSL2 (Windows Subsystem for Linux)
Line Endings
.gitattributesensures LF line endings in repositoryWorks correctly on Windows (CRLF) and Linux (LF)
Docker uses LF inside containers
Path Handling
All paths use forward slashes in code
path.join()used for cross-platform compatibilityWorks with Windows backslashes and Unix forward slashes
Contributing
Fork the repository
Create a feature branch:
git checkout -b feature-nameMake your changes
Test on both Windows and Linux (if possible)
Commit:
git commit -am "Add feature"Push:
git push origin feature-nameCreate a Pull Request
License
MIT License - See LICENSE file for details
Support
Issues: Report bugs at https://github.com/yourusername/yahoo-mail-mcp-server/issues
Discussions: Ask questions in GitHub Discussions
MCP Docs: https://modelcontextprotocol.io
Changelog
v3.0.0 (2025-01-18) - UID Migration
BREAKING CHANGES:
All tools now use
uidsparameter instead ofsequenceNumbersResponse format changed from plain text to structured JSON
UIDs are permanent identifiers that don't change when emails are deleted
New Features:
Enriched metadata: All emails include
uid,size,flags,hasAttachmentsPagination support:
list_emailsacceptsoffsetandlimitparametersAdvanced search filters:
dateFrom,dateTo,sender,unreadOnlyparametersFolder support: All tools accept
folderparameter (default: INBOX)New tool:
list_foldersto discover available IMAP foldersEnhanced error handling: Better timeout and connection error messages with Render spindown detection
Bug Fixes:
CRITICAL: Fixed batch operations bug where only first UID was processed
All batch operations now accurately process every UID in the array
Success/failure messages now report exact counts of processed emails
Migration Guide:
Replace
sequenceNumberswithuidsin all tool callsGet UIDs from
list_emailsorsearch_emailsresponsesUpdate code to handle JSON responses instead of plain text
See "Breaking Changes & Migration Guide" section above for details
v2.0.1 (2025-01-17)
Fixed: Enhanced input validation for all email operations
Added shared validation helper to prevent IMAP errors with invalid sequence numbers
Improved error messages for better debugging
v2.0.0 (2025-01-16)
Breaking Change:
read_emailnow usessequenceNumbers(array) instead ofsequenceNumber(single number)Added full email management with batch operations support
Seven new tools: delete_emails, archive_emails, mark_as_read, mark_as_unread, flag_emails, unflag_emails, move_emails
All modification operations support batch processing
Enhanced security with reversible operations (soft delete, no permanent deletion)
v1.0.0 (2025-01-11)
Initial release
Support for stdio and SSE transports
Docker and Docker Compose support
Render.com deployment configuration
Cross-platform compatibility (Windows/Linux)
Three core tools: list_emails, read_email, search_emails
Acknowledgments
Built with @modelcontextprotocol/sdk
Uses imap for IMAP access
Uses mailparser for email parsing
Deployed on Render.com
FAQ
Q: Can I use this with Gmail or other email providers?
A: Currently, this server is configured for Yahoo Mail. To support other providers, you'd need to modify the IMAP configuration in server.js (lines 166-179).
Q: Is this safe to use with my email account?
A: Yes! The server uses app-specific passwords (not your main password) and all modification operations are reversible. Delete operations move emails to Trash (recoverable), and the server never permanently deletes emails or sends emails on your behalf.
Q: How much does it cost to run on Render?
A: The free tier provides 750 hours/month, which is enough for moderate use. For always-on service, the Starter plan is $7/month.
Q: Can I run this on other cloud platforms?
A: Yes! The Docker configuration works on any platform that supports Docker containers (AWS ECS, Google Cloud Run, Azure Container Instances, Heroku, Fly.io, etc.).
Q: Do I need to keep my computer running?
A: No! Once deployed to Render.com (or another cloud platform), the server runs independently in the cloud.
Q: How do I update the server after deployment?
A: Simply push your changes to GitHub. Render automatically detects the push and redeploys the service.
Q: Can multiple people use the same deployed server?
A: The server connects to a single Yahoo Mail account (the one configured in environment variables). Each user would need their own deployment for their own email account.
Q: What if I forget my app-specific password?
A: You can generate a new one at https://login.yahoo.com/account/security/app-passwords and update it in your Render environment variables (Settings > Environment).
Next Steps
After successful deployment:
✅ Test the health endpoint
✅ Connect to Claude.ai
✅ Try listing your emails
✅ Read a few emails
✅ Search your inbox
🎉 Enjoy your Yahoo Mail MCP server!
Happy Coding! If you have questions or issues, please open an issue on GitHub.
Available Tools
11 toolsarchive_emailsC
Move emails to Archive folder using UIDs for long-term storage. UIDs are permanent identifiers.
| Name | Required | Description | Default |
|---|---|---|---|
| uids | Yes | Array of UIDs to archive | |
| folder | No | Source folder (default: INBOX) | INBOX |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It states the action (moving to Archive) but does not mention side effects (e.g., does it remove from INBOX? does it change read status?), required permissions, reversibility, or any limitations. The note about UIDs being permanent is useful but minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with the core action front-loaded. The second sentence adds a useful clarification about UIDs. No wasted words, though the description could have used the space to differentiate from move_emails or add usage guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no output schema and no annotations, the description is incomplete. It omits critical context such as whether the operation is reversible, what happens to the emails in the source folder, potential failure modes, or any prerequisites. It also fails to clarify how it differs from move_emails, which is a sibling that likely has similar behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents both parameters with descriptions (uids: 'Array of UIDs to archive'; folder: 'Source folder'). The description adds no additional parameter semantics beyond the UID permanence note, which is not strictly tied to parameter usage. Given 100% schema coverage, baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (move/archive), resource (emails), and destination (Archive folder). It also explains UIDs are permanent identifiers, which adds specificity. However, it does not explicitly differentiate from the sibling move_emails, leaving slight ambiguity about the distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives like move_emails or delete_emails. The phrase 'for long-term storage' implies a purpose but does not state conditions or exclusions. The agent is left to infer usage without direct direction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_emailsA
Move emails to Trash folder using UIDs (soft delete, recoverable). UIDs are permanent identifiers.
| Name | Required | Description | Default |
|---|---|---|---|
| uids | Yes | Array of UIDs to delete | |
| folder | No | Source folder (default: INBOX) | INBOX |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the core behavior (move to Trash, recoverable) but does not detail side effects, permissions, or what happens to related metadata. Basic transparency is present, but it could go deeper.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with zero fluff. The action and key attributes are front-loaded, making it easy to scan and understand.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool with no output schema and no annotations, the description covers what it does, how it works, and one critical behavioral note (recoverability). It doesn't mention the folder parameter, but the schema already covers that, so nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value by explaining 'UIDs are permanent identifiers', giving context beyond the schema's property description. This helps an agent understand the data format and stability of UIDs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Move emails to Trash folder'), the method (UIDs), and the key distinction from a hard delete ('soft delete, recoverable'). It clearly identifies the resource and operation, distinguishing it from siblings like move_emails or archive_emails.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use this tool via 'soft delete, recoverable', but it does not explicitly name alternatives or specify conditions when this tool is preferred over siblings like archive_emails or move_emails. Usage is inferred rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
flag_emailsB
Flag emails as important/starred using UIDs. UIDs are permanent identifiers.
| Name | Required | Description | Default |
|---|---|---|---|
| uids | Yes | Array of UIDs to flag | |
| folder | No | Folder containing emails (default: INBOX) | INBOX |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It only states that UIDs are permanent; it does not disclose that flagging mutates email state, whether the flag is reversible, what failures look like, or what the response contains.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short, front-loaded sentences with no filler. The first sentence states the action and the target; the second efficiently clarifies the permanence of UIDs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The schema fully covers the two parameters, so the main gaps are output behavior and failure semantics, which must be inferred for this mutating tool with no annotations. The low parameter count and simple action keep this gap moderate rather than severe.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% — both uids and folder already carry descriptions in the schema, so the baseline is 3. The description adds a small value-add by explaining UIDs are permanent and stable, but adds nothing about the folder parameter beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a clear verb+resource pair: 'Flag emails as important/starred using UIDs.' The 'important/starred' semantics implicitly distinguish it from siblings like mark_as_read, though the distinction is not made explicit by naming any sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use or when-not-to-use guidance is given, and no alternatives are named. The note 'UIDs are permanent identifiers' hints that UIDs are preferred over transient message numbers, which is a mild usage hint but leaves scenario selection to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_emailsA
List recent emails from a Yahoo Mail folder. Returns UIDs (permanent identifiers) and enriched metadata including size, flags, and attachment status.
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Number of emails to retrieve (default: 10, max: 50) | |
| folder | No | Folder to list emails from (default: INBOX). Use list_folders to see available folders. | INBOX |
| offset | No | Number of emails to skip (for pagination, default: 0) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden of behavioral disclosure. It states what is returned (UIDs and metadata) and implies a read-only 'list' operation, but does not explicitly confirm no side effects, auth requirements, or rate limits. It also does not clarify how 'recent' is determined, which is a behavioral gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no fluff. It front-loads the action and resource, then adds return details, with every phrase conveying necessary information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a simple list operation with no output schema or annotations, the description gives a solid overview of purpose and return contents. However, it omits an explicit read-only assurance and does not enumerate all metadata fields, which an agent might need for parsing without an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All three parameters (count, folder, offset) are fully documented in the schema with descriptions, defaults, and max, so the schema provides high coverage. The description adds minimal parameter meaning beyond 'recent,' which hints at recency ordering but does not elaborate on how count interacts with the list.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'List recent emails from a Yahoo Mail folder.' It specifies the resource (emails) and scope (folder), and names the return type (UIDs, metadata). This distinguishes it from siblings like read_email, search_emails, and list_folders.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides implied usage but no explicit when-to-use or alternative routing. The only cross-reference is in the folder parameter schema ('Use list_folders to see available folders'), not the main description. Agents must infer that listing is the appropriate tool for browsing a folder rather than searching or reading.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_foldersA
List all available IMAP folders/mailboxes in your Yahoo Mail account
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the action (list folders) but does not explicitly note that it is read-only or side-effect-free, nor does it mention any authentication or pagination details. The action implies safety, but absence of explicit disclosure leaves some room for doubt.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, grammatically complete sentence states the purpose without redundancy or filler. Every word earns its place, and the key information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (no parameters, no output schema, no annotations), the description is largely complete for an agent to invoke it correctly. It tells the agent what the tool lists and the account scope. A minor gap is the lack of any mention of the return structure (e.g., folder names vs. full paths), but this is not critical for a low-complexity tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so schema coverage is effectively 100%. The description needs to add nothing about parameters; the baseline for no parameters is 4, and the description does not detract from it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'List' and names the exact resource 'all available IMAP folders/mailboxes' within the scope 'Yahoo Mail account'. It is immediately clear what the tool does and distinct from sibling tools like list_emails or search_emails.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no explicit guidance on when to use this tool versus alternatives. While it is self-evident that this is for folders and not emails, there is no mention of exclusions or conditions, leaving the agent to infer its place among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mark_as_readB
Mark emails as read using UIDs. UIDs are permanent identifiers.
| Name | Required | Description | Default |
|---|---|---|---|
| uids | Yes | Array of UIDs to mark as read | |
| folder | No | Folder containing emails (default: INBOX) | INBOX |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states the mutation effect but does not mention idempotency, permanence of the read state, potential side effects, permissions, or response behavior. The 'UIDs are permanent identifiers' note adds some context but does not cover operational behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler. The primary action is front-loaded and the follow-up sentence provides meaningful context about UIDs. Every word contributes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, single-purpose mutation tool with no output schema, the description provides the essential context: the action, the resource, and the mechanism. It could be improved by noting reversibility (mark_as_unread exists) or the idempotent nature, but the low complexity means the current description is largely sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds semantic value by clarifying that UIDs are permanent identifiers, which helps agents understand that these are stable identifiers rather than transient session IDs. This goes beyond the bare schema descriptions of 'array of UIDs to mark as read' and 'folder containing emails'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Mark emails as read') and the resource (emails), with the mechanism ('using UIDs') and a useful clarification that UIDs are permanent identifiers. While it differentiates from mark_as_unread through the word 'read', it does not explicitly call out sibling distinctions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given about when to use this tool versus alternatives such as mark_as_unread, flag_emails, or delete_emails. The mention that UIDs are permanent identifiers implies why UIDs should be used, but there is no explicit context or exclusionary guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mark_as_unreadC
Mark emails as unread using UIDs. UIDs are permanent identifiers.
| Name | Required | Description | Default |
|---|---|---|---|
| uids | Yes | Array of UIDs to mark as unread | |
| folder | No | Folder containing emails (default: INBOX) | INBOX |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It only states the basic action and that UIDs are permanent; it does not mention side effects, mutability, permissions, failure behavior, or what happens to the email state beyond marking it unread.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the main action, followed by a relevant clarification about UIDs. It contains no filler, though it could include a bit more useful context without becoming bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter tool, the description plus schema is minimally adequate for invoking the tool. However, with no annotations and no output schema, it lacks information about expected return values, error conditions, or behavioral consequences, leaving noticeable gaps for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds a small amount of semantic value by noting that UIDs are permanent identifiers, which helps agents understand their stability, but it does not elaborate beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Mark emails as unread') and the resource (emails), with a specific method (using UIDs). It is not a tautology and is distinguishable from most siblings by the 'unread' intent, though it does not explicitly differentiate itself from the closely related mark_as_read.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives like mark_as_read or read_email. It provides no use-case context, prerequisites, or exclusions, so an agent must infer when this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
move_emailsA
Move emails to a specified folder using UIDs. UIDs are permanent identifiers. Use list_folders to see available folders.
| Name | Required | Description | Default |
|---|---|---|---|
| uids | Yes | Array of UIDs to move | |
| folderName | Yes | Name of the destination folder (e.g., "Work", "Personal"). Use list_folders to see available folders. | |
| sourceFolder | No | Source folder containing the emails (default: INBOX) | INBOX |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the responsibility. It adds useful context that UIDs are permanent identifiers, which clarifies how to refer to emails. However, it does not disclose potential side effects such as whether the emails are removed from the source, what happens if the destination folder is invalid, or whether the operation is reversible. Some context is given, but a destructive mutation warrants more disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The core action is front-loaded, and the additional information (UID permanence and list_folders reference) is relevant and concise. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is a mutating operation without an output schema and no annotations. The description covers the action, prerequisites, and the permanence of UIDs, but it does not mention what response the agent can expect, error conditions, or any impact on source folders. For a straightforward move operation, this is adequate but not rich; a bit more detail (e.g., success indication) would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each parameter is already documented. The description adds value by explaining that UIDs are permanent and referencing list_folders for folder names, which supplements the schema. However, it does not add deeper semantics beyond what the schema already states, so it aligns with the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a precise action ('Move emails to a specified folder'), a specific resource (emails by UIDs), and implies the target folder. It clearly differentiates from sibling tools like delete, archive, or mark_as_read by focusing on moving to a folder, and the mention of UIDs adds specificity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a prerequisite by pointing to list_folders for available folders, which aids usage, but it does not explicitly guide when to prefer this tool over alternatives like archive_emails or delete_emails. The usage is implied rather than explicitly contrasted with siblings, so it earns a middle score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_emailA
Read email content using UIDs (permanent identifiers). UIDs don't change when emails are deleted. Get UIDs from list_emails or search_emails.
| Name | Required | Description | Default |
|---|---|---|---|
| uids | Yes | Array of UIDs to read. UIDs are permanent identifiers from list_emails. | |
| folder | No | Folder containing the emails (default: INBOX) | INBOX |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states the tool reads email content, which implies no modification, but it does not explicitly confirm that it is non-destructive or mention any side effects (e.g., marking as read). It also does not describe behavior for invalid UIDs, missing folders, or rate limits. The description provides a useful fact about UID persistence but does not cover the tool's operational behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is exactly two sentences with no wasted words. It front-loads the core purpose ('Read email content using UIDs') and then adds a practical note about UID persistence and sourcing. This is concise and well-organized, earning a high score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter tool with no output schema, the description covers the essential usage: it explains the input (UIDs), the source of that input, and the purpose. However, it does not mention error handling (e.g., invalid UIDs, non-existent folder) or the structure of returned content. Given the lack of annotations and output schema, a bit more detail about expected outcomes or failure modes would improve completeness, but the core usage is adequately covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters, giving a baseline of 3. The description adds value by explaining what UIDs are (permanent identifiers) and how to obtain them, which clarifies the semantic meaning beyond the schema's basic 'Array of UIDs' description. However, it does not add details on format (e.g., integer range, array length constraints) or edge cases, so it meets the baseline without exceeding it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads email content using UIDs and differentiates from siblings by mentioning that UIDs are permanent and obtained from list_emails or search_emails. It specifies the resource (email content) and the action (read), which distinguishes it from listing, searching, or mutating tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a direct usage hint ('Get UIDs from list_emails or search_emails') which establishes the source of the required input. It implies the tool is for reading full content rather than listing metadata, but it does not explicitly state when to avoid using it or compare with alternative tools beyond the UID sourcing. The context is clear enough for an agent to infer the intended use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_emailsA
Search emails using UIDs with advanced filters. Returns UIDs which are permanent identifiers that don't change when emails are deleted. Get UIDs from results for subsequent operations.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Search term for subject or sender (can be empty for date-only searches) | |
| count | No | Number of results to return (default: 10, max: 50) | |
| dateFrom | No | Filter emails from this date onwards (ISO 8601 or RFC 2822 format) | |
| dateTo | No | Filter emails up to this date (ISO 8601 or RFC 2822 format) | |
| sender | No | Filter by specific sender email address or name | |
| unreadOnly | No | Only return unread emails (default: false) | |
| folder | No | Folder to search in (default: INBOX). Use list_folders to see available folders. | INBOX |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the burden. It adds useful non-obvious behavior: UIDs are permanent and do not change when emails are deleted, which helps agents trust them for future calls. It does not explicitly state read-only status, though 'Search' implies it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, all contributing value: the purpose is front-loaded, the UID permanence note is meaningful, and the chaining guidance is actionable. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description adequately explains the return value (UIDs) and how to use it. It covers the important chaining behavior and leaves parameter specifics to the highly detailed schema, making it sufficiently complete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed parameter descriptions, so the baseline is 3. The description adds no parameter-level meaning beyond the generic 'advanced filters' phrase, which does not enhance the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches emails with advanced filters and returns UIDs, which are stable identifiers. It distinguishes itself via the focus on UIDs for downstream operations, but does not explicitly contrast with sibling tools like list_emails, and the phrase 'using UIDs' is slightly awkward.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description tells agents to use this tool when they need UIDs for subsequent operations, providing a clear context. It does not explicitly state when to prefer list_emails or exclude alternatives, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unflag_emailsB
Remove flag/star from emails using UIDs. UIDs are permanent identifiers.
| Name | Required | Description | Default |
|---|---|---|---|
| uids | Yes | Array of UIDs to unflag | |
| folder | No | Folder containing emails (default: INBOX) | INBOX |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the action and notes that UIDs are permanent, but does not disclose what happens on invalid UIDs, whether the operation is reversible (unflagging can be undone by flag_emails), or any side effects. For a mutation tool with zero annotation coverage, this is a significant gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the action. The second sentence about UIDs being permanent is relevant and concise. No wasted words; the definition is efficiently structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, but without annotations, an agent needs to know error behavior or return values. The description does not cover what happens if UIDs are invalid, whether it confirms the action, or if any preconditions exist (e.g., folder must exist). Given no output schema and no annotations, this is incomplete for a complete usage scenario, but acceptable for a basic mutation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already describes both parameters (uids array and folder with default). The description adds minimal extra: it clarifies that UIDs are permanent identifiers, which is useful context for why UIDs are used but not specific to parameter handling. The baseline of 3 is appropriate since the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear action ('Remove flag/star from emails') and the resource, with the mechanism (UIDs). It does not explicitly differentiate from sibling tools like flag_emails, but the opposite verb makes the distinction obvious. A 5 would require naming the sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage: when you have UIDs and want to unflag emails. It mentions UIDs are permanent, which hints at when they are available. However, it does not give explicit guidance about when not to use this tool or mention alternatives like flag_emails. The guidance is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
11 tool updates
v3.0.0- First observed
archive_emails - First observed
delete_emails - First observed
flag_emails - First observed
list_emails - First observed
list_folders - First observed
mark_as_read - First observed
mark_as_unread - First observed
move_emails - First observed
read_email - First observed
search_emails - First observed
unflag_emails
TDQS
Scored across 11 tools
Each tool has a distinctly separate purpose: archiving, deleting, flagging, listing, marking read/unread, moving, reading, searching, and unflagging. No overlap in functionality.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., archive_emails, delete_emails, list_folders). No mixing of conventions.
11 tools is an appropriate number for an email management server, covering core operations without being overly numerous or sparse.
The tool set covers reading, searching, and organizing emails, but lacks tools for composing, sending, or drafting emails, which are significant missing operations for an email server.
Maintenance
Related MCP Connectors
Read, send, file and search email in any Gmail, Microsoft 365 or IMAP mailbox, plus its calendar.
- mailOAuthcom.anymailmcp
Read, send, organize, watch email on any IMAP mailbox: Gmail, iCloud, OVH, Zoho, Fastmail + CalDAV.
Never-stored live email: read, send, organize, schedule and auto-triage Gmail or any IMAP mailbox.
Manage Gmail end-to-end: search, read, send, draft, label, and organize threads. Automate workflow…
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables LLMs to read, search, and send emails through Yahoo Mail using secure OAuth2 authentication.-
- AlicenseNot gradedqualityDmaintenanceEnables reading, searching, composing, and managing Yahoo Mail emails via IMAP with OAuth support for both local and remote MCP clients.26 npmISC
- FlicenseAqualityBmaintenanceAn MCP server that provides full email management for Yahoo Mail via IMAP, including tools to list, read, search, delete, archive, flag, and move emails, with secure OAuth authentication and support for local and remote deployments.111-
- AlicenseNot gradedqualityBmaintenanceMCP server for Yahoo Mail over IMAP+SMTP that enables AI assistants to manage emails fully—listing, reading, searching, threading, flagging, moving, archiving, handling attachments, and sending/reply/forward/draft—using an app-specific password.MIT