지난번 LangConnect 에 대해서 포스트하였습니다. 최근 유튜브에서 TeddyNote 님이 공개한 영상에 언급한 LangConnect 에 GUI를 추가한 Client에 대한 영상 소개가 있어서 보자마자 바로 설치 및 사용을 해봤습니다.
LangConnect Client는 PostgreSQL과 pgvector 확장을 기반으로 한 벡터 데이터베이스를 관리하기 위한 직관적인 웹 인터페이스를 제공합니다. 이 Next.js 기반 GUI 도구는 문서 관리, 벡터 검색 기능, 그리고 Model Context Protocol(MCP)을 통한 AI 어시스턴트와의 원활한 통합을 지원합니다.
https://github.com/teddynote-lab/langconnect-client

주요 기능
컬렉션 관리
- 커스텀 메타데이터 지원을 통한 CRUD 작업
- 실시간 통계 및 대량 작업 지원
문서 관리
- 다양한 형식 지원 (PDF, TXT, MD, DOCX, HTML)
- 자동 텍스트 추출 및 청킹
- 드래그 앤 드롭 배치 업로드
- Metadata를 JSON 구조로 업데이트 가능

고급 검색 기능
- 시맨틱 검색: OpenAI 임베딩을 활용한 벡터 유사성 검색
- 키워드 검색: PostgreSQL 전체 텍스트 검색
- 하이브리드 검색: 구성 가능한 가중치로 결합된 검색

인증 시스템
- 자동 토큰 갱신 기능이 있는 Supabase JWT 인증
- 역할 기반 접근 제어
- NextAuth.js를 통한 안전한 리프레시 토큰 관리
MCP 통합
- Claude, Cursor 등 AI 어시스턴트를 위한 9개 이상의 도구
- stdio 및 SSE 전송 지원
직관적 UI
- Tailwind CSS를 활용한 Next.js
- streamlit
- 다크/라이트 테마, 다국어 지원(영어/한국어)
아키텍처
인증 흐름
인증 시스템은 안전한 토큰 갱신 메커니즘을 구현합니다:

주요 보안 기능:
- 리프레시 토큰이 클라이언트에 노출되지 않음
- 액세스 토큰 만료 시 자동 토큰 갱신
- 향상된 보안을 위한 각 갱신 시 토큰 회전
- httpOnly 쿠키에 암호화된 JWT 저장
시작하기
빠른 시작
# 클론 및 설정
git clone https://github.com/teddynote-lab/langconnect-client.git
cd langconnect-client
cp .env.example .env
# 자격 증명으로 .env 편집 후:
make build # Docker 이미지 빌드
make up # 모든 서비스 시작
MCP 구성 생성
make mcp
서비스 중지
make down
사전 요구 사항
- Docker 및 Docker Compose
- Node.js 20+ (MCP 인스펙터용)
- Python 3.11+ (UV 패키지 매니저 포함)
- Supabase 계정
설치
1. 저장소 클론
git clone https://github.com/teddynote-lab/langconnect-client.git
cd langconnect-client
2. 환경 변수 설정
cp .env.example .env
3. Supabase 구성
a. supabase.com에서 새 프로젝트 생성

b. API 자격 증명 가져오기:
- 프로젝트 설정 → API로 이동
- URL 및 anon public key 복사
c. .env 파일 업데이트:
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your-anon-public-key
4. 애플리케이션 빌드
make build
애플리케이션 실행
모든 서비스 시작
make up

서비스 접근
- 🎨 프론트엔드: http://localhost:3000
- 📚 API 문서: http://localhost:8080/docs
- 🔍 상태 확인: http://localhost:8080/health
서비스 중지
make down
로그 보기
make logs
MCP 통합
자동 설정
MCP 구성 생성:
make mcp
이 명령은 다음을 수행합니다:
- Supabase 자격 증명 입력 요청
- 액세스 토큰 자동 획득
- 토큰으로 .env 업데이트
- mcpserver/mcp_config.json 생성

