sbjang
← 목록으로

Uber Blog

Uber MCP Gateway: 기존 API를 고치지 않고 MCP 도구로 쓴다

Uber 블로그에 2026년 10월 1일 실린 “Designing MCP Gateway: Uber’s MCP Management Platform”을 정리했다. Uber는 AI 에이전트를 빠르게 도입하면서, 처음에는 팀마다 MCP(Model Context Protocol) 연동을 따로 만들었다. 에이전트가 실시간 비즈니스 맥락을 읽고 사내 서비스를 조회하고 사용자 대신 작업을 하게 되자 효과는 분명했다. 하지만 수백 개 팀이 에이전트 워크플로를 시도하면서 문제가 드러났다. 팀마다 도구가 갈라지고 같은 인프라가 여러 번 만들어졌으며, 도구는 찾기 어렵고 안정적으로 운영하기 힘들었고, 특정 서비스나 에이전트 구현에 강하게 묶여 있었다.

그래서 Uber는 사내의 모든 MCP 상호작용을 맡는 마이크로서비스인 MCP Gateway를 만들었다. 게이트웨이는 AI 에이전트와 기존 백엔드 서비스, 네이티브 MCP 서버 사이에서 호출을 조율하고 라우팅한다. HTTP, gRPC, TChannel 같은 프로토콜 차이를 감추고, 보안과 관측성을 모든 호출에 같은 방식으로 적용한다. 글을 쓴 시점에 게이트웨이가 호스팅하는 MCP 서버는 800개가 넘고, 도구는 5,000개가 넘는다. 글쓴이는 Principal Engineer Alok Srivastava를 비롯한 8명이다. GeekNews에 GN⁺ 글로 올라온 것을 보고 원문을 읽었다.

게이트웨이는 두 부분으로 나뉜다

MCP Gateway는 마이크로서비스 구조를 따르며, AI 기반 시스템과 Uber 백엔드 서비스를 잇는 중앙 통합 지점 역할을 한다. 플랫폼은 두 구성 요소로 이루어진다.

구성 요소 역할 하는 일
MCP Registry 컨트롤 플레인 사내 서비스를 바탕으로 한 MCP 서버 수백 개와 도구 수천 개의 카탈로그를 관리하고, 발견·소유권·활성화의 단일 기준이 된다
Proxy Gateway 데이터 플레인 실행 시점에 MCP 호출을 HTTP·gRPC·TChannel 요청으로 바꿔 백엔드 서비스에 보내고, 응답을 MCP 결과로 되돌린다

레지스트리에 담긴 도구는 두 종류다. 하나는 기존 API를 그대로 MCP 도구로 노출하는 노코드 정의이고, 다른 하나는 MCP 스펙에 맞춰 처음부터 구현한 네이티브 서버의 도구다. 어느 쪽이든 에이전트는 같은 MCP 인터페이스로 호출하고, 하위 서비스는 아무것도 바꾸지 않아도 된다. 원문의 Figure 1은 이 구조를, 네 종류의 호출자가 게이트웨이를 거쳐 서로 다른 프로토콜을 쓰는 네 종류의 하위 서비스로 라우팅되는 그림으로 보여 준다. 그림 제목은 “APIs as tools”다.

AutoCrawler가 API를 찾아 도구로 바꾼다

Uber에는 HTTP, gRPC, TChannel로 API를 내놓는 사내 서비스가 수천 개 있다. 이 API들은 AI 시스템에 유용한 맥락이지만, 팀마다 MCP 서버를 손으로 작성하게 하면 느리고 번거롭다. 그래서 만든 발견 엔진이 AutoCrawler다. AutoCrawler는 Cadence 기반의 분산 워크플로 시스템이고, Uber의 IDL 레지스트리와 사내 서비스 신호를 구독한다. 정해진 주기마다 cron 작업이 Cadence 워크플로를 실행해, 새로 추가된 서비스와 API, 스키마 변경을 찾는다.

찾은 대상마다 AutoCrawler가 하는 일은 세 가지다. MCP 서버 표현을 만들거나 갱신하고, 도구 정의와 스키마를 생성하거나 가져오고, 그 도구를 비활성 상태로 레지스트리에 등록한다. 원문은 이 공통 기반 덕분에 서비스 팀의 작업을 기다리지 않고도 발견 범위를 수천 개 서비스로 넓힐 수 있다고 설명한다. 원문의 Figure 2는 발견 원천, 소유자 검토, 저장소, 게이트웨이 처리를 한 흐름도에 묶어 도구와 스키마를 관리하는 과정을 보여 준다. 원문은 이어서 IDL 기반 서비스와 네이티브 서버의 발견 경로를 따로 설명하고, 서드파티 서버를 붙이는 방법을 덧붙인다.

