About KnowledgeOS
KnowledgeOS is an MCP server in the Documentation category: mCP server that gives AI agents a self-updating knowledge vault — agents read docs before acting and write guidelines after learning something new.
Install
git clone https://github.com/aequicor/KnowledgeOSThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about KnowledgeOS
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
5 checks have not been run yet.
README
KnowledgeOS
Система знаний для AI-агентов, которая умнеет по мере работы.
Документация — первична. Код — артефакт.
Идея
Традиционная разработка выглядит так:
Мысль → Код
KnowledgeOS меняет этот порядок:
Мысль → Документ (источник истины) → AI Agent → Код
AI-агент не просто выполняет задачи — он читает проектную документацию перед каждым действием и обновляет её после выполнения задачи. Столкнулся с нестандартным кейсом — написал гайдлайн. В следующий раз найдёт его сам.
Хочешь изменить поведение — правь документ, не код.
Архитектура
┌──────────────────────────────────────────────────────────┐
│ Оператор ИИ-агента │
│ ставит задачи · ревьюит · правит доки │
└──────────┬──────────────────────────────┬────────────────┘
│ задача │ ревью
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Obsidian Vault │◄────────────│ AI Agent │
│ │ читает / │ (OpenCode) │
│ concepts/ │ редактирует│ │
│ reference/ │ │ 1. search_docs │
│ how-to/ │ │ 2. читает доки │
│ tutorials/ │ │ 3. пишет код │
│ guidelines/ │ │ 4. пишет гайд │
│ [[wikilinks]] │ │ 5. update_doc │
└────────┬─────────┘ └────────┬─────────┘
│ файлы │ search_docs()
▼ ▼
┌──────────────────────────────────────────────────────────┐
│ MCP Server (Kotlin) │
│ │
│ [Metadata filter] │
│ BM25 ──────┐ │
│ Vector ────┼──► RRF Fusion ──► Wikilinks ──► Rerank ──► chunks │
│ │ │
└──────────────────────────────────────────────────────────┘
│
▼
┌─────────────┐
│ Codebase │
│ (артефакт) │
└─────────────┘
Три компонента
Obsidian Vault — мозг системы. Единственный источник истины. Хранит документацию по жанрам Diátaxis, связанную через [[wikilinks]]. Редактируется людьми и агентом.
MCP Server — нервная система. Индексирует vault, обрабатывает запросы агента. BM25 индекс персистируется на локальный диск, векторный индекс — в ChromaDB. Сервер можно перезапустить без полной переиндексации. Граф wikilinks поддерживается в памяти и обновляется инкрементально через file watcher; wikilinks разворачиваются on-demand при получении документа — если в чанке есть [[ссылки]], сервер автоматически загружает связанные документы. Реализован на Kotlin.
AI Agent (OpenCode) — исполнитель. Единственный кто пишет код. Перед каждым действием читает документацию. После — обновляет гайдлайны и связанные документы через три инструмента: search_docs, write_guideline, update_doc.
Структура Vault
vault/
├── _INDEX.md # карта vault — точка входа агента
│
├── concepts/ # ПОЧЕМУ и КАК устроено
│ ├── architecture.md
│ ├── domain-model.md
│ └── decisions/ # Architecture Decision Records
│ ├── 001-use-postgres.md
│ └── 002-no-orm.md
│
├── reference/ # ЧТО ЕСТЬ — полные списки
│ ├── api-endpoints.md
│ ├── db-schema.md
│ └── env-vars.md
│
├── how-to/ # КАК СДЕЛАТЬ конкретную задачу
│ ├── add-api-endpoint.md
│ ├── add-db-migration.md
│ └── write-tests.md
│
├── tutorials/ # НАУЧИТЬСЯ — для новых людей
│ └── onboarding.md
│
└── guidelines/ # ПРАВИЛА — накапливаются агентом
├── database.md
├── testing.md
├── error-handling.md
└── libs/
└── exposed.md # правила работы с конкретными либами
Жанровое разделение по Diátaxis: каждый документ отвечает на один тип вопроса — агент знает заранее где искать инструкции, где факты, а где правила.
Frontmatter документа
---
genre: guideline # concept | reference | how-to | tutorial | guideline
title: Правила работы с БД
topic: database
library: exposed # опционально — конкретная библиотека
triggers:
- "db query"
- "transaction"
- "migration"
related:
- [[reference/db-schema]]
- [[how-to/add-db-migration]]
confidence: high # low | medium | high
source: agent # agent | human
updated: 2024-01
---
Wikilinks как граф знаний
Связи между документами прописываются явно через [[название-документа]]. Это и есть граф знаний — без LLM-извлечения, без погрешностей, с полным контролем.
# Правила работы с транзакциями
Всегда оборачивай мутации в транзакцию. См. [[db-schema]].
При ошибках → [[error-handling]].
Паттерн репозитория: [[repository-pattern]].
При поиске по guidelines/database.md сервер автоматически подтягивает все прилинкованные документы — агент получает связанный кластер, а не изолированный чанк.
MCP Server
Инструменты агента
Агент видит три инструмента:
search_docs(
query: String, // что ищем
genre: String? = null, // concept | how-to | reference | tutorial | guideline
topic: String? = null, // database | auth | testing | ...
) → List<Chunk>
write_guideline(
content: String, // текст гайдлайна в markdown
topic: String, // куда положить
library: String? = null, // если про конкретную либу
related: List<String>? = null, // [[wikilinks]] на связанные документы
) → Unit
update_doc(
path: String, // путь к существующему документу в vault
content: String, // новое содержимое (полная замена или patch)
) → Unit
Retrieval pipeline
query
│
├─► [Metadata filter] сужаем по genre/topic до поиска
│
├─► [BM25] точные термины, имена функций, либ
│
├─► [Vector search] семантически похожие чанки
│
├─► [RRF Fusion] объединяем результаты оба ретривера
│
├─► [Wikilink expansion] подтягиваем [[связанные]] документы
│
└─► [Reranker] финальный отбор top-K
BM25 — exact match, работает без GPU, быстрый, хорош для кода. Vector — семантика, ловит синонимы и перефразировки. Wikilinks — граф расширения, подтягивает связанный контекст автоматически. Reranker — cross-encoder переранжирует объединённый результат, оставляет только релевантное.
Индексация
File watcher следит за vault. При изменении файла — инкрементальное обновление BM25, векторного индекса и графа wikilinks в памяти. Граф wikilinks не персистируется на диск: при каждом запросе к документу сервер on-demand разворачивает [[ссылки]] и загружает связанные документы. Contextual enrichment: перед индексацией каждый чанк обогащается контекстом через LLM — повышает точность retrieval.
Как агент умнеет
1. Агент получает задачу
↓
2. search_docs("задача") → читает релевантные гайдлайны
↓
3. Выполняет задачу по правилам
↓
4. Столкнулся с чем-то новым или нестандартным
↓
5. write_guideline("правило...") → новый .md в guidelines/
update_doc([[existing-doc]], добавляет [[ссылку]] на новый гайдлайн)
↓
6. Следующая похожая задача → агент найдёт это правило сам
Петля замкнута. Агент накапливает знания автоматически; человек фокусируется на концептах, архитектурных решениях и ревью.
Технический стек
| Компонент | Технология |
|---|---|
| MCP Server | kotlin-sdk |
| BM25 | Apache Lucene (Kotlin DSL) |
| Vector store | ChromaDB |
| Развёртывание | Docker Compose / Docker Desktop |
| Embeddings + Enrichment | DeepSeek deepseek/deepseek-v4-flash |
| Reranker | cross-encoder/ms-marco-MiniLM-L-6-v2 (ONNX) |
| File watching | Java WatchService |
| Frontmatter | Kaml (Kotlin YAML) |
| Wikilink parser | Regex + [[...]] |
| AI Agent | OpenCode |
| Vault | Obsidian |
Быстрый запуск
Без клонирования репозитория — только Docker.
1. Создайте файлы
my-project/
├── knowledge-docker-compose.yml
├── .env
└── vault/ ← сюда кладёте документацию
knowledge-docker-compose.yml
services:
chromadb:
image: chromadb/chroma
volumes:
- chroma-data:/chroma/chroma
restart: unless-stopped
environment:
- ALLOW_RESET=true
mcp:
image: aequicor/knowledgeos:latest
ports:
- "8081:8080"
env_file: .env
environment:
- CHROMA_URL=http://chromadb:8000
- CHROMA_COLLECTION=vault_my_project
- BM25_INDEX_PATH=/app/index
- VAULT_PATH=/vault
volumes:
- ./vault:/vault
- bm25-index:/app/index
- bm25-models:/app/model # ONNX models (download once, persist across rebuilds)
depends_on:
chromadb:
condition: service_started
restart: unless-stopped
volumes:
chroma-data:
bm25-index:
bm25-models:
.env
LLM_API_KEY=sk-...
LLM_BASE_URL=https://openrouter.ai/api/v1
Важно: добавьте
.envв.gitignore, чтобы ключ не попал в репозиторий.
2. Запустите
docker compose -f knowledge-docker-compose.yml up -d
MCP-сервер будет доступен на http://localhost:8081/mcp.
3. Обновление до новой версии
docker compose -f knowledge-docker-compose.yml pull
docker compose -f knowledge-docker-compose.yml up -d
Несколько проектов
Каждый проект — отдельный MCP-контейнер со своим vault, индексами и портом. Общий только ChromaDB (один инстанс, разные коллекции).
Структура
knowledgeos/
├── docker-compose.yml # в git — только ChromaDB
├── docker-compose.local.example.yml # в git — шаблон для копирования
├── docker-compose.local.yml # в .gitignore — ваша настройка проектов
├── .env # в .gitignore — общие переменные (API ключи, ...)
├── vaults/ # vault каждого проекта
│ ├── my-app/ # vault проекта "my-app"
│ │ ├── _INDEX.md
│ │ ├── concepts/
│ │ ├── guidelines/
│ │ └── ...
│ └── another-project/ # vault проекта "another-project"
│ └── ...
Настройка нового проекта
Добавьте блок в docker-compose.local.yml:
services:
mcp-new-project:
image: aequicor/knowledgeos:latest
ports:
- "8083:8080" # уникальный порт
env_file: .env
environment:
- CHROMA_URL=http://chromadb:8000
- CHROMA_COLLECTION=vault_new_project # уникальная коллекция
- BM25_INDEX_PATH=/app/index
- VAULT_PATH=/vault
volumes:
- ./vaults/new-project:/vault # уникальная папка vault
- bm25-new-project:/app/index # уникальный volume для BM25
- bm25-models:/app/model # ONNX models
depends_on:
chromadb:
condition: service_started
restart: unless-stopped
volumes:
bm25-new-project:
bm25-models:
Что должно быть уникальным для каждого проекта
| Параметр | Зачем |
|---|---|
ports (host port) |
Чтобы каждый MCP был доступен по своему порту |
CHROMA_COLLECTION |
Векторные индексы проектов не перемешиваются |
volumes (vault path) |
У каждого проекта свой vault |
volumes (BM25 named volume) |
BM25 индексы не пересекаются |
service name |
Уникальное имя Docker-сервиса |
Подключение нескольких проектов в OpenCode
{
"mcpServers": {
"knowledge-my-app": {
"type": "remote",
"url": "http://localhost:8081/mcp"
}
}
}
Конфигурация
.env — общие настройки для всех проектов
# .env.example
# OpenAI-compatible LLM (enrichment only — OpenRouter, DeepSeek, OpenAI, etc.)
LLM_API_KEY=sk-...
LLM_BASE_URL=https://openrouter.ai/api/v1
EMBEDDINGS_MODEL=deepseek/deepseek-v4-flash
ENRICHMENT_MODEL=deepseek/deepseek-v4-flash
ENRICHMENT_ENABLED=true
# Retrieval
RETRIEVAL_TOP_K=5
RETRIEVAL_CHUNK_SIZE=512
RETRIEVAL_CHUNK_OVERLAP=50
RETRIEVAL_WIKILINKS_HOPS=1
RETRIEVAL_RERANKER_ENABLED=true
RETRIEVAL_RERANKER_MODEL=cross-encoder/ms-marco-MiniLM-L-6-v2
# Vault watching
VAULT_WATCH=true
# ChromaDB
CHROMA_URL=http://chromadb:8000
CHROMA_PORT=8000
Важно: добавьте
.envв.gitignore, чтобы ключLLM_API_KEYне попал в репозиторий.
Логирование
По умолчанию сервер выводит логи на уровне INFO. Для диагностики доступен уровень DEBUG — он печатает параметры каждого вызова инструмента и усечённый результат (до 500 символов).
LOG_LEVEL=DEBUG
Локально:
LOG_LEVEL=DEBUG ./gradlew :mcp-api:run
В docker-compose.local.yml:
services:
mcp-my-app:
environment:
- LOG_LEVEL=DEBUG
Пример вывода:
12:34:56.789 [eventLoop] DEBUG i.k.server.Routes - search_docs called: query='transaction rollback' genre=guideline topic=null
12:34:56.923 [eventLoop] DEBUG i.k.server.Routes - search_docs result: [{"chunkId":"guidelines/database.md#0","docPath":…
docker-compose.local.yml — параметры конкретного проекта
Переменные, уникальные для каждого проекта, задаются в блоке environment:
| Переменная | Описание |
|---|---|
CHROMA_COLLECTION |
Уникальное имя коллекции в ChromaDB (vault_<project>) |
VAULT_PATH |
Путь к vault внутри контейнера (обычно /vault) |
BM25_INDEX_PATH |
Путь к Lucene индексу внутри контейнера (/app/index) |
Volumes и bind mounts
# docker-compose.local.yml (фрагмент)
services:
mcp-my-app:
volumes:
- ./vaults/my-app:/vault # bind mount — vault проекта
- bm25-my-app:/app/index # named volume — персистентный BM25 индекс
- bm25-models:/app/model # named volume — ONNX модели (скачиваются один раз)
chromadb:
volumes:
- chroma-data:/chroma/chroma # named volume — все векторные индексы
volumes:
bm25-my-app:
bm25-models:
chroma-data:
Структура проекта
knowledgeos/
├── build.gradle.kts
├── settings.gradle.kts
├── Dockerfile
├── docker-compose.yml # ChromaDB (общий, в git)
├── docker-compose.local.example.yml # шаблон для проектов (в git)
├── docker-compose.local.yml # ваша настройка проектов (.gitignore)
├── .env.example
├── .env # общие переменные (.gitignore)
├── vaults/ # vault'ы проектов
│ ├── my-app/ # vault проекта "my-app"
│ └── another-project/ # vault проекта "another-project"
│
├── buildSrc/ # convention plugins (kotlin-jvm)
│
├── mcp-api/ # контракты и точка входа
│ └── src/main/kotlin/
│ ├── server/
│ │ ├── McpServer.kt # MCP protocol handler
│ │ └── Routes.kt # HTTP endpoints
│ │
│ └── tools/
│ ├── SearchDocsTool.kt # MCP tool: search_docs
│ ├── WriteGuidelineTool.kt # MCP tool: write_guideline
│ └── UpdateDocTool.kt # MCP tool: update_doc
│
└── mcp-imp/ # реализация
└── src/main/kotlin/
├── vault/
│ ├── VaultWatcher.kt # file watcher
│ ├── FrontmatterParser.kt
│ └── WikilinkParser.kt
│
├── indexing/
│ ├── Chunker.kt
│ ├── ContextualEnricher.kt
│ └── IndexPipeline.kt
│
└── retrieval/
├── Bm25Retriever.kt
├── VectorRetriever.kt
├── WikilinkRetriever.kt
├── RrfFusion.kt # Reciprocal Rank Fusion
└── Reranker.kt
Философия
Код перестаёт быть источником истины — он становится его следствием.
Разработчик больше не спорит над кодом — он спорит над формулировкой в документе. Ошибка агента — это ошибка в документации, а не в имплементации. Дебаггинг становится лингвистическим.
Новый навык — умение писать точные, недвусмысленные документы — ценнее знания синтаксиса.
Лицензия
MIT
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.