Skip to main content
Glama
gufao

mcp-server-mail-agent

by gufao

MCP Email Server

A Model Context Protocol (MCP) server for email management supporting multiple providers and accounts with a unified inbox.

Features

  • Multi-Provider: Gmail (OAuth2), Outlook (Microsoft Graph), and any IMAP server

  • Multi-Account: Unified inbox across all your email accounts

  • Security-First: Secrets must use environment variables (plaintext rejected)

  • Docker-Ready: Runs in a container for security and portability

  • MCP Standard: Works with Claude Code, Claude Desktop, and any MCP-compatible client

Supported Providers

Provider

Auth Method

Features

Gmail

OAuth2

Full Gmail API access

Outlook

OAuth2

Microsoft Graph API

IMAP

App Password

Any email server (Gmail, Yahoo, iCloud, custom)

Quick Start

1. Clone & Install

git clone https://github.com/gufao/mcp-server-mail-agent.git
cd mcp-server-mail-agent
npm install

2. Configure

# Create credentials directory
mkdir -p credentials

# Copy example files
cp accounts.example.json credentials/accounts.json
cp .env.example .env

# Edit with your settings
nano credentials/accounts.json
nano .env

3. Set Up Provider

IMAP (Easiest - works with any email)

Edit .env:

IMAP_HOST=imap.gmail.com
IMAP_USER=your@gmail.com
IMAP_PASSWORD=your-app-password
SMTP_HOST=smtp.gmail.com

Edit credentials/accounts.json:

{
  "accounts": [
    {
      "id": "main",
      "name": "My Email",
      "provider": "imap",
      "default": true,
      "config": {
        "host": "${IMAP_HOST}",
        "port": 993,
        "user": "${IMAP_USER}",
        "password": "${IMAP_PASSWORD}",
        "tls": true,
        "smtpHost": "${SMTP_HOST}",
        "smtpPort": 587,
        "smtpSecure": false
      }
    }
  ]
}

Gmail (OAuth2)

  1. Go to Google Cloud Console

  2. Create project, enable Gmail API

  3. Create OAuth credentials (Desktop app)

  4. Download as credentials/gmail-credentials.json

  5. Run: npm run auth:gmail

Outlook (OAuth2)

  1. Go to Azure Portal > App registrations

  2. New registration > Set redirect URI: http://localhost:3000/callback

  3. Add API permissions: Mail.Read, Mail.Send, Mail.ReadWrite, offline_access

  4. Create client secret

  5. Set env vars and run: npm run auth:outlook

4. Build & Test

# Build
npm run build

# Test locally
source .env && ACCOUNTS_PATH=./credentials/accounts.json node dist/index.js

# Build Docker
docker build -t mcp-email-server .

# Test Docker
docker run --rm -v "$(pwd)/credentials:/app/credentials:ro" --env-file .env mcp-email-server

5. Add to Docker MCP Gateway

Step 1: Create v3 Catalog File

Create or update ~/.docker/mcp/catalogs/custom.yaml:

version: 3
name: custom
displayName: custom
registry:
  email:
    description: "Multi-account Email MCP Server supporting IMAP, Gmail, and Outlook"
    title: "Email Manager"
    type: server
    dateAdded: "2025-11-23T00:00:00Z"
    image: mcp-email-server:latest
    ref: ""
    tools:
      - name: list_accounts
      - name: fetch_unread_emails
      - name: search_emails
      - name: get_email
      - name: mark_as_read
      - name: mark_as_unread
      - name: send_email
      - name: get_all_folders
      - name: delete_email
    prompts: 0
    resources: {}
    volumes:
      - "/absolute/path/to/mcp-server-mail-agent/credentials:/app/credentials:ro"
    env:
      - name: ACCOUNTS_PATH
        value: "/app/credentials/accounts.json"
      - name: IMAP_HOST
        value: "{{email.imap_host}}"
      - name: IMAP_USER
        value: "{{email.imap_user}}"
      - name: IMAP_PASSWORD
        value: "{{email.imap_password}}"
      - name: SMTP_HOST
        value: "{{email.smtp_host}}"
    metadata:
      category: productivity
      tags: [email, imap, gmail, outlook]
      license: GPL-3.0
      owner: local

Important:

  • The catalog must be v3 format with version, name, displayName, and registry keys

  • Use template variables like {{email.imap_host}} instead of hardcoding credentials

  • Replace /absolute/path/to/ with your actual project path

Step 2: Add Credentials to Docker MCP Config

Edit ~/.docker/mcp/config.yaml to store your actual credentials:

email:
  imap_host: imap.example.com
  imap_user: user@example.com
  imap_password: your-app-password-here
  smtp_host: smtp.example.com

