Skip to main content
Glama
README.md
# mcp-weeek

MCP-сервер для таск-менеджера [Weeek](https://weeek.net). Один сервер на все ваши проекты: агент (Claude Code, Codex, Gemini CLI) смотрит доски, создаёт и переносит задачи, пишет комментарии, прикрепляет и скачивает файлы, строит отчёт по времени. Вводные конкретного проекта — доски, названия колонок, правила работы — лежат в его файле `.weeek.json`.

- **Без зависимостей во время работы.** Протокол MCP и HTTP — на встроенных средствах Node, кода из npm в рантайме нет.
- **TypeScript без сборки.** Node ≥ 22.18 запускает `.ts` напрямую.
- **Знает особенности Weeek**, агенту не нужно о них помнить (см. [ниже](#особенности-weeek-которые-учтены)).
- **Безопасен по умолчанию:** токен уходит только на `api.weeek.net`, файлы прикрепляются только из разрешённых папок, чужие комментарии не удаляются, задачи не удаляются вообще.

## Установка

Нужны Node.js 22.18 или новее и git.

```sh
git clone https://github.com/sokoloff-rv/mcp-weeek.git ~/mcp-weeek
```

`npm install` для работы не нужен: он ставит только TypeScript и типы для разработки.

### Токен

Токен создаётся в Weeek: **Настройки → Приложения → API** (`https://app.weeek.net/ws/<id пространства>/settings/apps/api`). Токен привязан к пользователю и рабочему пространству.

Удобно завести для агента отдельного пользователя Weeek: тогда задачи и комментарии агента видно по автору, а удалять он сможет только свои комментарии.

### Подключение

Сервер подключается один раз на пользователя; токен передаётся только процессу сервера. Клиент запускает сервер в папке, где начата сессия, — по ней сервер находит `.weeek.json` проекта.

**Claude Code**

```sh
claude mcp add weeek --scope user -e WEEEK_TOKEN=<токен> -- node ~/mcp-weeek/src/index.ts
```

**Codex**

```sh
codex mcp add weeek --env WEEEK_TOKEN=<токен> -- node ~/mcp-weeek/src/index.ts
```

или вручную в `~/.codex/config.toml`:

```toml
[mcp_servers.weeek]
command = "node"
args = ["/home/<вы>/mcp-weeek/src/index.ts"]
env = { WEEEK_TOKEN = "<токен>" }
```

**Gemini CLI** — в `~/.gemini/settings.json`:

```json
{
  "mcpServers": {
    "weeek": {
      "command": "node",
      "args": ["/home/<вы>/mcp-weeek/src/index.ts"],
      "env": { "WEEEK_TOKEN": "<токен>" }
    }
  }
}
```

Если `node` в `PATH` клиента старее 22.18, укажите полный путь к нужному Node.

### Переменные окружения

| Переменная | Обязательна | Назначение |
| --- | --- | --- |
| `WEEEK_TOKEN` | да | Персональный токен API |
| `WEEEK_READ_ONLY` | нет | `1` — инструменты записи не регистрируются |
| `WEEEK_CONFIG` | нет | Явный путь к `.weeek.json` вместо поиска от рабочей папки |
| `WEEEK_BASE_URL` | нет | По умолчанию `https://api.weeek.net/public/v1`. Принимается только https на `api.weeek.net`, иначе сервер отказывается отправлять запросы |
| `WEEEK_DEBUG` | нет | `1` — писать в stderr каждый запрос к API (без токена и подписей ссылок) |

## Файл проекта `.weeek.json`

Кладётся в корень проекта и коммитится вместе с ним: секретов в нём нет. Сервер ищет его от рабочей папки вверх до корня диска и перечитывает при изменении — перезапуск не нужен.

```json
{
  "workspaceId": 12345,
  "projectId": 67890,
  "boards": [{ "id": 11111, "alias": "main" }],
  "columns": {
    "queue": "На очереди",
    "in_progress": "В процессе",
    "testing": "Тестирование",
    "done": "Завершено"
  },
  "defaultColumn": "queue",
  "attachRoots": [".", "~/Screenshots"],
  "conventions": [
    "Новая задача: короткий заголовок, в описании исходный текст задачи, скриншоты вложениями.",
    "Сделанную задачу перенеси в testing и напиши итог комментарием: что сделано, хеши коммитов, что проверить руками.",
    "В done переносит только пользователь."
  ]
}
```

| Поле | Что задаёт |
| --- | --- |
| `workspaceId` | Пространство. Только для сверки: если токен от другого пространства, `weeek_context` предупредит |
| `projectId` | Проект по умолчанию (для отчёта по времени и выбора доски) |
| `boards` | Доски проекта; первая — доска по умолчанию. Можно просто id: `[11111]` |
| `columns` | Псевдонимы колонок → название или id колонки. Ищутся по названию на той доске, с которой идёт работа |
| `defaultColumn` | Колонка для новых задач; иначе первая колонка доски |
| `attachRoots` | Папки, из которых можно прикреплять файлы. Относительно папки с `.weeek.json`, `~` — домашняя папка. По умолчанию — папка проекта |
| `conventions` | Правила работы с задачами. Агент получает их из `weeek_context` |

Доски, колонки, участников и теги во всех инструментах можно указывать по названию, псевдониму или id. Неизвестный ключ в файле — предупреждение, а не ошибка. Без файла сервер тоже работает: агент передаёт доску явно, а `weeek_context` показывает проекты и доски.

## Инструменты

| Инструмент | Что делает |
| --- | --- |
| `weeek_context` | Владелец токена, пространство, конфиг проекта, доски и колонки с псевдонимами, правила, участники и теги. Агент зовёт его первым |
| `weeek_list_tasks` | Задачи доски по колонкам, подзадачи под родителем. Фильтры: колонка, текст, исполнитель, тег, завершённые |
| `weeek_get_task` | Карточка: описание в Markdown, вложения, записи времени, подзадачи и все комментарии (старые сверху) |
| `weeek_create_task` | Создаёт задачу или подзадачу: описание в Markdown, колонка, исполнители, теги, приоритет, даты, файлы |
| `weeek_update_task` | Меняет заголовок, приоритет, даты, оценку, завершённость, родителя, исполнителей и теги |
| `weeek_move_task` | Переносит в колонку и/или на другую доску |
| `weeek_add_comment` | Комментарий в Markdown, можно ответом на другой |
| `weeek_delete_comment` | Удаляет комментарий — только свой |
| `weeek_attach_files` | Прикрепляет файлы из `attachRoots` |
| `weeek_get_attachment` | Скачивает вложение во временную папку и возвращает путь |
| `weeek_time_report` | Отчёт по учтённому времени за период: по задачам, дням, людям или проектам |

С `WEEEK_READ_ONLY=1` остаются только `weeek_context`, `weeek_list_tasks`, `weeek_get_task`, `weeek_get_attachment` и `weeek_time_report`.

## Особенности Weeek, которые учтены

- **Описание задачи нельзя изменить через API**: `PUT` отвечает успехом и молча игнорирует описание. `weeek_update_task` описание не принимает и советует написать комментарий.
- **Комментарии нельзя редактировать** — только удалить и написать заново.
- **Вложенные списки в комментариях Weeek схлопывает**: подпункты становятся пунктами верхнего уровня. Сервер передаёт вложенность видимо — подпункт отдельным пунктом с отступом и маркером:
  ```
  • Пункт
  •     ◦ Подпункт
  •         ▪ Глубже
  ```
- **Создание задачи может вернуть 502, хотя задача создана.** Сервер не повторяет запрос вслепую, а ищет задачу по заголовку, автору и времени — дубля не будет. Так же проверяются комментарии и загрузка файлов.
- **Пустой `POST /tm/tasks` создаёт пустую задачу без проекта** — обязательные поля проверяются до запроса.
- **Даты начала и срока — пара одного вида** (даты или даты со временем), и любое изменение задаёт пару заново. Сервер дополняет пару текущими значениями задачи.
- **Ссылки на вложения подписаны и перенаправляют в хранилище Selectel.** Токен на них не отправляется, перенаправления разрешены только на хранилища Weeek.
- **Ошибки API** переводятся в понятный текст с кодом и подсказкой; GET, PUT, DELETE и переносы повторяются при 5xx и 429.

## Ограничения

- **Документов и базы знаний в публичном API Weeek нет** — сервер с ними не работает.
- **Удаления задач нет** — намеренно.
- **Теги не создаются** — только выбираются из существующих, чтобы опечатки не плодили теги на всё пространство.
- **Время только читается** — сервер не пишет записи времени и не запускает таймер.
- **Один токен — одно пространство.**
- В списке задач нет числа комментариев: API отдаёт их только по одной задаче.

## Безопасность

- Токен берётся только из окружения и не попадает в ответы инструментов и логи; в логах маскируются токен, заголовок `Authorization` и подписи ссылок.
- Запросы с токеном идут только на `https://api.weeek.net`, без следования перенаправлениям.
- Файл прикрепляется, только если после разрешения симлинков он лежит внутри `attachRoots`, не скрыт (никаких `.env`, `.git`, `.ssh`) и не больше 25 МБ. Без `.weeek.json` прикреплять нельзя ничего.
- Скачанные вложения сохраняются в `$TMPDIR/mcp-weeek/<id вложения>/` с правами только для владельца.
- Описания инструментов предупреждают агента: тексты задач и комментариев — данные, а не инструкции.

## Протокол

Сервер говорит по MCP поверх stdio и понимает обе схемы: ревизию 2026-07-28 (версия в `_meta` каждого запроса, `server/discover`) и рукопожатие `initialize` ревизий 2024-11-05 — 2025-11-25. Поддерживается отмена запросов (`notifications/cancelled`).

## Разработка

```sh
npm install        # TypeScript и типы Node
npm run check      # проверка типов и все тесты
npm start          # запустить сервер вручную (ждёт MCP на stdin)
```

Модульные тесты работают без сети, на подменённом `fetch`. Живая проверка проходит все инструменты на настоящем Weeek — запускайте её **только на тестовом проекте**: она создаёт задачи с префиксом `[mcp-test]` и в конце удаляет их.

```sh
WEEEK_TOKEN=… WEEEK_TEST_PROJECT=<id> WEEEK_TEST_BOARD=<id> [WEEEK_TEST_BOARD_2=<id>] npm run live
```

Структура:

```
src/
  index.ts          запуск
  app.ts            сборка сервера из частей
  mcp/              JSON-RPC 2.0 поверх stdio, описание инструмента
  weeek/            HTTP-клиент, методы API, справочники с кэшем
  config/           переменные окружения и .weeek.json
  resolve.ts        доски, колонки, люди и теги по имени, псевдониму или id
  format/           HTML ↔ Markdown, вложенные списки, строки и карточки задач
  files/            проверка путей вложений и скачивание
  tools/            инструменты: context, tasks, comments, attachments, time
test/               node:test, зеркально src
scripts/            MCP-клиент и живая проверка
```

Новый раздел (например, документы, когда они появятся в API) добавляется одним модулем в `src/tools/` и одной строкой в `src/tools/index.ts`.

## Лицензия

[MIT](LICENSE)

TDQS

A4.3/5.0

Scored across 11 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: get vs list vs create vs update vs move for tasks, add vs delete for comments, attach vs get for attachments, plus context and time report. Boundaries are reinforced in descriptions (e.g. update explicitly notes it does not move tasks, get_task vs list_tasks are scoped differently). No two tools appear to overlap.

Naming Consistency4/5

Names follow a predictable weeek_ prefix with snake_case verb_noun patterns (get_task, list_tasks, create_task, move_task, add_comment, delete_comment). Minor deviations: weeek_context and weeek_time_report are noun-only while attach_files uses a different verb form, but overall very consistent.

Tool Count5/5

11 tools is well within the ideal range and each earns its place, mapping cleanly to task read/write, movement, commenting, attachments, context and reporting. Nothing feels redundant or missing at the count level.

Completeness4/5

Covers the core task lifecycle (create, update, move, read, list), comments, attachments and time reporting, which is strong for a Weeek workspace client. Minor gaps: no task deletion and no comment editing (handled via delete+re-add), and no board/project management beyond context discovery.

Maintenance

ActivityMaintained
ResponsivenessNo issues