AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Mail Cal Drive Mcp

mcp-rumbitopi-mail-cal-drive-mcp · by rumbitopi

MCP server from rumbitopi/mail-cal-drive-mcp.

— No reviews yet
0 installs
24 views
0.0% view→install

Install

$ agentstack add mcp-rumbitopi-mail-cal-drive-mcp

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ● Network access Used
  • ✓ Filesystem access No
  • ✓ Shell / process execution No
  • ● Environment & secrets Used
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-rumbitopi-mail-cal-drive-mcp)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
○ 5mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Mail Cal Drive Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

mail-cal-drive-mcp

[](LICENSE) [](https://nodejs.org) [](https://docs.docker.com/compose/) [](https://modelcontextprotocol.io)

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 Portal → Azure Active Directory → App registrations → New 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 permissions → Add a permission → Microsoft Graph → Delegated permissions
  2. Add:
  • Mail.ReadWrite, Mail.Send
  • Calendars.ReadWrite, Calendars.Read.Shared
  • Files.ReadWrite, Files.ReadWrite.All
  • User.Read, offline_access
  1. Click "Grant admin consent" if you're an admin
Configure .env
MS_ENABLED=true
MS_CLIENT_ID=
MS_TENANT_ID=
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
  1. Credentials → Create OAuth client ID:
  • Type: Web application
  • Redirect URI: http://localhost:3100/auth/google/callback
Configure .env
GOOGLE_ENABLED=true
GOOGLE_CLIENT_ID=
GOOGLE_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: "user@example.com"
imapHost: "imap.example.com"
imapPort: 993
imapUsername: "user@example.com"
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 |

bulkmailaction

| 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 |

findfreetime

| 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](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. C

…

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.