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
Инструмент | Функция |
| Перечисляет поддерживаемые файлы в |
| Преобразует и индексирует один файл. Установление |
| Синхронизирует все исходные документы и пропускает неизменные файлы. |
| Выполняет семантический поиск и возвращает полные разделы Markdown с диска. |
| Читает конкретный раздел по его иерархическому пути. |
| +Докладывает о проиндексированных документах и количестве фрагментов. В примере итоговой реализации. |
Ой, это опечатка — "информ". Надо правильно писать: "Сообщает о проиндексированных документах и количестве фрагментов."+
Использование 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-сервера он не требуется.
Переменные окружения
Переменная | Значениепо умолчанию | Описание |
|
| Корень проекта, открытого в текущей попе. |
|
| Каталог исходных документов; |
|
| Каталог сохранения полных Markdown-файлов. |
|
| Локальный каталог постоянного хранения ChromaDB. |
|
| Имя коллекции в ChromaDB. |
|
| Целевой размер каждого фрагмента. |
|
| Режим Marker: |
|
| Принудительно выполнить OCR для всего документаного. |
|
| Включает гибридную 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:
Title
Para1
Para2 (Отступ)
Heading "## Поток данных"
Line GXP1
Para
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.jsoncPara
Heading "## Требования"
Para
"На macOS:"
brew install uv llama.cppPara
Heading "## Установка"
Para
cd /path/to/current-project unzip opencode-document-rag-mcp-v1.1.2.zip -d . uv sync --project .opencode/MCP/opencode-document-rag-mcpPara
.opencode/MCP/opencode-document-rag-mcpPara
Heading "## Конфигурация OpenCode"
Para
"Минимальная конфигурация:"
{ "$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" } } } }Para
opencode mcp listPara
Heading "## Инструменты MCP"
Table header, delimiter, six rows.
Heading "## Использование MCP-сервера в OpenCode"
Para
GXP8 (line)
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.Heading "## Расширенный поиск"
Para
Para
Para
Heading "## Преобразования и уравнения" — wait original "## Conversion and Equations" — I'll use "## Преобразование и уравнения".
Para
"На 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.
Heading "## Переменные окружения"
Table
Heading "## Безопасность и согласованность"
Para (three sentences about denies)
Para (collision)
Heading "## Тесты"
Para
PYTHONPATH=src python -m unittest discover -s tests -vPara ("You can also...") — the source has: "You can also check the syntax of the whole source tree with:" then GXP17. So: "Можно также проверить синтаксис всего исходного дерева с помощью:"
python -m compileall -q src testsHeading "## Лицензии"
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
This server cannot be installed
Maintenance
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
- AlicenseAqualityAmaintenancePrivacy-first local document search using semantic search. Runs entirely on your machine with no cloud services, supporting PDF, DOCX, TXT, and Markdown files.93,271371MIT
- FlicenseNot gradedqualityDmaintenanceEnables 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
- AlicenseNot gradedqualityDmaintenanceProvides 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.1MIT
- FlicenseNot gradedqualityCmaintenanceConverts documents (PDF, DOCX, XLSX, PPTX, HTML, TXT, MD) to Markdown and stores them locally with search and retrieval capabilities.
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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