Skip to main content
Glama
kremdigital

Team Vault MCP

by kremdigital
README.md
# Team Vault MCP

[MCP](https://modelcontextprotocol.io)-сервер, который отдаёт REST API Team Vault
как набор инструментов для ИИ-агентов. Позволяет другим агентам **читать и
править заметки вальта программно**, без Obsidian — поверх того же серверного
API, что использует плагин.

Транспорт — **stdio** (агент запускает процесс и общается по JSON-RPC).
Аутентификация — заголовок `X-API-Key`.

## Конфигурация (env)

| Переменная              | Обяз. | Описание                                                               |
| ----------------------- | ----- | ---------------------------------------------------------------------- |
| `TEAM_VAULT_URL`        | да    | URL сервера, напр. `https://teamvault.artillect.pro`                   |
| `TEAM_VAULT_API_KEY`    | да    | API-ключ Team Vault (веб-UI → API-ключи)                               |
| `TEAM_VAULT_PROJECT_ID` | нет   | проект по умолчанию для инструментов без `projectId`                   |
| `TEAM_VAULT_READ_ONLY`  | нет   | `1`/`true` — отключить запись (`write_note`/`move_note`/`delete_note`) |

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

| Инструмент           | Режим  | Что делает                                       |
| -------------------- | ------ | ------------------------------------------------ |
| `whoami`             | чтение | владелец API-ключа                               |
| `list_projects`      | чтение | доступные проекты (id, slug, name)               |
| `list_notes`         | чтение | пути файлов проекта (`prefix` — фильтр по папке) |
| `read_note`          | чтение | содержимое текстовой заметки по пути             |
| `list_note_versions` | чтение | история версий файла                             |
| `write_note`         | запись | создать/перезаписать заметку по пути             |
| `move_note`          | запись | переместить/переименовать                        |
| `delete_note`        | запись | мягко удалить (tombstone, восстановимо)          |

Инструменты **путь-ориентированы**: агент оперирует путями (`персонажи/кузьма-минин.md`),
а MCP сам резолвит путь ↔ fileId. Путь можно написать в любом виде, который
сервер сводит к одному: `./a.md`, `dir\a.md`, `dir//a.md`, `x/../dir/a.md` — это
те же `a.md` и `dir/a.md`. В `read_only`-режиме инструменты записи не
регистрируются вовсе.

## Надёжность: таймауты, повторы и `Idempotency-Key`

У каждого вызова инструмента один бюджет времени — **45 с на все его запросы
вместе** (резолв пути и запись). Это меньше 60-секундного таймаута запроса в
MCP SDK: вызов заканчивается раньше, чем хост от него откажется. Если хост всё
же отменил вызов (`notifications/cancelled`), текущий запрос обрывается и
повторов больше нет. Таймаут одной попытки — 20 с, но не больше остатка
бюджета; новая попытка не начинается, если от бюджета осталось меньше 2 с.

Повторяются только сбои без ответа: сетевая ошибка, таймаут, `429`, `502`,
`503`, `504` — до 3 попыток с паузами 1 и 3 с (плюс до 0,25 с случайно), с
учётом `Retry-After` сервера (не больше 10 с). `409 idempotency_key_in_use`
(предыдущая попытка ещё выполняется) повторяется до конца бюджета. Остальные
ответы (`400`, `401`, `403`, `404`, `409 path_exists`, `422`, `500`) не
повторяются.

Каждая запись (`write_note`, `move_note`, `delete_note`) отправляет заголовок
`Idempotency-Key` — один UUID на вызов, одинаковый во всех попытках. Сервер
применяет запись один раз, а повтор получает исходный ответ с заголовком
`Idempotent-Replayed: true`. `422 idempotency_key_mismatch` означает ошибку
клиента и не повторяется.

Новый вызов инструмента — новый ключ. Если запись упала без определённого
ответа (сеть, таймаут, `5xx`, ключ всё ещё занят), текст ошибки заканчивается
подсказкой «The change may or may not have been applied…»: перед новым вызовом
агенту стоит проверить состояние через `read_note` или `list_notes`.

Повторы записи безопасны только с сервером Team Vault с поддержкой
`Idempotency-Key` (ревизия `79fb5d9` и новее, на проде с 2026-10-05). Старый сервер заголовок молча
игнорирует, и повтор после таймаута может применить запись второй раз
или откатить правку коллеги. Поэтому сначала обновляйте сервер, потом MCP.

## Сборка и запуск

```bash
pnpm install
pnpm build          # tsup → dist/index.js (один бандл)
TEAM_VAULT_URL=… TEAM_VAULT_API_KEY=… node dist/index.js
```

Гейты: `pnpm typecheck && pnpm format:check && pnpm build && pnpm test`.

## Тесты

```bash
pnpm test           # vitest run (однократно); pnpm test:watch — в режиме наблюдения
```

Тесты не ходят в сеть: глобальный `fetch` в каждом тесте подменён заглушкой
(`tests/setup.ts`), а тест, которому нужен HTTP, ставит свой мок с ответами
сервера (`tests/helpers/fetch.ts`). Клиент перехватывает ошибку заглушки и
превращает её в обычную `TeamVaultError`, поэтому заглушка ещё и запоминает
каждый вызов: тест, который забыл мок, падает после выполнения, даже если сам
ждал ошибку.

- `tests/client.test.ts` — REST-клиент: заголовок `X-API-Key`, резолв пути
  через `GET /files?path=…` (включая `200` с пустым списком), `404`,
  `409 path_exists`, `5xx`, сетевые ошибки (одна попытка).
- `tests/client-retry.test.ts` — повторы и бюджет времени на поддельных
  таймерах: ключ `Idempotency-Key` одинаков во всех попытках и разный у разных
  вызовов, что повторяется и что нет (`422` — нет), паузы и `Retry-After`,
  ответ-повтор как успех, таймаут попытки по остатку бюджета, отмена.
- `tests/server.test.ts` — инструменты через настоящий MCP-клиент поверх
  in-memory транспорта: версия в `initialize`, режим только для чтения,
  `write_note` (создание и обновление), чтение, перемещение, удаление; путь в
  другом написании (`./a.md`, `dir\a.md`); общий бюджет резолва и записи,
  отмена вызова хостом, подсказка «may or may not have been applied».
- `tests/paths.test.ts` — написание пути, под которым его хранит сервер
  (`storedPathOf`).
- `tests/config.test.ts` — разбор переменных окружения.
- `tests/entry.test.ts` — точка входа `src/index.ts` как дочерний процесс по stdio
  (`initialize` + `tools/list`, выход с кодом 1 без обязательных переменных).
- `tests/network-guard.test.ts` — заглушка `fetch`: юнит-проверки и дочерний
  прогон vitest на `tests/fixtures/*.fixture.ts` (основной прогон эти файлы
  не собирает).

## Подключение в Claude Code / MCP-клиенте

```json
{
  "mcpServers": {
    "team-vault": {
      "command": "node",
      "args": ["/абсолютный/путь/TeamVaultMCP/dist/index.js"],
      "env": {
        "TEAM_VAULT_URL": "https://teamvault.artillect.pro",
        "TEAM_VAULT_API_KEY": "osync_…",
        "TEAM_VAULT_PROJECT_ID": "cmq…"
      }
    }
  }
}
```

## Лицензия

MIT · krem.digital

TDQS

A3.7/5.0

Scored across 8 tools

Disambiguation5/5

Each tool has a distinct purpose: note CRUD, versioning, project listing, user info, and file moves. No two tools overlap in function.

Naming Consistency4/5

Most tools follow a consistent 'verb_note' pattern (delete_note, list_notes, move_note etc.), with the exception of 'whoami', which deviates slightly but is a common convention.

Tool Count5/5

Eight tools is well-scoped for a note management system, covering creation, reading, deletion, listing, moving, versioning, project enumeration, and user info.

Completeness4/5

CRUD and versioning are covered, but there is no explicit restore for soft-deleted notes or support for binary file operations, which are noted as server-side recoverable or external respectively.

Maintenance

ActivityMaintained
ResponsivenessNo issues