Why this matters: Hardcoding credentials directly in the catalog env values causes authentication failures in the Docker MCP Gateway, even though the same values work with docker run. Using template variables that reference config.yaml resolves this issue.

Step 3: Import and Enable

# Import the catalog
docker mcp catalog import ~/.docker/mcp/catalogs/custom.yaml
# (the CLI will prompt for a name; enter "custom")

# Enable the email server
docker mcp server enable email

# Verify tools are available
docker mcp tools ls --format list | grep -E "list_accounts|fetch_unread_emails|send_email"

# Test authentication
docker mcp tools call list_accounts

Expected output should include your IMAP account with no authentication errors.

Step 4: Use in Claude Code

Run /mcp in Claude Code to reconnect, or restart Claude Desktop.

Available Tools

Tool

Description

list_accounts

List all connected email accounts

fetch_unread_emails

Get unread emails (all accounts or specific)

search_emails

Search across all accounts

get_email

Get full email content by ID

mark_as_read

Mark email as read

mark_as_unread

Mark email as unread

send_email

Send email from specific account

get_all_folders

List folders from all accounts

delete_email

Delete/trash an email

Security

Enforced Security

  • Plaintext secrets rejected: The server will refuse to start if password or clientSecret are hardcoded in accounts.json

  • Environment variables required: All secrets must use ${VAR_NAME} syntax

  • Validation on startup: Missing or empty secrets are reported

Best Practices

  • Never commit .env or credentials/ to git (already in .gitignore)

  • Use app passwords instead of regular passwords for IMAP

  • Docker volumes are mounted read-only

  • Container runs as non-root user

Common IMAP Servers

Provider

IMAP Host

SMTP Host

Gmail

imap.gmail.com

smtp.gmail.com

Outlook/Hotmail

outlook.office365.com

smtp.office365.com

Yahoo

imap.mail.yahoo.com

smtp.mail.yahoo.com

iCloud

imap.mail.me.com

smtp.mail.me.com

ProtonMail

127.0.0.1 (Bridge)

127.0.0.1 (Bridge)

Usage Examples

"What email accounts do I have?"
"Show me my unread emails"
"Search for emails from john@example.com"
"Read email ID abc123 from my work account"
"Send an email to jane@example.com about the meeting"
"Mark that email as read"
"Delete the spam email"

Project Structure

mcp-email-server/
├── src/
│   ├── index.ts              # MCP server entry
│   ├── types.ts              # TypeScript interfaces
│   ├── config.ts             # Environment configuration
│   ├── account-manager.ts    # Multi-account orchestration
│   ├── providers/
│   │   ├── base.ts           # Abstract EmailProvider
│   │   ├── gmail.ts          # Gmail API
│   │   ├── outlook.ts        # Microsoft Graph
│   │   ├── imap.ts           # IMAP/SMTP
│   │   └── index.ts          # Provider factory
│   └── auth/
│       ├── gmail-auth.ts     # Gmail OAuth setup
│       └── outlook-auth.ts   # Outlook OAuth setup
├── credentials/              # Your credentials (gitignored)
├── Dockerfile
├── docker-compose.yml
├── package.json
└── tsconfig.json

Development

# Install dependencies
npm install

# Build
npm run build

# Run locally
npm start

# Auth scripts
npm run auth:gmail
npm run auth:outlook

Troubleshooting

Issue

Solution

"SECURITY ERROR: plaintext secret"

Use ${ENV_VAR} syntax in accounts.json

"Environment variable X is not set"

Add the variable to .env and source it

"ENOENT: token.json"

Run the auth script for that provider

"ENOTFOUND"

Check IMAP/SMTP host settings

"Authentication failed"

Verify credentials, use app password for IMAP

"Failed to reconnect to MCP_DOCKER"

Restart Docker Desktop, check MCP Gateway is enabled

"yaml: unmarshal errors"

Check custom.yaml format - env must be array of {name, value} objects

Docker MCP Gateway auth fails (AUTHENTICATIONFAILED)

Don't hardcode credentials in catalog. Use template vars {{email.*}} and put actual values in ~/.docker/mcp/config.yaml

Empty accounts list in Gateway

Ensure catalog uses v3 format with template variables, and config.yaml has actual credential values

Gateway works with docker run but not MCP

Credentials hardcoded in catalog cause auth failures. Move them to config.yaml and use template variables

License

GPL-3.0 License - see LICENSE for details.

Author

Augusto Linhares - 18X Labs


Built with the Model Context Protocol

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
5wRelease cycle
2Releases (12mo)

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gufao/mcp-server-mail-agent'

If you have feedback or need assistance with the MCP directory API, please join our Discord server