Skip to main content
Glama
Surf-Team

SurfTracker MCP Server

Official
by Surf-Team
README.md
# SurfTracker MCP Server

MCP-сервер (Streamable HTTP) для доступа ИИ-клиентов к проектам и задачам
[SurfTracker](../SurfTracker). В отличие от `FileManagerMCP`/`IBP_mcp`, у этого сервера
нет своего хранилища API-ключей: он **проксирует** SurfTracker API-ключ (`User.apiKey`),
переданный MCP-клиентом, в каждый вызов `POST ${SURFTRACKER_BASE_URL}/api/1/external/*` —
всю авторизацию и контроль доступа (какие проекты/задачи видны) выполняет сам SurfTracker.

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

| Инструмент | Endpoint SurfTracker | Описание |
|---|---|---|
| `list_projects` | `listProjects` | Проекты, доступные владельцу API-ключа: колонки статусов, папки задач, релизы |
| `list_tasks` | `listTasks` | Задачи проекта с пагинацией и фильтрами (папка, включать завершённые) |
| `get_task` | `getTask` | Полная карточка задачи: описание, статусы/исполнители, подзадачи, чат |
| `search_tasks` | `searchTasks` | Полнотекстовый поиск задач по id/заголовку/описанию/чату |
| `create_task` | `createTask` | Создать задачу в проекте |
| `add_subscriber` | `addSubscriber` | Добавить подписчика к задаче |
| `add_subtask` | `addSubtask` | Связать задачи отношением родитель-подзадача |
| `assign_executor` | `assignExecutor` | Назначить исполнителя задаче/действию |
| `remove_executor` | `removeExecutor` | Снять исполнителя с задачи/действия |
| `send_notification` | `sendNotification` | Отправить пользователю уведомление о задаче |
| `add_comment` | `addComment` | Отправить комментарий в чат задачи (с упоминаниями) |
| `set_status` | `setStatus` | Изменить статус задачи/действия |
| `create_md_file` | `createMdFile` | Создать .md файл и прикрепить к задаче |
| `delete_task` | `deleteTask` | Мягко удалить задачу |
| `delete_task_notifications` | `deleteTaskNotifications` | Удалить уведомления, связанные с задачей |
| `list_releases` | `listReleases` | Релизы проекта вместе с их разделами |
| `list_release_sections` | `listReleaseSections` | Разделы конкретного релиза |
| `list_release_tasks` | `listReleaseTasks` | Задачи (действия), привязанные к релизу/разделу |
| `get_task_release_note` | `getTaskReleaseNote` | Релизный текст действия задачи |
| `set_task_release_note` | `setTaskReleaseNote` | Задать релизный текст действия задачи |

Полное описание параметров каждого метода — в `SurfTracker/docs/external-api.md`
(read-методы задач — разделы 11-14, релизы — 15-19, комментарии — раздел 20, остальные — 1-10).

## Требования

- Node.js 18+ (используется встроенный `fetch`)
- Работающий инстанс SurfTracker, доступный по сети из места запуска сервиса
- SurfTracker API-ключ (`User.apiKey`) пользователя, от имени которого работает ИИ

## Установка

```bash
npm install
cp .env.example .env   # указать PORT и SURFTRACKER_BASE_URL
```

## Переменные окружения (.env)

| Переменная | По умолчанию | Назначение |
|---|---|---|
| `PORT` | `3300` | Порт MCP-сервера |
| `SURFTRACKER_BASE_URL` | — (обязательна) | Базовый URL SurfTracker, без завершающего `/` |

## Запуск

```bash
npm start        # прод
npm run dev      # с автоперезапуском (--watch)
```

- MCP endpoint: `POST http://<host>:<PORT>/mcp` (требует SurfTracker API-ключ)
- Health check: `GET http://<host>:<PORT>/health` — доступность `SURFTRACKER_BASE_URL`
  (не проверяет валидность ключа — ключ есть только у клиента)

## Подключение MCP-клиента

```json
{
  "mcpServers": {
    "surftracker": {
      "url": "http://<host>:<PORT>/mcp",
      "headers": { "Authorization": "Bearer <SurfTracker API key>" }
    }
  }
}
```

Ключ можно передавать и в заголовке `X-API-Key`. Права ИИ-клиента полностью совпадают
с правами пользователя, которому принадлежит ключ (те же проекты и задачи, что видны
ему в SurfTracker).

## Модель безопасности

1. **Ключ не хранится.** Сервис не ведёт собственный список ключей/проектов — каждый
   вызов инструмента дословно пересылает заголовок `Authorization` в SurfTracker.
   Скомпрометировать этот сервис отдельно от SurfTracker невозможно: он не видит ничего,
   что не отдаёт сам SurfTracker по этому ключу.
2. **Авторизация и видимость данных — на стороне SurfTracker.** `ApiInstaller`
   (`authenticateByApiKey`, `Project.hasAccessToTask`) решает, какие проекты и задачи
   доступны конкретному ключу; здесь эта логика не дублируется.
3. **Ошибки SurfTracker (`success: false`) превращаются в `isError` MCP-результат**
   с тем же сообщением (`Unauthorized: Invalid API key`, `No access to project`, ...),
   без утечки внутренних деталей запроса.
4. **Rate limiting** на `/mcp`: до 6000 запросов в час на процесс (MCP-сессии дёргают
   по одному запросу на каждый вызов инструмента).