Elasticsearch에서 대규모 지식 기반을 다룰 때, 정보를 찾아내는 것은 첫 관문을 넘긴 것에 불과합니다. 엔지니어는 종종 여러 문서에서 결과를 종합하고, 요약을 작성하며, 답변을 출처까지 추적해야 합니다. 모델 컨텍스트 프로토콜(MCP)은 이를 달성하기 위해 Elasticsearch를 거대 언어 모델(LLM) 기반 애플리케이션과 연결하는 표준화된 방법을 제공합니다. Elastic은 Elastic Agent Builder(기능 중 MCP 엔드포인트 포함)와 같은 공식 솔루션을 제공하지만, 사용자 지정 MCP 서버를 구축하면 검색 논리, 결과 형식, 검색된 콘텐츠가 종합, 요약, 인용을 위해 LLM에 전달되는 방식을 완전히 제어할 수 있습니다.
이 글에서는 사용자 지정 Elasticsearch MCP 서버 구축의 장점을 살펴보고, Elasticsearch를 LLM 기반 애플리케이션에 연결하는 TypeScript로 서버를 생성하는 방법을 보여드리겠습니다.
사용자 지정 Elasticsearch MCP 서버를 구축해야 하는 이유는 무엇입니까?
Elastic은 MCP 서버에 대한 몇 가지 대안을 제공합니다.
MCP 서버가 Elasticsearch와 상호 작용하는 방식을 더 세밀하게 제어하고 싶다면, 직접 사용자 지정 서버를 구축하여 요구 사항에 딱 맞게 최적화할 수 있는 유연성을 확보할 수 있습니다. 예를 들어, Agent Builder의 MCP 엔드포인트는 Elasticsearch 쿼리 언어(ES|QL) 쿼리로 제한되지만, 사용자 지정 서버를 사용하면 전체 쿼리 DSL을 사용할 수 있습니다. 또한 결과를 LLM으로 전달되기 전에 결과의 서식을 지정하는 방법을 제어할 수 있으며, 이번 튜토리얼에서 다룰 OpenAI 기반 요약 기능과 같은 추가적인 처리 단계를 통합할 수도 있습니다.
이 글을 마칠 때쯤이면, Elasticsearch 인덱스에 저장된 정보를 검색하고, 요약하며, 인용을 제공하는 TypeScript로 된 MCP 서버를 갖게 됩니다. 검색에는 Elasticsearch를, 요약 및 인용 생성에는 OpenAI gpt-4o-mini 모델을 사용하며, 사용자 쿼리를 받고 응답을 제공하는 MCP 클라이언트와 UI로는 Claude Desktop을 사용할 것입니다. 최종적으로 엔지니어가 조직 내 기술 문서 전반에서 모범 사례를 발견하고 종합할 수 있도록 돕는 내부 지식 어시스턴트를 구축하게 됩니다.

필수 구성 요소:
- Node.js 20+
- Elasticsearch
- OpenAI API 키
- Claude Desktop
MCP란 무엇입니까?
MCP는 Anthropic에서 만든 오픈 표준으로, LLM과 Elasticsearch와 같은 외부 시스템 간에 안전한 양방향 연결을 제공합니다. MCP의 현황에 대한 자세한 내용은 이 글에서 확인할 수 있습니다.
MCP 환경은 광범위한 사용 사례를 지원하는 서버들이 등장하며 매일 진화하고 있습니다. 게다가, 이 글에서 보여 드릴 것처럼 자신만의 맞춤형 MCP 서버를 구축하는 것도 매우 쉽습니다.
MCP 클라이언트
사용 가능한 MCP 클라이언트 목록은 매우 방대하며, 각 클라이언트에는 저마다의 특징과 제한 사항이 있습니다. 단순함과 대중성을 고려하여 Claude Desktop을 MCP 클라이언트로 사용하겠습니다. Claude Desktop은 사용자가 자연어로 질문을 던지는 채팅 인터페이스 역할을 하며, MCP 서버에 노출된 도구를 자동으로 호출하여 문서를 검색하고 요약을 생성합니다.

