Skip to main content
Glama

Custom Framework MCP

MCP-сервер для внутренней документации построенной на основе Markdown-документации. Строит легковесный индекс и предоставляет инструменты для поиска и объяснений. Так же включает crawler, который может скачивать документацию Xafari с официального сайта, извлекать чистый текст и примеры кода.

Зачем нужен MCP

MCP (Model Context Protocol) позволяет IDE и агентам обращаться к локальным данным как к «инструментам». Вместо ручного поиска по сайту документации, ассистент вызывает методы search_docs, get_page и get_examples, а сервер отвечает структурированными данными. Это ускоряет работу, дает воспроизводимые ответы и снижает зависимость от внешних источников.

Как MCP ускоряет работу:

  • Меньше ручного поиска: вместо переходов по сайту и копипасты — один вызов search_docs/get_page.

  • Мгновенная выборка: локальный индекс и кэш дают ответы быстрее, чем браузер + поиск.

  • Точнее ответы: инструменты возвращают структуру (заголовки, ссылки, код), а не разрозненный текст.

  • Повторяемость: один и тот же запрос даёт одинаковый результат — удобно для командной работы.

  • Автодогрузка: если страницы нет в кэше, get_page может скачать её автоматически.

  • Офлайн-режим: можно работать без доступа к сайту после первичного краула.

Как работает MCP в этом проекте

  • Краулер

    • Скачивает HTML, извлекает читабельный markdown и сохраняет в data/pages.

    • Кэширует страницы и использует ETag/Last-Modified при повторных запусках.

    • Из markdown строится индекс pages.json + index.json для быстрого поиска.

  • MCP-сервер читает индекс и отвечает на вызовы инструментов через stdio/http.

  • IDE подключается к серверу и использует инструменты прямо в чате.

