myteam-mcp
by pohodnya
README.md
# myteam-mcp
MCP-сервер (Model Context Protocol) для HR-платформы **«МояКоманда»** ([моякоманда.рф](https://xn--80aalwjbieb2o.xn--p1ai/)). Даёт AI-ассистентам (Claude и другим MCP-клиентам) доступ к сущностям и действиям HR-платформы через её REST API: сотрудники, команды, календарь и отсутствия, заявки, база знаний, опросы, новости и геймификация.
> Не путать с мессенджером *VK Teams / Myteam* (mail.ru) — это другой продукт с другим API.
## Возможности
- **Два транспорта**: `stdio` (локально, у каждого свой токен) и `http` (Streamable HTTP, один общий сервер на пространство с **проброской авторизации per-request**).
- **~30 курируемых инструментов** по основным HR-сценариям + универсальный `myteam_request` для доступа к любому из ~2900 методов API.
- **Безопасность по умолчанию**: изменяющие операции и «сырой» доступ к API выключены и включаются явными флагами.
- **Права ролей соблюдаются автоматически** — API отдаёт данные в рамках роли пользователя, которому принадлежит токен.
- Готовые **Docker-образ** и **Helm-чарт**.
## Как это работает
Авторизация в «МояКоманда» — Laravel Sanctum. Токен получается методом `POST /api/login-mobile` (email/телефон + пароль) и передаётся во всех запросах заголовком `Authorization: Bearer <token>`. Базовый адрес — домен вашего тенанта (например `https://company.ismyteam.ru`), все методы под префиксом `/api`. Swagger доступен внутри пространства по адресу `/api-docs`.
## Установка
```bash
git clone https://github.com/pohodnya/myteam-mcp.git
cd myteam-mcp
npm install
npm run build
```
Требуется Node.js >= 20.
## Получение токена
```bash
npm run login -- https://company.ismyteam.ru user@company.ru 'ваш-пароль'
# выведет токен в stdout
```
или задайте `MYTEAM_BASE_URL`, `MYTEAM_LOGIN`, `MYTEAM_PASSWORD` и запустите `npm run login`.
## Конфигурация
| Переменная | Обязательна | Описание |
|---|---|---|
| `MYTEAM_BASE_URL` | да | URL тенанта, напр. `https://company.ismyteam.ru` |
| `MYTEAM_TOKEN` | для stdio | Bearer-токен API. В http может приходить per-request |
| `MYTEAM_TRANSPORT` | нет | `stdio` (по умолчанию) или `http` |
| `MYTEAM_HTTP_HOST` / `MYTEAM_HTTP_PORT` | нет | Хост/порт http-транспорта (`0.0.0.0` / `3000`) |
| `MYTEAM_ENABLE_WRITE` | нет | `true` — разрешить изменяющие операции |
| `MYTEAM_ENABLE_RAW` | нет | `true` — включить инструмент `myteam_request` |
| `MYTEAM_TIMEOUT_MS` | нет | Таймаут запросов, мс (`30000`) |
## Запуск в Claude Desktop / Claude Code (stdio)
```json
{
"mcpServers": {
"myteam": {
"command": "node",
"args": ["/абсолютный/путь/myteam-mcp/dist/index.js"],
"env": {
"MYTEAM_BASE_URL": "https://company.ismyteam.ru",
"MYTEAM_TOKEN": "ваш-токен"
}
}
}
}
```
## Общий сервер с проброской авторизации (http)
Один инстанс на всё пространство; токен не хранится на сервере, а берётся из заголовка `Authorization` каждого запроса — каждый пользователь работает под своей ролью.
```bash
MYTEAM_BASE_URL=https://company.ismyteam.ru MYTEAM_TRANSPORT=http npm start
```
```bash
curl -X POST http://localhost:3000/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'Authorization: Bearer <токен-пользователя>' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```
Health-check без авторизации: `GET /health`.
## OAuth 2.1 мост (per-user авторизация для коннекторов)
У «МояКоманда» нет OAuth — только логин по email/паролю. Чтобы работать с коннекторами claude.ai (которым нужен OAuth 2.1 + Dynamic Client Registration), сервер умеет **сам выступать Authorization Server**: показывает форму входа, аутентифицирует пользователя через `/api/login-mobile` и выдаёт собственный `access_token` (зашифрованный Sanctum-токен). На `/mcp` токен расшифровывается обратно.
Включение:
```bash
MYTEAM_BASE_URL=https://company.ismyteam.ru \
MYTEAM_TRANSPORT=http \
MYTEAM_ENABLE_OAUTH=true \
MYTEAM_OAUTH_SECRET='случайная-строка-не-короче-16-символов' \
MYTEAM_PUBLIC_URL=https://mcp.company.ru \
npm start
```
Реализовано: `Authorization Code + PKCE (S256)`, DCR (`POST /register`), метаданные
`/.well-known/oauth-authorization-server` и `/.well-known/oauth-protected-resource`,
`401` с заголовком `WWW-Authenticate` на `/mcp`. Коды и токены self-contained (AES-256-GCM),
серверное состояние не хранится — мост работает в stateless-режиме и масштабируется.
В коннекторе claude.ai укажите URL `https://mcp.company.ru/mcp` — остальное (discovery,
регистрация, вход) пройдёт автоматически. Каждый пользователь входит под своей учётной
записью и работает в рамках прав своей роли.
> Header-passthrough (без OAuth) остаётся доступным одновременно: если в заголовке пришёл
> «сырой» Sanctum-токен, он используется напрямую.
## Инструменты
**Система**: `get_company_info`, `whoami`, `healthz`
**Сотрудники и команды**: `list_users`, `search_users_by_filter`, `get_user`, `get_user_work`, `get_user_subordinates`, `list_teams`, `get_team`, `get_team_structure`
**Календарь и отсутствия**: `list_calendar_events`, `list_absences`, `who_is_absent`, `memorable_dates`
**Заявки**: `list_requests`, `get_request`, `requests_catalog`, `requests_need_action`
**База знаний**: `search_knowledge_base`, `list_kb_categories`, `get_kb_article`
**Опросы**: `list_surveys`, `get_survey`, `get_survey_participants`, `get_survey_questions`, `get_survey_statistics`, `list_survey_templates`
**ИПР (развитие)**: `list_development_plans`, `my_development_plans`, `get_user_development_plans`, `get_development_plan`
**Эффективность**: `list_evaluations`, `get_evaluation`, `get_evaluation_participants`, `get_evaluation_user_card`, `get_evaluation_matrix` (9-Box), `list_kpi`, `get_kpi`, `get_kpi_user_info`
**Вовлечённость**: `get_news_feed`, `get_my_activities`, `get_rating`, `get_prize_store`, `get_user_thanks`
**Изменяющие** (`MYTEAM_ENABLE_WRITE=true`): `create_calendar_event`, `send_thanks`, `share_coins`, `run_development_plan`, `set_development_material_status`, `save_kpi_progress`, `submit_evaluation_answer`, `complete_evaluation`, `answer_survey_question`, `publish_survey`, `remind_survey_participants`
**Расширенный** (`MYTEAM_ENABLE_RAW=true`): `myteam_request` — произвольный вызов любого эндпоинта `/api/...`
## Docker
```bash
docker build -t myteam-mcp .
docker run --rm -p 3000:3000 \
-e MYTEAM_BASE_URL=https://company.ismyteam.ru \
myteam-mcp
```
По умолчанию образ стартует в http-режиме с проброской токена.
## Helm
```bash
helm install myteam-mcp ./helm/myteam-mcp \
--set config.baseUrl=https://company.ismyteam.ru
```
По умолчанию `token.passthrough=true` (per-request). Для общего токена:
```bash
helm install myteam-mcp ./helm/myteam-mcp \
--set config.baseUrl=https://company.ismyteam.ru \
--set token.passthrough=false \
--set token.existingSecret=my-secret
```
## Разработка
```bash
npm run dev # watch-режим (stdio)
npm test # тесты (vitest)
npm run test:coverage
npm run typecheck
```
## Архитектура
```
src/
index.ts точка входа, выбор транспорта
config.ts конфигурация из ENV
client.ts HTTP-клиент REST API (Bearer, таймауты, ошибки)
auth.ts логин через /api/login-mobile
server.ts фабрика MCP-сервера, регистрация инструментов
http.ts Streamable HTTP транспорт с проброской токена
login.ts CLI получения токена
tools/ инструменты по модулям
```
## Лицензия
[MIT](./LICENSE)
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues