Skip to main content
Glama

Work Journal MCP Server

Размещённый MCP-сервер, который позволяет любому члену команды читать свой упрощённый HR Work Journal через Claude — всегда свои собственные записи, а также записи коллег, если существующие разрешения Work Journal это уже допускают.

Только чтение. Ни один инструмент здесь не может создавать, изменять или удалять записи.

Подключение из любого клиента Claude

Один поток, независимо от того, какой клиент вы используете: добавьте сервер по URL-адресу, затем войдите в открывшемся окне браузера.

Claude Desktop или claude.ai — Настройки → Коннекторы → Добавить пользовательский коннектор →

https://wj-mcp.dev.besimplified.net/mcp

Claude Code

claude mcp add work-journal --transport http https://wj-mcp.dev.besimplified.net/mcp

В любом случае откроется окно браузера. Войдите, используя свой адрес электронной почты и пароль Simplified HR. В dev-среде вы также вводите свой рабочий пространство, например development-hr.dev.besimplified.net.

Если это устройство, которое служба учётных записей раньше не видела, вам будет отправлен проверочный код по электронной почте или SMS. Введите его один раз; вас больше не спросят с того же клиента.

Ваш пароль никогда не попадает в Claude, и этот сервер никогда его не хранит.

Вход через службу учётных записей вместо этого

WJ_LOGIN_MODE=redirect заменяет форму выше. /authorize отправляет браузер на страницу входа в службу учётных записей для данной среды, участник входит там, и служба учётных записей возвращает его на /identifier с кратковременным маркером передачи, который этот сервер обменивает на сеанс. Отсюда следуют две вещи: пароль не вводится на странице, которую отображает этот сервер, и участник одновременно входит в веб-приложения BeSimplified, потому что сеанс — это тот, который служба учётных записей создала на своём собственном домене.

Он отключён по умолчанию, потому что у него есть предварительные условия, которых нет у режима формы:

  • Запись app_registrations в службе учётных записей, указывающая хост этого сервера как проверенный fqdn или как workspace, в каждой организации, члены которой его используют. Страница входа берёт хост из переданного ей referrer и ищет его; без записи она отвечает valid_workspace: false и возвращает браузер в приложение HR, а не сюда. Это запись в собственной базе данных службы учётных записей — код там не меняется.

  • WJ_PUBLIC_BASE_URL как https без порта. Служба учётных записей перестраивает обратный вызов как https://<host>/identifier только по имени хоста, поэтому порт или схема без шифрования не могут его получить. В противном случае сервер отказывается запускаться, а не обслуживает вход, который может начаться и никогда не завершиться.

  • Доступ на чтение к хранилищу сеансов учётных записей, WJ_REDIS_HOST и WJ_ACC_CACHE_PREFIX. Маркер передачи указывает на ключ там; без него нечего обменивать на маркер.

Хост обратного вызова проверяется по списку разрешённых в обоих режимах. Здесь это важнее: как только участник проходит аутентификацию в службе учётных записей, тот, кто назвал redirect_uri, получает код авторизации, и PKCE не помогает против злоумышленника, который начал поток.

Related MCP server: zulip-mcp

Инструменты

work_journal_get_entries

Записи с полной детализацией задач за дату или диапазон до 31 дня.

параметр

примечания

date

один день, YYYY-MM-DD

start_date, end_date

включающий диапазон, используется вместо date

type

необязательно, см. таблицу псевдонимов ниже; опустите для всех типов

member

необязательно, идентификатор другого участника из work_journal_find_member

include_tasks

необязательно, по умолчанию true; false возвращает только статусы, одним запросом

Спросите: "покажи мои записи EOD за прошлую неделю"

work_journal_get_day

Одна дата полностью: каждая задача с заметками и вложениями, уведомлённые получатели, срок выполнения и время отправки.

параметр

примечания

date

обязательно, YYYY-MM-DD

type

необязательно, сужает до одного типа записи

member

необязательно, идентификатор другого участника

Спросите: "что я записал 4 августа?"

work_journal_get_summary

