Problem
Pisanie dokumentacji to jeden z najmniej lubianych obowiązków w IT — i jeden z najlepszych przypadków użycia LLM-ów. Po skończonej pracy chat opisuje, co zostało zrobione, według ustalonego schematu i wrzuca markdown do repo. Problem w tym, że taka taśmowa produkcja szybko staje się trudna do ogarnięcia — szczególnie dla innych członków zespołu, a otwieranie repo za każdym razem jest mało praktyczne, jeśli i tak pracujemy głównie z czatem.
Model Context Protocol (MCP) rozwiązuje ten problem — to otwarty standard, który pozwala podłączyć dowolne źródło danych jako "tool" dostępny dla LLM-a. Bez przerywania flow developmentu można odpytać dokumentację (np. jak bezpiecznie postawić tę aplikację w naszej infrastrukturze?), a model sam dobierze parametry zapytania.
docs-mcp to serwer MCP w Go, który klonuje wskazane repo z GitHuba, indeksuje dokumenty algorytmem BM25 i udostępnia je jako narzędzia MCP (search, get document, list). Cały setup to jedno go build i trzy zmienne środowiskowe.
Dlaczego zdalny MCP (HTTP) zamiast stdio?
MCP definiuje kilka transportów — lokalny stdio i wariant HTTP. docs-mcp implementuje ten drugi: zwykły JSON-RPC over HTTP POST. W trybie stdio każdy developer musi mieć lokalnie sklonowane repo, token i uruchomiony proces. Tu serwer działa centralnie — klient potrzebuje tylko URL-a:
{
"mcpServers": {
"infra-docs": {
"url": "https://docs-mcp.internal:8000/mcp"
}
}
}
Dlaczego BM25 zamiast embeddingów?
Typowy RAG pipeline w Pythonie wymaga:
- Modelu embeddingowego (np.
sentence-transformers) — ~500 MB–2 GB RAM na sam model - Bazy wektorowej (FAISS, Chroma, Qdrant)
- Pythona z zależnościami (
torch,transformers,numpy)
docs-mcp używa BM25 — klasycznego algorytmu information retrieval opartego na statystyce słów (TF-IDF z normalizacją długości dokumentu). To podejście:
| Python + embeddingi | docs-mcp (Go + BM25) | |
|---|---|---|
| RAM na indeks | 500 MB – 2 GB+ (model + wektory) | ~10–50 MB (odwrócony indeks w pamięci) |
| Zależności | torch, transformers, numpy, vector DB | Tylko stdlib Go + go-git |
| Czas startu | Sekundy–minuty (ładowanie modelu) | < 1 s (tokenizacja + budowa indeksu) |
| Obraz Docker | 2–5 GB | ~30 MB (statyczna binaryka) |
BM25 nie rozumie synonimów ani semantyki — jeśli dokumentacja mówi "bucket" a pytasz o "storage", nie znajdzie dopasowania. docs-mcp łagodzi to dwoma mechanizmami boostingu: trafienia w nazwę pliku/ścieżkę oraz w tagi z YAML frontmattera:
---
tags: [vpn, staging, wireguard, network]
---
# Konfiguracja VPN do środowiska staging
To prosty, ale skuteczny "ludzki override" dla ograniczeń BM25 — autor dokumentu może dopisać synonimy i terminy domenowe, których nie ma w treści, a które realnie pojawiają się w pytaniach. W praktyce, w dokumentacji wewnętrznej, ludzie szukają konkretnymi terminami ("S3", "terraform", "deploy") i ten dodatek wystarczy, żeby trafność była na poziomie, który nie wymaga embeddingów.
Dla zespołu z kilkuset plikami Markdown to wystarczające rozwiązanie za ułamek kosztu operacyjnego.
Jak to działa w praktyce?
- Serwer klonuje repo (shallow clone, jedna gałąź)
- Parsuje Markdown, dzieli na chunki, buduje indeks BM25
- Co
SYNC_INTERVALsekund (domyślnie 30 min) robigit pulli przebudowuje indeks - Opcjonalnie GitHub webhook triggeruje natychmiastowy sync po pushu
Developer w Cursorze pyta: "jak skonfigurować VPN do staging?" → AI wywołuje tool search_docs → BM25 zwraca najlepiej dopasowane fragmenty → AI odpowiada w kontekście aktualnej dokumentacji zespołu.