Skip to main content
Glama
mike-tih

icloud-mcp

by mike-tih
README.md
# iCloud MCP Server

MCP (Model Context Protocol) server for iCloud integration, providing tools for managing calendars (CalDAV), contacts (CardDAV), and email (IMAP/SMTP).

## Features

- **Stateless Architecture**: No state stored between requests
- **Full CRUD Operations**: Complete management of calendars, contacts, and email
- **Flexible Authentication**: Via headers or environment variables
- **Multiple Transports**: stdio (local) or Streamable HTTP (server)
- **Docker Support**: Easy deployment with Docker and Docker Compose

## Supported Operations

### Calendar Tools (CalDAV)
- `calendar_list_calendars` - List all calendars
- `calendar_list_events` - List events with date filtering
- `calendar_create_event` - Create new event
- `calendar_update_event` - Update existing event
- `calendar_delete_event` - Delete event
- `calendar_search_events` - Search events by text

### Contacts Tools (CardDAV)
- `contacts_list` - List all contacts
- `contacts_get` - Get specific contact
- `contacts_create` - Create new contact (name, phones, emails, addresses, organization, title)
- `contacts_update` - Update existing contact
- `contacts_delete` - Delete contact
- `contacts_search` - Search contacts by text

### Email Tools (IMAP/SMTP)
- `email_list_folders` - List mail folders
- `email_list_messages` - List messages in folder
- `email_get_message` - Get full message details
- `email_get_messages` - Get multiple messages at once (bulk fetch)
- `email_search` - Search messages by text
- `email_send` - Send email via SMTP
- `email_move` - Move message to folder
- `email_delete` - Delete or trash message
- `email_mark_read` - Mark message as read
- `email_mark_unread` - Mark message as unread

## Installation

### Prerequisites

