Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Mail Cal Drive

БесплатноНе проверен

A self-hosted MCP server for managing email, calendar, and cloud storage across Microsoft 365, Google Workspace, and IMAP accounts, enabling natural language in

GitHubEmbed

Описание

A self-hosted MCP server for managing email, calendar, and cloud storage across Microsoft 365, Google Workspace, and IMAP accounts, enabling natural language interaction through any MCP client.

README

License: MIT Node.js Docker MCP

A self-hosted Model Context Protocol (MCP) server for multi-account email, calendar, and cloud storage. Connect Microsoft 365, Google Workspace, and IMAP accounts to any MCP client — Claude Desktop, Claude Code, VS Code, Cursor, and more.

Runs locally in Docker with Postgres. Credentials encrypted at rest. Survives reboots without re-authorization.

Provider Email Calendar Drive
Microsoft 365 ✅ OneDrive
Google Workspace ✅ Google Drive
IMAP

Prerequisites

Quick Start

# 1. Clone
git clone https://github.com/rumbitopi/mail-cal-drive-mcp.git
cd mail-cal-drive-mcp

# 2. Configure
cp .env.example .env

# 3. Generate keys (run 3 times — one for each)
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Paste into .env as POSTGRES_PASSWORD, CREDENTIAL_ENCRYPTION_KEY, and API_KEY
# Update DATABASE_URL to use the same POSTGRES_PASSWORD

# 4. Start (server runs with zero providers — configure them later)
docker compose up --build -d

# 5. Verify health
curl http://localhost:3100/health

# 6. Verify MCP
curl -X POST http://localhost:3100/mcp \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}},"id":1}'

Architecture

┌──────────────────────────────────────────────┐
│  Docker Compose                              │
│  ┌─────────────┐    ┌──────────────┐         │
│  │ workspace   │◄──►│ postgres:5432│         │
│  │ -mcp :3100  │    │ (persistent) │         │
│  │ Streamable  │    └──────────────┘         │
│  │ HTTP + Auth │                             │
│  └─────────────┘                             │
└──────────────────────────────────────────────┘

Protocol: MCP over Streamable HTTP (2024-11-05), MCP SDK 1.25.3

What persists across reboots (in Postgres):

  • Credentials (AES-256-GCM encrypted)
  • MSAL token cache (silent Microsoft refresh — no re-auth)
  • Pending auth flows (survive restarts mid-auth)

What's ephemeral (in memory):

  • MCP sessions (clients auto-reconnect)

Client Configuration

Claude Desktop

Claude Desktop speaks stdio, not HTTP. supergateway bridges the two.

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "workspace": {
      "command": "npx",
      "args": [
        "-y", "supergateway",
        "--streamableHttp", "http://localhost:3100/mcp",
        "--header", "Authorization: Bearer YOUR_API_KEY"
      ]
    }
  }
}

Claude Code

Add to .claude/settings.local.json in your project:

