Skip to main content
Glama
dev-com2020

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: Knowledge 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".

ParametersJSON Schema
NameRequiredDescriptionDefault
top_kNoLiczba wyników (domyślnie 5)
document_idYesIdentyfikator dokumentu bazowego

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It usefully discloses the ranking semantics ('najbardziej semantycznie podobne'), so the agent knows results are ordered by semantic closeness, but it says nothing about read-only safety, permissions, pagination, or result count limits beyond what the schema shows.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence that leads with the operation and its ranking behavior, with the usage example appended. No filler, though it is terse enough that it could afford one more clause of guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter read tool with no output schema and simple structure, the description covers what is returned and how it is ranked, which is largely sufficient. The count/default behavior lives in the schema, so little is genuinely missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both document_id and top_k are already documented in the schema. The description only echoes the 'po id' keying for document_id and adds no format or constraint detail beyond it, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Zwraca dokumenty najbardziej semantycznie podobne') plus the keying mechanism ('po id'), so an agent knows exactly what it retrieves. It is clear on its own, but it does not name or contrast itself with siblings like search_documents or get_document, leaving differentiation implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The example 'pokaż więcej takich jak ten' implies the intended usage pattern (find-more-like-this rather than a keyword search), which is helpful. However, it never states when to prefer this over search_documents or how it differs from get_document, and gives no when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_documentPobierz dokumentA

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

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesIdentyfikator dokumentu, np. "doc-001"

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the disclosure burden. It usefully states the payload ('pełną treść i metadane'), which is the key behavioral fact given there is no output schema, but it says nothing about read-only guarantees, permissions, or error behavior for an unknown id.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with no filler, front-loading the return payload and then the keying mechanism. Nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter read tool with no output schema, the description covers what is returned and where the id originates. Only error/missing-document behavior is unaddressed, a minor gap given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the id format is already documented, giving a baseline of 3. The description adds real value by stating the provenance of the id (results of search_documents), which tells the agent where the value must come from.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (zwraca) and resource (pełną treść i metadane jednego dokumentu) and ties the lookup to an id obtained elsewhere. It references the sibling search_documents, making the retrieve-vs-search split inferable, though it does not explicitly contrast with the other siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The parenthetical '(z wyników search_documents)' implies the intended workflow: get the id from a prior search, then fetch the full record here. There is no explicit statement of when not to use it or what to do if the document is missing, so guidance is implied rather than spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_video_segmentPobierz fragment transkryptu wideoC

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

ParametersJSON Schema
NameRequiredDescriptionDefault
endYesKoniec zakresu w sekundach
startYesPoczątek zakresu w sekundach
document_idYesIdentyfikator dokumentu typu mp4

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations present, the description carries the full behavioral burden. It discloses only that a transcript fragment is returned for a time range; it says nothing about transcript format (plain text, timestamps, language), permission requirements, or behavior when the range exceeds the video length.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence with no filler, and the time-range constraint is stated immediately. It is efficiently written, though arguably too terse given the absence of annotations and output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read tool with no output schema, the description should say more about what the returned transcript looks like (segments, timestamps, language). It covers the core contract (input range, transcript output) but leaves return-value detail and edge-case behavior unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters (document_id, start, end) are already documented in the schema. The description's only added detail is that units are seconds, which the schema property descriptions already state. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (zwraca) and resource (transkrypt fragmentu filmu instruktażowego) plus the scoping dimension (zakres czasu). It is clear what the tool does, though it does not explicitly contrast itself with siblings such as get_document or search_documents.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is used when a specific time range is known, but it gives no explicit when-to-use guidance, no prerequisites, and no mention of alternatives like get_document or search_documents. Usage must be inferred entirely.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
fieldYesPole, dla którego pobrać dostępne wartości

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses the returned payload (values with document counts), which is useful behavioral context, but says nothing about permissions, whether the list is exhaustive, or result size/pagination for a potentially large facet set.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence with no filler; the resource, the field list, the count detail, and the routing note are all packed in without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description must convey return content, and it does: values plus counts. For a one-parameter read-only lookup this is nearly complete, though the exact response shape (per-value count structure) is left implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single parameter is a fully enumerated enum, so the schema already defines the allowed values. The description restates the same three values and their filter role without adding syntax, format, or default semantics beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: returns the available values of a given field (doc_type, product or tags) plus document counts. The field enumeration and the count detail let an agent distinguish this lookup from search_documents and get_document immediately.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the intended context ('useful to learn which filters can be used in search_documents') and the alternative it replaces ('instead of guessing a product name or tag'), which is strong routing guidance. It does not state an explicit when-not-to-use condition, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagsNoOgranicz wyniki do dokumentów mających którykolwiek z podanych tagów
queryYesPytanie użytkownika w języku naturalnym, np. "jak zresetować ekspres"
top_kNoLiczba wyników (domyślnie 5)
productNoOgranicz wyniki do konkretnego produktu, np. "Ekspres X200"
doc_typeNoOgranicz wyniki do jednego typu pliku

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations the description carries the full burden, and it delivers meaningfully: it discloses the retrieval mechanism (lexical + semantic fusion), the corpus types covered, and the exact return form (best-matching fragments with source, plus per-segment timestamps for videos). It omits secondary operational details like permission/auth needs, rate limits, or that it is strictly read-only, so it falls short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with the search mechanism and corpus and then the return payload. Every clause carries information; nothing is redundant or padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema and no annotations, so the description must explain return values itself, and it does so well (fragments + source + video timestamps). The only gap is the absent when-to-use guidance relative to sibling retrieval tools, which slightly reduces completeness for a 5-parameter multi-source search tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all five parameters (query, tags, product, doc_type, top_k) including examples and constraints. The description adds no parameter-level meaning such as how tags, product, and doc_type filters combine, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific mechanism (hybrid BM25 + semantic) and resource (instruction base covering manuals, videos, PDFs, DOCX, images), so the agent knows exactly what this does. However, it never names or contrasts with siblings like find_similar or get_document, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by describing the return shape ('direct the user to the segment'). There is no explicit when-to-use, when-not-to-use, or routing to find_similar (semantic-only) or get_document (full-document retrieval), which are the obvious alternatives an agent would weigh.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

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

  1. 5 tool updatesv1.0.0
    • First observedfind_similar
    • First observedget_document
    • First observedget_video_segment
    • First observedlist_facets
    • First observedsearch_documents

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.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers