Skip to main content
Glama

Chakudya MCP Server

Сервер MCP (Model Context Protocol), который предоставляет API Chakudya Nutrition Registry (CNR) в виде набора MCP-инструментов, чтобы любой MCP-совместимый клиент (Claude, Claude Code, другие LLM-агенты) мог искать данные о малавийских продуктах, выполнять клинические запросы по питанию и напрямую обращаться к базе знаний RAG.

Это новый отдельный слой. Он не заменяет и не изменяет Chakudya Worker. Это небольшой HTTP-сервис на Node/TypeScript, который располагается перед вашим существующим API и преобразует вызовы MCP-инструментов в обычные HTTP-запросы к маршрутам, которые ваш Worker уже обслуживает.

MCP Client (Claude, etc.)
        │  Streamable HTTP (JSON-RPC over HTTP + SSE)
        ▼
Chakudya MCP Server  (this project)
        │  plain HTTPS fetch()
        ▼
Chakudya Worker API  (unchanged) → Supabase / Cohere / Groq / USDA / OFF / FatSecret

Почему отдельный сервер, а не Worker

StreamableHTTPServerTransport из официального TypeScript SDK MCP создан для http.IncomingMessage/ServerResponse из Node. Cloudflare Workers вместо этого используют Fetch API, а веб-стандартный вариант SDK (WebStandardStreamableHTTPServerTransport) новее и менее проверен для управления сессиями в продакшене. Запуск этого в виде обычного Node-сервиса (Docker, Render, Fly.io, VPS и т.д.) — более стандартный и лучше документированный путь на сегодня, и он полностью отделяет эту задачу от цикла развёртывания вашего Worker. Ничто не мешает вам позже перенести его на веб-стандартный транспорт в Workers, если вы хотите развёртывание на одной платформе — логика инструментов в src/tools/* не зависит от того, какой транспорт её оборачивает.

Related MCP server: MCP Task Assistant

Инструменты

Все 31 инструмент либо обращаются к вашему существующему Chakudya Worker по HTTPS, либо представляют собой чистые внутрипроцессные вычисления/поиск по таблицам — ни один из них не обращается напрямую к Supabase, Cohere или Groq, и ни одному не нужен ADMIN_API_KEY (все используемые ими маршруты являются публичными).

Инструмент

Используемые маршруты Chakudya

search_food

GET /foods → возвращается к GET /foods/lookup

get_food_details

GET /foods/:id

calculate_nutrients

GET /foods или /foods/:id, затем масштабирует значения на 100 г в процессе

analyze_meal

то же, что выше, в цикле с суммированием по нескольким позициям

barcode_lookup

GET /packaged?barcode= → возвращается к GET /foods/lookup?barcode=

packaged_food_search

GET /packaged и/или GET /products

diabetes_exchange_lookup

GET /exchange

renal_exchange_lookup

GET /renal

enteral_formula_lookup

GET /formulas

nutrition_calculator

нет — чистые расчёты BMI/BMR (Mifflin-St Jeor)/TDEE

rag_retrieve

POST /rag/retrieve

search_guidelines

POST /rag/ask (context: "clinical")

retrieve_evidence

POST /rag/ask (context: "both", выше top_k)

disease_information

POST /rag/ask, запрос сформулирован для образовательного обзора заболеваний

medicine_information

POST /rag/ask, запрос явно настроен на исключение дозировок/назначений

pediatric_fluid_requirements

нет — чистые расчёты по Holliday-Segar

pediatric_energy_requirements

нет — чистые расчёты Schofield/WHO BMR + DRI/FAO 2004 + DRI/IOM 2006

pediatric_protein_requirements

нет — чистый поиск по таблицам IOM 2005 / ASPEN для больных детей / недоношенных

pediatric_growth_velocity

нет — чистый поиск по таблицам скорости роста из справочника ASPEN

pediatric_enteral_feed_advancement

нет — чистый поиск по таблицам протокола энтерального питания

iom_dri_eer_calculator

нет — чистые расчёты по уравнениям прогнозирования EER IOM/DRI (2002/2005), все возрастные группы

met_activity_energy_calculator

нет — чистые расчёты MET x вес x длительность

alcohol_kcal_calculator

нет — чистые расчёты объём x крепость

respiratory_quotient_interpreter

нет — чистая интерпретация референсных значений RQ

preterm_fluid_energy_requirements

нет — чистый поиск по таблицам жидкости/энергии для недоношенных

macronutrient_distribution_check

нет — чистый поиск по таблицам диапазонов % макронутриентов DRI

tee_activity_band_estimator

нет — чистые расчёты REE x множитель уровня активности

fever_stress_ree_adjustment

нет — чистые расчёты корректировки REE при лихорадке

atwater_food_energy_calculator

нет — чистые расчёты по факторам Atwater (4/9/4/7)

dri_eer_reference_lookup

нет — чистый поиск по справочной таблице DRI Table 2.2

who_growth_zscore

нет — чистый расчёт z-показателя/процентиля по референсу роста WHO LMS (вес-к-возрасту, рост-к-возрасту, ИМТ-к-возрасту 0-5 лет, ИМТ-к-возрасту 5-19 лет, окружность головы-к-возрасту, вес-к-длине, вес-к-росту)

disease_information и medicine_information всегда возвращают образовательный дисклеймер вместе с ответом и настроены на избегание формулировок о диагностике/назначении — но это всё равно текст, сгенерированный LLM на основе содержимого вашей базы знаний RAG, а не проверенный медицинский справочник. Относитесь к ним как к отправной точке для обучающегося, как и к остальным инструментам на базе RAG.

Инструменты pediatric_* (источник: BND 415 Clinical Nutrition — Paediatric Medicine Resources) и iom_dri_eer_calculator/met_activity_energy_calculator/alcohol_kcal_calculator/respiratory_quotient_interpreter (источник: Nelms/Ireton-Jones, Nutrition Therapy and Pathophysiology, гл. 2) — это чистые инструменты расчёта/поиска: без сетевых вызовов, без зависимости от данных CNR. Применимо то же предупреждение о приблизительности: они не заменяют индивидуальную клиническую оценку или измеренную непрямую калориметрию.

Структура проекта

src/
├── index.ts                 Express app, Streamable HTTP session wiring, graceful shutdown
├── config/env.ts            Zod-validated environment config, loaded once at startup
├── clients/chakudyaClient.ts  Fetch wrapper for the Chakudya Worker (GET/POST, error normalization)
├── server/
│   ├── createServer.ts      Builds one McpServer instance and registers all tool modules
│   └── security.ts          Bearer auth + per-IP rate limiting for this server's /mcp endpoint
├── tools/
│   ├── foodTools.ts
│   ├── clinicalTools.ts
│   ├── ragTools.ts
│   ├── educationTools.ts
│   ├── pediatricTools.ts        Pediatric fluid/energy/protein/growth/enteral-feed calculators
│   └── energyExpenditureTools.ts  IOM/DRI EER, MET activity, alcohol kcal, RQ interpreter
│   └── whoGrowthTools.ts        WHO Child Growth Standards z-score/percentile calculator (LMS)
├── data/
│   └── who/                     WHO Child Growth Standards LMS tables (JSON, per standard+sex)
└── utils/
    ├── logger.ts             Structured JSON logging
    └── toolResult.ts         Consistent success/error shaping for every tool handler

Переменные окружения

Скопируйте .env.example в .env и заполните:

Переменная

Обязательна

Примечания

CHAKUDYA_API_BASE_URL

нет (по умолчанию — собственный Worker владельца)

Если вы форкаете этот репозиторий, чтобы использовать собственный экземпляр CNR, укажите URL своего Worker'а вместо значения по умолчанию

CHAKUDYA_ADMIN_API_KEY

нет

Не используется ни одним текущим инструментом; понадобится только если вы добавите позже инструмент с админ-доступом

PORT

нет (по умолчанию 8787)

MCP_AUTH_TOKEN

да, в продакшене

Bearer-токен, который обязаны отправлять MCP-клиенты. Сервер отказывается запускаться в продакшене без него

MCP_ALLOWED_ORIGINS

нет

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

MCP_RATE_LIMIT_PER_MIN

нет (по умолчанию 60)

Ограничение на IP для собственной конечной точки /mcp этого сервера

NODE_ENV

нет (по умолчанию development)

Установите production для деплоев

Вопросы безопасности

  • Аутентификация обязательна в продакшене. env.ts завершает процесс при запуске, если NODE_ENV=production, а MCP_AUTH_TOKEN не задан — это намеренная проверка с отказом по умолчанию, а не просто предупреждение.

  • Этот сервер находится перед вашими RAG-маршрутами с ограничением частоты. /rag/ask на вашем Worker'е ограничен 15 запросами в минуту на IP — но это ограничение на клиентский IP, как его видит Worker, а после деплоя это будет IP этого сервера, общий для всех, кто им пользуется. Ограничитель частоты на уровне MCP (MCP_RATE_LIMIT_PER_MIN) существует для того, чтобы один проблемный MCP-клиент не мог незаметно исчерпать этот бюджет для всех остальных. Уменьшите его, если ожидаете несколько одновременных MCP-клиентов.

  • Админ-ключ не встроен и не требуется. Каждый инструмент вызывает публичный маршрут CNR. Если вы добавите позже инструмент с админ-доступом, храните CHAKUDYA_ADMIN_API_KEY только на стороне сервера — никогда не раскрывайте его MCP-клиенту.

  • Состояние сессии хранится в памяти, в рамках процесса. Это нормально для одного экземпляра. Если вы когда-нибудь масштабируетесь до нескольких экземпляров за балансировщиком нагрузки, либо включите липкие сессии (маршрутизация по Mcp-Session-Id), либо замените карту transports в src/index.ts на общее хранилище.

  • CORS по умолчанию выключен. Включайте MCP_ALLOWED_ORIGINS только если у вас есть конкретный браузерный MCP- клиент; сервер-к-серверу MCP-клиентам (Claude Desktop, Claude Code и т.д.) он не нужен.

Локальный запуск

cd ~
git clone https://github.com/edisontaimu9-ui/chakudya-mcp-server.git
cd chakudya-mcp-server
cp .env.example .env
# edit .env: set MCP_AUTH_TOKEN to a long random string
npm install
npm run build
npm start

Или для итеративной разработки с автоперезагрузкой:

npm run dev

Проверка работоспособности: curl http://localhost:8787/health

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

Направьте любой MCP-клиент с поддержкой Streamable-HTTP на:

POST/GET/DELETE  https://<your-deployed-host>/mcp
Header: Authorization: Bearer <MCP_AUTH_TOKEN>

Для Claude Desktop / Claude Code добавьте его как удалённый MCP-сервер, указав этот URL с тем же bearer-токеном. Сверьтесь с актуальной документацией Anthropic по точному синтаксису файла конфигурации, поскольку он менялся со временем — проверьте https://docs.claude.com на предмет последнего формата удалённого сервера mcpServers.

Деплой на Render (рекомендуется — бесплатно, без кредитной карты)

В этом репозитории есть render.yaml, поэтому функция Blueprint от Render разворачивает его без какой-либо ручной настройки в панели управления.

  1. Запушьте этот репозиторий на GitHub (команды ниже).

  2. В панели Render: New → Blueprint, подключите свой аккаунт GitHub, выберите репозиторий chakudya-mcp-server. Render прочитает render.yaml автоматически.

  3. Render предоставит сервис на плане Free и автоматически сгенерирует случайный MCP_AUTH_TOKEN (через generateValue: true). После первого деплоя перейдите на вкладку Environment сервиса, чтобы скопировать сгенерированный токен — он понадобится вам в конфигурации MCP-клиента.

  4. Деплой. Ваша MCP-конечная точка будет https://<имя-вашего-сервиса>.onrender.com/mcp (проверьте в панели Render ваш фактический сгенерированный URL — он может содержать случайный суффикс, если выбранное вами имя занято).

Проблема засыпания на бесплатном тарифе и её решение

Бесплатные веб-сервисы Render выключаются через 15 минут без трафика, а затем тратят 30–60 секунд на пробуждение при следующем запросе. Для проверки работоспособности это нормально, но это может оборвать выполняющуюся MCP-сессию (состояние сессии хранится в памяти — см. src/index.ts), если клиент замолчит посреди разговора слишком надолго.

Решение: поддерживайте сервис в активном состоянии с помощью бесплатного монитора аптайма, пингующего /health каждые 5–10 минут.

  1. Зарегистрируйтесь на uptimerobot.com (бесплатный план, без карты).

  2. Добавьте новый монитор HTTP(s):

    • URL: https://<ваш-сервис>.onrender.com/health

    • Интервал: 5 минут

  3. Сохраните. /health намеренно не требует аутентификации, специально чтобы этому монитору не нужен был ваш MCP_AUTH_TOKEN.

Это поддерживает сервис активным 24/7 в рамках 750 часов в месяц бесплатного плана (с большим запасом для одного сервиса, пингуемого таким образом).

Обновление после изменения кода

Render автоматически передеплоивает при каждом пуше в подключённую ветку — дополнительных действий не нужно:

git add .
git commit -m "Update MCP server"
git push

Следите за деплоем на вкладке Events в панели Render; для проекта такого размера он обычно завершается за 1–2 минуты.

Другие варианты деплоя

Docker где угодно

docker build -t chakudya-mcp-server .
docker run -d -p 8787:8787 \
  -e NODE_ENV=production \
  -e MCP_AUTH_TOKEN=<long-random-string> \
  -e CHAKUDYA_API_BASE_URL=<your-chakudya-worker-url> \
  --name chakudya-mcp chakudya-mcp-server

Обычный VPS с менеджером процессов

npm install --omit=dev
npm run build
npx pm2 start dist/index.js --name chakudya-mcp

Поместите его за Nginx/Caddy для завершения TLS, если вы ещё не используете что-то, что обрабатывает HTTPS.

Обновление через командную строку

cd ~
# first time only:
git clone https://github.com/edisontaimu9-ui/chakudya-mcp-server.git
cd chakudya-mcp-server

# after any file update:
cp <path-to-updated-file>.ts src/<path>/<updated-file>.ts
git add .
git commit -m "Update MCP server"
git push

Затем передеплойте на выбранной вами платформе (Render/Railway/Fly автоматически передеплоивают при пуше, если вы подключили репозиторий GitHub; в противном случае запустите ручной передеплой или повторно выполните команды Docker/pm2 выше на вашем хосте).

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Exposes retrieval capabilities of two RAG systems as authenticated MCP tools, allowing any MCP client to perform graph-augmented and hybrid retrieval with JWT auth.
    1
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Exposes an existing RAG API as MCP tools, enabling health checks and document-based question answering with source evidence.
    -
  • F
    license
    A
    quality
    C
    maintenance
    MCP bridge to a multimodal RAG service, enabling hybrid search and Q&A over documents with tools for knowledge base queries and health checks.
    4
    -