mcp-imap
by andrewmalov
README.md
# MCP IMAP E-mail Server
[English](#english) | [Русский](#русский)
---
<a name="english"></a>
# English
MCP (Model Context Protocol) server for email operations via IMAP and SMTP protocols. This server enables AI agents to interact with email accounts through a standardized interface. Yandex.Mail is default mail server.
## Features
- **List mailboxes**: Enumerate available email folders
- **Search emails**: Find emails by various criteria (subject, sender, date, etc.)
- **Retrieve emails**: Get full email content including body and attachments
- **Send emails**: Compose and send email messages with optional attachments
- **Manage emails**: Mark emails as read, delete emails
## Architecture
The MCP Email Server is built using the [official MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) and follows the Model Context Protocol specification. It communicates via JSON-RPC 2.0 over stdin/stdout, making it compatible with any MCP client.
### Components
- **MCP Server** (`src/mcp_server/server.py`): Main server implementation using MCP SDK
- **IMAP Tools** (`src/mcp_server/tools/imap_tools.py`): Email retrieval and management operations
- **SMTP Tools** (`src/mcp_server/tools/smtp_tools.py`): Email sending operations
- **Configuration** (`src/mcp_server/config/settings.py`): Environment-based configuration management
- **Error Handling** (`src/mcp_server/errors.py`): Custom error hierarchy with proper error codes
### Connection Management
- **IMAPConnectionManager**: Async context manager for IMAP connections with automatic cleanup
- **SMTPConnectionManager**: Async context manager for SMTP connections with TLS/SSL support
- Both managers handle authentication, connection errors, and timeouts automatically
### Design Patterns
- **Async/Await**: All I/O operations are asynchronous for better performance
- **Context Managers**: Connection lifecycle management with automatic cleanup
- **Type Safety**: Pydantic models for request/response validation
- **Structured Logging**: JSON-formatted logs for better observability
## Quick Start
### Prerequisites
- Docker installed and running
- Email account credentials (username, password/app password)
- IMAP/SMTP server information (defaults to Yandex Mail)
### Installation
1. **Create environment file** (`.env`):
```bash
# Required - Email account credentials
IMAP_USERNAME=your_email@yandex.ru
IMAP_PASSWORD=your_app_password
# Optional - Server configuration (defaults shown)
IMAP_HOST=imap.yandex.ru
IMAP_PORT=993
SMTP_HOST=smtp.yandex.ru
SMTP_PORT=465
SMTP_USE_TLS=true
# Optional - Logging
LOG_LEVEL=INFO
```
**Security Note**: For Yandex Mail, use an [application password](https://yandex.ru/support/id/authorization/app-passwords.html) instead of your main account password.
2. **Build Docker image**:
```bash
docker build -t mcp-email-server .
```
3. **Run container**:
```bash
docker run --rm -i --env-file .env mcp-email-server
```
The server communicates via JSON-RPC 2.0 over stdin/stdout (MCP protocol).
## Using with MCP Clients
The MCP Email Server is compatible with any MCP client. Below are configuration examples for popular clients.
### Claude Desktop
1. **Locate 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`
2. **Add MCP Email Server configuration**:
```json
{
"mcpServers": {
"email": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"--env-file",
"/absolute/path/to/.env",
"mcp-email-server"
]
}
}
}
```
**Important**: Use absolute path to your `.env` file. On Windows, use forward slashes or escaped backslashes:
- Windows example: `"C:/Users/YourName/.env"` or `"C:\\\\Users\\\\YourName\\\\.env"`
3. **Restart Claude Desktop** to load the new configuration.
4. **Verify connection**: Open Claude Desktop and check that the email server appears in the MCP servers list.
### Cherry Studio
1. **Open Cherry Studio Settings** → **MCP Servers**
2. **Add new server** with the following configuration:
```json
{
"name": "Email Server",
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"--env-file",
"/absolute/path/to/.env",
"mcp-email-server"
]
}
```
3. **Save configuration** and restart Cherry Studio.
### Cline (VS Code Extension)
1. **Install Cline extension** in VS Code
2. **Open VS Code settings** (`.vscode/settings.json` or User Settings)
3. **Add MCP server configuration**:
```json
{
"cline.mcpServers": {
"email": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"--env-file",
"${workspaceFolder}/.env",
"mcp-email-server"
]
}
}
}
```
### MCP Inspector (Testing Tool)
MCP Inspector is a web-based tool for testing MCP servers:
1. **Install MCP Inspector**:
```bash
npm install -g @modelcontextprotocol/inspector
```
2. **Run inspector**:
```bash
mcp-inspector docker run --rm -i --env-file .env mcp-email-server
```
3. **Open browser** to the URL shown in the terminal (usually `http://localhost:3000`)
### Custom Client Integration
For custom clients or direct integration, the server communicates via JSON-RPC 2.0 over stdin/stdout:
**Connection Setup**:
```python
import subprocess
import json
# Start server process
process = subprocess.Popen(
["docker", "run", "--rm", "-i", "--env-file", ".env", "mcp-email-server"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
text=True
)
# Step 1: Initialize
init_request = {
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {"name": "my-client", "version": "1.0.0"}
}
}
process.stdin.write(json.dumps(init_request) + "\n")
process.stdin.flush()
# Read initialize response
init_response = json.loads(process.stdout.readline())
print("Initialized:", init_response)
# Step 2: List available tools
tools_request = {
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}
process.stdin.write(json.dumps(tools_request) + "\n")
process.stdin.flush()
tools_response = json.loads(process.stdout.readline())
print("Available tools:", tools_response)
# Step 3: Call a tool
tool_request = {
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "list_mailboxes",
"arguments": {}
}
}
process.stdin.write(json.dumps(tool_request) + "\n")
process.stdin.flush()
tool_response = json.loads(process.stdout.readline())
print("Tool result:", tool_response)
```
### Troubleshooting Client Connections
**Common Issues**:
1. **Server not appearing in client**:
- Verify Docker image is built: `docker images | grep mcp-email-server`
- Check `.env` file path is absolute and correct
- Verify `.env` file has correct permissions (readable)
2. **Authentication errors**:
- Ensure `.env` file contains valid credentials
- For Yandex Mail, use application password, not main password
- Check IMAP/SMTP are enabled in your email account settings
3. **Connection timeouts**:
- Verify IMAP_HOST and SMTP_HOST are correct
- Check firewall settings allow outbound connections
- Try increasing `CONNECTION_TIMEOUT` in `.env`
4. **Permission errors**:
- Ensure Docker has permission to read `.env` file
- On Linux/macOS: `chmod 600 .env` (restrict permissions for security)
## Configuration
### Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `IMAP_USERNAME` | Yes | - | Email account username |
| `IMAP_PASSWORD` | Yes | - | Email account password (use app password) |
| `IMAP_HOST` | No | `imap.yandex.ru` | IMAP server hostname |
| `IMAP_PORT` | No | `993` | IMAP server port |
| `SMTP_HOST` | No | `smtp.yandex.ru` | SMTP server hostname |
| `SMTP_PORT` | No | `465` | SMTP server port (465 for SSL, 587 for TLS) |
| `SMTP_USE_TLS` | No | `true` | Use TLS for SMTP |
| `LOG_LEVEL` | No | `INFO` | Logging level (DEBUG, INFO, WARN, ERROR) |
| `CONNECTION_TIMEOUT` | No | `30` | Connection timeout in seconds |
### Using Different Email Providers
#### Gmail
```bash
IMAP_HOST=imap.gmail.com
IMAP_PORT=993
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USE_TLS=true
```
#### Outlook/Office 365
```bash
IMAP_HOST=outlook.office365.com
IMAP_PORT=993
SMTP_HOST=smtp.office365.com
SMTP_PORT=587
SMTP_USE_TLS=true
```
## MCP Tools
The server exposes the following MCP tools:
1. **list_mailboxes**: List all available mailboxes
2. **search_emails**: Search emails by various criteria
3. **get_email**: Retrieve full email with body and attachments
4. **send_email**: Send email messages
5. **mark_email_read**: Mark email as read
6. **delete_email**: Delete emails
See [contracts/tools.md](specs/001-mcp-email-server/contracts/tools.md) for detailed API documentation.
### Additional Documentation
- **Architecture**: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) - System architecture and design patterns
- **Testing**: [docs/TESTING.md](docs/TESTING.md) - Test suite documentation and guidelines
- **Contributing**: [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) - Contribution guidelines and development setup
## Development
### Requirements
- Python 3.11+
- Docker (for containerization)
### Local Development
1. Install dependencies:
```bash
pip install -r requirements.txt
```
2. Set environment variables (see Configuration section)
3. Run server:
```bash
python -m mcp_server.server
```
### Testing
The project includes a comprehensive test suite with unit and integration tests.
#### Running Tests
```bash
# Install test dependencies
pip install -e ".[dev]"
# Run all tests
pytest
# Run with coverage
pytest --cov=mcp_server --cov-report=html
# Run specific test file
pytest tests/unit/test_imap_tools.py
# Run with verbose output
pytest -v
```
#### Test Structure
- **Unit Tests** (`tests/unit/`): Test individual components in isolation
- `test_server_sdk.py`: MCP server tests
- `test_imap_tools.py`: IMAP operation tests
- `test_smtp_tools.py`: SMTP operation tests
- `test_config.py`: Configuration tests
- `test_errors.py`: Error handling tests
- **Integration Tests** (`tests/integration/`): Test end-to-end server functionality
- `test_server_sdk_integration.py`: Full server lifecycle tests
- **Fixtures** (`tests/fixtures/`): Reusable test data and mocks
- `imap_responses.py`: Mock IMAP responses
- `smtp_responses.py`: Mock SMTP responses
- `email_samples.py`: Sample email data
#### Writing Tests
Tests use `pytest` with `pytest-asyncio` for async support. Mock IMAP/SMTP clients are provided via fixtures to avoid requiring actual email servers.
Example test:
```python
@pytest.mark.asyncio
async def test_list_mailboxes(mock_config, mock_imap_client):
with patch("mcp_server.tools.imap_tools.aioimaplib.IMAP4_SSL", return_value=mock_imap_client):
with patch("mcp_server.tools.imap_tools.get_config", return_value=mock_config):
result = await list_mailboxes({})
assert "mailboxes" in result
```
See [tests/README.md](tests/README.md) for more details on writing tests.
## Contributing
We welcome contributions! Please follow these guidelines:
### Development Setup
1. **Fork and clone the repository**:
```bash
git clone https://github.com/your-username/mcp-imap.git
cd mcp-imap
```
2. **Create a virtual environment**:
```bash
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
```
3. **Install dependencies**:
```bash
pip install -e ".[dev]"
```
4. **Set up pre-commit hooks** (optional):
```bash
pre-commit install
```
### Code Style
The project uses:
- **ruff**: Linting and code formatting
- **black**: Code formatting (via ruff)
- **mypy**: Type checking
Run checks:
```bash
ruff check .
ruff format .
mypy src/
```
### Pull Request Process
1. Create a feature branch from `main`
2. Make your changes with tests
3. Ensure all tests pass: `pytest`
4. Run code quality checks: `ruff check . && mypy src/`
5. Update documentation if needed
6. Submit a pull request with a clear description
### Issue Reporting
When reporting issues, please include:
- Description of the problem
- Steps to reproduce
- Expected vs actual behavior
- Environment details (Python version, OS, email provider)
- Relevant logs (with credentials redacted)
## Troubleshooting
### Common Issues
#### Authentication Failures
**Symptoms**: "Authentication failed" or "LOGIN failed" errors
**Solutions**:
1. Verify credentials are correct in `.env` file
2. For Yandex Mail: Use [application password](https://yandex.ru/support/id/authorization/app-passwords.html), not main password
3. For Gmail: Enable "App Passwords" in account settings
4. Check if 2FA requires app-specific password
5. Verify `IMAP_USERNAME` matches email address exactly
#### Connection Timeouts
**Symptoms**: "Connection timeout" or "Connection failed" errors
**Solutions**:
1. Verify IMAP/SMTP host and port are correct for your provider
2. Check firewall allows outbound connections on ports 993 (IMAP), 465/587 (SMTP)
3. Try different port:
- Port 465: SSL/TLS (use `SMTP_USE_TLS=true`)
- Port 587: STARTTLS (use `SMTP_USE_TLS=true`)
4. Increase timeout: `CONNECTION_TIMEOUT=60`
5. Check network connectivity: `telnet imap.yandex.ru 993`
#### Email Not Sending
**Symptoms**: SMTP send operations fail
**Solutions**:
1. Verify SMTP credentials match IMAP credentials
2. Check port matches encryption:
- Port 465: SSL (implicit TLS)
- Port 587: STARTTLS (explicit TLS)
3. Ensure `SMTP_USE_TLS` matches port configuration
4. Check server logs for specific error messages
5. Verify sender address matches authenticated account
#### Email Not Found
**Symptoms**: "Email UID not found" errors
**Solutions**:
1. Verify UID is correct (UIDs are mailbox-specific)
2. Check mailbox name is correct (case-sensitive)
3. Email may have been moved or deleted
4. Try searching for email first to get current UID
### Debug Logging
Enable detailed logging to troubleshoot issues:
```bash
LOG_LEVEL=DEBUG
```
Logs are output in JSON format to stderr. Example log entry:
```json
{
"host": "imap.yandex.ru",
"port": 993,
"event": "Connecting to IMAP server",
"timestamp": "2026-01-05T10:00:00Z",
"level": "info"
}
```
### Error Codes
The server uses structured error codes:
- `CONNECTION_ERROR`: Network or connection issues
- `AUTHENTICATION_ERROR`: Login/authentication failures
- `NOT_FOUND_ERROR`: Resource not found (email, mailbox)
- `VALIDATION_ERROR`: Invalid input parameters
- `TIMEOUT_ERROR`: Operation timeout
- `SERVER_ERROR`: Internal server error
See [src/mcp_server/errors.py](src/mcp_server/errors.py) for complete error definitions.
## API Reference
### ⚠️ Important: Request Format and Initialization
The server uses **newline-delimited JSON** format. Each JSON-RPC request must be sent as a **single line** terminated with a newline character. Sending JSON across multiple lines will cause parse errors.
**⚠️ CRITICAL: You must initialize the server before calling tools!**
According to the MCP protocol, you must first send an `initialize` request, wait for the response, and only then call tools. The server will reject tool calls sent before initialization.
**Step 1: Initialize the server**
```json
{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test-client", "version": "1.0.0"}}}
```
**Step 2: After receiving initialize response, call tools**
```json
{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "list_mailboxes", "arguments": {}}}
```
**Complete example using echo**:
```bash
# Initialize
echo '{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test-client", "version": "1.0.0"}}}' | docker run --rm -i --env-file .env mcp-email-server
# Then call tool (after initialization completes)
echo '{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "list_mailboxes", "arguments": {}}}' | docker run --rm -i --env-file .env mcp-email-server
```
**Complete example using Python**:
```python
import json
import subprocess
# Start server process
process = subprocess.Popen(
["docker", "run", "--rm", "-i", "--env-file", ".env", "mcp-email-server"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
text=True
)
# Step 1: Initialize
init_request = {
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {"name": "test-client", "version": "1.0.0"}
}
}
process.stdin.write(json.dumps(init_request) + "\n")
process.stdin.flush()
# Read initialize response
init_response = process.stdout.readline()
print("Initialize response:", json.loads(init_response))
# Step 2: Call tool (after initialization)
tool_request = {
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "list_mailboxes",
"arguments": {}
}
}
process.stdin.write(json.dumps(tool_request) + "\n")
process.stdin.flush()
# Read tool response
tool_response = process.stdout.readline()
print("Tool response:", json.loads(tool_response))
```
**Incorrect format** (multiple lines - will cause parse errors):
```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_mailboxes",
"arguments": {}
}
}
```
### Tools Overview
| Tool | Description | Parameters |
|------|-------------|------------|
| `list_mailboxes` | List all mailboxes | None |
| `search_emails` | Search emails by criteria | mailbox, subject, from, to, date_from, date_to, unread_only, has_attachments, limit |
| `get_email` | Retrieve full email | uid, mailbox, include_attachments |
| `send_email` | Send email message | to, subject, body_text, body_html, cc, bcc, attachments, reply_to |
| `mark_email_read` | Mark email as read | uid, mailbox |
| `delete_email` | Delete email | uid, mailbox, permanent |
### Detailed Documentation
- **Tool Contracts**: [specs/001-mcp-email-server/contracts/tools.md](specs/001-mcp-email-server/contracts/tools.md)
- **Data Models**: [specs/001-mcp-email-server/data-model.md](specs/001-mcp-email-server/data-model.md)
- **Quickstart Guide**: [specs/001-mcp-email-server/quickstart.md](specs/001-mcp-email-server/quickstart.md)
### Example Use Cases
#### Use Case 1: Monitor Unread Emails
```python
# 1. List mailboxes
mailboxes = await list_mailboxes({})
# 2. Search for unread emails in INBOX
unread = await search_emails({
"mailbox": "INBOX",
"unread_only": True,
"limit": 10
})
# 3. Get full content of first unread email
if unread["emails"]:
email = await get_email({
"uid": unread["emails"][0]["uid"],
"mailbox": "INBOX"
})
```
#### Use Case 2: Send Automated Response
```python
# 1. Get email to respond to
email = await get_email({"uid": "12345", "mailbox": "INBOX"})
# 2. Send reply
await send_email({
"to": [email["email"]["from"]],
"subject": f"Re: {email['email']['subject']}",
"body_text": "Thank you for your email. This is an automated response.",
"reply_to": email["email"]["message_id"]
})
# 3. Mark original as read
await mark_email_read({"uid": "12345", "mailbox": "INBOX"})
```
## Security
### Best Practices
1. **Use Application Passwords**: Never use your main account password
- Yandex Mail: [Create app password](https://yandex.ru/support/id/authorization/app-passwords.html)
- Gmail: Enable "App Passwords" in Google Account settings
- Outlook: Use app-specific passwords for 2FA accounts
2. **Secure Environment Files**: Protect `.env` files
```bash
chmod 600 .env # Restrict file permissions
```
3. **Docker Secrets**: For production, use Docker secrets instead of `.env` files
```bash
docker secret create imap_password .env
```
4. **TLS/SSL Only**: Never disable TLS in production
- IMAP: Always use port 993 (SSL)
- SMTP: Use port 465 (SSL) or 587 (STARTTLS)
5. **Network Isolation**: Run containers in isolated networks
```bash
docker network create mcp-network
docker run --network mcp-network ...
```
6. **Credential Management**:
- Never commit `.env` files to version control
- Use secret management services in production (AWS Secrets Manager, HashiCorp Vault)
- Rotate passwords regularly
7. **Logging**: Credentials are never logged
- Password fields are redacted in logs
- Enable DEBUG logging only in development
8. **Input Validation**: All inputs are validated using Pydantic schemas
- Email addresses are validated
- UIDs are validated
- File sizes are limited
### Security Features
- ✅ TLS/SSL connections mandatory
- ✅ Credential validation
- ✅ Input sanitization
- ✅ Error message sanitization (no credential leakage)
- ✅ Structured logging (no credential exposure)
- ✅ Connection timeout protection
- ✅ Rate limiting via connection management
## License
MIT
---
<a name="русский"></a>
# Русский
MCP (Model Context Protocol) сервер для работы с электронной почтой через протоколы IMAP и SMTP. Этот сервер позволяет AI-агентам взаимодействовать с почтовыми аккаунтами через стандартизированный интерфейс. По умолчанию используются сервера Яндекс.Почта.
## Возможности
- **Список почтовых ящиков**: Перечисление доступных папок электронной почты
- **Поиск писем**: Поиск писем по различным критериям (тема, отправитель, дата и т.д.)
- **Получение писем**: Получение полного содержимого письма включая тело и вложения
- **Отправка писем**: Составление и отправка писем с опциональными вложениями
- **Управление письмами**: Отметка писем как прочитанных, удаление писем
## Быстрый старт
### Требования
- Установленный и запущенный Docker
- Учетные данные почтового аккаунта (имя пользователя, пароль/пароль приложения)
- Информация о серверах IMAP/SMTP (по умолчанию Яндекс.Почта)
### Установка
1. **Создайте файл окружения** (`.env`):
```bash
# Обязательно - Учетные данные почтового аккаунта
IMAP_USERNAME=ваш_email@yandex.ru
IMAP_PASSWORD=ваш_пароль_приложения
# Опционально - Конфигурация сервера (показаны значения по умолчанию)
IMAP_HOST=imap.yandex.ru
IMAP_PORT=993
SMTP_HOST=smtp.yandex.ru
SMTP_PORT=465
SMTP_USE_TLS=true
# Опционально - Логирование
LOG_LEVEL=INFO
```
**Примечание по безопасности**: Для Яндекс.Почты используйте [пароль приложения](https://yandex.ru/support/id/authorization/app-passwords.html) вместо основного пароля аккаунта.
2. **Соберите Docker образ**:
```bash
docker build -t mcp-email-server .
```
3. **Запустите контейнер**:
```bash
docker run --rm -i --env-file .env mcp-email-server
```
Сервер общается через JSON-RPC 2.0 по stdin/stdout (протокол MCP).
## Использование с MCP клиентами
MCP Email Server совместим с любыми MCP клиентами. Ниже приведены примеры конфигурации для популярных клиентов.
### Claude Desktop
1. **Найдите файл конфигурации Claude Desktop**:
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
2. **Добавьте конфигурацию MCP Email Server**:
```json
{
"mcpServers": {
"email": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"--env-file",
"/абсолютный/путь/к/.env",
"mcp-email-server"
]
}
}
}
```
**Важно**: Используйте абсолютный путь к файлу `.env`. В Windows используйте прямые слеши или экранированные обратные слеши:
- Пример для Windows: `"C:/Users/ВашеИмя/.env"` или `"C:\\\\Users\\\\ВашеИмя\\\\.env"`
3. **Перезапустите Claude Desktop** для загрузки новой конфигурации.
4. **Проверьте подключение**: Откройте Claude Desktop и убедитесь, что email сервер появился в списке MCP серверов.
### Cherry Studio
1. **Откройте настройки Cherry Studio** → **MCP Servers**
2. **Добавьте новый сервер** со следующей конфигурацией:
```json
{
"name": "Email Server",
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"--env-file",
"/абсолютный/путь/к/.env",
"mcp-email-server"
]
}
```
3. **Сохраните конфигурацию** и перезапустите Cherry Studio.
### Cline (Расширение VS Code)
1. **Установите расширение Cline** в VS Code
2. **Откройте настройки VS Code** (`.vscode/settings.json` или Пользовательские настройки)
3. **Добавьте конфигурацию MCP сервера**:
```json
{
"cline.mcpServers": {
"email": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"--env-file",
"${workspaceFolder}/.env",
"mcp-email-server"
]
}
}
}
```
### MCP Inspector (Инструмент для тестирования)
MCP Inspector — это веб-инструмент для тестирования MCP серверов:
1. **Установите MCP Inspector**:
```bash
npm install -g @modelcontextprotocol/inspector
```
2. **Запустите inspector**:
```bash
mcp-inspector docker run --rm -i --env-file .env mcp-email-server
```
3. **Откройте браузер** по адресу, показанному в терминале (обычно `http://localhost:3000`)
### Интеграция с пользовательскими клиентами
Для пользовательских клиентов или прямой интеграции сервер общается через JSON-RPC 2.0 по stdin/stdout:
**Настройка подключения**:
```python
import subprocess
import json
# Запуск процесса сервера
process = subprocess.Popen(
["docker", "run", "--rm", "-i", "--env-file", ".env", "mcp-email-server"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
text=True
)
# Шаг 1: Инициализация
init_request = {
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {"name": "my-client", "version": "1.0.0"}
}
}
process.stdin.write(json.dumps(init_request) + "\n")
process.stdin.flush()
# Чтение ответа на инициализацию
init_response = json.loads(process.stdout.readline())
print("Инициализирован:", init_response)
# Шаг 2: Список доступных инструментов
tools_request = {
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}
process.stdin.write(json.dumps(tools_request) + "\n")
process.stdin.flush()
tools_response = json.loads(process.stdout.readline())
print("Доступные инструменты:", tools_response)
# Шаг 3: Вызов инструмента
tool_request = {
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "list_mailboxes",
"arguments": {}
}
}
process.stdin.write(json.dumps(tool_request) + "\n")
process.stdin.flush()
tool_response = json.loads(process.stdout.readline())
print("Результат инструмента:", tool_response)
```
### Устранение проблем с подключением клиентов
**Частые проблемы**:
1. **Сервер не появляется в клиенте**:
- Проверьте, что Docker образ собран: `docker images | grep mcp-email-server`
- Проверьте, что путь к файлу `.env` абсолютный и правильный
- Убедитесь, что файл `.env` имеет правильные права доступа (читаемый)
2. **Ошибки аутентификации**:
- Убедитесь, что файл `.env` содержит корректные учетные данные
- Для Яндекс.Почты используйте пароль приложения, а не основной пароль
- Проверьте, что IMAP/SMTP включены в настройках вашего почтового аккаунта
3. **Таймауты подключения**:
- Проверьте, что IMAP_HOST и SMTP_HOST указаны правильно
- Проверьте настройки файрвола, разрешающие исходящие подключения
- Попробуйте увеличить `CONNECTION_TIMEOUT` в `.env`
4. **Ошибки прав доступа**:
- Убедитесь, что Docker имеет права на чтение файла `.env`
- В Linux/macOS: `chmod 600 .env` (ограничить права доступа для безопасности)
## Конфигурация
### Переменные окружения
| Переменная | Обязательна | По умолчанию | Описание |
|------------|-------------|--------------|----------|
| `IMAP_USERNAME` | Да | - | Имя пользователя почтового аккаунта |
| `IMAP_PASSWORD` | Да | - | Пароль почтового аккаунта (используйте пароль приложения) |
| `IMAP_HOST` | Нет | `imap.yandex.ru` | Имя хоста IMAP сервера |
| `IMAP_PORT` | Нет | `993` | Порт IMAP сервера |
| `SMTP_HOST` | Нет | `smtp.yandex.ru` | Имя хоста SMTP сервера |
| `SMTP_PORT` | Нет | `465` | Порт SMTP сервера (465 для SSL, 587 для TLS) |
| `SMTP_USE_TLS` | Нет | `true` | Использовать TLS для SMTP |
| `LOG_LEVEL` | Нет | `INFO` | Уровень логирования (DEBUG, INFO, WARN, ERROR) |
| `CONNECTION_TIMEOUT` | Нет | `30` | Таймаут подключения в секундах |
### Использование различных почтовых провайдеров
#### Gmail
```bash
IMAP_HOST=imap.gmail.com
IMAP_PORT=993
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USE_TLS=true
```
#### Outlook/Office 365
```bash
IMAP_HOST=outlook.office365.com
IMAP_PORT=993
SMTP_HOST=smtp.office365.com
SMTP_PORT=587
SMTP_USE_TLS=true
```
## MCP Инструменты
Сервер предоставляет следующие MCP инструменты:
1. **list_mailboxes**: Список всех доступных почтовых ящиков
2. **search_emails**: Поиск писем по различным критериям
3. **get_email**: Получение полного письма с телом и вложениями
4. **send_email**: Отправка писем
5. **mark_email_read**: Отметка письма как прочитанного
6. **delete_email**: Удаление писем
Подробная документация API доступна в [contracts/tools.md](specs/001-mcp-email-server/contracts/tools.md).
## Примеры запросов
### ⚠️ Важно: Инициализация сервера
**Перед вызовом инструментов необходимо выполнить инициализацию сервера!**
Согласно протоколу MCP, сначала нужно отправить запрос `initialize`, дождаться ответа, и только после этого вызывать инструменты. Сервер отклонит вызовы инструментов, отправленные до инициализации.
**Шаг 1: Инициализация сервера**
```json
{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test-client", "version": "1.0.0"}}}
```
**Шаг 2: После получения ответа на initialize, вызывайте инструменты**
```json
{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "list_mailboxes", "arguments": {}}}
```
**Полный пример с использованием echo:**
```bash
# Инициализация
echo '{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test-client", "version": "1.0.0"}}}' | docker run --rm -i --env-file .env mcp-email-server
# Затем вызов инструмента (после завершения инициализации)
echo '{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "list_mailboxes", "arguments": {}}}' | docker run --rm -i --env-file .env mcp-email-server
```
**Полный пример с использованием Python:**
```python
import json
import subprocess
# Запуск процесса сервера
process = subprocess.Popen(
["docker", "run", "--rm", "-i", "--env-file", ".env", "mcp-email-server"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
text=True
)
# Шаг 1: Инициализация
init_request = {
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {"name": "test-client", "version": "1.0.0"}
}
}
process.stdin.write(json.dumps(init_request) + "\n")
process.stdin.flush()
# Чтение ответа на инициализацию
init_response = process.stdout.readline()
print("Ответ на инициализацию:", json.loads(init_response))
# Шаг 2: Вызов инструмента (после инициализации)
tool_request = {
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "list_mailboxes",
"arguments": {}
}
}
process.stdin.write(json.dumps(tool_request) + "\n")
process.stdin.flush()
# Чтение ответа на вызов инструмента
tool_response = process.stdout.readline()
print("Ответ инструмента:", json.loads(tool_response))
```
### 1. Список почтовых ящиков
**Запрос (после инициализации):**
```json
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "list_mailboxes",
"arguments": {}
}
}
```
**Ответ:**
```json
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"mailboxes": [
{
"name": "INBOX",
"message_count": 42,
"unread_count": 5
},
{
"name": "Sent",
"message_count": 123,
"unread_count": 0
}
]
}
}
```
### 2. Поиск писем
**Запрос:**
```json
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "search_emails",
"arguments": {
"mailbox": "INBOX",
"subject": "важно",
"unread_only": true,
"limit": 10
}
}
}
```
**Ответ:**
```json
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"emails": [
{
"uid": "12345",
"subject": "Важное обновление",
"from": "sender@example.com",
"date": "2026-01-04T10:30:00Z",
"flags": []
}
],
"total_count": 3,
"returned_count": 3
}
}
```
### 3. Получение письма
**Запрос:**
```json
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_email",
"arguments": {
"uid": "12345",
"mailbox": "INBOX",
"include_attachments": true
}
}
}
```
**Ответ:**
```json
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"email": {
"uid": "12345",
"subject": "Важное обновление",
"from": "sender@example.com",
"to": ["you@yandex.ru"],
"date": "2026-01-04T10:30:00Z",
"body_text": "Содержимое письма...",
"body_html": "<p>Содержимое письма...</p>",
"attachments": [],
"flags": []
}
}
}
```
### 4. Отправка письма
**Запрос:**
```json
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "send_email",
"arguments": {
"to": ["recipient@example.com"],
"subject": "Тестовое письмо",
"body_text": "Это тестовое письмо, отправленное через MCP сервер.",
"body_html": "<p>Это тестовое письмо, отправленное через MCP сервер.</p>"
}
}
}
```
**Ответ:**
```json
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"message_id": "<unique-message-id@server>",
"sent_at": "2026-01-04T11:00:00Z"
}
}
```
### 5. Отметка письма как прочитанного
**Запрос:**
```json
{
"jsonrpc": "2.0",
"id": 5,
"method": "tools/call",
"params": {
"name": "mark_email_read",
"arguments": {
"uid": "12345",
"mailbox": "INBOX"
}
}
}
```
**Ответ:**
```json
{
"jsonrpc": "2.0",
"id": 5,
"result": {
"success": true,
"uid": "12345"
}
}
```
### 6. Удаление письма
**Запрос:**
```json
{
"jsonrpc": "2.0",
"id": 6,
"method": "tools/call",
"params": {
"name": "delete_email",
"arguments": {
"uid": "12345",
"mailbox": "INBOX",
"permanent": false
}
}
}
```
**Ответ:**
```json
{
"jsonrpc": "2.0",
"id": 6,
"result": {
"success": true,
"uid": "12345"
}
}
```
## Разработка
### Требования
- Python 3.11+
- Docker (для контейнеризации)
### Локальная разработка
1. Установите зависимости:
```bash
pip install -r requirements.txt
```
2. Установите переменные окружения (см. раздел Конфигурация)
3. Запустите сервер:
```bash
python -m mcp_server.server
```
### Тестирование
```bash
pytest
```
## Безопасность
- Все учетные данные предоставляются через переменные окружения (никогда не захардкожены)
- Подключения TLS/SSL обязательны для IMAP и SMTP
- Пароли приложений рекомендуются для почтовых провайдеров
- Учетные данные не логируются в открытом виде
## Лицензия
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues