VPS에서 MCP 서버 구축 및 운영 가이드
VPS 환경에서 stdio 및 HTTP 전송 방식을 사용하여 MCP 서버를 안정적으로 운영하는 방법을 설명합니다. systemd 서비스 등록, nginx 리버스 프록시 설정, TLS 인증 및 JSON-RPC 스트림 무결성 유지 등 실무에서 발생하는 기술적 문제 해결책을 상세히 다룹니다.
구축할 시스템
하나의 VPS에서 두 가지 MCP 설정을 운영합니다. 첫 번째는 stdio 서버로, Claude Code가 자식 프로세스로 실행하여 파이프를 통해 통신하는 파일 시스템 또는 데이터베이스 도구입니다. 두 번째는 remote HTTP 서버로, systemd와 TLS가 적용된 nginx 리버스 프록시 뒤에서 상시 실행되는 네트워크 서비스이며, MCP 클라이언트가 연결할 수 있는 형태입니다. 두 방식 모두 설치 과정은 간단합니다. 이 가이드의 핵심은 가장 까다로운 두 가지 요소인 JSON-RPC 스트림의 무결성 유지와 인증되지 않은 도구 엔드포인트를 공용 인터넷에 노출하지 않는 것입니다.
MCP의 실체
Model Context Protocol은 AI 클라이언트(Claude Code, Claude Desktop, VPS에서 실행하는 Gemini CLI, 또는 사용자의 자체 스크립트)가 외부 도구를 호출하고 외부 리소스를 읽기 위한 표준 방식입니다. 모델 자체는 아무것도 실행하지 않습니다. 모델이 클라이언트에 요청하면, 클라이언트는 MCP 서버와 JSON-RPC 2.0으로 통신하고, 서버가 도구를 실행하여 결과를 반환합니다. 사람들이 에이전트 하니스(agent harness)라고 부르는 것이 바로 이 클라이언트입니다. 이는 모델을 둘러싼 루프로서 도구 목록, 권한 확인, 세션 상태를 관리하며, MCP는 이 중 도구 부분을 확장하는 수단일 뿐입니다. 단일 프로토콜을 사용하므로 한 번 작성한 서버는 MCP를 지원하는 모든 클라이언트와 호환됩니다. 이러한 구조가 생소하거나 모델이 도구를 사용하기로 결정하는 과정이 궁금하다면, 실제 자격 증명을 서버에 입력하기 전에 에이전트 기초 단계별 가이드를 한 시간 정도 학습하는 것을 권장합니다.
두 가지 전송 방식이 있으며, 이 가이드의 나머지 부분은 이 방식에 따라 나뉩니다.
- stdio. 클라이언트가 서버를 자식 프로세스로 생성하고 표준 입출력(stdin/stdout)을 통해 줄바꿈으로 구분된 JSON-RPC 메시지를 교환합니다. 네트워크나 포트, 인증이 필요 없으며 프로세스 자체가 신뢰 경계가 됩니다. 거의 모든 로컬 도구가 이 방식을 사용합니다.
- Streamable HTTP (및 이전 방식인 HTTP+SSE). 서버가 상시 실행되는 웹 서비스로 동작합니다. 클라이언트가 HTTP로 연결하면 서버는 Server-Sent Events를 통해 응답을 스트리밍할 수 있습니다. 여러 클라이언트가 하나의 서버를 공유하거나, 서버에 상주해야 하는 도구를 실행할 때 이 방식을 사용합니다.
도구가 특정 장비와 사용자에게 귀속된다면 stdio를 선택하십시오. 공유 서비스라면 HTTP를 선택하십시오.
사전 요구 사항 및 주의 사항
Ubuntu 24.04 기반의 신규 KVM VPS와 root 또는 sudo 권한이 있다고 가정합니다. 추가 요구 사항은 다음과 같습니다.
- 서버가 작성된 런타임. 대부분의 참조 서버는 Node 또는 Python으로 작성되었습니다. Ubuntu 24.04는 Node 18을 포함하고 있으나, 현재 많은 MCP 패키지가 Node 20 이상을 요구하므로
apt을 그대로 사용하기보다 NodeSource나 nvm을 통해 최신 LTS 버전을 설치하십시오. Python 3.12는 이미 설치되어 있습니다. - 도메인 및 DNS A 레코드. 원격 HTTP 서버에만 필요하며, TLS를 사용하려면 해당 VPS로 연결되는 도메인 이름이 필요합니다. stdio 예제는 DNS가 전혀 필요하지 않습니다.
- 512 MB RAM이면 충분합니다. MCP 서버는 가벼운 JSON-RPC 프로세스입니다. 메모리 사용량은 프로토콜 자체가 아니라 도구가 사용하는 데이터베이스 드라이버나 파일 캐시 등에 의해 결정됩니다.
- 사양은 초기 단계이며 계속 변화합니다. 2025-03-26 개정판에서 HTTP+SSE가 Streamable HTTP로 대체되었으며 SSE는 더 이상 권장되지 않습니다(deprecated). SSE는 여전히 작동하며 많은 서버가 이를 지원하므로, 전송 방식 고정은 절대적인 규칙으로 받아들이기보다 서버의 릴리스 노트를 확인하여 재검토해야 합니다.
1단계: Claude Code에 stdio 서버 연결하기
공식적으로 유지보수 중이며 Node만 있으면 실행 가능한 filesystem 서버부터 시작합니다. 아래 명령어를 실행하면 Claude Code에 서버가 등록되며, 현재 프로젝트 범위로 제한되어 커밋 가능한 파일로 저장됩니다.
cd /home/matt/projects/api
claude mcp add --scope project --transport stdio filesystem \
-- npx -y @modelcontextprotocol/server-filesystem /home/matt/projects/api-- 구분자는 중요합니다. 이 뒤에 오는 모든 내용은 Claude Code의 플래그가 아니라 Claude Code가 실행할 명령어입니다. 이 명령은 프로젝트 루트에 .mcp.json 파일을 생성합니다.
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/home/matt/projects/api"
]
}
}
}아직 아무것도 실행되지 않은 상태입니다. 이 디렉터리에서 Claude Code를 다음에 시작하면, 에이전트가 .mcp.json를 읽어 npx -y @modelcontextprotocol/server-filesystem ...를 자식 프로세스로 생성하고 해당 프로세스의 stdin/stdout을 통해 MCP 핸드셰이크를 수행합니다. 연결이 성공했는지 확인하십시오.
claude mcp list정상적인 서버는 명령어와 함께 녹색 체크 표시인 filesystem: npx -y @modelcontextprotocol/server-filesystem ... - ✓ Connected을 출력합니다. 세션 내부에서 /mcp 슬래시 명령어를 입력하면 서버가 노출하는 도구(read_file, write_file, list_directory) 목록이 표시되며, 이제 에이전트가 허용된 경로에서 해당 도구를 호출할 수 있습니다. 데이터베이스 도구도 같은 방식입니다. 패키지를 교체하고 연결 문자열을 마지막 인자로 전달하면 되지만, Postgres 참조 서버의 경우 여러 번 관리 주체가 바뀌었으므로 현재 패키지 이름은 서버의 공식 저장소에서 확인해야 합니다.
이것이 바로 에이전트를 서버에서 직접 실행하는 핵심 이유입니다. Claude Code 세션은 VPS 내부의 tmux에서 상주하며, stdio 서버는 그 바로 옆에서 프로젝트 파일과 로컬 서비스에 직접 접근하므로 네트워크 왕복 시간이 발생하지 않습니다. 에이전트가 write_file과 read_file를 모두 확보했다면, 가장 작은 단위의 변경을 지향하는 기술과 결합하는 것이 좋습니다. 파일 시스템 도구를 사용하면 방대한 코드 수정도 두 줄짜리 수정만큼이나 쉽게 수행할 수 있기 때문입니다. 이러한 연결 방식은 로컬 파일을 넘어 확장됩니다. 이미 VPS에서 검색 엔진을 운영 중이라면 직접 운영하는 SearXNG 인스턴스를 검색 도구로 에이전트에게 제공할 수 있습니다. 이렇게 하면 쿼리는 서버 내부에서 처리되면서도, 신뢰할 수 없는 페이지의 텍스트를 에이전트가 즉시 컨텍스트로 가져와 작업할 수 있습니다.
2단계: 원격 HTTP 서버 구축
stdio 서버는 부모 프로세스가 종료되면 함께 종료되며, 클라이언트당 하나씩 생성됩니다. 따라서 서로 작업을 주고받는 두 개의 Claude Code 세션을 실행하면 각 세션은 도구의 전용 복사본을 각각 갖게 됩니다. 모든 클라이언트가 공유하는 상시 가동 도구, 운영 도구, 데이터베이스 게이트웨이, 혹은 노트북과 CI 환경 모두에서 호출하는 서비스를 원한다면 HTTP 전송 방식과 실제 서비스가 필요합니다. 다음은 공식 SDK를 사용하여 하나의 도구를 노출하는 최소한의 Python 서버 예제입니다.
# /opt/mcp-ops/server.py
from mcp.server.fastmcp import FastMCP
import subprocess
mcp = FastMCP("ops-tools", host="127.0.0.1", port=8000)
@mcp.tool()
def disk_free() -> str:
"""Return `df -h` for the server."""
out = subprocess.run(["df", "-h"], capture_output=True, text=True)
return out.stdout
if __name__ == "__main__":
# Serves Streamable HTTP at /mcp on 127.0.0.1:8000
mcp.run(transport="streamable-http")host="127.0.0.1" 참고: 서버는 localhost에만 바인딩되므로 인증이 구현되기 전까지는 외부에서 직접 접근할 수 없으며, 이는 의도한 보안 구성입니다. systemd가 안정적인 인터프리터 경로를 참조할 수 있도록 전용 virtualenv에 설치하십시오.
sudo useradd --system --home /opt/mcp-ops --shell /usr/sbin/nologin mcp
sudo install -d -o mcp -g mcp /opt/mcp-ops
sudo -H -u mcp python3 -m venv /opt/mcp-ops/.venv
sudo -H -u mcp /opt/mcp-ops/.venv/bin/pip install "mcp[cli]"3단계: systemd로 서비스 유지하기
에이전트가 호출했을 때 도구가 실행 중이지 않다면, 아예 없는 것보다 못합니다. 클라이언트 자체가 장기 실행 프로세스일 때 이는 더욱 중요합니다. 재부팅 후에도 메모리와 스케줄을 유지하는 상시 가동 에이전트는 아무도 지켜보지 않는 상황에서 정해진 일정에 따라 도구를 호출하므로, 서버 역시 스스로 복구되어야 합니다. /etc/systemd/system/mcp-ops.service를 작성하십시오:
[Unit]
Description=MCP ops-tools server
After=network.target
[Service]
Type=simple
User=mcp
WorkingDirectory=/opt/mcp-ops
ExecStart=/opt/mcp-ops/.venv/bin/python /opt/mcp-ops/server.py
Restart=on-failure
RestartSec=2
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
[Install]
WantedBy=multi-user.targetExecStart에 지정된 venv Python의 절대 경로는 필수입니다. /usr/bin/python3을 가리키도록 설정하십시오. 시스템 인터프리터는 사용자의 pip install을 인식하지 못하므로, 프로세스는 ModuleNotFoundError: No module named 'mcp'로 시작됩니다. 활성화하고 확인하십시오:
sudo systemctl daemon-reload
sudo systemctl enable --now mcp-ops
sudo systemctl status mcp-ops
curl -si -H 'Accept: application/json, text/event-stream' \
-H 'Content-Type: application/json' \
-X POST http://127.0.0.1:8000/mcpstatus의 출력은 active (running)이어야 합니다. curl은 본문에 JSON-RPC 오류를 포함하여 HTTP/1.1 400 Bad Request 상태로 응답합니다. 요청에 세션과 유효한 JSON 페이로드가 없었기 때문이며, 이는 의도한 결과입니다. 포트가 응답하고 프로토콜을 처리하고 있음을 증명하기 때문입니다. Connection refused 또는 빈 응답이 돌아온다면 프로세스가 예상한 위치에 바인딩되지 않은 것입니다. journalctl -u mcp-ops -n 50를 확인하십시오.
단계 4: TLS와 리버스 프록시 배치
서버는 localhost에서 대기합니다. 외부에서 접근하려면 nginx에서 TLS를 종료하고 내부로 프록시해야 합니다. nginx를 설치하고 Certbot과 Let's Encrypt on nginx를 통해 인증서를 발급받은 뒤, location 블록을 작성합니다. 핵심은 버퍼링을 비활성화하는 것입니다. nginx의 기본 동작은 응답이 완료될 때까지 데이터를 보관하므로, SSE 스트림이 영원히 지연되기 때문입니다.
server {
listen 443 ssl;
server_name mcp.example.com;
# ssl_certificate lines managed by Certbot
location /mcp {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
# The four lines that make SSE work through nginx:
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
chunked_transfer_encoding off;
}
}sudo nginx -t && sudo systemctl reload nginx 명령으로 설정을 다시 불러옵니다. 이미 여러 컨테이너를 운영 중이라면 Traefik 리버스 프록시와 자동 TLS를 사용하여 동일한 작업을 수행할 수 있습니다. 이 도구는 인증서를 발급하고 호스트 이름에 따라 라우팅하며, 사용자는 MCP 컨테이너에 레이블만 추가하면 됩니다. 어떤 방식을 선택하든 리버스 프록시만이 공개 포트를 점유하게 되며, 아직 보안 설정이 되지 않은 서비스로 연결됩니다. URL을 외부에 공개하기 전에 반드시 이 보안 설정을 완료하십시오.
5단계: 이 주제를 관통하는 보안 규칙
인증되지 않은 MCP 엔드포인트를 절대 외부에 노출하지 마십시오. MCP 서버는 읽기 전용 API가 아닙니다. 이 서버는 파일, 데이터베이스, 때로는 셸에 대한 도구 접근 권한을 부여합니다. 공개 인터넷에 열려 있는 /mcp은 AI 에이전트와 동일한 권한을 가진 낯선 사람과 같습니다. 그들은 도구 목록을 확인한 뒤 즉시 실행할 수 있습니다. 이를 인증되지 않은 관리자 소켓과 동일하게 취급하십시오. 실제로도 그렇기 때문입니다. 탈취된 토큰으로 무엇을 할 수 있는지는 배후의 서버에 달려 있습니다. openGym 운동 추적기와 함께 제공되는 읽기 전용 MCP 서버는 훈련 데이터만 반환할 수 있지만, 파일 시스템이나 셸 도구는 서버 전체에 대한 제어권을 넘겨줍니다.
선호도 순으로 세 가지 방어 전략을 제시합니다.
- 공개하지 마십시오. 서버를
127.0.0.1에 유지하고 SSH 터널을 통해 노트북에서 접속하십시오.ssh -L 8000:127.0.0.1:8000 matt@vps을 사용하고 클라이언트를http://127.0.0.1:8000/mcp로 지정하십시오. 그 어떤 것도 외부에 노출되지 않습니다. - 사설 네트워크에 배치하십시오. 직접 호스팅하는 WireGuard VPN의 터널 주소에 바인딩하고 VPN 피어만 접근하도록 허용하십시오. 공개 인터넷에서는 포트가 닫힌 것으로 보입니다.
- 공개해야 한다면 토큰을 요구하십시오. 올바른 방법은 HTTP 전송이 기본적으로 지원하는 MCP OAuth 흐름을 사용하는 것입니다. 현실적인 최소한의 조치는 프록시에서 확인하는 공유 Bearer 토큰입니다. 이는 비용이 저렴하며 무작위 공격을 완전히 차단합니다.
location /mcp {
if ($http_authorization != "Bearer REPLACE_WITH_LONG_RANDOM") {
return 401;
}
proxy_pass http://127.0.0.1:8000;
# ...buffering-off block from above...
}openssl rand -hex 32으로 토큰을 생성하십시오. 앞서 언급한 방어 수단 없이 서버 자체를 0.0.0.0에 바인딩하지 마십시오. 클라이언트는 토큰을 헤더로 전송합니다. Claude Code의 경우 다음과 같습니다.
claude mcp add --scope project --transport http ops-tools https://mcp.example.com/mcp \
--header 'Authorization: Bearer ${MCP_TOKEN}'MCP_TOKEN를 셸에 설정하여 비밀값이 .mcp.json에 평문으로 남지 않도록 하십시오. Claude Code는 읽기 시점에 환경 변수에서 ${MCP_TOKEN}를 확장합니다.
위의 모든 방어 수단은 이미 토큰을 보유한 에이전트가 아닌 엔드포인트를 보호합니다. 이는 문제의 나머지 절반을 해결합니다. 클라이언트가 DeepSeek Harness라면, 에이전트가 호출할 수 있는 도구를 제한하고 도구 출력에서 주입된 명령을 검사하는 플러그인이 해당 측면을 보완합니다.
6단계: MCP Inspector로 디버깅하기
서버가 비정상적으로 동작할 때 에이전트 내부에서 추측하지 말고, 공식 웹 기반 테스트 클라이언트인 Inspector를 사용하여 직접 제어하십시오. stdio 서버의 경우, 에이전트가 실행하는 것과 동일한 명령어를 전달합니다.
npx @modelcontextprotocol/inspector \
npx -y @modelcontextprotocol/server-filesystem /tmp이 도구는 http://localhost:6274에서 UI를 시작합니다(최신 버전은 MCP_PROXY_AUTH_TOKEN 쿼리 문자열이 포함된 URL을 출력하므로, 해당 링크를 그대로 사용해야 UI에서 거부되지 않습니다). 또한 6277 포트에서 프록시를 실행합니다. Connect를 클릭한 다음 List Tools를 선택하고, 실제 인자를 사용하여 Call Tool을 실행하십시오. Inspector에서는 정상 작동하지만 에이전트에서 실패한다면, 버그는 서버가 아닌 클라이언트 설정에 있는 것입니다. 원격 HTTP 서버의 경우 Streamable HTTP 전송 방식을 선택하고 https://mcp.example.com/mcp을 입력한 뒤, Authorization 헤더를 추가하여 연결하십시오. 이는 에이전트가 개입하기 전에 인증과 프록시 설정이 올바른지 확인하는 가장 빠른 방법입니다.
서버 업데이트 유지
MCP는 빠르게 변화하므로 정기적인 일정에 따라 패치를 적용해야 합니다. npx -y로 시작하는 노드 서버는 실행할 때마다 최신 버전을 가져오는데, 이는 편리하지만 재현성이 떨어집니다. 서버가 중요해지면 테스트를 마친 정확한 버전을 고정하십시오. npm view @modelcontextprotocol/server-filesystem version에서 버전을 확인한 뒤 .mcp.json(@modelcontextprotocol/server-filesystem@<version>)의 패키지 이름 뒤에 추가하고, 의도적으로 버전을 올리십시오. systemd에서 실행되는 파이썬 서버는 sudo -H -u mcp /opt/mcp-ops/.venv/bin/pip install -U "mcp[cli]"을 실행한 후 sudo systemctl restart mcp-ops를 수행하여 업데이트합니다. 업그레이드 시 SDK가 타겟팅하는 사양 버전을 확인하십시오. SSE에서 Streamable-HTTP 경계로 넘어가면 클라이언트가 요청해야 하는 전송 방식이 변경될 수 있습니다.
실패 유형 및 확인되는 문자열
에이전트가 서버 실패를 표시합니다. claude mcp list는 ✗ Failed to connect을 출력하고, TUI는 MCP server 'filesystem' failed to start을 보고합니다. claude --debug을 실행하면 보통 Error: spawn npx ENOENT가 나타나는데, 이는 해당 명령어가 에이전트의 PATH에 없기 때문입니다. 런타임이 누락되었거나 에이전트가 찾는 위치에 없습니다. Node가 설치되지 않았거나, npx이 없거나, 가상 환경의 Python이 단순 이름으로 참조된 경우입니다. 명령어를 절대 경로로 수정하거나 런타임을 설치한 뒤 다시 연결하십시오.
stdio 서버가 연결 직후 끊깁니다. 클라이언트 로그에 Unexpected token 'S', "Server sta"... is not valid JSON 또는 Failed to parse message와 같은 JSON 파싱 오류가 기록됩니다. 원인은 항상 동일합니다. 서버가 stdout으로 로그 라인을 출력했기 때문입니다. stdio 환경에서 stdout은 JSON-RPC 채널 그 자체이므로, 불필요한 텍스트가 섞이면 스트림이 손상되어 핸드셰이크가 실패합니다. Node에서는 console.log이 stdout으로 출력되므로 console.error를 사용하십시오. Python에서는 단순 print()가 stdout으로 출력되므로, sys.stderr로 설정된 logging을 사용하여 로그를 작성하거나 file=sys.stderr을 전달하십시오. 규칙은 절대적입니다. stdio에서는 stdout에 JSON-RPC만 출력하고, 사람이 읽는 모든 내용은 stderr로 출력해야 합니다.
원격 서버의 타임아웃 또는 핸드셰이크 도중 연결 종료. 클라이언트가 MCP error -32000: Connection closed 오류를 내거나, Inspector가 Connect 상태에서 멈추고 도구 목록을 불러오지 못합니다. nginx 뒤에 있다면 버퍼링 문제입니다. 프록시가 SSE 스트림을 즉시 전송하지 않고 붙잡고 있어, 클라이언트는 오지 않을 응답을 기다리게 됩니다. location에 proxy_buffering off;(및 4단계의 나머지 블록)을 추가하십시오. 공용 URL을 대상으로 curl -N를 실행하여 확인하십시오. 이벤트 데이터가 한꺼번에 출력되지 않고 점진적으로 도착해야 합니다.
인증이 거부됩니다. 클라이언트가 Error POSTing to endpoint (HTTP 401) 또는 단순히 401 Unauthorized를 보고합니다. 헤더가 누락되었거나, 토큰이 잘못되었거나, 클라이언트가 설정을 읽을 때 셸 변수가 비어 있는 경우입니다. 이는 흔한 실수인데, 변수가 설정되지 않으면 ${MCP_TOKEN}가 빈 값으로 확장되어 nginx가 Bearer 을 값 없이 인식하기 때문입니다. 변수를 echo로 확인하고 헤더를 다시 추가한 뒤, 정확한 바이트가 nginx if의 토큰과 일치하는지 검증하십시오.
systemd에서 서비스가 시작되지 않습니다. journalctl -u mcp-ops은 ModuleNotFoundError: No module named 'mcp'를 보여주며, ExecStart은 venv 인터프리터 대신 시스템 Python을 가리킵니다. 또는 Address already in use 오류가 발생하며 다른 프로세스가 8000 포트를 점유 중일 수 있습니다. sudo ss -ltnp | grep 8000를 사용하여 해당 프로세스를 찾으십시오.
FAQ
MCP 서버란 정확히 무엇입니까?
MCP 서버는 Model Context Protocol을 통해 AI 클라이언트에 도구와 리소스를 제공하는 프로그램이며, JSON-RPC 2.0을 사용합니다. AI 모델은 도구를 직접 실행하지 않으며, 클라이언트에 요청을 보내면 클라이언트가 MCP 서버를 호출하고, 서버가 이를 실행하여 결과를 반환합니다. 프로토콜이 표준화되어 있으므로, Claude Code, Claude Desktop, Gemini CLI 등 규격을 준수하는 모든 클라이언트에서 하나의 서버를 사용할 수 있습니다.
stdio와 HTTP 전송 방식의 차이점은 무엇입니까?
stdio 서버는 클라이언트가 자식 프로세스로 실행하며 stdin/stdout을 통해 통신하므로, 단일 머신의 단일 클라이언트와 생애 주기를 같이하며 네트워크나 인증이 필요하지 않습니다. 반면 HTTP 서버는 여러 클라이언트가 동시에 접근할 수 있는 상시 가동 네트워크 서비스이므로 TLS와 인증이 필수적입니다. 로컬의 단일 사용자 도구에는 stdio를 사용하고, 공유하거나 지속적인 서비스가 필요한 경우에는 HTTP(현재 서버에서는 Streamable HTTP)를 사용하십시오.
원격 MCP 서버는 어떻게 보안을 유지합니까?
MCP 서버는 사용자의 파일, 데이터베이스, 셸에 대한 접근 권한을 부여할 수 있으므로, 인증 없이 노출해서는 안 됩니다. 가장 좋은 방법은 localhost에 바인딩한 뒤 SSH 터널이나 사설 VPN을 통해 접근하는 것입니다. 만약 반드시 공개해야 한다면, Bearer 토큰이나 MCP OAuth 흐름을 강제하는 리버스 프록시 뒤에 배치하십시오. 토큰은 openssl rand -hex 32으로 생성하며, 이러한 보안 조치 없이 서버를 0.0.0.0에 바인딩하지 마십시오.
서버가 시작되지 않을 때 어떻게 디버깅합니까?
먼저 claude mcp list, ✗ Failed to connect을 확인하십시오. spawn ... ENOENT 오류가 발생한다면 명령어나 런타임이 누락된 것이므로 경로를 수정하거나 설치해야 합니다. 연결 후 JSON 파싱 오류와 함께 종료된다면, 서버가 stdout으로 로그를 출력하여 JSON-RPC 스트림을 오염시키고 있는 것이므로 모든 로그를 stderr로 출력하도록 변경하십시오. 그 외의 문제는 MCP Inspector를 사용하여 해당 명령어를 직접 실행해 보십시오. 서버를 격리된 환경에서 구동하므로 서버 자체의 버그인지 클라이언트 설정 문제인지 구분할 수 있습니다.