
MCPX 실전 — 여러 개의 MCP 서버를 하나의 게이트웨이로 묶어 셀프 호스팅하기
요약
여러 개의 MCP 서버를 관리할 때 발생하는 설정 중복 문제를 해결하기 위해 MCPX 게이트웨이를 Docker로 셀프 호스팅하는 방법을 다룹니다. MCPX를 통해 에이전트와 서버 간의 연결 구조를 M×N에서 M+1+N으로 단순화하고, 도구 단위의 액세스 제어를 구현할 수 있습니다.
핵심 포인트
- MCPX를 사용하여 여러 MCP 서버를 하나의 엔드포인트로 통합 가능
- 에이전트와 서버 간의 연결 복잡도를 M×N에서 M+1+N으로 획기적으로 감소
- 도구(tool) 단위의 액세스 제어 및 사용자별 권한 관리 기능 제공
- Docker를 이용한 간편한 셀프 호스팅 및 관리 UI 지원
MCP (Model Context Protocol) 서버를 사용하기 시작하면 곧 어떤 문제에 부딪히게 됩니다. 서버가 늘어날수록 클라이언트 측의 설정이 눈덩이처럼 불어난다는 점입니다.
GitHub용, Slack용, 사내 DB용, 메모리용…… 이렇게 서버를 추가하다 보면 Claude Code, Claude Desktop, Cursor 각각의 설정 파일에 동일한 서버 정의를 반복해서 작성하게 됩니다. 에이전트(M개)와 서버(N개)의 조합은 M×N으로 불어나며, 인증 정보도 곳곳에 흩어지게 됩니다.
이 기사에서는 그 M×N 문제를 M+1+N으로 간략화하는 OSS인 MCP 게이트웨이 MCPX (Lunar.dev 제작 · MIT 라이선스)를 Docker로 셀프 호스팅하여 Claude Code에서 사용하는 방법까지 핸즈온으로 해설합니다.
대상 독자: 여러 개의 MCP 서버를 운용하고 있으며, 설정 중복이나 액세스 제어에 어려움을 겪고 있는 엔지니어
목표: 로컬에 MCPX를 구축하여, 여러 상류(upstream) MCP 서버를 하나의 엔드포인트로 집약하고, tool 단위의 액세스 제어를 설정할 수 있는 상태를 만드는 것
전제 조건: Docker가 동작하는 환경 (Docker Desktop도 가능)
본 기사의 커맨드 및 설정은 공식 문서와 GitHub 리포지토리 (
TheLunarCompany/lunar
)의 기재 내용을 바탕으로 합니다. MCPX는 활발하게 업데이트되고 있으므로, 버전이나 엔드포인트 경로는 공식 Docs와 Control Plane UI의 표시를 최종적인 정답으로 간주해 주십시오.
- MCPX는 여러 상류 MCP 서버를 집약하는 MCP 서버 (Aggregator)입니다. 에이전트는 단 1개의 연결만 가지면 됩니다.
docker run한 번으로 기동됩니다. 포트는 **9000(본체) / 5173(관리 UI) / 3000(메트릭스)**입니다.- 설정은 2개의 파일로 구성됩니다.
app.yaml로 상류 서버를 정의하고,mcp.json으로 인증·권한·tool 그룹을 정의합니다. permissions.base: "block"을 기점으로, consumer(이용자)별로 사용할 수 있는 tool을 제한하는 거버넌스가 표준으로 탑재되어 있습니다.- Claude Code / Claude Desktop / Cursor 등 MCP 호환 클라이언트로부터 하나의 URL로 모든 tool에 액세스할 수 있습니다.
MCP 서버를 클라이언트에 직접 연결하는 구성에서는 에이전트의 수 M과 서버의 수 N의 곱만큼 연결·설정·인증 정보가 필요하게 됩니다.
게이트웨이를 하나 사이에 두면, 각 에이전트는 게이트웨이로의 1개 연결만 가지며, 게이트웨이가 상류의 N개 서버를 묶어줍니다. 연결의 총수는 M + 1 + N (에이전트 M개 + 게이트웨이 + 서버 N개)으로 수렴하여, 조합 폭발이 사라집니다.
| 관점 | 직접 연결 (M×N) | 게이트웨이 경유 (M+1+N) |
|---|---|---|
| 클라이언트 설정 | 서버마다 각 클라이언트에 기술 | 게이트웨이 1건만 기술 |
| ... |
MCPX는 이 게이트웨이 계층을 OSS로 제공하며, tool 단위의 액세스 제어 · 이용자 식별 · 감사 로그 · 인증 정보의 격리를 표준으로 갖추고 있습니다.
먼저 설정 파일을 둘 디렉토리를 만듭니다. MCPX는 이 디렉토리에서 app.yaml과 mcp.json을 찾으러 갑니다.
mkdir mcpx-config
cd mcpx-config
Docker가 동작하고 있는지 확인합니다.
docker version
공식 Quick Start 커맨드로 MCPX를 기동합니다. MCPX는 상류 서버를 Docker로 기동하기 때문에 --privileged (Docker-in-Docker)가 필요합니다.
docker run --rm --pull always --privileged \
-v ./:/lunar/packages/mcpx-server/config \
-p 9000:9000 -p 5173:5173 -p 3000:3000 \
...
공개되는 포트의 역할은 다음과 같습니다.
공개되는 포트의 역할은 다음과 같습니다.
| 포트 | 역할 |
|---|---|
| 9000 | 본체 (MCP 엔드포인트) |
| ... | |
설정 후 브라우저에서 http://localhost:5173/를 엽니다. 이곳이 상위 서버의 추가나 클라이언트 연결 스니펫을 확인할 수 있는 관리 화면입니다. |
--privileged는 강력한 권한을 부여하는 플래그입니다. 실제 운영 환경에서는 Kubernetes용 구성(공식 Docs에 전용 가이드 있음)이나, 신뢰할 수 있는 네트워크 내부에서의 운용을 검토해 주세요. 개인 테스트에서는 문제가 없지만, 무조건 프로덕션 환경으로 가져가지는 않도록 주의해야 합니다.
MCPX가 묶는 상위 서버들은 mcp.json에 작성합니다. 시작 시 이 파일을 읽어 각 서버를 MCPX 프로세스 내에서 구동합니다.
mcpx-config/mcp.json을 생성하고, 예시로 memory(영구 메모리)와 time(시간) 두 가지를 등록합니다.
{
"mcpServers": {
"memory": {
...
각 서버의 필드는 다음과 같습니다.
| 필드 | 필수 | 설명 |
|---|---|---|
command | ◯ | 서버를 구동하는 실행 파일 (npx / uvx 등) |
args | ◯ | 커맨드 인수의 배열 |
env | — | 해당 서버 프로세스에 전달할 환경 변수 |
icon | — | 관리 UI에서 식별하기 위한 이모지 라벨 |
참고로, 서버의 식별명은 mcpServers의 키 이름(위 예시에서는 `
설정 후에는 클라이언트를 재시작합니다. 이렇게 하면 Claude Code에서는 mcpx라는 단 하나의 서버만 보이게 되며, 그 이면에는 memory · time · (추가한 만큼의) GitHub · Slack……과 같은 상위 tool들이 모두 연결됩니다.
연결용 엔드포인트(Endpoint)의 정확한 경로는 MCPX의 버전에 따라 달라질 수 있습니다.
http://localhost:5173/ 의 Control Plane UI에 표시되는 연결 스니펫(Snippet)을 복사하는 것이 가장 확실합니다. Claude Desktop · Cursor · VSCode · n8n · CrewAI · LangChain 등 다른 MCP 호환 클라이언트에서도 동일한 방식으로 1개의 연결로 집약할 수 있습니다.
실제로 구축할 때 빠지기 쉬운 주의 사항을 정리해 둡니다.
| 증상 | 원인 | 회피책 |
|---|---|---|
| 상위 서버가 실행되지 않음 | --privileged 옵션 누락 (Docker-in-Docker 불가) | docker run 시 반드시 --privileged를 추가 |
| 모든 tool이 차단됨 | permissions.base: "block" 상태에서 허용 설정을 하지 않음 | consumer에 allow 또는 profiles.allow를 설정하고, tool을 tool 그룹에 등록 |
| 클라이언트에서 연결되지 않음 | 엔드포인트 경로 오류 또는 재시작 누락 | Control Plane UI의 연결 스니펫을 사용하고, 설정 후 클라이언트를 재시작 |
| 설정 파일이 읽히지 않음 | -v 마운트 경로가 잘못됨 | mcp.json / app.yaml을 config 디렉토리 직하에 두고 마운트 상태를 확인 |
MCPX를 사용하면 어지럽게 널려 있는 MCP 서버군을 하나의 게이트웨이 뒤로 숨겨, 클라이언트 설정의 중복 · 인증 정보의 분산 · 액세스 제어(Access Control)의 부재라는 세 가지 고통을 한꺼번에 해결할 수 있습니다.
mcp.json으로 상위 서버를 집약하여, 에이전트는 단 하나의 연결만 가짐 (M+1+N)app.yaml의base: "block"+toolGroups를 통해 업무 단위의 권한을 게이트웨이에 집중- OSS (MIT)이므로 셀프 호스팅이 가능하며, 인증 정보를 클라이언트 외부에 격리할 수 있음
MCP 서버가 3개를 넘어가는 시점부터 게이트웨이 도입의 비용 대비 효과는 급격히 상승합니다. 우선은 memory + time 두 가지를 묶는 것부터 직접 시도해 보세요.
- MCPX (GitHub · TheLunarCompany/lunar): https://github.com/TheLunarCompany/lunar
- MCPX README: https://github.com/TheLunarCompany/lunar/blob/main/mcpx/README.md
- 공식 Docs (Quick Start): https://docs.lunar.dev/mcpx/get_started/
- mcp.json 사양: https://docs.lunar.dev/mcpx/mcp.json/
- 액세스 제어 설계 (공식 블로그): https://www.lunar.dev/post/mcp-gateway-access-controls-defining-permissions-for-llm-agents
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기