{
  "mcpServers": {
    "workspace": {
      "type": "streamable-http",
      "url": "http://localhost:3100/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

VS Code (GitHub Copilot)

Add to .vscode/settings.json:

{
  "github.copilot.chat.mcpServers": {
    "workspace": {
      "type": "streamable-http",
      "url": "http://localhost:3100/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

Cursor

Add to .cursor/mcp.json:

{
  "mcpServers": {
    "workspace": {
      "url": "http://localhost:3100/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

Provider Setup

Microsoft 365

Uses device code flow — no redirect URI needed.

Azure App Registration

  1. Go to Azure PortalAzure Active DirectoryApp registrationsNew registration
  2. Name: Workspace MCP (or anything)
  3. Supported account types: "Accounts in any organizational directory and personal Microsoft accounts"
  4. Redirect URI: Leave blank
  5. Click Register

Enable Public Client Flow

  1. Go to your app → Authentication
  2. Under Advanced settings, set "Allow public client flows" to Yes
  3. Click Save

Add API Permissions

  1. Go to API permissionsAdd a permissionMicrosoft GraphDelegated permissions
  2. Add:
    • Mail.ReadWrite, Mail.Send
    • Calendars.ReadWrite, Calendars.Read.Shared
    • Files.ReadWrite, Files.ReadWrite.All
    • User.Read, offline_access
  3. Click "Grant admin consent" if you're an admin

Configure .env

MS_ENABLED=true
MS_CLIENT_ID=<Application (client) ID from Overview page>
MS_TENANT_ID=<Directory (tenant) ID, or "common" for multi-tenant>

Connect

Call auth_start with provider: "microsoft". You'll get a URL and code. Visit the URL, enter the code, sign in. Then call auth_complete. One-time setup — refresh tokens persist across reboots.


Google Workspace

Uses OAuth callback flow — requires a redirect URI.

Google Cloud Setup

  1. Go to Google Cloud Console → create or select a project
  2. Enable APIs: Gmail API, Google Calendar API, Google Drive API
  3. OAuth consent screen:
    • User Type: External (or Internal for Workspace)
    • Add scopes: gmail.modify, gmail.labels, calendar, calendar.events, drive, drive.file
    • Add yourself as a test user
  4. CredentialsCreate OAuth client ID:
    • Type: Web application
    • Redirect URI: http://localhost:3100/auth/google/callback

Configure .env

GOOGLE_ENABLED=true
GOOGLE_CLIENT_ID=<Client ID>
GOOGLE_CLIENT_SECRET=<Client Secret>
GOOGLE_REDIRECT_URI=http://localhost:3100/auth/google/callback

Connect

Call auth_start with provider: "google". Open the URL, sign in, grant permissions. The callback saves your tokens. Then call auth_complete. One-time setup.


IMAP

No external setup needed — provide credentials directly.

Connect

Call auth_start with:

provider: "imap"
accountName: "Personal Email"
email: "[email protected]"
imapHost: "imap.example.com"
imapPort: 993
imapUsername: "[email protected]"
imapPassword: "your-app-password"
imapTls: true

No auth_complete needed — IMAP accounts are ready immediately.

Common IMAP Servers

Provider Host Port Notes
Gmail imap.gmail.com 993 Requires App Password
Outlook/Hotmail outlook.office365.com 993 Requires App Password
Yahoo imap.mail.yahoo.com 993 Requires App Password
Fastmail imap.fastmail.com 993 Requires App Password

MCP Tools (36 total)

Authentication (4)

Tool Description
auth_status List all accounts with connection status
auth_start Start OAuth/device code flow or IMAP setup
auth_complete Complete pending authentication
auth_revoke Remove an account

Email (10)

Tool Description
list_accounts List all configured email accounts
list_folders Get folders/labels for an account
list_messages Messages with pagination
get_message Full message with body and attachments
get_attachment Download attachment (text decoded, binary as blob)
search_messages Search with filters (see parameters below)
move_message Move to folder
delete_message Trash or permanent delete
mark_read Mark read/unread
bulk_mail_action Batch operations with dry-run support

Calendar (8)

Tool Description
list_calendars All calendars for an account
list_events Events in a date range
get_event Full event details
create_event Create with attendees, recurrence, conferencing
update_event Modify existing event
delete_event Delete event
find_free_time Find available time slots across accounts
check_conflicts Detect scheduling conflicts

Drive (14)

Tool Description
list_files List files and folders
get_file File metadata
get_file_content Download file content
search_files Search by name, content, or type
upload_file Upload new file (text or base64)
create_folder Create folder
move_file Move file/folder
copy_file Copy file
rename_file Rename file/folder
delete_file Delete (trash or permanent)
get_sharing View sharing permissions
share_file Share with user or create link
unshare_file Remove sharing
get_storage_quota Storage usage info

Tool Parameter Reference

get_attachment

Parameter Type Required Description
accountId string Yes Account ID
messageId string Yes Message ID
attachmentId string Yes Attachment ID from get_message

Returns text content for text-based files, or an MCP EmbeddedResource with blob for binary files (PDF, images, etc.). Max 5MB.

search_messages

Parameter Type Required Description
accountIds string[] Yes Account IDs to search
from string No Filter by sender email
to string No Filter by recipient email
subject string No Filter by subject (partial match)
body string No Search in message body
folder string No Limit to specific folder
hasAttachment boolean No Filter by attachment presence
isRead boolean No Filter by read status
isStarred boolean No Filter by starred status
after string No Messages after date (ISO 8601)
before string No Messages before date (ISO 8601)
labels string[] No Filter by labels (Gmail)
limit number No Max results per account (default: 50)

create_event

Parameter Type Required Description
accountId string Yes Account ID
title string Yes Event title
startTime string Yes Start time (ISO 8601)
endTime string Yes End time (ISO 8601)
calendarId string No Calendar ID (default: primary)
description string No Event description
location string No Event location
isAllDay boolean No All-day event
timeZone string No Time zone (default: UTC)
attendees array No [{email, optional?}]
visibility string No "public" or "private"
addConference boolean No Add video conference link

bulk_mail_action

Parameter Type Required Description
accountId string Yes Account ID
action string Yes "move", "delete", "markRead", "markUnread", "star", "unstar", "archive"
dryRun boolean No Preview without executing (default: false)
targetFolder string No Destination folder (required for "move")
from string No Filter by sender
subject string No Filter by subject
folder string No Limit to folder
isRead boolean No Filter by read status
after string No After date (ISO 8601)
before string No Before date (ISO 8601)
limit number No Max messages to process

find_free_time

Parameter Type Required Description
accountIds string[] Yes Account IDs to check
startDate string Yes Start of range (ISO 8601)
endDate string Yes End of range (ISO 8601)
duration number Yes Required duration in minutes
calendarIds string[] No Calendars to check (default: primary)

upload_file

Parameter Type Required Description
accountId string Yes Account ID
name string Yes File name
content string Yes File content (text or base64)
folderId string No Parent folder ID (default: root)
mimeType string No MIME type
isBase64 boolean No Content is base64 encoded

share_file

Parameter Type Required Description
accountId string Yes Account ID
fileId string Yes File ID
type string Yes "user", "group", or "anyone"
role string Yes "reader", "writer", or "commenter"
email string No Email (required for user/group)
sendNotification boolean No Send email notification
message string No Notification message

Environment Variables

Variable Required Default Description
DATABASE_URL Yes Postgres connection string
POSTGRES_PASSWORD Yes Postgres password (used by Docker Compose)
CREDENTIAL_ENCRYPTION_KEY Yes 64 hex chars (32 bytes) for AES-256-GCM
API_KEY Yes Min 32 chars, used as Bearer token
NODE_ENV No development development or production
MCP_PORT No 3100 Server port
LOG_LEVEL No info error, warn, info, debug
MS_ENABLED No false Enable Microsoft 365
MS_CLIENT_ID If MS Azure App client ID
MS_TENANT_ID If MS common Azure tenant ID
GOOGLE_ENABLED No false Enable Google Workspace
GOOGLE_CLIENT_ID If Google OAuth client ID
GOOGLE_CLIENT_SECRET If Google OAuth client secret
GOOGLE_REDIRECT_URI If Google OAuth callback URL
IMAP_ENABLED No true Enable IMAP provider

Endpoints

Endpoint Method Auth Description
/health GET No Health check
/mcp POST Bearer MCP JSON-RPC endpoint
/mcp GET Bearer SSE stream for notifications
/mcp DELETE Bearer Session cleanup
/auth/google/callback GET No Google OAuth redirect handler

Security

This server is designed for localhost use only. Do not expose it to the internet without additional hardening.

  • Encryption at rest: All credentials, MSAL token cache, and pending auth flows encrypted with AES-256-GCM before storage in Postgres
  • Bearer auth: Timing-safe token comparison (crypto.timingSafeEqual) on all protected endpoints
  • Session limits: Max 100 concurrent sessions, 30-minute TTL with automatic eviction
  • Network: Binds to 127.0.0.1 only — not accessible from other machines
  • Body size: 10MB request limit to prevent memory exhaustion
  • IMAP note: IMAP credentials are passwords (not OAuth tokens) — encrypted at rest, but inherently less secure than OAuth. Use app passwords where possible.
  • Logging: All logs to stderr (MCP requirement). No tokens, passwords, or keys logged.
  • Token rotation: To rotate the encryption key, generate a new one, re-run auth_start for each account, and update .env. There is no in-place re-encryption (accounts must be re-authorized).

See SECURITY.md for vulnerability reporting.

Troubleshooting

Container won't start

  • Check docker compose logs workspace-mcp for errors
  • Verify DATABASE_URL matches the Postgres container credentials
  • Ensure Postgres is healthy: docker compose logs postgres

Microsoft device code expired

  • Device codes expire after 15 minutes. Call auth_start again for a fresh code.

Google OAuth: "Access blocked" or consent screen issues

  • Make sure your Google Cloud app is in "Testing" mode with your email added as a test user
  • Verify the redirect URI in Google Cloud Console matches GOOGLE_REDIRECT_URI exactly

IMAP connection refused

  • Verify host, port, and TLS settings for your provider
  • Most providers require an App Password when 2FA is enabled (not your regular password)
  • Check if your provider blocks third-party IMAP access (Gmail: enable "Less secure apps" or use App Password)

"Invalid or expired session" on tool calls

  • MCP sessions expire after 30 minutes of inactivity and are lost on container restart. Your client should auto-reconnect. If not, restart the client.

Development

# Install dependencies
npm install

# Start with hot reload (requires local Postgres on DATABASE_URL)
npm run dev

# Build TypeScript
npm run build

# Production start
npm start

# Run tests
npm test

# Type check
npm run typecheck

# Migrate credentials from old file-based storage
DATABASE_URL=... CREDENTIAL_ENCRYPTION_KEY=... npm run migrate

Project Structure

mail-cal-drive-mcp/
├── src/
│   ├── index.ts              # Entry point
│   ├── server.ts             # Express server
│   ├── config.ts             # Environment config
│   ├── logger.ts             # Structured console logger
│   ├── auth/
│   │   ├── types.ts          # Credential interfaces
│   │   ├── storage.ts        # Postgres credential storage
│   │   └── bearer.ts         # Bearer token middleware
│   ├── storage/
│   │   ├── postgres.ts       # Postgres client + encrypted CRUD
│   │   ├── msal-cache.ts     # MSAL cache plugin (Postgres)
│   │   └── pending-flows.ts  # Pending auth flow storage
│   ├── providers/
│   │   ├── base.ts           # Abstract interfaces
│   │   ├── types.ts          # Shared types
│   │   ├── microsoft/        # Graph API (mail, calendar, drive)
│   │   ├── google/           # Google APIs (Gmail, Calendar, Drive)
│   │   └── imap/             # ImapFlow (mail only)
│   ├── mcp/
│   │   ├── handler.ts        # MCP request routing
│   │   ├── session.ts        # Session management
│   │   └── tools/            # 35 MCP tools
│   └── utils/                # Timezone, recurrence, MIME helpers
├── db/migrations/            # Postgres schema
├── docker-compose.yml
├── Dockerfile
└── .env                      # Configuration (gitignored)

License

MIT

from github.com/rumbitopi/mail-cal-drive-mcp

Установка Mail Cal Drive

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/rumbitopi/mail-cal-drive-mcp

FAQ

Mail Cal Drive MCP бесплатный?

Да, Mail Cal Drive MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Mail Cal Drive?

Нет, Mail Cal Drive работает без API-ключей и переменных окружения.

Mail Cal Drive — hosted или self-hosted?

Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.

Как установить Mail Cal Drive в Claude Desktop, Claude Code или Cursor?

Открой Mail Cal Drive на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Mail Cal Drive with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории communication