
Conciergent 제작기: MCP 도구에 Slack, LINE 또는 Discord 채팅 인터페이스와 실제 인채팅 OAuth 기능 부여하기
요약
MCP 서버를 Slack, LINE, Discord와 같은 채팅 인터페이스로 변환해 주는 Conciergent 제작기를 소개합니다. 사용자별 OAuth 인증, 파괴적 작업 전 승인 단계, 플랫폼별 네이티브 응답 렌더링 기능을 통해 비기술 인력도 쉽게 AI 도구를 사용할 수 있게 합니다.
핵심 포인트
- MCP 서버를 Slack, LINE, Discord 봇으로 변환 가능
- 채팅 인터페이스 내에서 사용자별 OAuth 인증 지원
- 파괴적 작업 실행 전 Human-in-the-loop 승인 단계 제공
- 각 플랫폼에 최적화된 구조화된 응답 렌더링
얼마 전 저는 어떤 OpenAPI 명세(spec)든 MCP 서버로 변환해 주는 openapi-mcp-gateway를 만들었습니다. 그것으로 공급 측면의 문제는 해결되었습니다. 하지만 이러한 도구를 가장 필요로 하는 사람들인 제품 담당자, 지원 인력, 운영팀(ops)은 Claude Desktop을 설치하고 설정 파일에 서버 URL을 붙여넣는 일을 결코 하지 않을 것입니다. 그들은 Slack과 LINE에서 활동합니다.
진정한 작업은 비기술적인 사람도 바로 대화할 수 있도록 이러한 도구에 채팅 인터페이스(chat face)를 입히는 것이었습니다. 일단 시도해 보면, 세 가지 요소가 매우 빠르게 선택이 아닌 필수가 됩니다.
첫째, **채팅 내부에서 이루어지는 사용자별 인증 (per-user auth)**이 필요합니다. 왜냐하면 OAuth 흐름을 완료하기 위해 누군가를 JSON 설정 파일로 보낼 수는 없으며, 팀 전체가 하나의 공유 서비스 계정으로 활동하게 해서도 안 되기 때문입니다. 둘째, **파괴적인 작업이 실행되기 전의 확인 단계 (confirmation step)**가 필요합니다. 실제 API에 쓰기 권한(write access)을 가진 LLM은 결국 자신 있게 잘못된 행동을 시도할 것이기 때문입니다. 셋째, **각 플랫폼에서 네이티브하게 렌더링되는 응답 (replies that render natively)**이 필요합니다. 한 클라이언트에서는 괜찮아 보이는 Markdown 벽이 다른 클라이언트에서는 깨져 보일 수 있기 때문입니다.
이 세 가지가 모두 작동할 때쯤, 저는 **Conciergent**를 갖게 되었습니다.
이 도구는 모든 Model Context Protocol (MCP) 서버(또는 OpenAPI 명세에 직접)에 연결하여 실제로 무언가를 '수행'할 수 있는 Slack, LINE 또는 Discord 봇으로 변환합니다. 사용자별 OAuth는 대화 내부에서 처리되고, 파괴적인 도구는 승인 카드(approval card) 뒤에서 일시 중지되며, 에이전트는 각 인터페이스가 자체적으로 렌더링할 수 있는 하나의 구조화된 응답을 내보냅니다. YAML 파일을 지정하기만 하면 바로 실행됩니다.
이것이 무엇을 하는가만큼이나 누구를 위한 것인가도 중요합니다. 이것은 자신을 위해 실행하는 개인 비서가 아니라, 각 사용자가 자신으로 로그인하여 사용하는, 사용자를 위해 세워두는 봇입니다.
사용해 보기
uv add "conciergent[gateway]"
uv run conciergent init # 주석이 달린 manifest.yml을 작성합니다
스캐폴딩(scaffolded)된 manifest.yml은 surface와 store가 이미 연결된 전체 설정 파일입니다. 에이전트(agent)를 MCP 서버로 지정하거나 OpenAPI 스펙을 넣고, Slack, LINE 또는 Discord 자격 증명을 환경 변수(env vars)로 설정한 뒤 다음을 실행하세요:
uv run conciergent run
가장 빠른 엔드-투-엔드(end-to-end) 경로는 번들로 제공되는 Docker compose를 사용하는 것입니다. 이는 예시 설정 중 하나를 사용하여 Redis, Postgres 및 앱을 한꺼번에 실행합니다:
cp examples/openapi-chat.yml manifest.yml
docker compose up
Python 3.12+ 버전이 필요합니다. 세 가지 모델 제공자(OpenAI, Google Gemini, Anthropic Claude)가 기본적으로 포함되어 있습니다. agent.model을 provider:model 문자열로 설정하고 해당 제공자의 키를 내보내기(export) 하세요.
Conciergent이 실제로 하는 일
설정에서 확인할 수 있는 세 가지 기능이 있습니다.
1. 모든 MCP 서버 또는 OpenAPI 스펙 직접 사용
가장 유용한 봇은 하나 이상의 요소에 접근합니다. 에이전트를 임의의 MCP 서버 URL로 지정하세요:
# manifest.yml
agent:
model: openai:gpt-4o-mini
...
만약 가지고 있는 것이 MCP 서버가 아닌 REST API라면, 이를 위해 별도의 프로세스를 실행할 필요가 없습니다. gateway extra를 추가하면 Conciergent가 openapi-mcp-gateway를 **프로세스 내부(in-process)**에 내장하므로, 스펙이 즉시 MCP 도구(tools)가 됩니다:
gateway:
enabled: true
specs:
...
각 스펙은 /{name}/mcp에서 서비스되며, agent.mcp_servers에 이미 있는 항목들과 함께 에이전트에 자동으로 연결됩니다. 스펙 항목은 openapi-mcp-gateway의 서버별 설정을 반영하므로, 대규모 API의 경우 exposure: dynamic을 사용하여 (에이전트가 엔드포인트당 하나가 아닌 세 개의 메타 도구를 볼 수 있도록) 설정하거나, 모델로부터 엔드포인트를 격리하기 위한 policy 필터 또는 auth를 사용할 수 있습니다.
2. 인채팅 OAuth (설계를 이끈 제약 사항)
이 부분은 채팅 봇을 노트북에서 실행되는 MCP 클라이언트와 다르게 만드는 핵심 요소입니다. 도구(tool)에 권한 부여(authorization)가 필요할 때, 수정할 설정 파일도 없고 거쳐 가야 할 데스크톱 앱도 없습니다. 사용자는 Slack, LINE 또는 Discord DM(Direct Message) 안에 있으며, 권한 부여는 바로 그 자리에서 이루어져야 합니다.
따라서 Conciergent는 전체 OAuth 핸드오프(handoff)를 대화 내부에서 실행합니다. 도구가 처음으로 토큰(token)을 필요로 할 때, 봇은 채팅창에 권한 부여 링크를 게시합니다. 사용자가 이를 탭하여 승인하면 다시 동일한 DM으로 돌아옵니다. Conciergent는 토큰을 저장하고, 그 이후부터는 사용자별로 토큰을 갱신(refresh)합니다. 아무도 대화를 떠나지 않으며, 팀 전체가 하나의 자격 증명(credential)을 공유하지도 않습니다.
동일한 핸드오프 방식이 임베디드 게이트웨이(embedded gateway) 뒤의 oauth2 사양을 지원하므로, 각 사용자는 도구가 실행되기 전에 자신의 업스트림(upstream) 계정을 직접 승인합니다. 또한 이 흐름은 시간 제한(time-bounded)이 있어, 인증이 지연되더라도 요청이 멈춰 있는 대신 깔끔하게 만료됩니다.
토큰은 Postgres에 영구 저장되므로, 재배포(redeploy)를 하더라도 모든 사용자의 로그아웃이 발생하지 않습니다. 채팅 기록은 Redis에만 존재하며, 다른 일시적인 상태(승인, 대기 중인 핸드오프 등)와 함께 자체적으로 만료되기 전까지 컨텍스트(context) 유지를 위해 필요한 만큼만 유지됩니다. 사용자가 말한 내용은 해당 기간이 지나면 보관되지 않습니다.
3. 승인 게이트(Approval Gate), 그리고 어디서나 렌더링되는 하나의 응답
두 가지 문제, 하나의 설계.
Human-in-the-loop (인간 참여형). MCP 서버가 파괴적(destructive)이라고 표시한 모든 도구는 실행되기 전 '확인 / 취소(Confirm / Cancel)' 카드 뒤에서 일시 중지됩니다. 모델이 동작을 제안하면, 인간이 이를 확정(commit)합니다. 대기 중인 승인에는 자체적인 TTL(Time-To-Live)이 있어, 무시된 카드가 쓰기 작업을 열어둔 채 영원히 남아 있지 않습니다.
Surface-agnostic replies (플랫폼 무관 응답). 에이전트는 Slack, LINE 또는 Discord의 언어로 직접 말하지 않습니다. 대신 세 가지 형태 중 하나를 방출(emit)하며, 각 플랫폼(surface)은 이를 네이티브하게 렌더링합니다:
str: 일반 텍스트용.Card: 헤더, 텍스트 섹션, 선택적 히어로 이미지(hero image), 각주, 링크 버튼, 그리고 제안용 퀵 리플라이(quick-replies)를 위한 용도.Carousel: 사용자가 선택할 수 있는 소수의 옵션 카드 세트를 위한 용도.
제안(suggestion)은 상호작용을 위한 기본 단위(primitive)입니다. 제안을 탭하면 사용자가 직접 입력한 것처럼 해당 프롬프트가 에이전트(agent)에게 다시 전송됩니다. 이러한 모델의 필드 설명(field descriptions)이 곧 에이전트의 구조화된 출력 스키마(structured-output schema)이므로, 모델이 이를 직접 채우게 되며 동일한 응답 객체(reply object)가 Slack, LINE, Discord에서 올바르게 렌더링됩니다.
UI 텍스트(버튼, 프롬프트, 인사말) 또한 하드코딩되지 않습니다. 이는 로케일 카탈로그(locale catalog)에 저장되어 각 사용자의 플랫폼 언어에 맞춰 선택되므로, 봇은 메시지마다 별도의 번역 호출을 하지 않고도 사용자의 언어로 답변할 수 있습니다.
비교 분석
이 분야를 구분 짓는 질문은 어떤 에이전트가 더 많은 기능을 가졌느냐가 아니라, 이 봇이 누구를 위한 것이냐 하는 점입니다. Conciergent는 사용자가 이미 사용 중인 Slack, LINE 또는 Discord에서 자신의 사용자들에게 봇을 제공하고자 하는 서비스 제공자(service provider)를 위해 구축되었습니다. 이와 비교되는 대부분의 프로젝트는 타인을 위해 구축되었으므로 서로 다른 트레이드오프(trade-offs)를 가집니다. 가장 자주 언급되는 두 그룹은 다음과 같습니다:
- 개인용 비서(Personal assistants): Hermes Agent 및 OpenClaw와 같은 사례입니다. 자신을 위해 봇을 실행하고 어떤 채팅 앱에서든 접속할 수 있습니다. 이들은 Conciergent보다 훨씬 더 많은 기능(음성, 메모리, 자기 개선 기술, 수십 개의 채널 등)을 제공하지만, 각 설치본은 단일 자격 증명(credentials)을 가진 단일 소유자만을 위해 작동하므로 별도의 최종 사용자(end-users)라는 개념이 없습니다.
- 셀프 호스팅 AI 플랫폼(Self-hosted AI platforms): Dify, Open WebUI, LibreChat과 같은 사례입니다. 이들은 멀티 테넌트 배포(multi-tenant deployments), 사용자별 OAuth, 네이티브 MCP, 그리고 많은 유지보수 필요성 측면에서 가장 많이 겹칩니다. 하지만 사용자는 플랫폼 자체의 웹 앱을 통해 이들에 접속합니다. Slack이나 Discord로 확장하려면 웹 앱의 채팅을 DM으로 전달하는 릴레이(relay)가 필요하며, 이는 텍스트 중심적이고 네이티브 카드(native cards)나 대화 중 사용자별 OAuth를 지원하지 않습니다.
| Conciergent | 개인 비서 (Personal assistants) | 셀프 호스팅 AI 플랫폼 (Self-hosted AI platforms) | |
|---|---|---|---|
| 대상 (Built for) | 사용자 (Your users) | 오직 당신 (Just you) | 사용자 (Your users) |
| ... |
이러한 인터페이스(surfaces)에 도달하는 비서들은 단일 소유자를 위해 실행되거나, 멀티 테넌트(multi-tenant) 플랫폼은 웹 앱에 머물러 있습니다. 두 방식 모두 채팅 자체 내에서 네이티브 응답(native replies) 기능을 갖춘 사용자별 봇(per-user bot)을 제공하지는 않습니다.
Conciergent는 특히 다음 세 가지 상황에 적합합니다:
- 비기술직 팀원을 위한 내부 도구 (Internal tools). 지원(Support), 운영(Ops), 재무(Finance) 팀 등이 해당됩니다. 이들은 MCP 설정을 절대 열어보지 않겠지만, 봇에게 DM(Direct Message)은 보낼 것입니다. Conciergent를 내부 MCP 서버(또는 명세/spec)로 연결하기만 하면 이들이 바로 대화할 수 있습니다.
- 실제 사용자의 명의로 동작해야 하는 모든 경우. 요청 승인, 레코드 이동, 누군가를 대신하여 티켓 종료 등 상위 감사 로그(upstream audit log)에 실제 사람이 나타나야 하는 경우입니다. 채팅 내 사용자별 OAuth(in-chat per-user OAuth)가 이 과정을 엔드 투 엔드(end to end)로 처리합니다.
- 챗봇으로 빠르게 데모하고 싶은 REST API. 게이트웨이를 활성화하고 명세(spec)를 넣기만 하면, 별도의 서버를 실행할 필요 없이 Slack, LINE 또는 Discord 봇을 바로 사용할 수 있습니다.
무엇이 있고, 무엇이 아직 없는가
위의 모든 기능은 현재 바로 사용할 수 있습니다.
여기서부터 주요 작업 방향은 더 많은 인터페이스(surfaces)를 확보하는 것입니다. 각 인터페이스는 인터페이스 계약(surface contract) 뒤에서 단일 클래스로 동작하며, 런타임(runtime)과 에이전트(agent)는 변경되지 않으므로 재작성 없이 목록을 계속 확장할 수 있습니다. 다음 타겟은 Telegram과 Teams입니다. 만약 귀하의 플랫폼이나 사용 사례가 아직 지원되지 않는다면, 문제의 형태를 담아 이슈(issue)를 생성해 주세요. 저의 추측보다는 구체적인 사용 사례가 설계를 더 강력하게 이끌어냅니다.
마치며
Conciergent는 openapi-mcp-gateway의 동반자입니다. 게이트웨이가 REST API를 MCP 도구로 변환하면, Conciergent는 해당 도구에 채팅 인터페이스(chat face)를 부여합니다. 이 둘을 함께 사용하면 하나 이상의 OpenAPI 명세(spec)를 사용자가 대화할 수 있는 봇으로 완전히 구현할 수 있습니다. 게이트웨이와 마찬가지로, 이 프로젝트는 개인적인 오픈 소스 사이드 프로젝트입니다. 위의 상황들이 귀하의 상황과 비슷할 경우를 대비해 이곳에 공유합니다.
- Repository: github.com/mroops0111/conciergent
- Companion Project: github.com/mroops0111/openapi-mcp-gateway
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기