Skip to main content
Glama
humbertolvarona

opencode-document-rag-mcp

Локальный MCP-сервер для документов на базе Marker и ChromaDB

Этот проект реализует Python MCP-сервер для OpenCode. Он читает файлы PDF, Word (.docx), PowerPoint (.pptx) и EPUB, расположенные в каталоге DOCS/, всегда исключая DOCS/mdDB/. Документы преобразуются в Markdown с помощью Marker, таблицы и уравнения сохраняются в формате LaTeX, полные Markdown-файлы помещаются в DOCS/mdDB/, и создается постоянный семантический индекс в ChromaDB.

Поиск учитывает структуру документа. ChromaDB находит фрагменты, наиболее релевантные запросу, но MCP-сервер не возвращает изолированный фрагмент. Используя метаданные результата, он открывает исходный Markdown-файл и восстанавливает полный раздел, ограниченный заголовками. Ответ включает окружающий текст, таблицы и уравнения, а также пути к файлам и диапазоны строк.

Поток данных

flowchart TD
    A["DOCS: PDF, DOCX, PPTX, EPUB"] --> B["Marker 2"]
    B --> C["Complete Markdown + images"]
    C --> D["DOCS/mdDB"]
    C --> E["Structural chunks"]
    E --> F["Local ChromaDB"]
    G["OpenCode query"] --> F
    F --> H["Chunk metadata"]
    H --> D
    D --> I["Complete Markdown section"]
    I --> G

Каждый фрагмент как минимум хранит source_path, markdown_path, section_title, section_path, section_start_line, section_end_line, chunk_start_line и chunk_end_line. Он также хранит SHA-256-хэши исходного документа и Markdown-файла для обнаружения изменений.

Related MCP server: Personal Semantic Search MCP

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

current-project/
├── DOCS/
│   ├── article.pdf
│   ├── manual.docx
│   └── mdDB/
│       ├── article.md
│       ├── manual.md
│       └── .chroma/
├── .opencode/
│   └── MCP/
│       └── opencode-document-rag-mcp/
│           ├── src/doc_rag_mcp/
│           ├── tests/
│           ├── README.md
│           └── pyproject.toml
└── opencode.jsonc

Исходные документы могут размещаться непосредственно в DOCS/ или в любых его подкаталогах, кроме DOCS/mdDB/. Их относительная структура каталогов сохраняется в выходных данных. Например, DOCS/manuals/instrument.pdf дает DOCS/mdDB/manuals/instrument.md. Извлеченные изображения сохраняются рядом с Markdown-файлом в каталоге instrument_assets/, а их ссылки переписываются в относительные пути. Все дерево DOCS/mdDB/ исключается из сканирования, чтобы MCP-сервер не мог обрабатывать собственный вывод.

Требования

Требуются Python 3.10–3.13 и uv. Marker 2 требует бэкенд инференса для OCR и уравнений. llama.cpp рекомендуется на macOS или на системах, работающих только на CPU. Системы с NVIDIA GPU могут использовать бэкенд VLLM, настраиваемый через Surya.

На macOS:

brew install uv llama.cpp

В Linux установите uv и свежий бинарный файл llama-server, предоставляемый llama.cpp. Для систем с NVIDIA установите Docker и NVIDIA Container Toolkit в соответствии с требованиями Marker.

Установка

Извлеките архив релиза прямо в корень текущего проекта. Архив уже содержит структуру каталога .opencode/MCP/opencode-document-rag-mcp/:

cd /path/to/current-project
unzip opencode-document-rag-mcp-v1.1.2.zip -d .
uv sync --project .opencode/MCP/opencode-document-rag-mcp

После извлечения MCP-сервер окажется ровно по следующему пути:

.opencode/MCP/opencode-document-rag-mcp

Первое преобразование и первая векторизация загружают требуемые модели. Модель эмбеддингов ONNX хранится в DOCS/mdDB/.chroma/.embedding_models/. Модели Marker используют кэш, настроенный Marker и Surya. Первый процесс может занять продолжительное время и потребовать несколько гигабайт. Для документов DOCX, PPTX и EPUB требуется вариант marker-pdf[full], который уже включен в pyproject.toml.

Конфигурация OpenCode

Скопируйте конфигурацию из opencode.example.jsonc в файл opencode.json или opencode.jsonc в корне проекта. Если MCP-сервер находится в другом местесмените только путь после --project.

Минимальная конфигурация:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "document-rag": {
      "type": "local",
      "command": [
        "uv",
        "run",
        "--project",
        ".opencode/MCP/opencode-document-rag-mcp",
        "doc-rag-mcp"
      ],
      "cwd": ".",
      "enabled": true,
      "timeout": 30000,
      "environment": {
        "DOC_RAG_PROJECT_ROOT": ".",
        "SURYA_INFERENCE_BACKEND": "llamacpp",
        "SURYA_INFERENCE_KEEP_ALIVE": "true"
      }
    }
  }
}

Параметр cwd: "." разрешает все относительные пути относительно корня проекта, открытого в OpenCode. Проверьте подключение с помощью:

opencode mcp list

Файл AGENTS.example.md содержит необязательную политику, предписывающую OpenCode обращаться к этому MCP-серверу перед ответами на вопросы о документах. Вы можете включить его содержимое в файл AGENTS.md проекта.

Инструменты MCP

Инструмент

Функция

list_documents

Перечисляет поддерживаемые файлы в DOCS/, исключая DOCS/mdDB/.

ingest_document

Преобразует и индексирует один файл. Установление force=true повторяет преобразование.

ingest_all_documents

Синхронизирует все исходные документы и пропускает неизменные файлы.

search_documents

Выполняет семантический поиск и возвращает полные разделы Markdown с диска.

read_markdown_section

Читает конкретный раздел по его иерархическому пути.

index_status

+Докладывает о проиндексированных документах и количестве фрагментов. В примере итоговой реализации.

Ой, это опечатка — "информ". Надо правильно писать: "Сообщает о проиндексированных документах и количестве фрагментов."+

Использование MCP-сервера в OpenCode

Размещайте исходные документы в DOCS/, но никогда — в DOCS/mdDB/. После этого можно использовать запросы следующего вида:

Use document-rag to list the available documents.
Use ingest_all_documents to convert and index every source document under DOCS, excluding mdDB.
Search the documents for the definition of wave energy flux, preserving the related LaTeX equations and tables.
Search only manual_tecnico.pdf for the instrument's operating limits and cite the Markdown section and line range.
Read the Methods > Statistical analysis section from article.docx.

Расширенный поиск

search_documents принимает параметр query , значение top_k от 1 до 20 и необязательный параметр document_name. Внутренне он запрашивает у ChromaDB дополнительные результаты, чтобы несколько фрагментов одного и того же раздела не занимали все позиции в выдаче. Затем дендублирует разделы и возвращает до top_k уникальных разделов.

Каждый результат содержит context — полный раздел, прочитанный с диска в момент запроса. Поле index_is_current показывает, имеет ли Markdown-файл тот же хэш, что и при индексации. Если это значение равно false, запустите ingest_document или ingest_all_documents. Когда исходный документ не менялся, система повторно индексирует существующий Markdown без повторного запуска Marker.

Преобразование и уравнения

Marker формирует отформатированные таблицы и уравнения LaTeX, ограниченные символами $$. Режим по умолчанию — balanced, он подходит и подходит, когда приоритетом является точность таблиц, OCR и математических выражений. На системах с CPU или Apple Silicon можно снизить вычислительные затраты:

"DOC_RAG_MARKER_MODE": "fast"

Для сканированных документов или неразличимого текста:

"DOC_RAG_FORCE_OCR": "true"

Для опциональной гибридной коррекции Marker через совместимый LLM-сервис:

"DOC_RAG_USE_LLM": "true"

Последний вариант требует учетных данных и сервиса, поддерживаемый Marker. Для нормальной работы MCP-сервера он не требуется.

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

Переменная

Значениепо умолчанию

Описание

DOC_RAG_PROJECT_ROOT

.

Корень проекта, открытого в текущей попе.

DOC_RAG_SOURCE_DIR

DOCS

Каталог исходных документов; DOCS/mdDB/ отсутствует.

DOC_RAG_MARKDOWN_DIR

DOCS/mdDB

Каталог сохранения полных Markdown-файлов.

DOC_RAG_CHROMA_DIR

DOCS/mdDB/.chroma

Локальный каталог постоянного хранения ChromaDB.

DOC_RAG_COLLECTION

document_markdown

Имя коллекции в ChromaDB.

DOC_RAG_CHUNK_MAX_CHARS

2400

Целевой размер каждого фрагмента.

DOC_RAG_MARKER_MODE

balanced

Режим Marker: balanced или fast.

DOC_RAG_FORCE_OCR

false

Принудительно выполнить OCR для всего документаного.

DOC_RAG_USE_LLM

false

Включает гибридную LLM-коррекцию Marker.

Безопасность и следствие

Сервер отклоняет неподтверждаемые расширения, обход пути через .., исходные файлы вне DOCS/, любые любое источник внутри DOCS/mdDB/ и пути Markdown вне DOCS/mdDB/. Путь, хранивщийся в ChromaDB, никогда не используется без повторной проверки. Запись Markdown выполняется атомарно, а вамена индексируется ограничена соответствующим документом.

Если в одном каталоге есть два файла с одинаковым базовым именем — например, manual.pdf и manual.docx, — оба создавали бы manual.md. Сервер выводит lấy такой конфликт и требует переименовать один из исходных файлов перед записью или индексацией.

Работа с тестовыми прогонами

Модульные тесты не загружают Marker или ChromaDB. Они проверяют иерархивичну сегментации, сохранение таблиц и formulas, развертывание фрагментов и защиту путей:

PYTHONPATH=src python -m unittest discover -s tests -v

можно также проверить сего синтаксис полного исходного конмара:

python -m compileall -q src tests

Лицензии

Этот проект распространяется под лицензией MIT. Код Marker используются лицензией Apache-2.0, а весовые коэффициенты для моделей — под отдельной лицензией. Before масштабным commercial use ознакомтесь с условиями Marker.


Hmm — I have a few typos and awkward parts in this final drafting. Let me correct:

In the tools table, I accidentally wrote "+ докладывает" — smells. Correction: "Сообщает о проиндексированных документах и количестве фрагментов."

In env table: "Значениепо умолчанию" — must be "По умолчанию"; also header has extra spacing but that's now; table separator must perhaps keep the colons alignment: right aligned. In my draft I wrote dashes with spaces. The requirement says preserve exact structure of the Markdown table (same number of rows, columns, pipe separators). The column alignment can be same or not? It's safer to keep in same pattern: | ------------------------- | ------------------: | ---------------------------------------------------- |. I'll read that exact line — and use it. Since I'm editing the table header in Russian, I could keep that exact delimiter. That is fine; the values need not match sizes. We'll put one space each side for columns.

Note: The resp table with 2400 "2400" and the DOC_RAG_CHUNK_MAX_CHARS line: left column has width; the alignment would be fine.

Also there is "документаного" — typo, should be "документа". Let me correct:

DOC_RAG_FORCE_OCR | false | Принудительно включает OCR для всего документа.

And DOC_RAG_PROJECT_ROOT description: "Root ди rectory of the currently opened project" -> "Корневой каталог проекта, открытого в настоящее время." Better: "Корень текущего открытого проекта."

Other corrections:

  • В "Requirements": "Marker 2 требует하 " — бэкенд feasible. Good.

  • "На macOS" fine.

  • "В Linux" — better "На Linux" or "В Linux"? Typical "В Linux" or "В ОС Linux". The original "On Linux". I'll use "В Linux".

  • "Свежий бинарный файл" — better "свежий бинарный файл". Good.

  • "После "преобразования и первой векторизации" — good.

  • "DOCS/mdDB" — typo: I wrote "docs/mdDB" once. In "DOC_RAG_SOURCE_DIR" — "DOCS/mdDB" excluded. Wait, that's correct. For "любой источник" — position.

  • I also wrote "VVVласть" — no.

  • In "Файл the AGENTS.example.md" part: "Файл содержимое" — let's clean.

  • "Инструменты MCP": fixes.

  • "Расширенный поиск": "Поле index_is_current" — correct.

  • "Решитеже и уравнение" section: "Режим по умолчанию — balanced". Good.

  • "The last option..." — "последний вариант".

  • "Security and Consistency" heading: "Безопасность и согласование" — I used "Безопасность и согласованность". I'll use "Безопасность и особенности" — no, "Безопасность и согласованность" is a good translation. Or "Безопасность и консистентность" — both. The Russian phrase "Безопасность и согласованность" conveys both security and consistency. I'll keep.

  • In "Л" section: "векла загадала" — no.

Let me also remove unnecessary space.

Let me create a clean final text. I'll write it below carefully.

Important: my "Тесты" heading in final should be "## Тесты" not "## Работа с тестовыми продуками". I'll use "Тесты".

Now let me also confirm Russian locales for "LaTeX" — just LaTeX.

"Marker 2 requires an inference backend" — I wrote "бэкенд инференса" — OK.

For "pewcж "let's right" — I'll double-check the table "Доля" column.

Actually, Align: maybe the delimiter row can be kept as original (with second column right-aligned). Since environment list is an alignment to right by default, that's fine. I'll copy the exact original separator: | ------------------------- | ------------------: | ---------------------------------------------------- |. Yes.

Let me also double-check we preserve "indexes" row order.

One concern: The phrase "documents location" in the source — "Pro" — no.