Быстрый старт

  1. Запустить краулер и собрать локальный индекс:

    • npm run crawl

  2. Запустить MCP-сервер (stdio):

    • npm run start

  3. Запустить HTTP-режим (опционально):

    • npm run start:http

  4. Пересобрать индекс без краулинга:

    • npm run reindex

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

  • DOCS_BASE_URL (например: https://documentation.galaktika-soft.com/xafari/)

  • MAX_PAGES_PER_SESSION (по умолчанию: 10000)

  • FETCH_ON_MISS (по умолчанию: true, только если задан DOCS_BASE_URL)

  • DATA_DIR (по умолчанию: ./data)

  • REQUEST_TIMEOUT_MS (по умолчанию: 15000)

  • USER_AGENT

  • LOG_FILE (по умолчанию: logs/mcp.jsonl, путь относительно DATA_DIR)

  • LOG_STDOUT (по умолчанию: false) — если true, логи дублируются в stdout (удобно в Docker)

  • CODE_LANGUAGES (по умолчанию: cs,js,ts,json,yaml,xml,html,css)

  • HTTP_PORT (по умолчанию: 3333)

  • TOOLS_PREFIX — если задана (непустая), инструменты будут иметь имена вида ${TOOLS_PREFIX}search_docs, ${TOOLS_PREFIX}get_page, ...

Примеры кода

  • Примеры сохраняются только для языков из CODE_LANGUAGES.

  • Языки нормализуются: c#/csharpcs, javascriptjs, typescriptts, ymlyaml.

  • Если язык не разрешен — блок кода не сохраняется.

Fetch on miss

get_page может автоматически догружать страницу, если ее нет в кэше. Управляется флагом FETCH_ON_MISS (по умолчанию true если задан DOCS_BASE_URL).

Подключение MCP в IDE на примере Cursor

stdio-режим (локальный запуск)

  1. Откройте настройки MCP в Cursor.

  2. Добавьте новый сервер со следующими параметрами:

    • name: custom-framework-mcp

    • command: node

    • args: ["C:\\Projects\\custom-framework-mcp\\src\\index.js"]

    • cwd: C:\\Projects\\custom-framework-mcp

Пример ~/.cursor/mcp.json

{ "mcpServers": { "custom-framework-mcp": { "command": "node", "args": ["C:\\Projects\\custom-framework-mcp\\src\\index.js"], "cwd": "C:\\Projects\\custom-framework-mcp" } } }

stdio-режим (через Docker)

Если сервис запущен в Docker, можно использовать docker exec:

{ "mcpServers": { "custom-framework-mcp": { "command": "docker", "args": ["exec", "-i", "mcp-service", "node", "/app/src/index.js"] } } }

HTTP-режим (SSE)

Если сервис запущен в HTTP-режиме (например, через docker compose), используйте SSE transport:

{ "mcpServers": { "custom-framework-mcp": { "url": "http://localhost:3333/sse" } } }

Примечание: HTTP-режим требует, чтобы сервис был запущен с npm run start:http или через docker compose (который автоматически запускает HTTP-сервер).

  1. Перезапустите MCP-сервер в Cursor.

Чтобы проверить в окне чата напишите

list tools

Запросите какую-либо документацию с источника

Запуск через docker compose

git clone https://github.com/QuAzI/custom-framework-mcp.git cd custom-framework-mcp docker compose up -d

Запуск через npx

Локально в репозитории:

  • npm install

  • npx . — запустит MCP-сервер (stdio) через src/index.js.

Чтобы запускать из любого каталога:

  • npm link

  • npx --no-install custom-framework-mcp

Запуск прямо из GitHub (без публикации в npm):

  • npx github:QuAzI/custom-framework-mcp

Опции краулера:

  • npm run crawl — по умолчанию скачивает только новые страницы.

  • npm run crawl -- --force — перекачать все страницы.

  • npm run crawl -- --no-only-new — отключить режим "только новые".

Примечание:

  • --no-only-new делает полный обход с кешем (ETag/Last-Modified), а --force перекачивает все без учета кеша.

GitLab CI/CD (внешний репозиторий документации → индекс → деплой на VM)

В репозитории есть пример пайплайна .gitlab-ci.yml для сценария:

  • скачать документацию из внешнего git-репозитория

  • собрать индекс из markdown (npm run reindex, данные в DATA_DIR/pages)

  • задеплоить на VM по SSH и перезапустить docker compose, чтобы HTTP-сервер поднялся с актуальными pages.json/index.json

CI/CD variables (настраиваются в GitLab → Settings → CI/CD → Variables)

Переменные для скачивания документации:

  • DOCS_REPO_URL — URL внешнего репозитория документации (SSH или HTTPS)

  • DOCS_REF — ветка/тег (по умолчанию: main)

  • DOCS_SUBDIR — подкаталог в репозитории документации с markdown-деревом (по умолчанию: docs)

  • DOCS_SSH_PRIVATE_KEYопционально, SSH ключ для доступа к docs repo (если DOCS_REPO_URL по SSH)

  • DOCS_HTTP_TOKENопционально, токен для доступа по HTTPS (используется через ~/.netrc)

  • DOCS_HTTP_USERопционально, логин для ~/.netrc (по умолчанию: oauth2, удобно для GitLab)

Переменные для деплоя на VM:

  • DEPLOY_HOST — хост VM (DNS/IP)

  • DEPLOY_USER — пользователь на VM

  • DEPLOY_PATH — каталог на VM, где лежит сервис

  • DEPLOY_SSH_PRIVATE_KEY — SSH ключ для деплоя

  • DEPLOY_SSH_PORTопционально, порт SSH (по умолчанию: 22)

  • DEPLOY_COMPOSE_SERVICEопционально, имя сервиса compose (по умолчанию: mcp-service)

  • DEPLOY_HEALTHCHECK_URLопционально, URL для проверки после деплоя (например http://<host>:3333/health)

Ожидаемая структура на VM (DEPLOY_PATH)

Пайплайн предполагает, что на VM уже есть каталог сервиса с docker-compose.yml и исходниками (а CI обновляет только data/):

DEPLOY_PATH/ docker-compose.yml package.json src/ data/ # обновляется из CI (pages/, pages.json, index.json, assets/)

После доставки data.tgz CI выполняет:

  • docker compose up -d --remove-orphans

  • docker compose restart mcp-service (чтобы сервер перечитал индекс, т.к. он кэшируется в памяти процесса)

Расписание (Schedule)

Чтобы документация/индекс обновлялись регулярно:

  1. GitLab → CI/CD → Schedules → Create a new schedule

  2. Выберите ветку master

  3. Добавьте нужные variables (например DOCS_REPO_URL, DOCS_REF, DOCS_SUBDIR)

Job deploy_vm в .gitlab-ci.yml уже настроен так, чтобы запускаться только для master и schedule (и не запускаться в Merge Request pipeline).

MCP-инструменты

  • search_docs(query, limit?)

    • Ищет по индексу документации и возвращает список результатов с title, url, excerpt, headings.

    • limit ограничивает количество результатов (1–20, по умолчанию 5).

  • get_page(slug | url)

    • Возвращает полный контент страницы (markdown-текст, headings, codeBlocks, links, breadcrumbs).

    • slug — короткая форма (например, doc_recursive_helper).

    • url — полный адрес страницы документации.

  • get_examples(topic, limit?)

    • Ищет страницы по теме и извлекает фрагменты кода.

      • Делает search_docs(topic, limit) по индексу.

      • Берёт первые подходящие страницы и вытаскивает их codeBlocks.

      • Возвращает список примеров с slug, title, url, code.

    • limit ограничивает количество примеров (1–20, по умолчанию 5).

  • explain_concept(name)

    • Возвращает краткое описание концепта и ссылку на наиболее релевантную страницу.

      • Делает search_docs(name, 3).

      • Берёт самый релевантный результат и возвращает:

        • summary — это excerpt из результата,

        • page — основная ссылка,

        • related — оставшиеся 1–2 страницы.

    • В related добавляет похожие разделы документации.

stdio-режим

stdio — MCP-сервер общается с IDE через стандартные потоки ввода/вывода. Это нативный режим MCP: быстрее, проще в настройке, без сети и портов. Подходит для локального использования.

Транспорт и формат обмена:

  • Общение по stdin/stdout.

  • Формат: JSON-RPC 2.0, построчно или через Content-Length.

    • Построчно — каждое сообщение это одна JSON-строка, разделенная \n. Сервер читает строки и парсит каждую как отдельный JSON-RPC запрос.

    • Через Content-Length — перед сообщением идут заголовки (как в LSP). Сервер сначала читает длину, потом ровно столько байт JSON-тела.

Использовать можно не только из IDE, но и как локальную сервис-утилиту:

  • CLI/скрипты: можно запускать сервер и слать ему JSON-RPC из скриптов (например, на CI или для массового прогрева кэша).

  • Мост/прокси: stdio удобнее как backend для собственного HTTP-прокси — он проще, чем держать внутри сервера HTTP-слой.

  • Интеграции: другой агент/процесс может общаться с MCP через pipe/stdin-stdout, без открытого порта.

  • Безопасность: нет открытых портов, меньше требований к сетевой конфигурации.

Примеры stdio-запросов

{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "search_docs", "arguments": { "query": "Performance Enhancement" } } }

HTTP-режим

http — режим, в котором MCP-сервер поднимает HTTP-endpoint и принимает запросы по сети. Удобно для внешних клиентов и инструментов (например, HTTPYac), но требует поднять отдельный процесс и порт.

  • Сервер поднимается командой npm run start:http (порт HTTP_PORT, по умолчанию 3333).

  • Каждый инструмент доступен через POST /tools/{toolName} с JSON-телом аргументов.

  • Для проверки доступен GET /health.

Примеры HTTP-запросов

Подходят для инструментов типа HTTPYac, плагинов HTTP Request в IDE.

POST http://localhost:3333/tools/search_docs Content-Type: application/json { "query": "Как работает модуль Performance Enhancement?", "limit": 5 }
POST http://localhost:3333/tools/search_docs Content-Type: application/json { "query": "подключение к DevExpress XAF", "limit": 5 }
POST http://localhost:3333/tools/get_page Content-Type: application/json { "slug": "doc_recursive_helper" }
POST http://localhost:3333/tools/get_page Content-Type: application/json { "url": "https://documentation.galaktika-soft.com/xafari/doc_recursive_helper" }
POST http://localhost:3333/tools/get_examples Content-Type: application/json { "topic": "Business Components", "limit": 5 }
POST http://localhost:3333/tools/explain_concept Content-Type: application/json { "name": "Security System" }

Формат хранения

  • Сырые страницы сохраняются в data/pages/*.md с метаданными в заголовке.

  • pages.json формируется из markdown-файлов после завершения краулинга (по умолчанию это NDJSON: один JSON-объект на строку, чтобы файл можно было читать потоково даже при больших объёмах).

  • При сохранении учитываются breadcrumbs: страницы попадают в поддиректории по темам.

  • Ассеты (PDF/картинки) сохраняются в data/assets, ссылки в markdown остаются абсолютными.

Ручное пополнение документации

  1. Создайте .md в data/pages (подкаталоги = breadcrumbs).

  2. Добавьте YAML-front-matter с минимумом полей:

    --- slug: my_custom_doc url: https://example.local/my_custom_doc title: Мой документ breadcrumbs: - Custom - Docs ---
  3. Добавьте тело документа ниже фронт-маттера.

  4. Пересоберите индекс без краулинга:

    • npm run reindex

Логи

Структурированные логи пишутся в data/logs/mcp.jsonl (JSON Lines) при DATA_DIR=./data и дефолтном LOG_FILE=logs/mcp.jsonl.

Install Server
A
security – no known vulnerabilities
F
license - not found
A
quality - confirmed to work

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/QuAzI/xafari-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server