
MCP를 사용하여 Slackbot을 기업용 리서치 에이전트로 전환하기
요약
Model Context Protocol(MCP)을 활용하여 Slack 에이전트를 기업용 리서치 에이전트로 구축하는 방법과 아키텍처를 소개합니다. SWIRL MCP 서버를 통해 OneDrive, SharePoint 등 다양한 데이터 소스를 연동하고, 권한 관리가 적용된 RAG 기반 검색 기능을 구현하는 과정을 다룹니다.
핵심 포인트
- MCP를 통한 Slack 에이전트와 연합 검색 엔진의 연결 방식 설명
- SWIRL MCP 서버의 주요 기능(search, search_rag 등) 및 아키텍처 소개
- OAuth 2.1 및 PKCE를 활용한 프로덕션 환경의 보안 및 권한 관리 구현
- 데이터 복사 없이 원본 소스에서 직접 쿼리하는 RAG 워크플로우
우리는 Model Context Protocol (MCP)을 통해 Slack 에이전트를 연합 검색 엔진 (federated search engine)에 연결했고, 오직 우리의 OneDrive만이 답할 수 있는 질문을 던졌습니다. 에이전트는 검색을 수행하고, 문서를 읽은 뒤, Slack에서 보장 한도를 표 형태로 정리하고 SharePoint의 정확한 문장을 열 수 있는 인용구를 포함하여 답변했습니다.
이 포스트에서는 아키텍처 (architecture), 연결 방식 (wiring), 그리고 실제 디버깅 시간을 잡아먹었던 두 가지 주의사항 (gotchas)에 대해 다룹니다.
아키텍처 (The architecture)
모두 표준적인 세 가지 구성 요소입니다:
- 클라이언트로서 MCP를 사용하는 Slack 에이전트. Slack의 에이전트 플랫폼을 사용하면 봇이 자신의 매니페스트 (manifest)에 MCP 서버를 선언하고 런타임 (runtime)에 연결할 수 있습니다.
- SWIRL의 MCP 서버. SWIRL은 연합 검색 (federated search) + RAG 엔진입니다. 이 엔진의 MCP 서버는
search,search_rag(인용구가 포함된 근거 있는 답변),read_document,score_document,list_providers, 그리고chat기능을 노출합니다. 이는 HTTP를 통해 실행 중인 SWIRL 배포 환경을 호출하는 독립적인 프로세스이므로, 라이선싱, 스로틀링 (throttling), 사용자별 권한 관리는 다른 API 클라이언트와 마찬가지로 SWIRL에 의해 정확하게 집행됩니다. - 데이터 소스 (The sources). SharePoint, OneDrive, Box, 데이터베이스, 웹 API 등이 포함되며, SWIRL은 데이터가 존재하는 위치에서 직접 쿼리합니다. 그 어떤 것도 봇, 모델, 또는 벡터 데이터베이스 (vector database)로 복사되지 않습니다.
연결 방식 (The wiring)
Slack 측에서는 봇의 매니페스트가 MCP 서버를 선언하며, 봇은 슬래시 커맨드 (slash command)를 통해 연결됩니다. SWIRL 측에서는 서버가 HTTP 전송 모드 (HTTP transport mode)로 실행됩니다:
SWIRL_MCP_TRANSPORT=http SWIRL_MCP_PORT=8675 \
SWIRL_MCP_TOKEN=<api-key> \
python -m swirl_mcp
데모를 위해 우리는 인증을 비활성화한 터널을 통해 노출했습니다. 프로덕션 (production) 환경에서는 절대로 이렇게 하지 마십시오. 프로덕션 경로는 서버의 OAuth 2.1 리소스 서버 모드(SWIRL_MCP_AUTH=oidc)입니다. MCP 호스트는 사용자의 IdP를 대상으로 PKCE를 실행하고, 서버는 각 베어러 JWT (bearer JWT: 발행자, 대상, JWKS 서명)를 검증하며, SWIRL은 토큰을 실제 호출한 사용자와 매핑합니다. 따라서 모든 검색은 호출자별로 권한이 제한됩니다.
쿼리 예시 (What a query looks like)
"OneDrive에서 SWIRL의 보험 정책을 검색해줘"라고 질문했을 때, 봇은 다음과 같이 동작합니다:
list_providers를 호출하여 OneDrive 소스 ID를 찾습니다.- 해당 제공자(provider)로 범위를 제한하여
search를 호출합니다. - 검색 결과에 대해 근거 있는 답변을 얻기 위해
search_rag를 호출합니다.
답변에는 보험 한도가 표 형태로 포함되며, 해당 보험에서 전문 서비스(professional services)가 제외된다는 점을 표시하고, text_fragment_url 인용을 포함합니다. 이는 인용된 정확한 구절로 스크롤되어 원본 문서를 여는 딥 링크(deep link)입니다.


알아두면 좋은 두 가지 주의사항 (gotchas)
타임아웃 불일치 (Timeout mismatch). Slack은 MCP 도구 호출(tool call)에 약 60초를 할당합니다. 반면 SWIRL의 search_rag는 콜드 로컬 모델(cold local model)의 규모에 맞춰 RAG 답변을 위해 최대 90초 동안 폴링(poll)합니다. 모델의 속도가 느리면 Slack 호출이 먼저 종료되어 봇은 실패를 보고하지만, 답변은 몇 초 후에 도착하게 됩니다. 해결책: Slack 대응용 RAG에는 빠른 모델을 사용하거나, 실패 보고가 정직하게 이루어지도록 SWIRL_MCP_RAG_POLL_TIMEOUT 값을 낮추십시오.
도구 설명은 UX입니다. 데모에서 봇의 첫 번째 행동은 SWIRL의 도구들을 자신의 언어로 정확하게 설명하는 것입니다. 이는 봇이 똑똑해서가 아니라, MCP 서버의 도구 설명(tool descriptions)이 LLM(대규모 언어 모델) 사용자를 위해 작성되었기 때문입니다. 만약 에이전트가 도구를 잘못 사용한다면, 에이전트를 수정하기 전에 설명(description)부터 수정하십시오.
핵심 요약 (The takeaway)
에이전트에게는 데이터를 직접 주입(ingest)할 필요가 없습니다. 대신 관리되는 검색 계층(governed search layer)이 필요합니다. 봇은 우리의 문서를 직접 보유하지 않았습니다. 봇은 권한이 강제되고 인용이 첨부된 상태로, 우리를 대신하여 문서를 검색할 수 있는 서버와의 연결을 보유했을 뿐입니다.
동일한 MCP 서버는 Claude Desktop과 Claude Code 모두에서 작동합니다. 전체 스택을 구축해 주는 Claude Code 플러그인이 있습니다: swirl-claude-plugin, 그리고 2분 분량의 데모 영상은 여기에서 확인할 수 있습니다: [LINK-TO-VIDEO].
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기