Skip to main content
Glama
MCP Elasticsearch Demo

MCP Elasticsearch Demo

by dev-com2020

Demo: MCP dla wyszukiwarki dokumentacji (Elasticsearch)

Działający przykład tego, jak może wyglądać serwer MCP opisany w propozycji technicznej: 5 narzędzi, które dowolny agent LLM (Claude Desktop, Claude Code, własny chatbot na Claude API) może wywołać, żeby przeszukać bazę instrukcji, filmów instruktażowych, PDF-ów, DOCX-ów i zdjęć — zamiast dostawać surowy dostęp do indeksu.

Demo ma dwa tryby, ten sam kod serwera i te same narzędzia w obu:

  • memory (domyślny) — 10 przykładowych dokumentów z data/documents.json, wyszukiwanie hybrydowe (BM25 + wektor) liczone w pamięci procesu Node. Zero zależności zewnętrznych, działa od razu, po npm install.

  • elasticsearch — te same narzędzia, ale dane trzymane w prawdziwym Elasticsearch (docker-compose). Pokazuje ścieżkę do wdrożenia produkcyjnego.

Szybki start (tryb memory, bez Dockera)

npm install
npm run test:e2e        # uruchamia realnego klienta MCP i sprawdza wszystkie narzędzia

test/demo-client.js to nie jest test jednostkowy funkcji — to prawdziwy klient MCP, który odpala src/server.js jako osobny proces i rozmawia z nim po protokole MCP przez stdio, dokładnie tak jak zrobiłby to Claude Desktop.

Related MCP server: rag-hub-mcp

Podłączenie do Claude Desktop

  1. Otwórz konfigurację Claude Desktop (Settings → Developer → Edit Config).

  2. Dopisz zawartość claude_desktop_config.example.json, podmieniając ścieżkę na pełną ścieżkę do src/server.js na Twoim dysku.

  3. Zrestartuj Claude Desktop.

  4. Zapytaj np. "jak zresetować ekspres X200?" albo "pokaż jak wymienić filtr wody" — Claude sam wywoła search_documents, ewentualnie doprecyzuje przez list_facets, i odpowie z cytowaniem źródła (dla filmu — z konkretną minutą).

Narzędzia (tools)

Narzędzie

Do czego służy

search_documents

Wyszukiwanie hybrydowe (BM25 + wektor) z filtrami doc_type, product, tags. Dla wideo zwraca znacznik czasu najlepiej pasującego segmentu.

get_document

Pełna treść i metadane jednego dokumentu po id.

list_facets

Dostępne wartości pola (doc_type, product, tags) z licznikiem — żeby agent znał opcje filtrowania zamiast zgadywać.

find_similar

Dokumenty podobne semantycznie do podanego.

get_video_segment

Transkrypt fragmentu filmu z zadanego zakresu czasu (sekundy).

Przykładowe zapytania testowe (patrz test/demo-client.js) celowo używają innych słów niż dokumenty źródłowe — np. "zacięta kartka w drukarce" trafia w dokument mówiący o "zacięciu papieru", a "jak zresetować" trafia w dokumenty mówiące o "przywracaniu ustawień fabrycznych". To demonstruje mechanizm opisany w propozycji: dopasowanie działa mimo że słowa się nie pokrywają.

Ważne zastrzeżenie co do jakości wyszukiwania w trybie memory

Wektor semantyczny w src/embeddings.js to uproszczony zamiennik demo (hashed bag-of-words + ręczna normalizacja kilkunastu synonimów domenowych), nie prawdziwy model embeddingowy. Wystarcza, żeby pokazać mechanizm hybrydowego wyszukiwania i to, że synonimy/parafrazy trafiają w wynik — ale nie ma prawdziwego rozumienia znaczenia zdań. W produkcji embed() zamienia się na wywołanie realnego modelu (self-hosted bge-m3/multilingual-e5, albo API OpenAI/Voyage/Cohere) — interfejs (embed(text) -> wektor) zostaje ten sam, zmienia się tylko ta jedna funkcja.

Tryb produkcyjny: prawdziwy Elasticsearch (lokalnie)

docker compose up -d              # startuje ES 8.15 lokalnie
npm run seed:elasticsearch        # tworzy indeks i ładuje data/documents.json
STORE_BACKEND=elasticsearch npm start

src/store/elasticsearchStore.js implementuje dokładnie ten sam kontrakt co memoryStore.js (patrz src/store/interface.js) — serwer MCP przełącza się między nimi zmienną środowiskową STORE_BACKEND, bez zmian w warstwie narzędzi (src/createMcpServer.js). To pokazuje, że warstwa MCP jest niezależna od tego, gdzie faktycznie stoją dane.

Uwaga: zapytanie hybrydowe w elasticsearchStore.js używa rank.rrf, które działa na ES 8.9–8.12. Od 8.13 zalecany jest nowszy DSL retriever — przed wdrożeniem u klienta sprawdź wersję klastra (patrz komentarz w tym pliku).

Wdrożenie na zdalny serwer (Docker, HTTP)

Do lokalnego użycia z Claude Desktop służy src/server.js (transport stdio). Do wdrożenia na serwerze, gdzie ma być dostępny przez sieć, służy src/httpServer.js — te same 5 narzędzi, transport HTTP zamiast stdio, z autoryzacją Bearer-token (MCP_API_KEY).

Pełna instrukcja krok po kroku (kopiowanie na serwer, docker-compose.prod.yml z Elasticsearch + seed + appką, reverse proxy z TLS, podłączenie zdalnego serwera MCP do klienta) jest w DEPLOY.md.