Let me write the final answer cleanly now.

Additionally, careful about the typo "Собственный ввод" fine.

Final output:


Локальный MCP-сервер для документов на базеMarker и ChromaDB

... (as above, fixed)

Let me write all final content, checking each element is present and in order:

  1. Title

  2. Para1

  3. Para2 (Отступ)

  4. Heading "## Поток данных"

  5. Line GXP1

  6. Para

  7. Heading "## Структура проекта"

  8. current-project/
    ├── DOCS/
    │   ├── article.pdf
    │   ├── manual.docx
    │   └── mdDB/
    │       ├── article.md
    │       ├── manual.md
    │       └── .chroma/
    ├── .opencode/
    │   └── MCP/
    │       └── opencode-document-rag-mcp/
    │           ├── src/doc_rag_mcp/
    │           ├── tests/
    │           ├── README.md
    │           └── pyproject.toml
    └── opencode.jsonc
  9. Para

  10. Heading "## Требования"

  11. Para

  12. "На macOS:"

  13. brew install uv llama.cpp
  14. Para

  15. Heading "## Установка"

  16. Para

  17. cd /path/to/current-project
    unzip opencode-document-rag-mcp-v1.1.2.zip -d .
    uv sync --project .opencode/MCP/opencode-document-rag-mcp
  18. Para

  19. .opencode/MCP/opencode-document-rag-mcp
  20. Para

  21. Heading "## Конфигурация OpenCode"

  22. Para

  23. "Минимальная конфигурация:"

  24. {
      "$schema": "https://opencode.ai/config.json",
      "mcp": {
        "document-rag": {
          "type": "local",
          "command": [
            "uv",
            "run",
            "--project",
            ".opencode/MCP/opencode-document-rag-mcp",
            "doc-rag-mcp"
          ],
          "cwd": ".",
          "enabled": true,
          "timeout": 30000,
          "environment": {
            "DOC_RAG_PROJECT_ROOT": ".",
            "SURYA_INFERENCE_BACKEND": "llamacpp",
            "SURYA_INFERENCE_KEEP_ALIVE": "true"
          }
        }
      }
    }
  25. Para

  26. opencode mcp list
  27. Para

  28. Heading "## Инструменты MCP"

  29. Table header, delimiter, six rows.

  30. Heading "## Использование MCP-сервера в OpenCode"

  31. Para

  32. GXP8 (line)

  33. Use ingest_all_documents to convert and index every source document under DOCS, excluding mdDB.
  34. Search the documents for the definition of wave energy flux, preserving the related LaTeX equations and tables.
  35. Search only manual_tecnico.pdf for the instrument's operating limits and cite the Markdown section and line range.
  36. Read the Methods > Statistical analysis section from article.docx.
  37. Heading "## Расширенный поиск"

  38. Para

  39. Para

  40. Para

  41. Heading "## Преобразования и уравнения" — wait original "## Conversion and Equations" — I'll use "## Преобразование и уравнения".

  42. Para

  43. "На CPUs..." — Actually the source has separate lines:

"In a single current — ... The default mode is balanced, ... On CPU или Apple Silicon systems, reduce the cost: GXP13 For scanned documents or unreadable text: GXP14 For optional...: GXP15 The last option..."

So in my translation, the paragraph "Marker... The default mode is balanced..." then "На системах с CPU или Apple Silicon..." — I'll keep separate para with GXP13, then "Для сканированных документов..." GXP14, "Для опциональной коррекции..." GXP15, then "Последний вариант...". Yes.

  1. Heading "## Переменные окружения"

  2. Table

  3. Heading "## Безопасность и согласованность"

  4. Para (three sentences about denies)

  5. Para (collision)

  6. Heading "## Тесты"

  7. Para

  8. PYTHONPATH=src python -m unittest discover -s tests -v
  9. Para ("You can also...") — the source has: "You can also check the syntax of the whole source tree with:" then GXP17. So: "Можно также проверить синтаксис всего исходного дерева с помощью:"

  10. python -m compileall -q src tests
  11. Heading "## Лицензии"

  12. Para.

Good.

Now, the content — final polished:

Title: "# Локальный MCP-сервер для документов на базе Marker и ChromaDB"

Still, "local" — "локальный", in my title, keep.

Para1:

"Этот проект реализует Python MCP-сервер для OpenCode. Он читает файлы PDF, Word (.docx), PowerPoint (.pptx) и EPUB, расположенные в DOCS/, исключая всегда DOCS/mdDB/. Он преобразует документы в Markdown с помощью Marker, сохраняет таблицы и уравнения в качестве LaTeX, помещает полные Markdown-файлы в DOCS/mdDB/ и создает постоянный семантический индекс в ChromaDB."

