habitica-mcp
habitica-mcp
MCP-сервер для самостоятельно размещаемого экземпляра Habitica, работающий поверх Streamable HTTP, чтобы его можно было запускать как обычный сетевой сервис, а не как подпроцесс stdio на одного клиента.
Зачем это существует
Существующий community-сервер (iBreaker/habitica-mcp-server) зашивает https://habitica.com/api/v3, работает только через stdio и не поддерживается уже через три дня после своего создания. Всё это не подходит для самохостируемого экземпляра за ingress-контроллером.
Здесь HABITICA_BASE_URL обязательна и не имеет значения по умолчанию — ошибочное указание на другой экземпляр становится невозможным, а не лишь не рекомендуется.
Related MCP server: habitca-mcp
Инструменты
Инструмент | Примечания |
| Необязательный фильтр по типу; история исключена (см. ниже) |
| |
| Не идемпотентен — Habitica не имеет ключа идемпотентности |
| Частичное обновление |
| Деструктивная операция |
| Деструктивное — изменяет золото/опыт/серии и не может быть отменено |
| |
| Принимают имя тега, которое преобразуется в его UUID |
| Серверная проекция, а не полный документ пользователя |
Конфигурация
Переменная | Обязательность | По умолчанию | Назначение |
| да | — | например, |
| да | — |
|
| да | — |
|
| нет | (пусто — проверка отключена) | Разрешённый список Host (через запятую) для |
| нет |
| |
| нет |
| |
| нет |
|
Эндпоинты: POST/GET/DELETE /mcp и GET /healthz.
Заметки по дизайну
Четыре важных и неочевидных решения:
Проекция ответа, а не пагинация
GET /tasks/user в Habitica возвращает history: [{date, value}] для каждой привычки и ежедневной задачи — по одной записи на каждое событие начисления очков за всё время жизни аккаунта, и эта опция включена по умолчанию. API не предоставляет limit/offset, поэтому решением является проекция: этот сервер всегда отправляет history=false и дополнительно проецирует каждую задачу на фиксированный набор полей, чтобы изменение схемы на стороне API не могло незаметно внести сотни килобайт в контекст модели. get_user_stats использует ?userFields= по той же причине.
Фильтр списка — во множественном числе и неправильный. GET /tasks/user?type= принимает habits | dailys | todos | rewards | completedTodos (обратите внимание на dailys), тогда как тело запроса создания использует единственное число habit | daily | todo | reward. Инструменты отдают пользователю единственное число и преобразуют его внутри; передача единственного числа в эндпоинт списка даёт ошибку 400.
Проверка Host ограничена только /mcp, никогда не распространяется на всё приложение. createMcpExpressApp применяет её глобально, что сломало бы и пробы kubelet (при httpGet-пробе отправляется Host: <podIP>, а IP-адреса подов нельзя добавить в список разрешённых), и blackbox-мониторинг (он отправляет Host: <твщество>.<namespace>.svc). Поэтому /healthz находится вне проверки; он не раскрывает ничего, а защита от DNS-rebinding важна только для JSON-RPC.
/healthz сообщает только о живости процесса — и никогда о доступности Habitica. Проверка связанности с Habitica превратила бы её перезапуск в CrashLoopBackOff, и тогда liveness-проба продолжала бы убивать процесс, который полностью здоров и просто не можем общаться. Сбои Habitica видны как чистая ошибка JSON-RPC в отдельном инструменте.
Транспорт
Stateless Streamable HTTP (sessionIdGenerator: undefined), построенный на @modelcontextprotocol/server v2 — текущей стабильной основной версии, чей HTTP-транспорт находится в отдельных адаптерах @modelcontextprotocol/express / @modelcontextprotocol/node. Согласованная версия протокола — 2025-11-25 (LATEST_PROTOCOL_VERSION в SDK); v1.x теперь выпускается только с исправлениями безопасности и ошибок.
Новый экземпляр McpServer + транспорт создаётся на каждый запрос и уничтожается по событию close ответа. Создание на каждый запрос обязательно, а не просто для порядка: SDK v1 явно выбрасывает исключение при повторном использовании stateless-транспорта («Stateless transport cannot be reused across requests»), поскольку это вызывает коллизии идентификаторов сообщений между одновременно работающими клиентами.
Стоимость такого подхода реальна и о ней стоит знать: каждый запрос пересобирает ~11 конвертаций zod→JSON-Schema, что составляет примерно 0,5 МБ мусора на вызов. Этот мусор перерабатывается при работе GC (1500 последовательных вызовов стабилизировались на ~193 МиБ при ограничении кучи в 96 МиБ), а не утекают, но именно поэтому при деплое запрашивается больше памяти, чем говорит потребление в известных процессах.
GET /mcp возвращает 405 с Allow: POST. Это допускается спецификацией (сервер может отказать в простоте потоку) и именно этого ожидает MCP-клиент: он обрабатывает 405 как «здесьнет ещё и поток сервера» и останавливается.
Более ранняя версия пыталась пойти навстречу, возвращая пустой SSE-поток. Это привело к бесконечному циклу переподключения: клиент интерпретирует чисто завершённый поток без ответа как потерь соединения и планирует новое подключение, но счётчик повторных попыток увеличивается только при ошибке, потону успешный пустой поток не сбрасывал ничего. Зазмер показал \~1 запрос/сек вечно — 1 → 4 → 8 → 12 GET-запросов за 12 с бездействия, примерно 86 000 запросов в день на подключённого клиента, без каких-либо ошибок где-либо. Возврат 405 удерживает это значение ровно на 1.
Отсутствие (stateless) имеет реальную стоимость, а не только плюсы: двусторонние обмены сервер→клиент (sampling, elicitation) и незапрашиваемые уведомления *ListChanged не могут работать, потому что ответ клиента приходит как отдельный HTTP-запрос, попадающий на новый экземпляр сервера, у которого нет никакой памяти о ожидающем вызове. Уведомления о прогрессе работают — они идут через исходный поток самого запроса. Для CRUD-инструментов это неважно, но не имеся на этих возможностях не стоит строить.
Безопасность
Эндпоинт /mcp не требует аутентификации. Учетные данные Habitica живут на стороне сервера, поэтому любой, кто может получить доступ к эндпоинту, может читать и записывать весь список задач аккаунта. Это осознанное решение: auth-прокси перед MCP-эндпоинтом ломает работу клиентов MCP — и именно поэтому деплой ограничен частной сетью и одним экземпляром.
API-токен — это учётные данные на уровне пользователя Habiticа (хранится в открытом виде самим Habitica), поэтому утечка токена означает полную компрометацию аккаунта. Вся запись ляёт через редактирующую оболочку, а набор теста`и проверяет, что токен никогда не проявляется ни в одной строке.
Разработка
npm ci
npm test
npm run lint && npm run typecheck
npm run build && node dist/index.jsЛицензия
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Host any HTTP API as a standard MCP server; auto-distribute to 12+ mainstream agent platforms.
The **OTTTA MCP server** lets you manage your habit trackers. Add / create / update / delete groups, trackers and values. The idea behind OTTTA is to make tracking very easy. The app is simple, you create groups, in the groups you put things to track on a daily basis and then it generates graphs. You can log values to the trackers via the [OTTTA website](https://ottta.com/), via our API, our MCP of course and via the OTTTA Chrome Extension. Soon more ways will be available.
Remote MCP server exposing SMI Aware tools, resources, and skills over Streamable HTTP.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA standalone MCP server for managing habits and quit trackers through a jhabit instance. It enables users to list trackers, log entries, and retrieve detailed statistics like streaks and abstinence time.-
- AlicenseBqualityDmaintenanceExposes the Habitica v3 API as MCP tools, allowing AI assistants to read and manage tasks, habits, dailies, rewards, pets, inventory, and notifications.28MIT
- AlicenseCqualityDmaintenanceHabitica MCP server built with Effect v4, currently exposing a hello-world tool, resource, and prompt over stdio for early development and testing.124 npmMIT
- AlicenseNot gradedqualityDmaintenanceMCP server for managing Habitica as a daily execution layer, enabling agents to read and (with explicit confirmation) create, complete, and score tasks via the Habitica API.24 npmMIT