MCP 서버 실전 운영 (2편) - 원격 연결과 Git 동기화의 경계

목차
1편에서는 블로그 검색을 AI 도구로 연결했습니다. 이 글은 연결 위치를 넓힐 때 무엇이 달라지는지 다룹니다. 이전 글은 FastAPI의 REST 엔드포인트를 원격 MCP 서버와 동일하게 설명하고 모든 인스턴스가 웹훅 직후 동기화된다고 표현했습니다. 둘 다 보장되지 않으므로 정정합니다.
로컬 stdio와 원격 MCP, 일반 REST
공개 저장소의 서버 코드에는 MCP SDK의 stdio_server로 실행하는 server.py와 FastAPI의 rest_api.py가 별도로 있습니다. 공통 검색 함수를 공유하더라도 연결 계약은 다릅니다.
| 구성 | 연결 | 확인할 것 |
|---|---|---|
| 로컬 MCP | 클라이언트가 프로세스를 실행하고 표준 입출력으로 통신 | 클라이언트가 해당 stdio 설정을 지원하는가 |
| REST API | HTTP 경로와 요청·응답을 별도로 정의 | API 인증·스키마·오류 처리가 맞는가 |
| 원격 MCP | MCP SDK가 제공하는 HTTP transport를 통해 프로토콜 메시지 교환 | 초기화·도구 목록·도구 호출과 클라이언트 호환성 |
stdio는 Claude Desktop 전용이 아닙니다. 해당 방식을 지원하는 다른 클라이언트에서도 설정할 수 있습니다. 반대로 REST API를 Cloud Run에 배포했다고 MCP 프로토콜과 자동으로 호환되는 것은 아닙니다. 원격 MCP가 필요하면 지원되는 Streamable HTTP transport와 클라이언트 버전·인증을 명시하고 실제 MCP 초기화와 도구 호출을 확인해야 합니다. MCP transport 명세를 기준으로 확인하세요.
Private Git 자료를 최신 상태로 읽기
GitHub push 웹훅을 받은 REST 서버가 작업 사본을 갱신하는 방식은 구현할 수 있습니다. 하지만 한 인스턴스의 git pull은 다른 인스턴스의 파일이나 메모리 캐시를 바꾸지 않습니다. Cloud Run에서 새 인스턴스가 시작되거나 요청이 다른 인스턴스로 분산되면 서로 다른 버전이 보일 수 있습니다. 웹훅 전달과 처리도 실패·중복될 수 있으므로 “push 후 5초 이내 전체 동기화”는 보장하지 않습니다.
컨테이너 파일시스템은 인스턴스 수명에 종속되고 쓰기에는 메모리가 사용됩니다. /tmp도 영구적인 공유 스토리지가 아닙니다. Cloud Run 컨테이너 계약을 참고하세요.
대안은 변경 빈도와 운영 부담으로 고를 수 있습니다.
- 배포 단위 스냅샷: 콘텐츠를 빌드에 포함하고 commit별 새 리비전을 배포합니다. 서버가 어떤 버전을 제공하는지 명확하지만 반영은 배포 주기에 따릅니다.
- 공유 버전 저장소: 버전별 스냅샷과 manifest를 공유 저장소에 두고 검증된 버전으로 전환합니다. 여러 인스턴스의 일관성과 접근 제어를 별도로 설계해야 합니다.
- 인스턴스별 Git 동기화: 기존 방식을 유지한다면 각 인스턴스가 시작·복구 시 버전을 확인하고, 파일 갱신과 검색 인덱스 전환 사이의 경쟁을 처리해야 합니다.
위 대안은 설계 선택지입니다. 현재 저장소에 모두 구현되어 있다는 뜻은 아닙니다. 어떤 방식을 택하든 결과에 문서 버전과 원문 링크를 남기면 서로 다른 응답을 비교하기 쉽습니다.
웹훅과 저장소 권한
웹훅 서명은 원본 요청 바이트로 HMAC을 계산해 상수 시간 비교를 사용합니다. secret이 없으면 검증을 생략하지 않고 거부해야 합니다. 저장소·브랜치·이벤트를 제한하고 delivery ID의 중복을 처리해야 합니다. 서명이 맞는다는 것은 발신 검증이지 모든 수신 내용을 무조건 실행해도 된다는 뜻은 아닙니다.
Git 인증 정보는 최소 권한으로 서버 비밀 저장소에 두고 URL·프로세스 로그·오류 응답에 남기지 않아야 합니다. 검색 도구와 저장소를 수정하는 도구는 권한을 분리하고, 검 색 문서 안에 적힌 지시는 실행 명령이 아니라 신뢰하지 않는 자료로 취급합니다.
배포 전에 재현할 검증
- stdio 클라이언트에서 MCP 초기화 → 도구 목록 → 검색 호출이 성공하는지 확인합니다.
- REST 경로는 별도로 HTTP 상태·인증·입력 제한을 확인합니다.
- 두 인스턴스에서 같은 commit의 결과를 주는지, 삭제한 글이 검색 캐시에 남지 않는지 검사합니다.
- 웹훅 중복·서명 오류·secret 누락·Git 접근 실패와 인스턴스 재시작을 각각 재현합니다.
- 응답 시간과 비용은 같은 요청 수, 인스턴스 설정, 외부 호출량으로 측정합니다. 기존 글의 고정 5초와 월 비용은 재현 조건을 확인할 수 없어 삭제했습니다.
구체적인 블로그 검색 및 웹훅 구현에서 REST와 MCP가 나뉘는 예는 블로그에 AI 기능 붙이기 2편에 정리했습니다. 이 글은 배포·동기화 경계를 중심으로 읽어 주세요.