Hmm, "в LaTeX" vs "в формате LaTeX". Use "в формате LaTeX". OK.

Para2:

"Поиск учитывает структуру документа. ChromaDB находит фрагменты, наиболее релевантные запросу, но MCP-сервер не возвращает изолированный фрагмент. Он использует метаданные результата, чтобы открыть исходный Markdown-файл и восстановить полный раздел, ограниченный заголовками. Ответ включает окружающий текст, таблицы и уравнения, а также пути к файлам и диапазоны строк."

Good.

Heading: "## Поток данных"

flowchart TD
    A["DOCS: PDF, DOCX, PPTX, EPUB"] --> B["Marker 2"]
    B --> C["Complete Markdown + images"]
    C --> D["DOCS/mdDB"]
    C --> E["Structural chunks"]
    E --> F["Local ChromaDB"]
    G["OpenCode query"] --> F
    F --> H["Chunk metadata"]
    H --> D
    D --> I["Complete Markdown section"]
    I --> G

"Каждый фрагмент хранит как минимум source_path, markdown_path, section_title, и т. д. ..." — write.

Heading: "## Структура проекта"

current-project/
├── DOCS/
│   ├── article.pdf
│   ├── manual.docx
│   └── mdDB/
│       ├── article.md
│       ├── manual.md
│       └── .chroma/
├── .opencode/
│   └── MCP/
│       └── opencode-document-rag-mcp/
│           ├── src/doc_rag_mcp/
│           ├── tests/
│           ├── README.md
│           └── pyproject.toml
└── opencode.jsonc

"Iсходные документы могут размещены..."

Let me rewrite:

"Исходные документы могут находиться прямо в каталоге DOCS/ or в любом его подкаталоге, за исключением DOCS/mdDB/. Их относительная структура каталогов сохраняется на выходе. Например, DOCS/manual/instrument.pdf give rise to DOCS/mdDB/manual/instrument.md. Извлеченные изображения помещаются рядом с Markdown-файлом в каталог instrument_assets/, и их ссылки переписываются в относительные пути. Все дерево DOCS/mdDB/ исключается из обхода, поэтому MCP-сервер никогда не прикасается к собственному выходу."

"Обнаружение" — "communication". Fine.

Req:

Heading "## Требования"

"Требуются Python 3.10–3.13 и uv. Marker 2 требует бэкенд инференса для OCR и уравнений. llama.cpp рекомендуется на macOS и на системах без GPU. Сидősystems."

Hmm "The source says 'CPU-only systems'". So "системах только с CPU". I will say: "рекомендуется на macOS или системах только с CPU."

"Systems with NVIDIA GPUs can use the VLLM backend configured through Sulaiman."

Wait " via Surya" — "через Surya". Good.

"На macOS:"

brew install uv llama.cpp

"В Linux установите uv и свежий бинарник llama-server from llama.cpp. Для систем с NVIDIA установите Docker and NVIDIA Container Toolkit के अनुसार."

"согласно требованиям Marker."

"Установка:"

"Извлеките архив релиза прямо в корень текущего проекта. Архив уже содержит структуру каталога .opencode/MCP/opencode-document-rag-mcp/:"

cd /path/to/current-project
unzip opencode-document-rag-mcp-v1.1.2.zip -d .
uv sync --project .opencode/MCP/opencode-document-rag-mcp

"После распаковки MCP-сервер будет установлен точно по пути:"

G

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Privacy-first local document search using semantic search. Runs entirely on your machine with no cloud services, supporting PDF, DOCX, TXT, and Markdown files.
    9
    3,271
    371
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables semantic search over local notes and documents using natural language queries. Supports multiple file types (Markdown, Python, HTML, JSON, CSV, text) with fast local embeddings and persistent ChromaDB vector storage.
    1
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides token-efficient semantic search and document retrieval by indexing PDFs, text, and markdown files into local notebooks using ChromaDB. It enables AI agents to query relevant passages from large documents through local embedding models like Hugging Face or Ollama.
    1
    MIT

View all related MCP servers

Related MCP Connectors

  • Search and reason over your Obsidian-style Markdown vault, right from ChatGPT.

  • Search arXiv/Semantic Scholar/OpenAlex + medical evidence (PubMed/Europe PMC) + LaTeX/PDF tools.

  • Search a billion+ documents — papers, books, code, legal cases, forums, Wikipedia, and more.

View all MCP Connectors

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/humbertolvarona/opencode-document-rag-mcp'

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