Struktura projektu

mcp-elasticsearch-demo/
  data/documents.json           przykładowe dokumenty (pdf/docx/jpg/mp4)
  src/embeddings.js              uproszczony "embedding" demo + synonimy
  src/store/interface.js         kontrakt wspólny dla obu backendów
  src/store/memoryStore.js       backend w pamięci (domyślny)
  src/store/elasticsearchStore.js backend na prawdziwym ES
  src/createMcpServer.js          rejestracja 5 narzędzi MCP (współdzielona)
  src/storeFactory.js             wybór backendu wg STORE_BACKEND
  src/server.js                   wejście stdio — lokalnie, Claude Desktop
  src/httpServer.js               wejście HTTP — zdalny serwer, patrz DEPLOY.md
  scripts/seed-elasticsearch.js   tworzy indeks + ładuje dane do ES
  docker-compose.yml              lokalny klaster ES (do dev, bez appki)
  docker-compose.prod.yml         pełny stack do wdrożenia (ES + seed + app)
  Dockerfile                      obraz dla src/httpServer.js
  .env.example                    szablon zmiennych (MCP_API_KEY, PORT)
  DEPLOY.md                       instrukcja wdrożenia na serwer
  test/demo-client.js             klient MCP do testu end-to-end
  claude_desktop_config.example.json  jak podłączyć do Claude Desktop (stdio)

Co dalej (poza zakresem tego demo)

  • Prawdziwy model embeddingowy zamiast src/embeddings.js.

  • Indeksowanie segmentów wideo jako osobnych dokumentów ES (trafność na poziomie minuty filmu, nie całego pliku) — patrz uwaga w elasticsearchStore.js.

  • Autoryzacja / filtrowanie wyników wg uprawnień użytkownika po stronie serwera MCP, nie po stronie agenta.

  • Warstwa RAG (synteza odpowiedzi z cytowaniami) jako kolejne narzędzie albo prompt MCP — patrz faza 3 w dokumencie technicznym.

Available Tools

5 tools
find_similarZnajdź podobne dokumentyA

Zwraca dokumenty najbardziej semantycznie podobne do podanego (po id) — np. "pokaż więcej takich jak ten".

Inputs: document_id (required), top_k.

get_documentPobierz dokumentA

Zwraca pełną treść i metadane jednego dokumentu po jego id (z wyników search_documents).

Inputs: id (required).

get_video_segmentPobierz fragment transkryptu wideoC

Zwraca transkrypt fragmentu filmu instruktażowego z podanego zakresu czasu (w sekundach).

Inputs: end (required), start (required), document_id (required).

list_facetsLista wartości filtraA

Zwraca dostępne wartości danego pola (doc_type, product albo tags) wraz z liczbą dokumentów — przydatne, żeby dowiedzieć się jakich filtrów można użyć w search_documents, zamiast zgadywać nazwę produktu czy tagu.

Inputs: field (required).

search_documentsSzukaj w dokumentacjiA

Wyszukiwanie hybrydowe (leksykalne BM25 + semantyczne) w bazie instrukcji, filmów instruktażowych, PDF-ów, DOCX-ów i zdjęć. Zwraca najlepiej dopasowane fragmenty wraz ze źródłem; dla filmów dodatkowo znacznik czasu konkretnego segmentu, do którego warto skierować użytkownika.

Inputs: query (required), tags, top_k, product, +1 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 5 tools

    Disambiguation4/5

    Each tool has a distinct retrieval purpose: search_documents queries by text, find_similar queries by example id, list_facets enumerates filter values, get_document fetches a full doc by id, and get_video_segment pulls a time-bounded transcript. The main mild overlap is search_documents vs find_similar (both return ranked recommendations), but the input mode (query vs id) and descriptions differentiate them adequately.

    Naming Consistency5/5

    All five names follow a consistent snake_case verb_noun pattern (get_video_segment, search_documents, get_document, list_facets, find_similar). Verb choice is predictable and readable across the set.

    Tool Count5/5

    Five tools is well-scoped for a hybrid search/retrieval server, covering search, drill-down, filtering discovery, similarity, and a media-specific accessor. Every tool earns its place with no redundant filler.

    Completeness4/5

    The retrieval lifecycle is well covered: search, fetch full content, discover facets, find similar, and extract a video segment. It lacks any indexing/write operations (create/update/delete or list-all), which may be intentional for a read-only demo but leaves the surface one-sided.

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      A
      maintenance
      Enables agents to build self-hosted knowledge bases from document folders and search them via hybrid vector and keyword retrieval, with eight tools for listing, adding, deleting, and reindexing content.
      114 npm
      1
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables any MCP-capable LLM client to search self-hosted long-term memory over markdown and PDF documents, combining dense semantic vectors with BM25 keyword retrieval and optional cross-encoder reranking. Exposes a read-only tool surface for querying incidents, runbooks, and other knowledge-base content, while writes happen out-of-band through ingestion jobs or a token-gated internal API.
      2
      MIT
    • A
      license
      Not graded
      quality
      Not graded
      maintenance
      Enables agents to retrieve relevant context via a zero-dependency hybrid search engine that blends sparse keyword-based lexical ranking with dense vector similarity scores into one fused result set, then refines it with knowledge graph triplet expansion and lost-in-the-middle context reordering. It also provides episodic memory consolidation, recency decay, and semantic query caching, exposed as a JSON-RPC 2.0 stdio MCP server for clients such as Claude Desktop, Cursor, and Windsurf.
      MIT