Protobuf나 Thrift IDL로 정의한 기존 백엔드 서비스는 IDL 레지스트리에서 바로 MCP 서버와 도구를 만든다. service:API 그룹마다 다음 다섯 단계를 거친다.

  1. MCP 서버 upsert: 발견한 서비스에 대응하는 가상 MCP 서버를 만들거나 갱신한다
  2. IDL 파싱: Protobuf나 Thrift 파일에서 메서드 이름, 요청·응답 스키마, 문서 주석을 뽑는다
  3. 도구 설명 생성: 뽑아낸 스키마와 주석을 바탕으로 LLM이 에이전트가 읽기 좋은 도구 설명을 쓴다
  4. 스키마 변환: Protobuf나 Thrift 스키마를 MCP와 호환되는 JSON-RPC 2.0 스키마로 바꾼다
  5. 도구 upsert: 만든 도구를 비활성 상태로 레지스트리에 등록하거나 갱신한다

네이티브 서버는 다른 경로로 찾는다. Uber는 네이티브 MCP 서버를 MCPFx라는 프레임워크로 만들고, 각 서버는 자신이 실행 중이고 요청을 받을 준비가 되었음을 알리는 하트비트 지표를 내보낸다. AutoCrawler는 이 하트비트를 계속 지켜보다가 새 서버를 찾으면 listTools를 호출해, 그 서버가 노출하는 도구와 스키마를 받아 온다. 그리고 그 도구를 모두 담은 가상 프록시 MCP 서버를 레지스트리에 비활성 상태로 만든다.

Jira나 Google 같은 서드파티(3P) MCP 서버도 게이트웨이를 거친다. 여기서는 두 구성 요소가 역할을 나눈다.

  • MCP Gateway: 호출한 사용자의 토큰을 하위로 넘기면서, 인가와 속도 제한, 민감 데이터 가림 같은 게이트웨이 기능을 그대로 적용한다
  • 3P MCP 서비스: 외부 MCP 서버로 요청을 보내기 전에, 사내 사용자 토큰을 그에 대응하는 서드파티 인증 토큰으로 교환한다

발견했다고 바로 공개하지는 않는다

AutoCrawler는 서비스 팀을 거치지 않고 MCP 서버를 만들지만, 그 서버의 소유권과 통제권은 서비스 팀에 있어야 한다. 그래서 MCP Gateway의 핵심 설계 원칙은 “발견했다고 노출하는 것은 아니다(discovery doesn’t imply exposure)“로 정해졌다. 모든 MCP 서버와 도구는 비활성 상태로 시작하고, 소유 팀이 명시적으로 검토하고 켜야 공개된다. 서비스 소유자는 켜기 전에 자동으로 만들어진 도구 정의를 검토하고 다듬을 수 있다.

켠 뒤의 변경도 같은 절차를 거친다. 도구 설명을 바꿀 때마다 설정 변경 diff가 생기고, 서버 소유자가 승인해야 반영된다. 소유자는 승인한 변경을 배포하고, 필요하면 이전에 확인된 버전으로 롤백한다.

원문은 관리 화면도 두 장 보여 준다. Figure 3의 MCP Registry 화면은 검증된 MCP 서버 목록을 도구, 에이전트, 서비스 티어 같은 정보와 함께 나열한다. Figure 4의 도구 화면에서는 logging-mcp 서버의 도구를 고르고, 로그 조회 설정 스키마를 JSON 편집기로 고친다.

데이터 플레인은 설정을 읽어 가상 서버를 띄운다

데이터 플레인은 MCP 요청을 실제로 실행하는 런타임 서비스다. 컨트롤 플레인에서 서버와 도구 설정을 계속 받아 정해진 주기로 메모리 상태를 갱신하므로, 도구 수정이나 활성화 변경이 서비스를 재시작하거나 다시 배포하지 않아도 곧바로 반영된다. 데이터 플레인은 이 설정을 바탕으로 가상 MCP 서버를 동적으로 만들고, 가상 서버마다 /<service-name>/mcp 엔드포인트 하나를 연다. 에이전트의 요청은 이 엔드포인트로 들어와, 내장 프록시 서버를 거쳐 해당 서버 핸들러로 연결된다. 원문의 Figure 5는 이 흐름을 호출자에서 게이트웨이, 미들웨어, 도구 런타임을 거쳐 하위 서비스에 닿는 6계층 구조도로 그렸다.