Elasticsearch MCP 서버 생성하기
TypeScript SDK를 사용하면, 사용자 쿼리 입력을 기반으로 Elasticsearch 데이터를 쿼리하는 방법을 이해하는 서버를 쉽게 만들 수 있습니다.
이 글에서는 Elasticsearch MCP 서버를 Claude Desktop 클라이언트와 통합하는 단계를 설명합니다.
Elasticsearch용 MCP 서버 구성
시작하려면 Node 애플리케이션을 초기화하십시오:
이렇게 하면 package.json 파일이 생성되며, 이를 통해 이 애플리케이션에 필요한 의존성을 설치하기 시작할 수 있습니다.
- @elastic/elasticsearch 패키지를 통해 Elasticsearch Node.js 라이브러리에 액세스할 수 있습니다.
- @modelcontextprotocol/sdk는 MCP 서버 생성 및 관리, 도구 등록, MCP 클라이언트와의 통신 처리를 위한 핵심 도구를 제공합니다.
- openai를 사용하면 OpenAI 모델과 상호 작용하여 요약이나 자연어 응답을 생성할 수 있습니다.
- zod는 각 도구의 입력 및 출력 데이터에 대해 구조화된 스키마를 정의하고 검증하는 것을 돕습니다.
ts-node, @types/node, typescript 는 개발 중에 코드의 타입을 지정하고 스크립트를 컴파일하는 데 사용됩니다.
데이터셋 설정
Claude Desktop이 MCP 서버를 통해 쿼리할 수 있는 데이터를 제공하기 위해, 가상의 내부 지식 기반 데이터 세트를 사용하겠습니다. 이 데이터 세트의 문서는 다음과 같습니다.
데이터를 수집하기 위해, Elasticsearch에 인덱스를 생성하고 데이터 세트를 로드하는 스크립트를 준비했습니다. 여기서 확인하실 수 있습니다.
MCP 서버
index.ts(이)라는 이름의 파일을 생성하고, 의존성을 가져오고 환경 변수를 처리하기 위해 다음 코드를 추가하세요.
또한, Elasticsearch와 OpenAI 호출을 처리할 클라이언트들을 초기화해 보겠습니다.
구현을 더 견고하게 만들고 입력 및 출력 데이터의 구조를 보장하기 위해, zod(을)를 사용하여 스키마를 정의하겠습니다. 이를 통해 런타임에 데이터를 검증하고, 오류를 조기에 발견하며, 도구의 응답을 프로그램 방식으로 더 쉽게 처리할 수 있습니다.
구조화된 출력을 자세히 알아보려면 여기를 참조하세요.
이제 MCP 서버를 초기화해 보겠습니다.
MCP 도구 정의
모든 구성이 완료되면, MCP 서버가 외부에 제공할 도구를 작성하기 시작할 수 있습니다. 이 서버는 두 가지 도구를 외부에 제공합니다.
search_docs: 전체 텍스트 검색을 사용하여 Elasticsearch에서 문서를 검색합니다.summarize_and_cite: 사용자의 질문에 답하기 위해, 이전에 검색된 문서들로부터 정보를 요약하고 종합합니다. 이 도구는 또한 출처 문서를 참조하는 인용 정보를 추가합니다.
이 도구들은 함께 작동하여 간단한 '검색 후 요약' 워크플로우를 형성합니다. 하나의 도구가 관련 문서를 가져오면, 다른 도구가 해당 문서들을 바탕으로 인용구가 포함된 요약 응답을 생성하는 방식입니다.
도구 응답 형식
각 도구는 임의의 입력 매개변수를 허용할 수 있지만, 다음과 같은 구조로 응답해야 합니다.
- 내용: 비정형 형식으로 된 도구의 응답입니다. 이 필드는 일반적으로 텍스트, 이미지, 오디오, 링크 또는 임베딩을 반환하는 데 사용됩니다. 이 애플리케이션의 경우 도구가 생성한 정보를 포함한 서식 있는 텍스트를 반환하는 데 사용됩니다.
- structuredContent: 각 도구의 결과를 구조화된 형식으로 제공하기 위해 사용되는 선택적 반환 값입니다. 이는 프로그램 방식의 처리에 유용합니다. 비록 이 MCP 서버에서는 사용되지 않지만, 다른 도구를 개발하거나 결과를 프로그램 방식으로 처리하고자 할 때 유용하게 활용될 수 있습니다.
그 구조를 염두에 두고, 각 도구에 대해 자세히 살펴보겠습니다.
Search_docs 도구
이 도구는 사용자의 쿼리를 기반으로 가장 관련성 높은 문서들을 검색하기 위해 Elasticsearch 인덱스에서 전체 텍스트 검색을 수행합니다. 또한 주요 일치 항목을 강조하고, 연관성 점수와 함께 빠른 개요를 제공합니다.
We configure fuzziness: “AUTO” to have a variable typo tolerance based on the length of the token that’s being analyzed. We also set title^2 to increase the score of the documents where the match happens on the title 필드.
summarize_and_cite 도구
이 도구는 이전 검색에서 가져온 문서들을 바탕으로 요약을 생성합니다. 사용자의 질문에 답하기 위해 OpenAI의 gpt-4o-mini 모델을 사용하여 가장 관련성 높은 정보를 종합하며, 검색 결과에서 직접 도출된 응답을 제공합니다. 요약과 더불어, 사용된 출처 문서들에 대한 인용 메타데이터도 함께 반환합니다.
마지막으로, stdio를 사용하여 서버를 시작해야 합니다. 이는 MCP 클라이언트가 서버의 표준 입력과 표준 출력 스트림을 읽고 씀으로써 통신하게 된다는 것을 의미합니다. stdio는 가장 단순한 전송 옵션이며, 클라이언트를 통해 하위 프로세스로 실행되는 로컬 MCP 서버에 적합합니다. 파일 끝에 다음 코드를 추가합니다.
이제 다음 명령어를 사용하여 프로젝트를 컴파일하십시오:
이렇게 하면 dist 폴더가 생성되고, 그 안에 index.js 파일이 생성됩니다.
MCP 서버를 Claude Desktop에 로드
Claude Desktop에서 MCP 서버를 구성하려면 이 가이드를 따르세요. Claude 구성 파일에서 다음 값들을 설정해야 합니다.
args 값은 dist 폴더 안에 있는 컴파일된 파일을 가리켜야 합니다. 또한 코드에 정의된 것과 똑같은 이름으로 구성 파일 내에 환경 변수를 설정해야 합니다.
테스트해 보기
각 도구를 실행하기 전에, 검색 및 도구를 클릭하여 도구들이 활성화되어 있는지 확인하세요. 여기에서 각 도구를 개별적으로 활성화하거나 비활성화할 수도 있습니다.

