에이전트에 도구를 붙이는 표준으로 MCP(Model Context Protocol)가 자리를 잡으면서, 서비스 회사가 직접 MCP 서버를 내놓는 일이 늘었다. 그런데 설치 안내는 대개 "내 PC 에 런타임을 깔고 실행"이다. 내 PC 는 보안 정책 때문에 새 실행 파일이 막혀 있어서 그렇게 할 수 없었다. 결국 MCP 서버는 원격 서버의 컨테이너에서 돌리고, PC 의 에이전트는 ssh 로만 붙는 구성으로 풀었고, 써 보니 이쪽이 오히려 나았다.
원리
MCP 의 가장 단순한 연결 방식은 표준 입출력(stdio)이다. 에이전트가 명령 하나를 실행하고 그 프로세스와 입출력으로 대화한다. 여기서 "명령"이 꼭 로컬 프로그램일 필요는 없다. ssh 도 표준 입출력을 그대로 이어 주는 명령이다.
에이전트(PC) ──stdio──▶ ssh my-server run-mcp.sh ──▶ docker run -i ... (MCP 서버)
서버 쪽
- MCP 서버 저장소를 받아 이미지를 만든다.
- 실행 스크립트를 하나 둔다. 컨테이너를
-i(표준 입력 연결)로 띄우고, 끝나면 지워지게--rm을 준다.#!/bin/sh # ~/bin/run-mcp.sh exec docker run --rm -i \ -e MCP_TRANSPORT=stdio \ --env-file /home/user/mcp.env \ my-mcp:local
내가 쓴 서버는 Dockerfile 기본값이 HTTP 방식이어서 stdio 로 바꾸는 환경 변수가 필요했다. 이런 것은 저장소의 설정 문서를 봐야 안다.
PC 쪽
에이전트의 MCP 설정에 ssh 명령을 등록한다.
ssh -o BatchMode=yes my-server bin/run-mcp.sh
BatchMode=yes는 비밀번호를 묻는 프롬프트가 뜨지 않게 한다. 프롬프트가 뜨면 그 글자가 프로토콜에 섞여 연결이 깨진다. 키 인증이 되어 있어야 한다.- 서버의 로그인 셸이 접속할 때 환영 문구를 출력하면 역시 프로토콜이 깨진다. 비대화형 접속에서는 아무것도 찍지 않게 한다.
겪은 함정
- 경로가 멋대로 바뀐다. Windows 의 Git Bash 에서 등록 명령을 실행하면서 서버 쪽 절대 경로(
/home/user/bin/...)를 인자로 줬더니, 셸이 그것을 Windows 경로로 "친절하게" 바꿔서 저장했다. 상대 경로를 쓰거나, 변환을 끄는 환경 변수(MSYS_NO_PATHCONV=1)를 붙여야 한다. - 인증 토큰 충돌 가능성. 같은 API 키로 기존 앱과 MCP 서버가 각자 토큰을 발급받으면 서로의 토큰을 무효로 만드는 서비스가 있다. 앱 쪽에 "토큰 무효 오류면 재발급 후 한 번 재시도"를 넣어 두었다.
이 구성이 더 나았던 점
- 비밀 값이 PC 에 없다. API 키는 서버의 설정 파일에만 있고, 컨테이너에 환경 변수로만 전달된다. 에이전트의 설정 파일에도, PC 디스크에도 남지 않는다.
- 위험한 도구를 서버에서 잠근다. 내가 쓴 MCP 서버는 조회 도구와 실행 도구가 나뉘어 있고, 실행 도구는 환경 변수로 켜야만 등록됐다. 실행 스크립트에서 그 값을 "꺼짐"으로 고정해 두면 에이전트가 무슨 말을 듣든 그 도구는 존재하지 않는다. 프롬프트로 "하지 마"라고 하는 것과는 차원이 다른 안전장치다.
- 호출 IP 가 고정된다. IP 를 등록해야 하는 API 는 PC 에서 부르면 장소를 옮길 때마다 막힌다. 서버에서 부르면 늘 같은 IP 다.
- 여러 계정을 나눠 붙일 수 있다. 스크립트 인자로 설정을 바꿔, 같은 서버를 이름만 다르게 여러 개 등록했다.
정리
MCP 서버를 꼭 에이전트와 같은 기기에서 돌릴 필요는 없다. stdio 를 ssh 로 늘이기만 하면 설치 제약을 피할 수 있고, 키와 권한을 서버 한 곳에서 관리하게 되는 덤이 따라온다.
댓글 없음:
댓글 쓰기