MCP 서버 운영 체크리스트: AI 에이전트에 내부 도구를 안전하게 붙이는 법
MCP 서버를 붙이면 AI 에이전트는 단순 답변기가 아니라 내부 시스템을 호출하는 작업자가 된다. Model Context Protocol은 AI 애플리케이션을 파일, 데이터베이스, 검색, 계산기, 전문 프롬프트 같은 외부 시스템에 연결하는 open protocol이다. Claude, ChatGPT, VS Code, Cursor 등 여러 클라이언트가 지원하므로 한 번 만든 서버를 여러 에이전트에서 재사용할 수 있다는 장점이 있다.
문제는 연결이 쉬워질수록 사고도 쉬워진다는 점이다. Notion 읽기 도구와 production DB 쓰기 도구는 같은 “tool”이라는 이름으로 보일 수 있지만 위험도는 완전히 다르다. MCP 도입의 성패는 서버 구현보다 권한, 감사, 승인, 샌드박스 경계를 먼저 설계했는지에 달려 있다.
MCP를 왜 쓰는가
MCP는 흔히 “AI용 USB-C 포트”로 설명된다. 각 AI 앱마다 Notion API, Google Calendar API, 사내 DB, Jira, GitHub 연동을 따로 만들지 않고 표준 프로토콜로 연결하자는 접근이다. 개발자 입장에서는 통합 비용을 줄이고, 에이전트 입장에서는 더 많은 데이터와 도구를 쓸 수 있다.
예를 들어 사내 장애 분석 에이전트가 있다고 하자. 에이전트는 Git commit, 배포 이력, APM 지표, 고객 문의, runbook을 함께 봐야 한다. MCP가 없으면 각 도구별 glue code를 별도로 만들고, 에이전트 런타임마다 다시 붙여야 한다. MCP 서버로 “최근 배포 조회”, “서비스 latency 조회”, “runbook 검색”을 표준화하면 여러 클라이언트에서 같은 인터페이스를 쓸 수 있다.
하지만 표준화가 곧 안전을 의미하지는 않는다. USB-C 포트에 충전기만 꽂을 수도 있고, 악성 장치를 꽂을 수도 있다. MCP 서버도 마찬가지다. 어떤 데이터를 읽고 어떤 행동을 할 수 있는지, 누가 호출했는지, 호출 결과가 어디에 남는지 정하지 않으면 에이전트가 실수했을 때 책임 경로가 사라진다.
첫 번째 원칙: read-only부터 시작한다
처음부터 쓰기 도구를 붙이면 운영팀이 감당해야 할 리스크가 급격히 커진다. 첫 MCP 서버는 read-only가 좋다. 문서 검색, 로그 조회, 이슈 목록 읽기, feature flag 상태 확인, dependency 정보 조회처럼 결과를 읽기만 하는 기능으로 시작한다.
read-only 단계에서도 권한은 최소화해야 한다. 전체 DB를 SELECT할 수 있는 도구 대신 “주문 ID로 상태 요약 조회”, “최근 30분 에러율 조회”, “특정 서비스의 배포 이력 조회”처럼 목적별 도구를 만든다. 에이전트에게 SQL 콘솔을 주는 것과 안전한 조회 함수를 주는 것은 다르다.
쓰기 도구가 필요해질 때는 dry-run을 먼저 만든다. 예를 들어 “Jira 티켓 생성” 전에 “생성될 티켓 preview 반환”, “feature flag 변경” 전에 “변경 계획과 영향 서비스 반환”을 둔다. 사람이 preview를 보고 승인하면 별도 endpoint가 실행되게 한다.
두 번째 원칙: tool 이름보다 정책이 중요하다
MCP 서버의 도구 이름은 모델이 이해하기 쉬워야 하지만, 보안은 이름에 의존하면 안 된다. delete_user라는 이름이 위험해 보이니 모델이 조심할 것이라고 기대하면 안 된다. 서버가 실제로 권한과 입력을 검사해야 한다.
도구마다 네 가지 정책을 붙이는 것을 권장한다. 첫째, 허용 사용자 또는 서비스 계정. 둘째, 허용 리소스 범위. 셋째, 읽기·쓰기·삭제 같은 동작 등급. 넷째, 승인 필요 여부다. 이 정책은 프롬프트가 아니라 서버 코드와 gateway에서 강제해야 한다.
예를 들어 get_customer_summary는 고객 상담팀과 운영 에이전트만 호출할 수 있고, 주민등록번호나 결제 토큰은 마스킹한다. restart_service는 staging만 자동 실행, production은 approval required로 둔다. run_query 같은 범용 도구는 개발 초기에는 편하지만 장기 운영에서는 가장 먼저 제한해야 할 대상이다.
세 번째 원칙: 감사 로그는 사람이 읽을 수 있어야 한다
에이전트 사고를 조사할 때 “모델이 그렇게 말했다”는 설명은 도움이 되지 않는다. MCP 서버는 누가, 언제, 어떤 프롬프트 맥락에서, 어떤 도구를, 어떤 인자로 호출했고, 결과가 무엇이었는지 남겨야 한다. 단, 민감 데이터는 로그에도 그대로 남기지 않는다.
좋은 감사 로그에는 request_id, session_id, user_id 또는 agent_id, tool_name, sanitized arguments, decision, latency, result summary가 있다. 쓰기 도구라면 before/after 또는 rollback reference도 필요하다. 로그는 보안팀만 보는 곳에 숨기지 말고, 개발자가 장애 대응 때 검색할 수 있어야 한다.
또한 실패 로그가 중요하다. 모델이 거부된 도구를 반복 호출했는지, 권한 없는 리소스를 자꾸 요청했는지, timeout이 특정 MCP 서버에 몰리는지 보면 프롬프트 문제와 서버 정책 문제를 구분할 수 있다.
네 번째 원칙: secret은 에이전트에게 보이지 않게 한다
MCP 서버가 외부 API를 호출하려면 토큰이 필요하다. 이때 토큰을 모델 문맥이나 tool result에 노출하면 안 된다. 에이전트는 “배포 이력을 조회해줘”라고 요청하고, 서버가 내부적으로 인증해야 한다. 모델에게 Bearer token을 보여주거나, tool output에 응답 헤더를 그대로 돌려주는 구현은 피해야 한다.
네트워크 allowlist도 필요하다. MCP 서버가 호출할 수 있는 도메인과 내부 시스템을 제한하고, production과 staging 토큰을 분리한다. 사내망 접근이 필요한 경우에는 프록시와 인증서 설정을 코드로 관리하고, 새 도구를 추가할 때 보안 리뷰를 거치게 한다.
샌드박스 에이전트와 MCP를 같이 쓰는 경우도 경계를 분명히 해야 한다. 에이전트가 파일을 쓸 수 있는 sandbox와 MCP 서버가 접근하는 내부 시스템은 별도 권한이다. sandbox 파일에 secret을 저장하거나, tool result로 내려보내는 방식은 나중에 transcript나 artifact에 남을 수 있다.
다섯 번째 원칙: 승인 흐름을 제품처럼 만든다
사람 승인은 “위험하면 물어봐”라는 문장으로 끝나지 않는다. 승인 화면에는 무엇이 바뀌는지, 왜 필요한지, 어떤 계정으로 실행되는지, 실패하면 어떻게 되돌릴지 보여줘야 한다. 승인자는 개발자일 수도 있고 운영 담당자일 수도 있다. 업무별로 다르다.
좋은 승인 메시지는 짧지만 구체적이다. “production feature flag new_checkout을 5%에서 20%로 올림. 대상: KR iOS users. 예상 영향: 결제 실험 확대. 롤백: 5%로 되돌리기.” 이런 식이어야 한다. “작업을 계속 진행할까요?”는 승인 정보가 부족하다.
승인 이후에도 에이전트가 실행 결과를 다시 보고해야 한다. 성공 여부, 실제 변경값, 관련 링크, 다음 확인 지표를 남긴다. 그래야 사람이 승인만 하고 결과를 놓치는 일을 줄일 수 있다.
실행 체크리스트
- 첫 MCP 서버는 read-only 도구로 시작하고, 쓰기 도구는 dry-run과 preview를 먼저 만든다.
- 범용 SQL·shell 도구 대신 목적별 조회 함수와 제한된 액션 도구를 제공한다.
- tool별로 사용자 범위, 리소스 범위, 동작 등급, 승인 필요 여부를 정책으로 강제한다.
- 모든 호출에 request_id, sanitized arguments, decision, result summary를 남긴다.
- secret은 MCP 서버 내부에서만 쓰고 모델 문맥과 tool output에 노출하지 않는다.
- production 쓰기 작업은 승인 화면에 변경 전후, 실행 계정, 롤백 기준을 표시한다.
- 실패·거부·timeout 로그를 주기적으로 보고 프롬프트와 서버 정책을 함께 개선한다.
출처: Model Context Protocol 공식 문서, OpenAI Codex 및 Gemini Managed Agents 관련 공개 문서.