마지막으로 Claude Desktop 채팅에서 MCP 서버를 테스트하고 질문을 시작하십시오:

'인증 방법 및 역할 기반 액세스 제어에 관한 문서를 검색해 줘'라는 질문에 대해, search_docs 도구가 실행되어 다음과 같은 결과를 반환합니다.
응답 내용은 다음과 같습니다. '좋습니다! 인증 방식 및 역할 기반 액세스 제어에 관한 관련 문서 5개를 찾았습니다. 검색된 내용은 다음과 같습니다.'
도구 호출은 응답 페이로드의 일부로 소스 문서들을 반환하며, 이 문서들은 나중에 인용구를 생성하는 데 사용됩니다.

한 번의 상호 작용 내에서 여러 도구를 연결하여 사용할 수도 있습니다. 이 경우, Claude Desktop은 사용자의 질문을 분석한 뒤, 관련 문서를 가져오기 위해 먼저 search_docs(을)를 호출하고, 그 결과를 summarize_and_cite에 전달하여 최종 답변을 생성해야 한다고 판단합니다. 이 모든 과정은 별도의 사용자 프롬프트 없이 이루어집니다.

이 경우, '우리 시스템 전반의 인증 및 액세스 제어를 개선하기 위한 핵심 권장 사항이 뭐야? 참고 문헌 포함해 줘.'라는 쿼리에 대한 답변입니다. 다음과 같은 결과를 얻었습니다.
이전 단계와 마찬가지로, 이 질문에 대한 각 도구의 응답을 확인할 수 있습니다.

참고: 각 도구 사용 승인 여부를 묻는 하위 메뉴가 나타나면 항상 허용 또는 한 번 허용을 선택하십시오.

결론
MCP 서버는 로컬 및 원격 애플리케이션 모두를 위한 LLM 도구 표준화를 향한 중요한 진전을 의미합니다. 완전한 호환성을 구현하기 위해 아직 작업 중이지만, 이를 향해 빠르게 나아가고 있습니다.
이 글에서 Elasticsearch를 LLM 기반 애플리케이션에 연결하는 사용자 지정 MCP 서버를 TypeScript로 구축하는 방법을 배웠습니다. 서버는 두 가지 도구를 제공합니다. Query DSL을 사용하여 관련 문서를 가져오는 search_docs(와)과, OpenAI 모델을 통해 인용구가 포함된 요약을 생성하고 Claude Desktop을 클라이언트 UI로 사용하는 summarize_and_cite입니다.
다양한 클라이언트와 서버 제공 업체 간의 호환성 미래는 매우 유망해 보입니다. 다음 단계로는 에이전트에 더 많은 기능과 유연성을 추가하는 과정이 포함됩니다. 검색 템플릿을 사용하여 쿼리를 매개변수화함으로써 정확도와 유연성을 얻는 방법에 대한 실용적인 글을 읽어 보실 수 있습니다.