프로토콜 변환은 Proxy Gateway 안의 서버 핸들러가 맡는다. 핸들러는 자신이 어떤 도구를 다루는지, 요청을 어느 하위 서비스로 보내야 하는지 알고 있어서 실행 시점에 요청을 올바르게 라우팅한다. 기존 백엔드 서비스를 바탕으로 한 도구라면, 핸들러는 HTTP 엔드포인트 설정이나 gRPC·TChannel 프로시저 같은 하위 목적지 정보를 메모리에 매핑해 두고 요청을 네 단계로 처리한다.

  1. 페이로드 변환: 들어온 JSON 페이로드를 알맞은 와이어 포맷으로 바꾼다
  2. 직렬화: 요청을 Protobuf나 Thrift 바이트로 직렬화한다
  3. 전달: 요청을 하위 서비스로 보낸다
  4. 응답 역변환: Protobuf나 Thrift 바이트 응답을 MCP 호환 JSON으로 바꿔 호출한 에이전트에게 돌려준다

실제 하위 요청은 모든 백엔드 서비스 옆에서 함께 실행되는 Uber의 서비스 메시 사이드카 Muttley가 수행한다. 요청 실행을 Muttley에 맡기기 때문에, 게이트웨이는 서비스 간 라우팅 기능을 따로 만들지 않고 기존 기능을 그대로 쓴다.

네이티브 MCP 서버도 레지스트리에 가상 서버로 등록되지만, 이 가상 서버는 원래 서버의 프록시 역할만 한다. 실행 시점에 요청은 그대로 하위 서버로 전달되고, 응답도 그대로 호출자에게 돌아온다.

보안: 도구 단위 권한과 응답 가림

게이트웨이는 모든 서버에 인가와 가림 처리를 도구 단위로 기본 제공한다. 인가에는 Uber의 사내 Access Control System을 쓴다. 게이트웨이는 호출 주체가 사람인지, 서비스인지, 에이전트인지 판별하고, 각 주체에 설정된 charter 정책을 다르게 적용한다. charter 정책은 서버 단위로 만들고, 필요하면 도구 단위로 덮어쓴다.

이와 별도로 게이트웨이는 도구 응답에 들어 있는 PII와 민감 데이터를 기본으로 가린다. 앞에서 본 것처럼 서드파티 서버로 가는 요청에도 게이트웨이가 인가, 속도 제한, 민감 데이터 가림을 적용한다.

서버가 수백 개가 되자 생긴 문제

게이트웨이가 서버 수백 개와 도구 수천 개로 커지자, 작은 규모에서는 없던 문제가 드러났다. 원문은 이를 컨텍스트가 지나치게 커지는 문제와 과도한 비용으로 요약한다. 출발점은 MCP에 서버를 가로지르는 검색 개념이 없다는 점이다. 에이전트는 어느 서버에 물어볼지 미리 알아야 그 서버의 도구 목록을 물어볼 수 있다. 그리고 에이전트가 MCP 서버를 쓰게 하려면 서버 URL, 자격 증명, 도구 목록을 일일이 연결해 두어야 한다. 서버 수백 개를 이렇게 연결하면 그 정보만으로 모델의 컨텍스트 한도가 찬다. Uber는 이 문제를 세 가지 방법으로 풀었다.

Omni MCP는 MCP 클라이언트가 게이트웨이의 모든 서버에 접근할 수 있게 하는 프록시 서버 하나다. 클라이언트는 서버를 하나씩 연결하는 대신 Omni MCP 하나만 연결하고, 필요한 정보를 단계적으로 찾아 들어간다. Omni MCP가 노출하는 도구는 네 개다.

도구 하는 일
discover_server 질의 의도에 맞는 MCP 서버를 찾는다
discover_tools 한 서버의 도구 목록을 조회한다
get_tool_schema 도구 하나의 JSON 스키마를 가져온다
invoke_tool 도구를 호출한다

필요한 만큼만 단계적으로 찾으므로 컨텍스트와 토큰을 아낄 수 있고, 접근 제어를 비롯한 게이트웨이 기능도 그대로 적용된다.

Response Projection은 MCP 도구를 GraphQL처럼 호출하는 방식이다. 게이트웨이가 도구 요청 스키마에 필드 하나를 새로 넣어 두면, LLM은 그 필드에 실제로 필요한 응답 필드의 중첩 경로를 배열로 채운다. 게이트웨이는 실행 시점에 응답에서 그 경로에 해당하는 필드만 남기고 나머지를 잘라 낸다. 원문은 이 방식 덕분에 MCP의 API 스키마 호환성을 기업 규모로 넓힐 수 있었다고 적었지만, 추가하는 필드의 이름이나 실제 요청 예시는 싣지 않았다.

Code Mode는 셸 환경에서 일하는 코딩 에이전트를 위한 방식이다. 이런 에이전트에게는 도구 출력을 모델 컨텍스트에 전부 싣는 것보다 파일로 바로 쓰는 쪽이 효율적이다. Code Mode는 Uber가 에이전트 작업용으로 만든 CLI인 aifx로 제공되며, MCP 서버를 따로 설치하지 않아도 MCP 호출을 게이트웨이로 보낸다. MCP 정의를 컨텍스트에 올려 두지 않고도 에이전트가 작업에 맞는 도구를 찾게 하는 것이 목적이다. aifx가 제공하는 명령은 세 가지다.

aifx mcp list    # 사용할 수 있는 MCP 서버 목록
aifx mcp search  # 모든 MCP 서버에서 도구 검색
aifx mcp call    # MCP Gateway를 거쳐 MCP 도구 호출

에이전트는 이 명령들을 한 번의 명령으로 이어 실행하고 출력을 파일로 쓴 다음, 필요한 부분만 grep으로 골라 컨텍스트에 올린다. 원문에 따르면 Code Mode는 지금 Uber에서 코딩 에이전트가 MCP 도구를 쓰는 사내 기본 방식이다. 원문의 마지막 흐름도는 MCP 클라이언트와 코딩 에이전트가 Omni MCP와 MCP Gateway를 거쳐 도구에 접근하는 과정을, 도구 발견 단계와 함께 보여 준다.

읽고 남는 것

원문은 게이트웨이의 이점으로 쉬운 발견과 설치, 기존 API의 노코드 노출, 내장된 관측성과 보안, 중앙의 소유권과 거버넌스 네 가지를 꼽는다. 결론에서는 수십 개 팀이 제각각 연동을 만들던 파편화 문제가, 지금은 어느 팀이든 몇 분 만에 연결할 수 있는 통합 플랫폼이 되었다고 정리한다. 설계를 이끈 판단은 “기존 API가 에이전트에게 도구를 주는 가장 빠른 길”이라는 것이었다. 팀에게 에이전트 환경에 맞춰 서비스를 다시 쓰라고 요구하는 대신, 게이트웨이가 HTTP·gRPC·TChannel 호출을 Muttley를 거쳐 MCP 상호작용으로 바꾸고 하위 서비스는 하나도 고치지 않는다. 그리고 에이전트 시스템을 대규모로 만든다면 가장 어려운 부분은 AI가 아니라고 말한다. 실제 운영 환경에서 에이전트가 사용자를 대신해 움직여도 될 만큼 믿을 수 있게 하는 발견·보안·신뢰성의 연결 기반이 더 어렵다는 것이다.

이 글에서 가장 눈에 띄는 것은 자동화와 통제를 나눈 방식이다. AutoCrawler는 서비스 팀을 기다리지 않고 수천 개 서비스의 API를 도구로 만들고, 도구 설명까지 LLM이 쓴다. 대신 그렇게 만든 도구는 모두 꺼진 상태로 등록되고, 소유 팀이 검토하고 켜야 공개되며, 이후 설명을 바꿀 때도 diff 승인을 거친다. LLM이 쓴 설명이 검토 없이 에이전트에게 노출되지 않도록 사람의 승인을 기본값에 넣어 둔 셈이다.

두 번째는 MCP 스펙이 제공하지 않는 서버 간 검색을 게이트웨이 쪽에서 채웠다는 점이다. Omni MCP는 서버 수백 개 대신 도구 네 개만 컨텍스트에 올리게 하고, Code Mode는 도구 출력도 컨텍스트가 아닌 파일에 쓰게 한다. 특히 사내 코딩 에이전트의 기본값이 MCP 서버를 직접 연결하는 방식이 아니라 CLI로 게이트웨이를 부르는 방식이라는 점이 흥미롭다. 도구가 많아질수록 MCP 서버를 연결하는 일보다 무엇을 컨텍스트에 올릴지 고르는 일이 더 중요해진다는 뜻으로 읽힌다. 다만 원문에는 지연 시간이나 토큰 절감량 같은 수치가 없고, 이점으로 꼽은 관측성도 어떻게 구현했는지 설명하지 않아서, 이 설계로 비용이 얼마나 줄었는지는 글만으로 판단하기 어렵다.


원문: Designing MCP Gateway: Uber’s MCP Management Platform (Uber Blog, 2026-10-01. 글쓴이는 Alok Srivastava, Deepanshu Mehndiratta, Gaurav Gill, Prashik Sahare, Vaibhav Tayal, Shiven Tripathi, Uday Kiran Medisetty, Abhishek Bhatia 8명이다. GeekNews 글은 GN⁺ 등록 글이고, 2026-10-13에 확인했을 때 댓글은 없었다. 원문의 그림은 라이선스 표기가 없어 싣지 않고 본문에서 말로 설명했다)