- **Python 3.10 - 3.12** (Python 3.13+ not yet supported due to dependency compatibility)
- iCloud account with App-Specific Password ([Generate here](https://appleid.apple.com/account/manage))

### Local Installation

```bash
# Clone repository
git clone <repository-url>
cd icloud-mcp

# Create virtual environment with Python 3.10-3.12
python3.12 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install package in editable mode
pip install -e .

# Configure environment
cp .env.example .env
# Edit .env with your credentials
```

### Docker Installation

```bash
# Clone repository
git clone <repository-url>
cd icloud-mcp

# Configure environment
cp .env.example .env
# Edit .env with your credentials

# Build and run with Docker Compose
docker-compose up -d
```

## Configuration

### Environment Variables

Create a `.env` file with the following variables:

```env
# iCloud Credentials (fallback if not in headers)
ICLOUD_EMAIL=your-email@icloud.com
ICLOUD_APP_SPECIFIC_PASSWORD=xxxx-xxxx-xxxx-xxxx

# iCloud Servers (optional, defaults to standard iCloud servers)
CALDAV_SERVER=https://caldav.icloud.com
CARDDAV_SERVER=https://contacts.icloud.com
IMAP_SERVER=imap.mail.me.com
SMTP_SERVER=smtp.mail.me.com

# Server Configuration
MCP_SERVER_PORT=8000
IMAP_PORT=993
SMTP_PORT=587
```

### Authentication

The server supports two authentication methods (checked in order):

1. **Request Headers** (recommended for multi-user scenarios):
   - `X-Apple-Email`: iCloud email address
   - `X-Apple-App-Specific-Password`: App-specific password

2. **Environment Variables** (fallback):
   - `ICLOUD_EMAIL`
   - `ICLOUD_APP_SPECIFIC_PASSWORD`

If credentials are not found in either location, the server returns a 401 error.

## Usage

### Local Usage (stdio transport)

```bash
# Using Python directly
python run.py

# Or using the module
python -m icloud_mcp.server
```

### Server Usage (Streamable HTTP transport)

```bash
# Using Python
python run.py --http --port 8000

# Using Docker Compose
docker-compose up
```

The server will be available at `http://localhost:8000/mcp`.

## Integration with Claude Desktop

This method allows Claude Desktop to directly launch the MCP server as a subprocess.

**Step 1:** Install dependencies locally:
```bash
pip install -e .
```

**Step 2:** Create a `.env` file with your credentials:
```bash
cp .env.example .env
# Edit .env and add your iCloud credentials
```

**Step 3:** Find your Claude Desktop configuration file:

- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux**: `~/.config/Claude/claude_desktop_config.json`

**Step 4:** Add this configuration (replace the path):

```json
{
  "mcpServers": {
    "icloud": {
      "command": "python",
      "args": ["/absolute/path/to/icloud-mcp/run.py"],
      "network": {
        "enabled": true,
        "allowedDomains": [
          "caldav.icloud.com",
          "contacts.icloud.com",
          "*.contacts.icloud.com",
          "imap.mail.me.com",
          "smtp.mail.me.com"
        ]
      }
    }
  }
}
```

**Important:** Replace `/absolute/path/to/icloud-mcp/` with the actual full path to your project directory.

**Example on macOS:**
```json
{
  "mcpServers": {
    "icloud": {
      "command": "python",
      "args": ["/Users/username/Projects/icloud-mcp/run.py"],
      "network": {
        "enabled": true,
        "allowedDomains": [
          "caldav.icloud.com",
          "contacts.icloud.com",
          "*.contacts.icloud.com",
          "imap.mail.me.com",
          "smtp.mail.me.com"
        ]
      }
    }
  }
}
```

**Note:** The `network.allowedDomains` configuration is **required** for contacts to work properly, as the server needs to access iCloud's CardDAV servers.

**Step 5:** Restart Claude Desktop completely (Quit and reopen)

### Verification

After restarting Claude Desktop:

1. Open Claude Desktop application
2. Look for the šŸ”Ø (tools/hammer) icon in the bottom-right corner
3. You should see "icloud" server listed with green status
4. Try commands like:
   - "List my calendars"
   - "Show my contacts"
   - "Get my unread emails"

### Troubleshooting

**Server doesn't appear:**
- Check JSON syntax in config file (use a JSON validator)
- View logs: Help → Show Logs in Claude Desktop
- Verify the path to `run.py` is absolute (not relative)
- Ensure Python is in your PATH
- Check that you're using Python 3.10-3.12 (not 3.13+)

**401 Authentication errors:**
- Ensure you're using an **App-Specific Password**, not your regular Apple password
- Generate one at: https://appleid.apple.com/account/manage
- Check `.env` file has correct credentials

**Contacts not working (empty results or errors):**
- Ensure you've added the `network.allowedDomains` configuration to Claude Desktop config
- The domains `contacts.icloud.com` and `*.contacts.icloud.com` must be in the allowed list
- Restart Claude Desktop after updating the config

**Tools fail with 500 errors:**
- Check server logs for details
- Verify iCloud credentials are valid
- Ensure network connectivity to iCloud servers

## Architecture

### Stateless Design

The server is fully stateless:
- No sessions or state stored between requests
- Each request contains all necessary authentication information
- Connections to iCloud services are created per-request and closed immediately
- Perfect for horizontal scaling and serverless deployments

### Technical Implementation

- **Transport**: Streamable HTTP protocol with `/mcp` endpoint
- **Calendar (CalDAV)**: Uses `caldav` library for standard CalDAV operations
- **Contacts (CardDAV)**: Direct HTTP/WebDAV implementation using `requests` with proper RFC 6352 CardDAV protocol
- **Email (IMAP/SMTP)**: Uses `imapclient` for IMAP and standard `smtplib` for SMTP
- **Authentication**: Headers via `get_http_headers()` with environment variable fallback

### Security Considerations

- Always use HTTPS in production when using HTTP transport
- Store App-Specific Passwords securely (use secret management tools)
- Consider using header-based authentication for multi-user scenarios
- Never commit `.env` file to version control
- Network access is restricted to allowed iCloud domains only

## Development

### Project Structure

```
icloud-mcp/
ā”œā”€ā”€ src/
│   └── icloud_mcp/
│       ā”œā”€ā”€ __init__.py
│       ā”œā”€ā”€ config.py       # Configuration management
│       ā”œā”€ā”€ auth.py         # Authentication handling
│       ā”œā”€ā”€ calendar.py     # CalDAV tools
│       ā”œā”€ā”€ contacts.py     # CardDAV tools (direct HTTP/WebDAV)
│       ā”œā”€ā”€ email.py        # IMAP/SMTP tools
│       └── server.py       # FastMCP server and tool registration
ā”œā”€ā”€ .env.example            # Example environment configuration
ā”œā”€ā”€ .gitignore
ā”œā”€ā”€ Dockerfile
ā”œā”€ā”€ docker-compose.yml
ā”œā”€ā”€ pyproject.toml          # Python project configuration and dependencies
ā”œā”€ā”€ run.py                  # Entry point script
└── README.md
```

### Running Tests

```bash
# Install development dependencies
pip install -e ".[dev]"

# Run tests (when added)
pytest
```

### Code Formatting

```bash
# Format code
black src/

# Lint code
ruff check src/
```

## License

MIT License - See LICENSE file for details

## Contributing

Contributions are welcome! Please:
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Submit a pull request

## Support

For issues and questions:
- Open an issue on GitHub
- Check existing issues for solutions
- Review iCloud API documentation

## Acknowledgments

Built with:
- [FastMCP](https://github.com/jlowin/fastmcp) - MCP server framework
- [caldav](https://github.com/python-caldav/caldav) - CalDAV library for calendar operations
- [requests](https://github.com/psf/requests) - HTTP library for CardDAV operations
- [IMAPClient](https://github.com/mjs/imapclient) - IMAP library
- [vobject](https://github.com/py-vobject/vobject) - vCard/iCalendar parsing