Model Context Protocol (MCP) сервер для полной интеграции с Weeek API
Weeek MCP Server — это полнофункциональный MCP сервер на Python, который интегрирует все 71 endpoint Weeek API v1 и предоставляет их как MCP tools для использования с AI-клиентами (Claude Desktop, Perplexity, собственные MCP-клиенты и др.).
- ✅ 71 инструмент — полная интеграция всех endpoint'ов Weeek API
- ✅ Надёжный HTTP-клиент с retry логикой и обработкой ошибок
- ✅ Безопасность — автоматическое сокрытие токенов в логах
- ✅ Типизация — полная поддержка type hints
- ✅ Async/await — асинхронная архитектура
- ✅ Docker поддержка — готовый Dockerfile
- ✅ SSE транспорт — удалённый доступ через HTTP для n8n, web-клиентов
- Python 3.10 или выше
- pip (менеджер пакетов Python)
- Аккаунт Weeek с API токеном
# Клонировать репозиторий
git clone https://github.com/your-repo/weeek-mcp-server.git
cd weeek-mcp-server
# Создать виртуальное окружение
python -m venv venv
source venv/bin/activate # Linux/macOS
# или
venv\Scripts\activate # Windows
# Установить зависимости
pip install -r requirements.txt- Войдите в ваш аккаунт Weeek
- Перейдите в Settings → API
- Нажмите "Add token"
- Дайте токену имя и скопируйте его
# Скопировать пример конфигурации
cp env.example .env
# Отредактировать .env файл
# Вставить ваш токен в WEEEK_TOKENСодержимое .env:
WEEEK_TOKEN=your-api-token-here
WEEEK_BASE_URL=https://api.weeek.net/public/v1
REQUEST_TIMEOUT=30
RETRY_ATTEMPTS=3
LOG_LEVEL=INFOpython -m src.server# Сборка образа
docker build -t weeek-mcp .
# Запуск с передачей токена
docker run -e WEEEK_TOKEN="your-token" -it weeek-mcp
# Или с использованием .env файла
docker run --env-file .env -it weeek-mcp# Создать .env файл из примера
cp env.example .env
# Отредактировать .env и добавить WEEEK_TOKEN
# Запуск
docker-compose up -d
# Или для сборки и запуска
docker-compose up --build -dMCP сервер поддерживает два режима работы:
- stdio (по умолчанию) — для локальных клиентов (Claude Desktop, Cursor)
- sse — для сетевого доступа через HTTP (n8n, удалённые клиенты)
# В .env файле
TRANSPORT=sse
SERVER_HOST=0.0.0.0
SERVER_PORT=3847- Подготовка VPS:
# Склонировать репозиторий на VPS
git clone https://github.com/your-repo/weeek-mcp-server.git
cd weeek-mcp-server
# Создать .env файл
cp env.example .env
nano .env- Настройка .env (ОБЯЗАТЕЛЬНО):
WEEEK_TOKEN=ваш-weeek-api-токен
TRANSPORT=sse
MCP_API_KEY=ваш-секретный-ключ-минимум-32-символаГенерация безопасного API ключа:
python -c "import secrets; print(secrets.token_urlsafe(32))"
# Пример: Kx7mN9pQ2rS5tU8vW0xY3zA6bC9dE2fG- Запуск:
docker-compose up -d --build- Проверка работы:
# Проверить статус
docker-compose ps
# Просмотр логов
docker-compose logs -f
# Проверить health endpoint (без авторизации)
curl http://localhost:3847/health
# Проверить SSE endpoint (с авторизацией)
curl -H "Authorization: Bearer YOUR_MCP_API_KEY" http://localhost:3847/sse| Endpoint | Описание | Авторизация |
|---|---|---|
http://host:3847/sse |
SSE endpoint для подключения MCP клиентов | Требуется |
http://host:3847/messages |
Endpoint для отправки сообщений | Требуется |
http://host:3847/health |
Health check endpoint | Не требуется |
Все запросы к /sse и /messages требуют API ключ. Передавайте его одним из способов:
# Способ 1: Authorization header (рекомендуется)
curl -H "Authorization: Bearer YOUR_MCP_API_KEY" http://host:3847/sse
# Способ 2: X-API-Key header
curl -H "X-API-Key: YOUR_MCP_API_KEY" http://host:3847/messagesЕсли порт 3847 занят, измените в .env:
SERVER_PORT=9999И в docker-compose.yml обновите порты:
ports:
- "9999:9999"-
Убедитесь, что MCP сервер запущен в SSE режиме на VPS
-
В n8n используйте HTTP Request ноду для вызова MCP endpoints:
URL: http://your-vps-ip:3847/messages
Method: POST
Headers:
Content-Type: application/json
Authorization: Bearer YOUR_MCP_API_KEY
Body (JSON):
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_tasks",
"arguments": {
"project_id": "your-project-id",
"limit": 10
}
}
}
-
Настройка HTTP Request ноды в n8n:
- Method: POST
- URL:
http://your-vps-ip:3847/messages - Authentication: Predefined Credential Type → Header Auth
- Name:
Authorization - Value:
Bearer YOUR_MCP_API_KEY
- Name:
- Body Content Type: JSON
-
Пример Code ноды с авторизацией:
// Вызов MCP tool из n8n Code ноды
const MCP_API_KEY = 'your-mcp-api-key'; // Лучше хранить в credentials
const response = await $http.request({
method: 'POST',
url: 'http://your-vps-ip:3847/messages',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${MCP_API_KEY}`
},
body: JSON.stringify({
jsonrpc: '2.0',
id: Date.now(),
method: 'tools/call',
params: {
name: 'create_task',
arguments: {
title: 'Task from n8n',
project_id: 'proj_123',
priority: 'high'
}
}
})
});
return response.data;Создание задачи:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_task",
"arguments": {
"title": "New task from n8n workflow",
"project_id": "7",
"description": "Created automatically",
"priority": "medium"
}
}
}Получение списка проектов:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "list_projects",
"arguments": {
"limit": 50
}
}
}Поиск задач:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "search_task_global",
"arguments": {
"q": "urgent"
}
}
}Для продакшена рекомендуется:
- Настроить firewall — открыть порт только для IP n8n сервера:
# UFW (Ubuntu)
ufw allow from YOUR_N8N_IP to any port 3847
# iptables
iptables -A INPUT -p tcp -s YOUR_N8N_IP --dport 3847 -j ACCEPT
iptables -A INPUT -p tcp --dport 3847 -j DROP- Использовать reverse proxy (nginx) с SSL:
server {
listen 443 ssl;
server_name mcp.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:3847;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_buffering off;
proxy_cache off;
}
}Для локального запуска без Docker используйте stdio транспорт.
Файл конфигурации:
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Linux:
~/.config/claude/claude_desktop_config.json
{
"mcpServers": {
"weeek": {
"command": "python",
"args": ["-m", "src.server"],
"cwd": "/path/to/weeek-mcp-server",
"env": {
"WEEEK_TOKEN": "your-api-token-here"
}
}
}
}Добавьте в .cursor/mcp.json:
{
"mcpServers": {
"weeek": {
"command": "python",
"args": ["-m", "src.server"],
"cwd": "/path/to/weeek-mcp-server",
"env": {
"WEEEK_TOKEN": "your-api-token-here"
}
}
}
}Если MCP сервер запущен в Docker на том же компьютере, используйте SSE транспорт.
cd weeek-mcp-server
# Создайте .env с настройками
cp env.example .env
# Отредактируйте: добавьте WEEEK_TOKEN и MCP_API_KEY
# Запустите контейнер
docker-compose up -d --build{
"mcpServers": {
"weeek": {
"url": "http://localhost:3847/sse",
"headers": {
"Authorization": "Bearer YOUR_MCP_API_KEY"
}
}
}
}Примечание: Замените YOUR_MCP_API_KEY на значение из вашего .env файла.
В файле .cursor/mcp.json:
{
"mcpServers": {
"weeek": {
"url": "http://localhost:3847/sse",
"headers": {
"Authorization": "Bearer YOUR_MCP_API_KEY"
}
}
}
}# Проверить что контейнер запущен
docker-compose ps
# Проверить health endpoint
curl http://localhost:3847/health
# Проверить SSE с авторизацией
curl -H "Authorization: Bearer YOUR_MCP_API_KEY" http://localhost:3847/sseПосле настройки перезапустите Claude Desktop или Cursor для применения изменений.
Для подключения к MCP серверу на VPS используйте его внешний IP или домен.
{
"mcpServers": {
"weeek": {
"url": "http://YOUR_VPS_IP:3847/sse",
"headers": {
"Authorization": "Bearer YOUR_MCP_API_KEY"
}
}
}
}{
"mcpServers": {
"weeek": {
"url": "http://YOUR_VPS_IP:3847/sse",
"headers": {
"Authorization": "Bearer YOUR_MCP_API_KEY"
}
}
}
}С SSL (рекомендуется для продакшена):
{
"mcpServers": {
"weeek": {
"url": "https://mcp.yourdomain.com/sse",
"headers": {
"Authorization": "Bearer YOUR_MCP_API_KEY"
}
}
}
}| Tool | Описание |
|---|---|
get_workspace |
Получить информацию о рабочем пространстве |
| Tool | Описание |
|---|---|
get_current_user |
Получить текущего пользователя |
list_users |
Список пользователей |
get_user_by_id |
Получить пользователя по ID |
update_user |
Обновить пользователя |
delete_user |
Удалить пользователя |
| Tool | Описание |
|---|---|
list_tags |
Список тегов |
create_tag |
Создать тег |
update_tag |
Обновить тег |
delete_tag |
Удалить тег |
| Tool | Описание |
|---|---|
list_custom_fields |
Список пользовательских полей |
create_custom_field |
Создать поле |
update_custom_field |
Обновить поле |
delete_custom_field |
Удалить поле |
| Tool | Описание |
|---|---|
list_currencies |
Список валют |
| Tool | Описание |
|---|---|
list_projects |
Список проектов |
get_project_by_id |
Получить проект |
create_project |
Создать проект |
update_project |
Обновить проект |
delete_project |
Удалить проект |
| Tool | Описание |
|---|---|
list_portfolio |
Список портфелей |
create_portfolio |
Создать портфель |
update_portfolio |
Обновить портфель |
delete_portfolio |
Удалить портфель |
| Tool | Описание |
|---|---|
list_boards |
Список досок |
get_board_by_id |
Получить доску |
create_board |
Создать доску |
update_board |
Обновить доску |
delete_board |
Удалить доску |
| Tool | Описание |
|---|---|
list_board_columns |
Список столбцов |
get_board_column_by_id |
Получить столбец |
create_board_column |
Создать столбец |
update_board_column |
Обновить столбец |
delete_board_column |
Удалить столбец |
| Tool | Описание |
|---|---|
list_tasks |
Список задач с фильтрацией |
get_task_by_id |
Получить задачу |
create_task |
Создать задачу |
update_task |
Обновить задачу |
delete_task |
Удалить задачу |
search_task_in_project |
Поиск в проекте |
search_task_global |
Глобальный поиск |
| Tool | Описание |
|---|---|
list_funnels |
Список воронок |
get_funnel_by_id |
Получить воронку |
create_funnel |
Создать воронку |
update_funnel |
Обновить воронку |
delete_funnel |
Удалить воронку |
| Tool | Описание |
|---|---|
list_funnel_statuses |
Список статусов |
get_funnel_status_by_id |
Получить статус |
create_funnel_status |
Создать статус |
update_funnel_status |
Обновить статус |
delete_funnel_status |
Удалить статус |
| Tool | Описание |
|---|---|
list_deals |
Список сделок |
get_deal_by_id |
Получить сделку |
create_deal |
Создать сделку |
update_deal |
Обновить сделку |
delete_deal |
Удалить сделку |
| Tool | Описание |
|---|---|
list_organizations |
Список организаций |
get_organization_by_id |
Получить организацию |
create_organization |
Создать организацию |
update_organization |
Обновить организацию |
delete_organization |
Удалить организацию |
| Tool | Описание |
|---|---|
list_contacts |
Список контактов |
get_contact_by_id |
Получить контакт |
create_contact |
Создать контакт |
update_contact |
Обновить контакт |
delete_contact |
Удалить контакт |
| Tool | Описание |
|---|---|
get_attachment |
Получить вложение |
upload_attachment |
Загрузить файл |
delete_attachment |
Удалить вложение |
| Tool | Описание |
|---|---|
get_tag_details |
Детали тега |
get_tasks_by_tag |
Задачи по тегу |
# Через MCP клиент
result = await mcp_client.call("create_task", {
"title": "Implement user authentication",
"project_id": "proj_abc",
"description": "Add OAuth2 integration",
"priority": "high",
"due_date": "2025-12-31",
"assigned_to": "user_123",
"tags": ["backend", "security"]
})# Найти высокоприоритетные открытые задачи
tasks = await mcp_client.call("list_tasks", {
"project_id": "proj_abc",
"status": "open",
"priority": "high",
"search": "bug",
"limit": 10
})# Создать сделку
deal = await mcp_client.call("create_deal", {
"title": "Enterprise License",
"funnel_id": "funnel_123",
"status_id": "status_new",
"amount": 50000,
"currency": "USD",
"contact_id": "contact_456"
})
# Переместить сделку в другой статус
await mcp_client.call("update_deal", {
"deal_id": deal["id"],
"status_id": "status_won"
})# Создать контакт
contact = await mcp_client.call("create_contact", {
"first_name": "John",
"last_name": "Doe",
"email": "john@example.com",
"organization_id": "org_123"
})
# Получить контакты организации
contacts = await mcp_client.call("list_contacts", {
"organization_id": "org_123",
"limit": 20
})# Установить токен и запустить тесты
WEEEK_TOKEN="your-token" python tests/test_integration.py- Workspace info
- User operations
- Project CRUD
- Task CRUD
- Tag operations
- Board operations
- Funnel & Deal operations
- Contact & Organization operations
- Error handling (401, 404, 429)
- ✅ Токены никогда не логируются (автоматическая редакция)
- ✅ Все данные передаются через HTTPS
- ✅ Поддержка переменных окружения для секретов
- ✅ Валидация всех входных данных
weeek-mcp-server/
├── README.md # Документация
├── requirements.txt # Зависимости
├── env.example # Пример конфигурации
├── .env # Локальная конфигурация (не в git)
├── .gitignore
├── Dockerfile # Docker образ
├── docker-compose.yml # Docker Compose конфигурация
├── .dockerignore # Исключения для Docker
├── run_server.py # Скрипт запуска
├── src/
│ ├── __init__.py
│ ├── server.py # MCP сервер
│ ├── weeek_client.py # HTTP клиент
│ ├── config.py # Конфигурация
│ ├── tools/ # Все MCP инструменты
│ │ ├── workspace_tools.py
│ │ ├── user_tools.py
│ │ ├── tag_tools.py
│ │ ├── task_tools.py
│ │ └── ...
│ ├── schemas/
│ │ └── models.py # Pydantic модели
│ └── utils/
│ ├── errors.py # Обработка ошибок
│ └── logger.py # Логирование
└── tests/
└── test_integration.py # Интеграционные тесты
Сервер обрабатывает все типы ошибок Weeek API:
| HTTP код | Ошибка | Описание |
|---|---|---|
| 400 | WeeekValidationError |
Неверные параметры запроса |
| 401 | WeeekAuthError |
Проблема с токеном |
| 403 | WeeekForbiddenError |
Нет прав доступа |
| 404 | WeeekNotFoundError |
Ресурс не найден |
| 429 | WeeekRateLimitError |
Превышен лимит запросов |
| 5xx | WeeekServerError |
Ошибка сервера Weeek |
- Fork репозитория
- Создайте feature branch (
git checkout -b feature/amazing) - Commit изменения (
git commit -m 'Add amazing feature') - Push в branch (
git push origin feature/amazing) - Откройте Pull Request
MIT License - см. LICENSE файл.
- Weeek API Documentation: https://developers.weeek.net/api/
- MCP Specification: https://modelcontextprotocol.io/
- Issues: GitHub Issues
Made with ❤️ for the Weeek community