MCP SSE 실행
만약 Stdio가 아니라, SSE 로 실행하고자 하면, 아래의 명령을 실행합니다.
./run_mcp_sse.py
mcp server를 sse로 실행할 경우, 인증 후 세션이 1시간으로 제한되는 문제가 있습니다. 어플리케이션으로 Token만료를 체크하고 갱신하도록 하기 위해서는 별도의 개발이 필요한 상황입니다. 이 부분을 해결하기 위해 부득이 n8n의 도움을 받았습니다.
n8n에서 아래와 같이 MCP Server를 생성하고, MCP Server용 sse 경로를 생성하고, workflow를 통해서 인증 여부를 체크한 다음 accessToken이 없을 경우, 인증을 있을 경우, API를 통해 문서를 요청하도록 추가하였습니다.

위 설정에 따른 json 파일은 아래와 같습니다. (n8n 사용시 참고 바랍니다.)
{
"name": "LangConnect-RAG",
"nodes": [
{
"parameters": {
"workflowInputs": {
"values": [
{
"name": "query"
}
]
}
},
"type": "n8n-nodes-base.executeWorkflowTrigger",
"typeVersion": 1.1,
"position": [
0,
0
],
"id": "2e7b72a6-6ed2-420d-acbf-a1d2e35718e9",
"name": "When Executed by Another Workflow"
},
{
"parameters": {
"method": "POST",
"url": "http://langConnect-API-Server/collections/38b03cad-7589-421c-9e1f-b05e569d2e3a/documents/search",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "collection_id",
"value": "38b03cad-7589-421c-9e1f-b05e569d2e3a"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $json.accessToken }}"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "query",
"value": "={{ $('When Executed by Another Workflow').item.json.query }}"
},
{
"name": "limit",
"value": "10"
},
{
"name": "search_type",
"value": "hybrid"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
700,
-160
],
"id": "b9729fae-8e48-4d35-aac5-b3585336e1a0",
"name": "HTTP Request"
},
{
"parameters": {
"path": "f48bc9f6-c957-481e-bea6-ab87e4a9ffa5"
},
"type": "@n8n/n8n-nodes-langchain.mcpTrigger",
"typeVersion": 2,
"position": [
-420,
-160
],
"id": "82606c12-d711-4327-a21e-5df67fbbd045",
"name": "MCP Server Trigger",
"webhookId": "f48bc9f6-c957-481e-bea6-ab87e4a9ffa5"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "001a843a-c350-49ed-9cd3-39c8af2c96e4",
"name": "accessToken",
"value": "={{ $json.access_token }}",
"type": "string"
},
{
"id": "8c0a5bf5-9709-4e73-96e0-0eee34bc0511",
"name": "query",
"value": "={{ $json.query }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
220,
0
],
"id": "75a56dea-f775-404d-bd62-ac3747a1f622",
"name": "Edit Fields"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "8bff8f31-0680-41b0-8279-33d33daeeb53",
"leftValue": "={{ $json.accessToken }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
440,
0
],
"id": "479e5f3b-6270-4ec7-8463-4f3b1b10cf80",
"name": "If"
},
{
"parameters": {
"method": "POST",
"url": "http://langConnect-API-Server/auth/signin",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "email",
"value": "(supabase ID)"
},
{
"name": "password",
"value": "(supabase password)"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
660,
100
],
"id": "39a92bf0-b8b3-4b33-9a45-5255d37b81cf",
"name": "Auth"
},
{
"parameters": {
"description": "RAG에 대한 정보를 제공하는 RAG 시스템인 도구입니다.",
"workflowId": {
"__rl": true,
"value": "agbWAy2l1Ui5ydaR",
"mode": "list",
"cachedResultName": "LangConnect-RAG"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {},
"matchingColumns": [],
"schema": [
{
"id": "query",
"displayName": "query",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string",
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
}
},
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
"typeVersion": 2.2,
"position": [
-340,
60
],
"id": "3ee9120c-b447-4338-89d3-764aae3a334e",
"name": "LangConnect-RAG"
}
],
"pinData": {},
"connections": {
"When Executed by Another Workflow": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[]
]
},
"Edit Fields": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"If": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
],
[
{
"node": "Auth",
"type": "main",
"index": 0
}
]
]
},
"Auth": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"LangConnect-RAG": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "e957d4f8-599f-480b-b80f-fc7b07d380ad",
"meta": {
"instanceId": "c800c01c11791c282fbf19f9904400fc4b5efa68352e5e18fe37e9d569fc00f5"
},
"id": "agbWAy2l1Ui5ydaR",
"tags": []
}
AI 어시스턴트와의 통합
Claude Desktop용:
- mcpserver/mcp_config.json의 내용 복사
- Claude Desktop의 MCP 설정에 붙여넣기
Cursor용:
- MCP 구성 복사
- Cursor 설정의 MCP 통합에 추가
사용 가능한 MCP 도구
- search_documents – 시맨틱/키워드/하이브리드 검색 수행
- list_collections – 모든 컬렉션 나열
- get_collection – 컬렉션 세부 정보 가져오기
- create_collection – 새 컬렉션 생성
- delete_collection – 컬렉션 삭제
- list_documents – 컬렉션의 문서 나열
- add_documents – 텍스트 문서 추가
- delete_document – 문서 삭제
- get_health_status – API 상태 확인
- multi_query – 단일 질문에서 여러 검색 쿼리 생성
환경 변수
LangConnect Client를 설정하기 위한 주요 환경 변수:
- OPENAI_API_KEY: 임베딩을 위한 OpenAI API 키 (필수)
- SUPABASE_URL: Supabase 프로젝트 URL (필수)
- SUPABASE_KEY: Supabase anon public key (필수)
- NEXTAUTH_SECRET: NextAuth.js 비밀 키 (필수)
- NEXTAUTH_URL: NextAuth URL (기본값: http://localhost:3000) (필수)
- NEXT_PUBLIC_API_URL: 프론트엔드용 공개 API URL (필수)
- POSTGRES_HOST: PostgreSQL 호스트 (기본값: postgres)
- POSTGRES_PORT: PostgreSQL 포트 (기본값: 5432)
- POSTGRES_USER: PostgreSQL 사용자 (기본값: teddynote)
- POSTGRES_PASSWORD: PostgreSQL 비밀번호
- POSTGRES_DB: PostgreSQL 데이터베이스 이름
- SSE_PORT: MCP SSE 서버 포트 (기본값: 8765)
결론
LangConnect Client는 벡터 데이터베이스 관리와 AI 어시스턴트 통합을 위한 강력하고 직관적인 솔루션을 제공합니다. GUI, 고급 검색 기능, 그리고 MCP 통합을 통해 문서 관리와 RAG(Retrieval-Augmented Generation) 시스템 구축을 간소화합니다. 오픈 소스 프로젝트로서, TeddyNote LAB에서 개발한 이 도구는 AI 기반 애플리케이션 개발자와 데이터 관리자에게 빠른 RAG 시스템 빌드를 도와줄수 있습니다.
다만, MCP 연결하는 측면에서 사전 Instruction 설정하는 방법은 다소 복잡해보이는데, Claude 연결을 위해 부득이 그렇게 진행된 것으로 보입니다. 아마도 괜찮은 MCP Client와 연결된다거나, LangConnect Client 자체에 MCP Client 기능을 구현하고 Instrcution이나 MCP연결을 자유롭게 해줄수 있다면, 더욱 활용성이 높지 않을까 생각해봅니다.
최근 개인적으로 RAG에 관심이 많아서 이것저것 해보면서 우연히 찾은 어플리케이션인데, 설치도 쉽고, UI도 예뻐서 간단하게 이용해보았습니다. 이후에도 좀더 개선되는 모습 기대해볼만 합니다.
관련 링크
답글 남기기