MCP 서버 PATH 문제 완전 해결 가이드

“spawn uvx ENOENT” 에러를 중심으로

📋 목차

  1. 문제 상황과 증상
  2. 근본 원인 분석
  3. 즉시 해결 방법
  4. 플랫폼별 특성
  5. 개발자를 위한 예방책
  6. 테스트 및 검증
  7. 빠른 해결 체크리스트

문제 상황과 증상

🔥 실제 에러 로그

1
2
2025-07-14T01:02:03.249Z [MCP-timeserver] [error] spawn uvx ENOENT
{"context":"connection","stack":"Error: spawn uvx ENOENT\n    at ChildProcess._handle.onexit (node:internal/child_process:285:19)"}

🤔 이상한 점들

  • ✅ 터미널에서 uvx --version 정상 작동
  • which uvx 결과: /Users/username/.local/bin/uvx
  • ❌ Claude Desktop에서만 “uvx를 찾을 수 없음” 에러
  • ✅ 같은 설정에서 npx, sh는 정상 작동

근본 원인 분석

🎯 핵심 문제: GUI vs Shell 환경의 PATH 차이

Interactive Shell 환경 (터미널)

1
2
3
4
5
6
7
# 터미널 시작 시 실행되는 설정 파일들
~/.zshrc → export PATH="/Users/username/.local/bin:$PATH"
~/.bash_profile → export PATH="/Users/username/.local/bin:$PATH"

# 결과 PATH
echo $PATH
# /Users/username/.local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin

GUI Application 환경 (Claude Desktop)

1
2
3
4
5
# GUI 앱이 보는 기본 PATH (macOS launchd로부터 상속)
/usr/bin:/bin:/usr/sbin:/sbin

# 사용자 커스텀 경로는 포함되지 않음!
# ~/.local/bin, /opt/homebrew/bin 등이 누락

📊 명령어별 위치 비교

명령어일반적인 설치 위치GUI 환경 접근 가능
sh/bin/sh
npx/usr/local/bin/npx
uvx~/.local/bin/uvx
cargo~/.cargo/bin/cargo

즉시 해결 방법

🚀 방법 1: env 섹션에 PATH 명시 (권장)

claude_desktop_config.json 수정:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  "mcpServers": {
    "my-server": {
      "command": "uvx",
      "args": ["my-mcp-server"],
      "env": {
        "PATH": "/Users/username/.local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
      }
    }
  }
}

장점:

  • ✅ 프로젝트별 독립적 설정
  • ✅ 다른 시스템으로 이식 시 명확한 의존성
  • ✅ 다른 앱에 영향 없음

🛡️ 방법 2: 절대 경로 사용

1
2
3
4
5
6
7
8
{
  "mcpServers": {
    "my-server": {
      "command": "/Users/username/.local/bin/uvx",
      "args": ["my-mcp-server"]
    }
  }
}

장점:

  • ✅ 즉시 해결

  • ✅ 환경 변수 설정 불필요 단점:

  • ❌ 하드코딩된 경로

  • ❌ 다른 시스템에서 경로가 다를 수 있음

⚙️ 방법 3: 시스템 레벨 PATH 설정

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 1. 현재 세션에 적용
launchctl setenv PATH "/Users/username/.local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"

# 2. 영구 설정 (plist 파일 생성)
cat > ~/Library/LaunchAgents/setenv.PATH.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>setenv.PATH</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/launchctl</string>
        <string>setenv</string>
        <string>PATH</string>
        <string>/Users/username/.local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
EOF

# 3. plist 로드
launchctl load ~/Library/LaunchAgents/setenv.PATH.plist

# 4. 확인
launchctl getenv PATH

플랫폼별 특성

🍎 macOS

  • 문제: GUI 앱이 셸 설정 파일을 읽지 않음
  • 해결: launchctl 또는 개별 앱 설정에서 PATH 지정
  • 테스트: launchctl getenv PATH로 GUI 환경 PATH 확인

🪟 Windows

  • 문제: PowerShell 세션 vs GUI 앱의 환경 변수 차이
  • 해결: 시스템 환경 변수에서 Path 수정 (영구적)
  • 주의: 환경 변수 변경 후 앱 재시작 필요
1
2
3
4
5
:: Windows에서 사용자 Path 확인
echo %PATH%

:: 시스템 환경 변수 GUI로 설정
:: Win + R → sysdm.cpl → 환경 변수 → 사용자 변수의 Path 편집

🐳 Docker

  • 해결책: Dockerfile에서 ENV로 명시적 설정
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
FROM python:3.10-slim

# 커스텀 도구 설치
COPY --from=builder /path/to/uvx /usr/local/bin/uvx
RUN chmod +x /usr/local/bin/uvx

