mcp-yandex-wiki
by slartus
README.md
# mcp-yandex-wiki
Минимальный MCP-сервер для [Яндекс Вики](https://wiki.yandex.ru/) (read + write).
## Установка
```bash
cd ~/.claude/mcp/yandex-wiki
npm install
```
Регистрация в `~/.claude.json`:
```json
{
"mcpServers": {
"yandex-wiki": {
"type": "stdio",
"command": "node",
"args": ["/Users/<user>/.claude/mcp/yandex-wiki/index.mjs"],
"env": {
"YW_OAUTH_TOKEN": "y0__...",
"YW_ORG_ID": "1234567",
"YW_ORG_HEADER": "X-Org-Id"
}
}
}
}
```
## Переменные окружения
| Переменная | Обязательна | Описание |
|---|---|---|
| `YW_OAUTH_TOKEN` | да | OAuth-токен Яндекса со скоупом `wiki:read` / `wiki:write` |
| `YW_ORG_ID` | да | ID организации |
| `YW_ORG_HEADER` | нет | `X-Org-Id` для Яндекс 360 (по умолчанию), `X-Cloud-Org-Id` для Yandex Cloud Organization |
Токен от Яндекс Трекера подходит, если тому же приложению выданы и wiki-скоупы — механика авторизации общая (`OAuth` + заголовок организации). Подробнее — [Про скоупы токена](#про-скоупы-токена).
Сервисный аккаунт Yandex Cloud для Wiki API не годится — только пользовательский.
## Инструменты
| Инструмент | API | Описание |
|---|---|---|
| `myself` | `GET /users/me` | Текущий пользователь, организация, домашний кластер |
| `get_page` | `GET /pages?slug=` / `GET /pages/{id}` | Страница по slug или id. Тело — только при `fields: ["content"]` |
| `search` | `POST /search` | Полнотекстовый поиск, до 10 результатов |
| `list_descendants` | `GET /pages/{id}/descendants` | Подстраницы |
| `list_resources` | `GET /pages/{id}/resources` | Вложения + таблицы одним списком |
| `list_attachments` | `GET /pages/{id}/attachments` | Вложения |
| `list_grids` | `GET /pages/{id}/grids` | Динамические таблицы |
| `create_page` | `POST /pages` | Создать страницу (`slug`, `title` обязательны) |
| `update_page` | `POST /pages/{id}` | Изменить `title` / `content` / `slug` |
| `delete_page` | `DELETE /pages/{id}` | Удалить страницу (необратимо) |
### `fields` у `get_page`
`redirect`, `breadcrumbs`, `attributes`, `content`, `access_policy`, `access_lists`, `owner`.
Без `fields` возвращаются только `id`, `slug`, `title`, `page_type`.
## Особенности API
- **Поиск не пагинируется.** `total_pages` всегда `1`, отдаётся максимум 10 результатов; параметры `page` / `offset` игнорируются. Сужай запрос.
- **`PATCH` и `PUT` не поддерживаются.** Обновление — это `POST /pages/{id}`. Разрешённые методы: `/pages` → `POST, GET`; `/pages/{id}` → `POST, GET, DELETE`.
- **Readonly-страницы отдают HTTP 403** на запись — см. [Как читать HTTP 403](#как-читать-http-403).
## Статус проверок
| Инструмент | Статус |
|---|---|
| `myself`, `get_page`, `search`, `list_descendants`, `list_resources`, `list_attachments`, `list_grids` | проверены на живом API |
| `update_page` | проверен: round-trip заголовка на реальной странице, контент побайтово не изменился |
| `create_page`, `delete_page` | **не проверялись** — схема восстановлена из ошибок валидации API и заголовка `Allow` |
### Про скоупы токена
Документация [называет два скоупа](https://yandex.ru/support/wiki/ru/api-ref/access): `wiki:read` (только чтение) и `wiki:write` (создание, редактирование, удаление). Плюс отдельный гейт — права пользователя: «запросы выполняются от имени пользователя… пользователь должен иметь соответствующие права в Вики».
**На практике wiki-скоупы оказались не нужны.** Токен приложения, которому выданы только скоупы Яндекс Трекера и ни одного wiki-скоупа, читает и пишет в Вики без ошибок — проверено на живом API, включая `POST` на страницу.
Механика этого не установлена, возможны два объяснения:
- Wiki API не проверяет скоуп вообще и пускает по личности пользователя;
- скоуп Трекера покрывает и Вики по дизайну — сервисы одного продуктового куста.
Различить можно токеном с посторонним скоупом (например, только `login:info`): пройдёт — первое, `403` — второе.
Enforcement у Яндекса **посервисный, а не глобальный**: тот же токен на Яндекс.Диск (`cloud_api:disk.read` не выдан) получает `HTTP 403 «Возможно, у приложения недостаточно прав»`. То есть «Диск проверяет скоуп» не означает, что его проверяет Вики — не переносите вывод с одного API на другое.
Практический итог: **если у вас уже есть токен Яндекс Трекера, отдельные wiki-скоупы можно не выдавать.** Обратная сторона — отдельный «wiki-only» токен не изолирует Вики: её откроет и токен Трекера.
### Как читать HTTP 403
Скоуп тут почти наверняка ни при чём — смотрите на права:
- у пользователя нет прав на страницу;
- страница readonly: `get_page` с `fields: ["attributes"]` → `attributes.is_readonly`. Системные страницы (владелец `yandex360-wiki`) readonly — например, главная.
Если 403 приходит вообще на всё, включая чтение, — проверьте `X-Org-Id` и то, что токен принадлежит пользователю, а не сервисному аккаунту.
### Побочный эффект записи
Любой `POST /pages/{id}` бампает `modified_at`, даже если в теле нет ни одного значимого поля. Страница отметится как изменённая.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues