MCP(Model Context Protocol) 서버 연결 오류(spawn ENOENT) 해결 및 로컬·원격 보안 설정 완벽 가이드
Claude Desktop, Cursor, Claude Code, Antigravity 등 최신 AI 에이전트 환경에서 외부 데이터베이스(PostgreSQL, Supabase), GitHub, 브라우저 제어, 사내 API를 연결할 때 MCP(Model Context Protocol)는 사실상 표준 인터페이스로 자리 잡았습니다. 하지만 처음 MCP 서버를 등록하거나 Node.js 버전 관리자(nvm, fnm, volta)를 사용하는 macOS·Linux·Windows 환경에서는 spawn npx ENOENT, Server disconnected, 혹은 JSON-RPC 파싱 에러로 인해 연결이 즉시 끊어지는 문제가 빈번하게 발생합니다.
이번 글에서는 1) 로컬(stdio) vs 원격(SSE / Streamable HTTP) MCP 아키텍처 및 운영 비용·보안 비교, 2) 가장 많이 발생하는 3대 연결 오류의 정확한 원인과 해결 명령어, 3) 실무 환경에서 API 키 유출과 프롬프트 인젝션을 막는 보안 설정 원칙을 정리합니다.
1. MCP 전송 방식(Transport) 비교: 로컬 stdio vs 원격 HTTP/SSE
MCP 서버는 구동 위치와 통신 채널에 따라 크게 로컬 프로세스(stdio) 방식과 클라우드·사내 서버에 배포하는 원격(SSE / Streamable HTTP) 방식으로 나뉩니다. 팀 단위 도입이나 클라우드 배포 전 아래 기준표를 먼저 확인하세요.
| 비교 항목 | 로컬 stdio 방식 | 원격 SSE / Streamable HTTP | 권장 도입 환경 |
|---|---|---|---|
| 구동 원리 | 클라이언트 앱이 자식 프로세스(npx, uvx, docker)를 직접 실행 |
외부 클라우드 서버·컨테이너와 HTTPS/SSE 엔드포인트로 통신 | 개인 개발 PC는 stdio, 다수 팀원 공유는 원격 HTTP |
| 인증 및 보안 | 로컬 설정 파일(JSON) 내 환경변수(env)로 토큰 전달 |
OAuth 2.1, Bearer Token, Cloudflare Access 등 API 게이트웨이 연동 | 사내 DB·클라우드 인프라는 중앙 인증 가능한 원격 권장 |
| 주요 장애 원인 | GUI 앱의 PATH 환경변수 누락, stdout 일반 로그 출력 오염 |
리버스 프록시(Nginx/ALB) 타임아웃, CORS 및 버퍼링 설정 오류 | 방화벽·프록시 환경에서는 Keep-Alive 튜닝 필수 |
| 리소스 및 비용 | 서버 호스팅 비용 없음 (로컬 RAM/CPU 점유) | 컨테이너/서버리스(Cloud Run, AWS Fargate, Workers) 호스팅 비용 발생 | 트래픽에 맞춰 오토스케일링 서버리스 활용 시 비용 최소화 |
2. MCP 서버 연결 실패 3대 오류 원인과 해결법
① Error: spawn npx ENOENT / spawn uvx ENOENT 해결
원인: macOS나 Linux에서 터미널(zsh/bash)을 열 때는 .zshrc가 로드되어 nvm이나 homebrew 경로가 잡히지만, GUI 애플리케이션(Claude Desktop, Cursor 등)을 아이콘으로 실행하면 기본 시스템 경로(/usr/bin:/bin)만 참조하기 때문에 npx나 node 실행 파일을 찾지 못해 발생합니다.
해결 방법: 터미널에서 which npx와 which node로 절대 경로를 확인한 뒤, 설정 JSON의 command에 절대 경로를 적고 env.PATH를 명시적으로 주입하면 100% 해결됩니다.
{
"mcpServers": {
"postgres-db": {
"command": "/opt/homebrew/bin/npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://readonly_user:password@localhost:5432/prod_db"
],
"env": {
"PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
}
}
}
}
Windows 환경에서 동일한 오류가 난다면 "command": "cmd", "args": ["/c", "npx", "-y", "@modelcontextprotocol/..."] 형태로 래핑하면 정상 구동됩니다.
② SyntaxError: Unexpected token / JSON-RPC 파싱 오류로 즉시 종료될 때
원인: stdio 기반 MCP 서버는 표준 출력(stdout)을 오직 JSON-RPC 2.0 메시지 통신 채널로만 사용합니다. 만약 직접 작성한 MCP 서버 코드나 서드파티 라이브러리에서 console.log("DB connected")나 dotenv 배너를 stdout에 출력하면 클라이언트가 이를 깨진 JSON으로 인식해 즉시 연결을 끊습니다.
해결 방법: 모든 디버그 로그는 반드시 표준 에러(stderr)로 출력해야 합니다.
// 잘못된 예시 (stdio JSON-RPC 스트림을 깨뜨림)
console.log("Starting MCP Server...");
// 올바른 예시 (stderr로 출력하여 프로토콜 간섭 방지)
console.error("[MCP] Starting server on stderr...");
③ 원격 SSE / Streamable HTTP 연결이 60초마다 끊기는 현상
원인: Nginx, Cloudflare, AWS ALB 뒤에 원격 MCP 서버를 배치했을 때, 프록시 버퍼링(proxy_buffering)이 켜져 있거나 기본 유휴 타임아웃(60초)이 적용되어 스트리밍 연결이 강제 종료되는 경우입니다.
해결 방법: 리버스 프록시 설정에서 SSE 엔드포인트의 버퍼링을 끄고 타임아웃을 확장합니다.
location /mcp/ {
proxy_pass http://127.0.0.1:8080/mcp/;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
chunked_transfer_encoding off;
}
3. 실무 도입 시 반드시 지켜야 할 MCP 보안 및 비용 최적화 체크리스트
- 최소 권한 계정(Read-Only) 분리: 데이터베이스나 클라우드 인프라 MCP 서버를 연결할 때는 절대
superuser나 루트 API 키를 넣지 마세요. 조회 전용(SELECT권한만 부여된 DB 계정)으로 연결해야 에이전트의 오작동이나 프롬프트 인젝션으로 인한 데이터 유실을 원천 차단할 수 있습니다. - Docker 컨테이너 샌드박싱: 검증되지 않은 외부 오픈소스 MCP 패키지를 로컬에서 바로
npx -y로 실행하면 호스트 파일시스템(`~/.ssh`, `~/.aws` 등)에 접근할 수 있습니다. 민감한 환경에서는docker run -i --rm --network none또는 필요한 디렉토리만 마운트(`-v`)하여 격리 실행하는 것이 안전합니다. - 불필요한 MCP 서버 비활성화로 토큰 절약: 활성화된 MCP 서버가 많을수록 매 대화 턴마다 수십 개의 도구 스키마(Tool Definitions)가 시스템 프롬프트에 포함되어 수천 토큰이 기본 차감됩니다. 현재 프로젝트에 쓰지 않는 MCP 서버는 비활성화해 두어야 응답 속도와 API 비용을 동시에 아낄 수 있습니다.
'컴, 하드웨어, IT' 카테고리의 다른 글
| AI 코딩 에이전트 & LLM API 요금제 비교 및 토큰 비용 70% 절감·429 에러 해결 가이드 (0) | 2026.11.07 |
|---|---|
| 블루투스 Classic 와 BLE( Bluetooth Low Energy) 검색방식 비교 (0) | 2019.01.19 |
| Bluetooth Packet type (DH1/DM1, DH3/DM3, DH5/DM5) (0) | 2019.01.18 |