Подсчёты по типу и статусу за любой период, без детализации по дням. Используйте это для периодов длиннее 31 дня.

параметр

примечания

start_date, end_date

включающий диапазон

year

весь календарный год, используется, когда явный диапазон не задан

type

необязательно

member

необязательно, идентификатор другого участника

Спросите: "сколько отчётов EOW я пропустил в этом году?"

work_journal_find_member

Находит коллегу по части имени или адреса электронной почты и возвращает его идентификатор участника для использования в качестве member в инструментах выше.

параметр

примечания

query

часть имени или адреса электронной почты, не менее двух символов

Спросите: "найди идентификатор участника Рахула"

work_journal_get_team_report

По одной строке на участника с подсчётами отправленных, ожидающих и пропущенных записей за период.

параметр

примечания

start_date, end_date

обязательно, включающий диапазон

type

необязательно, по умолчанию EOD

team

необязательно, идентификатор команды или литерал unassigned

status

необязательно: submitted, pending или missed

member

необязательно, сужает до одного участника

limit, page

необязательно; по умолчанию 15 строк, максимум 50

Спросите: "кто пропустил свой EOD на прошлой неделе?"

Псевдонимы типов

вы можете сказать

разрешается в

отображается как

eod, daily, end of day

daily

EOD

eow, weekly, end of week

weekly

EOW

group eow, group weekly

group_weekly

Group EOW

eom, monthly, end of month

monthly

EOM

Сопоставление не учитывает регистр и считает пробелы, дефисы и подчёркивания эквивалентными.

Кто может видеть чей журнал

Этот сервер не применяет никаких собственных разрешений. Каждый запрос несёт ваш собственный сеанс Simplified HR, и API Work Journal применяет ровно те разрешения, которые он применяет в веб-интерфейсе:

  • Разрешение экземпляра — вы можете читать любого участника вашей компании

  • Групповое разрешение — вы можете читать участников в вашем поддереве отчётности

  • Ни то, ни другое — вы можете читать только свой собственный журнал, и любая попытка прочитать журнал другого участника отклоняется

Две вещи, которые нужно знать при чтении записей коллеги: запрос может быть отклонён outright, а представление администратора исключает черновики, запланированные и приватные записи. Поэтому отсутствующая запись не доказывает, что ничего не было записано.

Ограничения

  • work_journal_get_entries отклоняет диапазоны длиннее 31 дня и направляет вас к work_journal_get_summary

  • Одновременно выполняется не более 4 запросов на вызов инструмента, поэтому широкий диапазон остаётся щадящим для API

  • Относительные даты, такие как "прошлая неделя", разрешаются Клодом перед вызовом; инструменты принимают только YYYY-MM-DD

Запуск локально

npm install
cp .env.example .env      # then fill in the two secrets
WJ_ENV=dev \
WJ_PUBLIC_BASE_URL=http://localhost:8080 \
WJ_TOKEN_KEY=$(openssl rand -hex 32) \
WJ_FINGERPRINT_SECRET=$(openssl rand -hex 32) \
npm start

GET /healthz должен ответить {"status":"ok"}. Запуск node src/index.js без окружения должен немедленно завершиться, перечислив все отсутствующие переменные.

Окружение

переменная

требуется

назначение

WJ_ENV

да

выбирает пресет хоста: dev или prod. Значения по умолчанию нет, поэтому пустое значение не может молча направить продакшн на dev-хосты

WJ_PUBLIC_BASE_URL

да

внешне доступный origin, публикуется в документах обнаружения OAuth

WJ_TOKEN_KEY

да

64 шестнадцатеричных символа; шифрует конверт сеанса

WJ_FINGERPRINT_SECRET

да

не менее 32 символов; выводит отпечаток устройства каждого участника

WJ_API_BASE_URL

нет

хост плагинного API, когда он отличается от пресета для WJ_ENV

WJ_AUTH_BASE_URL

нет

origin службы учётных записей, когда он отличается от пресета

WJ_PORT

нет, по умолчанию 8080

порт прослушивания

WJ_REQUEST_TIMEOUT_MS

нет, по умолчанию 15000