# PATH 명시적 설정 (권장)
ENV PATH="/usr/local/bin:${PATH}"

CMD ["python", "mcp_server.py"]

개발자를 위한 예방책

🏗️ 1. 의존성 번들링 (최고의 해결책)

1
2
3
4
5
6
// Electron 앱 예시: 앱 패키지에 바이너리 포함
const path = require('path');
const { spawn } = require('child_process');

const uvxPath = path.join(__dirname, '..', 'bin', process.platform, 'uvx');
const child = spawn(uvxPath, ['my-server']);

⚙️ 2. 설정에서 실행 파일 경로 지정

1
2
3
4
5
6
7
8
9
{
  "mcpServers": {
    "my-server": {
      "executablePath": "/Users/username/.local/bin/uvx",
      "args": ["my-server"],
      "env": {...}
    }
  }
}

📝 3. 명확한 오류 메시지 (즉시 적용 가능)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// 기존: 모호한 에러
// Error: spawn uvx ENOENT

// 개선: 구체적인 안내
const errorMessage = `
❌ 'uvx' 실행 파일을 찾을 수 없습니다.

해결 방법:
1. MCP 설정에서 env.PATH에 uvx 경로 추가:
   "env": { "PATH": "/Users/username/.local/bin:$PATH" }

2. 또는 절대 경로 사용:
   "command": "/Users/username/.local/bin/uvx"

3. uvx 설치 확인:
   터미널에서 'which uvx' 실행 후 경로 확인

자세한 설정 방법: https://docs.example.com/path-setup
`;

🔍 4. 환경 진단 도구

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// 개발자가 문제를 쉽게 진단할 수 있는 헬퍼
function diagnosePath() {
  console.log('=== PATH 진단 ===');
  console.log('Current PATH:', process.env.PATH);
  console.log('PATH entries:', process.env.PATH.split(':'));

  const commonPaths = [
    '/usr/local/bin',
    '/opt/homebrew/bin',
    process.env.HOME + '/.local/bin',
    process.env.HOME + '/.cargo/bin'
  ];

  commonPaths.forEach(path => {
    const exists = require('fs').existsSync(path);
    const inPath = process.env.PATH.includes(path);
    console.log(`${path}: exists=${exists}, inPath=${inPath}`);
  });
}

테스트 및 검증

🧪 CI/CD에서 환경 차이 테스트

GitHub Actions 예시:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
name: MCP PATH Test
on: [push]

jobs:
  test-path-handling:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v3

      # uvx 설치
      - name: Install uvx
        run: pip install uvx

      # 기본 PATH에서 테스트 (실패 예상)
      - name: Test with minimal PATH
        run: |
          env -i PATH=/usr/bin:/bin node test-mcp.js          
        continue-on-error: true

      # 수정된 설정으로 테스트 (성공 예상)
      - name: Test with corrected config
        run: node test-mcp.js --config config-with-path.json

🔬 로컬 환경 시뮬레이션

1
2
3
4
5
# GUI 환경과 유사한 최소 PATH로 테스트
env -i PATH=/usr/bin:/bin /bin/sh -c 'your-mcp-command'

# 또는 Docker로 깨끗한 환경 테스트
docker run --rm -v $(pwd):/app alpine:latest /bin/sh -c 'cd /app && your-test'

빠른 해결 체크리스트

⚡ 즉시 확인사항

[ ] 터미널에서 which uvx 실행 → 경로 확인 [ ] GUI 환경 PATH 확인: launchctl getenv PATH [ ] MCP 설정에 env 섹션 있는지 확인

🛠️ 즉시 해결 (5분)

[ ] MCP 설정에 env.PATH 추가 [ ] 또는 절대 경로로 command 변경 [ ] Claude Desktop 재시작

🏗️ 완전 해결 (30분)

[ ] 시스템 레벨 PATH 설정 (plist 파일) [ ] 다른 MCP 서버들도 동일 패턴 적용 [ ] 테스트 케이스 작성

👥 팀 공유용

[ ] claude_desktop_config.json 예시 문서화 [ ] 환경 설정 가이드 작성 [ ] 공통 PATH 값들 표준화

🎯 핵심 포인트

  1. GUI 앱은 터미널과 다른 PATH를 가진다
  2. MCP 설정의 **env** 섹션이 가장 안전한 해결책
  3. 절대 경로는 빠른 임시 해결책
  4. 시스템 레벨 설정은 모든 GUI 앱에 영향

이 가이드가 도움이 되었다면, 같은 문제로 고생하는 동료들과 공유해 주세요! 🚀

추가 리소스