Factograph MCP
Enables building and exploring a knowledge graph from files (PDF, DOCX, code) with AI enrichment via Ollama or Claude. Supports pinning documents, linking entities, and traversing the graph.
README
🧠 Factograph MCP v4
Граф знаний с файловым вводом и AI-обогащением через локальный Ollama (Qwen3:14b) или Anthropic API.
Архитектура: MCP-сервер живёт на Ubuntu-сервере, читает файлы локально, а LLM-инференс уходит по сети на Windows-машину с видеокартой (Ollama).
Что нового в v4
Три изменения, сделанные по итогам реальной сессии в mcphost:
-
Файлы без расширения больше не отбрасываются. Раньше
ingest_file/ingest_directory/list_server_filesпомечали такие файлы какsupported: false. Дампы технической документации (напримерinstall core,multiapnбез.txt) теперь читаются как обычный текст автоматически — расширение не обязательно. -
Новый инструмент
auto_link_collection— массовое связывание документов одним вызовом. Решает конкретный сценарий: пользователь просит "установи связи между всеми документами", а модели нужно было самой спланировать цикл "обогатить каждый → сравнить" — задача, с которой 14B-модель не справлялась. Теперь это один детерминированный вызов на сервере. -
Описания
enrich_document/find_relatedобновлены — явно указывают, что для массового связывания нужно использоватьauto_link_collection, а не вызывать их в цикле по одному документу.
Если у тебя 0 связей после импорта
Это не баг и не "функция не поддерживается" (как иногда отвечает модель) — это значит, что у документов ещё не извлечены сущности, а без них Jaccard-сравнению просто не с чем работать. Раньше для этого нужно было вызвать enrich_document на каждый документ вручную; теперь auto_link_collection делает это сама перед расчётом связей.
Установка на Ubuntu Server
git clone <repo> factograph-mcp # или просто распакуй архив
cd factograph-mcp
npm install
npm run build
cp .env.example .env
nano .env # вписать IP Windows-машины и разрешённые папки
Зависимости для PDF/DOCX (опционально)
pdf-parse и mammoth лежат в optionalDependencies — если npm install их не поставил:
npm install pdf-parse mammoth
Настройка Ollama на Windows 11
-
Установи Ollama, стяни модель:
ollama pull qwen3:14b -
Разреши сетевой доступ (по умолчанию Ollama слушает только localhost):
Через переменную окружения перед запуском —
$env:OLLAMA_HOST = "0.0.0.0:11434" ollama serveИли навсегда: Win+R →
sysdm.cpl→ Advanced → Environment Variables → добавитьOLLAMA_HOST=0.0.0.0:11434→ перезапустить Ollama. -
Открой порт в Windows Firewall:
New-NetFirewallRule -DisplayName "Ollama" -Direction Inbound -LocalPort 11434 -Protocol TCP -Action Allow -
Узнай IP машины:
ipconfig→ IPv4 Address (например192.168.1.50). -
Проверь с Ubuntu-сервера:
curl http://192.168.1.50:11434/api/tagsДолжен вернуться список моделей.
Либо тем же самым через MCP-инструмент:
ping_ollama {}
Установка mcphost (хост на Ubuntu Server)
Важно: разработка
mcphostостановлена, репозиторий заархивирован автором — проект пометили как замороженный (без новых фич и фиксов), а преемником названKit(тот же автор, более новая архитектура). Для текущей задачиmcphostвсё ещё рабочий вариант — последний релиз стабилен и именно его используют примеры в этом README — но если в будущем что-то перестанет собираться или захочется новых возможностей, стоит посмотреть наKitв репозиторияхmark3labsна GitHub.
1. Установи Go (если ещё нет)
sudo apt update
sudo apt install golang-go
go version # проверка
2. Установи mcphost
go install github.com/mark3labs/mcphost@latest
Бинарник ставится в ~/go/bin. Добавь эту папку в PATH, если её там нет:
echo 'export PATH=$PATH:~/go/bin' >> ~/.bashrc
source ~/.bashrc
mcphost --help # проверка, что бинарник нашёлся
Альтернатива без сборки — скачать готовый бинарник со страницы Releases под свою архитектуру, не устанавливая Go вовсе.
3. Настрой подключение к Ollama для самого mcphost
Это отдельная переменная окружения от той, что в .env нашего MCP-сервера — mcphost сам общается с Ollama напрямую для самого чата с моделью, а .env факторграфа отвечает только за то, как enrich_document/synthesize_cluster достают Ollama. Их обычно указывают на один и тот же адрес, но задаются они раздельно:
export OLLAMA_HOST=http://192.168.1.50:11434
Для других провайдеров (если когда-нибудь понадобятся) — ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY тем же способом.
4. Создай конфиг ~/.mcp.json
{
"mcpServers": {
"factograph": {
"command": "node",
"args": ["/home/user/factograph-mcp/dist/index.js"],
"env": {
"OLLAMA_HOST": "http://192.168.1.50:11434",
"OLLAMA_MODEL": "qwen3:14b",
"ALLOWED_ROOTS": "/home/user/documents:/mnt/data",
"AUTO_SAVE_PATH": "/home/user/.document-pinboard/graph.json"
}
}
}
}
5. Запусти
mcphost --model ollama:qwen3:14b --config ~/.mcp.json
При старте в логе должно появиться что-то вроде Loaded 25 tools from MCP servers — если число другое, проверь, не упал ли factograph-сервер при старте (смотри stderr — там пишет [factograph-mcp] запущен).
Конфигурация .env
OLLAMA_HOST=http://192.168.1.50:11434
OLLAMA_MODEL=qwen3:14b
# Папки, из которых MCP разрешено читать файлы (через :)
ALLOWED_ROOTS=/home/user/documents:/mnt/data
# Авто-сохранение графа на диск при старте/остановке сервера
AUTO_SAVE_PATH=/home/user/.document-pinboard/graph.json
Если OLLAMA_HOST не задан, но задан ANTHROPIC_API_KEY — сервер автоматически переключится на Claude API как fallback.
Подключение к Claude Desktop
Если хочешь использовать тот же MCP-сервер не через mcphost, а из Claude Desktop:
{
"mcpServers": {
"factograph": {
"command": "node",
"args": ["/home/user/factograph-mcp/dist/index.js"],
"env": {
"OLLAMA_HOST": "http://192.168.1.50:11434",
"OLLAMA_MODEL": "qwen3:14b",
"ALLOWED_ROOTS": "/home/user/documents:/mnt/data",
"AUTO_SAVE_PATH": "/home/user/.document-pinboard/graph.json"
}
}
}
}
Конфиг для mcphost (~/.mcp.json) — смотри раздел «Установка mcphost» выше, формат mcpServers идентичен.
Все инструменты (25 штук)
Слой 1 — Пинборд (8)
pin_document · list_pins · search_pins · get_pin · update_pin · unpin · list_collections · export_collection
Слой 2 — Граф знаний (10)
link_documents · get_connections · traverse_graph · enrich_document · find_by_entity · find_related · auto_link_collection · get_facts · synthesize_cluster · graph_stats
Слой 3 — Файлы на сервере + диск-хранилище (7)
| Инструмент | Описание |
|---|---|
ingest_file |
Прочитать файл (PDF/DOCX/код/текст, в т.ч. без расширения) и добавить в базу |
ingest_directory |
Массовый импорт папки (рекурсивно, с фильтром расширений) |
list_server_files |
Посмотреть содержимое директории на сервере |
ping_ollama |
Проверить связь с Windows-машиной и список моделей |
save_graph |
Сохранить весь граф (узлы+связи+факты) в JSON на диск |
load_graph |
Загрузить граф из JSON (merge, skip/overwrite конфликтов) |
export_edges |
Связи → CSV (Excel) или DOT (Graphviz-визуализация) |
auto_link_collection — как это работает
auto_link_collection {
collection: "research", // опционально — иначе вся база
use_ai: true, // обогатить документы без сущностей перед связыванием
min_jaccard: 0.1 // порог схожести для авто-связей
}
Шаг 1 — для каждого документа в наборе проверяется, есть ли у него извлечённые сущности. Если нет и use_ai: true — документ прогоняется через enrich_document (Ollama/Anthropic) автоматически.
Шаг 2 — для всех документов набора считается Jaccard-пересечение сущностей, создаются связи similar_to (Jaccard ≥ 0.25) или shares_topic (ниже).
Возвращает сводку: сколько документов обогащено, сколько связей создано, и сами связи (до 50 штук в ответе). Если связей всё равно 0 — подсказка в поле hint рекомендует понизить min_jaccard.
Типичный рабочий процесс
1. Узнать что лежит на сервере
list_server_files { path: "/mnt/data/papers" }
2. Массовый импорт (без авто-обогащения на этом шаге — дешевле и быстрее)
ingest_directory {
path: "/mnt/data/papers",
recursive: true,
extensions: ["pdf", "md"], // не указывать — заберёт и файлы без расширения
collection: "research"
}
3. Связать все документы коллекции одним вызовом
auto_link_collection { collection: "research" }
4. Исследовать граф
traverse_graph { doc_id: "...", max_depth: 3 }
find_by_entity { entity: "transformer" }
5. Сохранить граф на диск (бэкап / версионирование)
save_graph { path: "/home/user/backups/graph-2026-06-19.json" }
6. Визуализировать
export_edges { path: "/tmp/graph.dot", format: "dot" }
# затем на сервере: dot -Tsvg /tmp/graph.dot > graph.svg
Диск-хранилище графа: как это устроено
Граф всегда живёт в SQLite (~/.document-pinboard/pins.db) — это основной источник истины.
JSON-снэпшоты через save_graph/load_graph — это:
- Бэкапы — на случай порчи БД
- Версионирование —
git add graph.jsonдля истории изменений графа - Перенос — скопировать граф на другую машину без переноса всего SQLite-файла
- AUTO_SAVE_PATH — если задан в
.env, граф автоматически грузится при старте сервера и сохраняется при остановке (SIGINT/SIGTERM)
load_graph по умолчанию работает в режиме skip — не трогает существующие записи при совпадении ID, что делает его безопасным для повторного запуска.
Безопасность
ALLOWED_ROOTSограничиваетingest_file/ingest_directory/list_server_filesтолько указанными директориями. Если оставить пустым — доступ к всей файловой системе сервера (не рекомендуется на боевом сервере).- Все пути проходят через
safePath(), который резолвит..-трюки и directory traversal.
Известные ограничения
- Tool-calling у Qwen3:14b не идеален. Модель иногда домысливает параметры, которых нет в схеме (например, пыталась вызвать
ingest_fileсpathsвместоpath).mcphostсам отдаёт ошибку обратно модели и она обычно восстанавливается на следующей попытке — но это вероятностное поведение, не гарантия. - Описания тулов — это намёк, а не команда. Несмотря на явные формулировки в
auto_link_collectionпро "не вызывай по одному", модель технически может всё равно выбрать ручной цикл поenrich_document. Если заметишь такое поведение — попроси прямо: "используй auto_link_collection". - Авто-связи (
similar_to/shares_topic) считаются только по пересечению сущностей. Если у документов мало общих именованных сущностей, но они тематически близки — Jaccard может не найти связь. В этом случае выручитsynthesize_clusterили ручнойlink_documents.
Структура файлов
src/
├── types.ts ← PinnedDocument schema
├── pdf-parse.d.ts ← минимальные типы для pdf-parse (он их не публикует)
├── db.ts ← DocumentDB (docs + FTS5)
├── processor.ts ← URL fetch, HTML→text
├── ingest.ts ← чтение файлов с диска (PDF/DOCX/код/текст, поддержка файлов без расширения) + сканирование папок
├── graph-types.ts ← Connection, Fact, Relation
├── graph.ts ← GraphDB (связи, сущности, факты, BFS, Jaccard, настраиваемый autoConnectByEntities)
├── ollama.ts ← HTTP-клиент Ollama (JSON mode, /no_think для Qwen3)
├── enricher.ts ← AI-обогащение (Ollama приоритетно, Anthropic fallback)
├── graph-store.ts ← save/load графа в JSON, экспорт CSV/DOT
├── file-tools.ts ← MCP-инструменты слоя 3 (ingest_*, save_graph, ...)
└── index.ts ← MCP-сервер, все 25 инструментов (включая auto_link_collection)
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.