таймаут на запрос

WJ_EXTRA_REDIRECT_HOSTS

нет

дополнительные хосты обратного вызова, через запятую, помимо claude.ai, anthropic.com и loopback

WJ_LOGIN_MODE

нет, по умолчанию form

form или redirect; см. ниже

WJ_REDIS_HOST

только когда WJ_LOGIN_MODE=redirect

хранилище сеансов учётных записей

WJ_REDIS_PORT

нет, по умолчанию 6379

WJ_REDIS_TLS

нет

true для подключения через TLS с проверкой сертификата

WJ_REDIS_TLS_SERVERNAME

нет

имя, на которое выдан сертификат Redis, когда оно отличается от подключаемого хоста

WJ_REDIS_TLS_INSECURE

нет

true отключает проверку сертификата; только как крайняя мера

WJ_ACC_CACHE_PREFIX

только когда WJ_LOGIN_MODE=redirect

собственный CACHE_PREFIX службы учётных записей, который она также возвращает как sso_prefix

WJ_FINGERPRINT_SECRET должен быть одинаковым для каждой задачи и не должен ротироваться без необходимости. Он выводит стабильный отпечаток устройства каждого участника; его изменение заставит всю команду снова проходить проверочный код.

Заметки по развёртыванию

  • Прилипание cookie на /authorize требуется только при WJ_LOGIN_MODE=form. В режиме redirect между двумя этапами в памяти процесса ничего не хранится — запрос авторизации возвращается из сервиса учётных записей в зашифрованном токене redirect_page, — поэтому /authorize и /identifier не хранят состояние и не требуют прилипания.

  • Прилипание cookie требуется только на /authorize. Отправка OTP должна попасть в ту задачу, которая начала вход, потому что незавершённый вход хранится в памяти этого процесса в течение пяти минут. /mcp и /token не хранят состояние и не должны быть липкими.

  • Оба секрета должны храниться в SSM Parameter Store как SecureString и ссылаться из блока secrets определения задачи — никогда не как литералы окружения. Создайте их один раз для каждого окружения перед первым развёртыванием; ничто другое на платформе не использует префикс /hr/work-journal-mcp/, поэтому их ещё не существует:

    aws ssm put-parameter --type SecureString --name /hr/work-journal-mcp/<env>/token_key           --value "$(openssl rand -hex 32)"
    aws ssm put-parameter --type SecureString --name /hr/work-journal-mcp/<env>/fingerprint_secret  --value "$(openssl rand -hex 32)"

    Роли ecsTaskExecutionRole нужны права ssm:GetParameters и kms:Decrypt на оба секрета, иначе задача завершится ошибкой ResourceInitializationError при запуске, до того как начнёт выполняться этот код.

  • Продакшен отклоняет поле входа workspace, которое требуется в dev, поэтому страница входа скрывает его вне dev.

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

  • Пароли никогда не хранятся, не логируются и не возвращаются в браузер в каком-либо виде. Они существуют только в памяти, на те секунды, что длится вход.

  • Состояние сессии передаётся в зашифрованном конверте AES-256-GCM, который может открыть только этот сервер. Simplified HR JWT никогда не попадает к Claude или модели.

  • Конверты access, refresh и authorization-code криптографически привязаны к своему типу, поэтому один нельзя использовать вместо другого.

  • Попытки входа ограничены по частоте для каждого адреса электронной почты.

  • Каждый вызов инструмента логируется с указанием вызывающего, инструмента и участника, чей журнал был прочитан, поэтому чтения между участниками поддаются аудиту. Токены и содержимое записей никогда не логируются.

Тесты

npm test

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Read-only MCP server that proxies deepHR's API to MCP clients, enabling interaction with deepHR modules such as payroll and employees through natural language.
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    A read-only MCP server that gives Claude safe access to Kubernetes clusters, enabling listing, describing, and monitoring resources without mutation risks and with secret masking.
    1
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    A local MCP server that reads logged hours from an internal time tracker, providing tools to list time entries, projects, and the active timer. It is read-only, enabling Claude Code to see time-tracking data without writing.
    -