# MCP 서버 디버깅 가이드

이 가이드에서는 Copilot SDK를 사용할 때 MCP(모델 컨텍스트 프로토콜) 서버와 관련된 디버깅 기술에 대해 설명합니다.

<!-- markdownlint-disable GHD046 GHD005 -->

<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->

## 목차

* [빠른 진단](#quick-diagnostics)
* [독립적으로 MCP 서버 테스트](#testing-mcp-servers-independently)
* [일반적인 문제](#common-issues)
* [플랫폼별 문제](#platform-specific-issues)
* [고급 디버깅](#advanced-debugging)

## 빠른 진단

### Checklist

자세히 살펴보기 전에 다음 기본 사항을 확인합니다.

* [ ] MCP 서버 실행 파일이 존재하며 실행 가능
* [ ] 명령 경로가 올바르다(의심할 경우 절대 경로 사용)
* [ ] 도구가 사용하도록 설정됨(`tools: ["*"]` 또는 특정 도구 이름)
* [ ] 서버가 MCP 프로토콜을 올바르게 구현하여 `initialize`에 응답함
* [ ] 프로세스를 차단하는 방화벽/바이러스 백신 없음(Windows)

### MCP 디버그 로깅 사용

MCP 서버 구성에 환경 변수를 추가합니다.

```typescript
mcpServers: {
  "my-server": {
    type: "local",
    command: "/path/to/server",
    args: [],
    env: {
      MCP_DEBUG: "1",
      DEBUG: "*",
      NODE_DEBUG: "mcp",  // For Node.js MCP servers
    },
  },
}
```

## MCP 서버를 독립적으로 테스트

항상 먼저 SDK 외부에서 MCP 서버를 테스트합니다.

### 수동 프로토콜 테스트

stdin을 통해 `initialize` 요청을 보냅니다.

```bash
# Unix/macOS
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | /path/to/your/mcp-server

# Windows (PowerShell)
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | C:\path\to\your\mcp-server.exe
```

**예상 응답:**

```json
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"your-server","version":"1.0"}}}
```

### 테스트 도구 목록

초기화 후 도구 목록을 요청합니다.

```bash
echo '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' | /path/to/your/mcp-server
```

**예상 응답:**

```json
{"jsonrpc":"2.0","id":2,"result":{"tools":[{"name":"my_tool","description":"Does something","inputSchema":{...}}]}}
```

### 대화형 테스트 스크립트

MCP 서버를 대화형으로 디버그하는 테스트 스크립트를 만듭니다.

```bash
#!/bin/bash
# test-mcp.sh

SERVER="$1"

# Initialize
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'

# Send initialized notification
echo '{"jsonrpc":"2.0","method":"notifications/initialized"}'

# List tools
echo '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'

# Keep stdin open
cat
```

사용법:

```bash
./test-mcp.sh | /path/to/mcp-server
```

## 일반적인 문제

### 서버가 시작되지 않음

**증상:** 도구가 표시되지 않고 로그에 오류가 없습니다.

**원인 및 솔루션:**

| 원인                                 | 해결 방법                             |
| ---------------------------------- | --------------------------------- |
| 잘못된 명령 경로                          | 절대 경로 사용: `/usr/local/bin/server` |
| 실행 권한이 없습니다.                       |                                   |
| `chmod +x /path/to/server`을 실행합니다. |                                   |
| 누락된 종속성                            | Linux를 사용하여 확인하거나 수동으로 실행         |
| 작업 디렉터리 문제                         | 구성에서 `cwd`을 설정하세요.                |

**수동으로 실행하여 디버그:**

```bash
# Run exactly what the SDK would run
cd /expected/working/dir
/path/to/command arg1 arg2
```

### 서버가 시작되지만 도구가 표시되지 않음

**증상:** 서버 프로세스가 실행되지만 사용할 수 있는 도구는 없습니다.

**원인 및 솔루션:**

1. **구성에서 사용하도록 설정되지 않은 도구:**

   ```typescript
   mcpServers: {
     "server": {
       // ...
       tools: ["*"],  // Must be "*" or list of tool names
     },
   }
   ```

2. **서버는 도구를 노출하지 않습니다.**
   * `tools/list` 요청을 수동으로 테스트
   * 서버가 `tools/list` 메서드를 구현하는지 확인

3. **초기화 핸드셰이크가 실패합니다.**
   * 서버가 `initialize` 올바르게 응답해야 합니다.
   * 서버에서 처리해야 합니다. `notifications/initialized`

### 도구가 나열되었지만 호출되지 않았습니다.

**증상:** 도구는 디버그 로그에 표시되지만 모델은 이를 사용하지 않습니다.

**원인 및 솔루션:**

1. **프롬프트에는 도구가 명확하게 필요하지 않습니다.**

   ```typescript
   // Too vague
   await session.sendAndWait({ prompt: "What's the weather?" });

   // Better - explicitly mentions capability
   await session.sendAndWait({ 
     prompt: "Use the weather tool to get the current temperature in Seattle" 
   });
   ```

2. **도구 설명 불분명:**

   ```typescript
   // Bad - model doesn't know when to use it
   { name: "do_thing", description: "Does a thing" }

   // Good - clear purpose
   { name: "get_weather", description: "Get current weather conditions for a city. Returns temperature, humidity, and conditions." }
   ```

3. **도구 스키마 문제:**
   * 유효한 JSON 스키마인지 확인 `inputSchema`
   * 필수 필드는 배열에 있어야 합니다.`required`

### 시간 제한 오류

**증상:**`MCP tool call timed out` 오류.

**솔루션:**

1. **시간 제한 늘리기:**

   ```typescript
   mcpServers: {
     "slow-server": {
       // ...
       timeout: 300000,  // 5 minutes
     },
   }
   ```

2. **서버 성능 최적화:**
   * 병목 상태를 식별하기 위한 진행률 로깅 추가
   * 비동기 작업을 고려하세요
   * 차단 I/O가 있는지 확인

3. **장기 실행 도구의 경우** 지원되는 경우 스트리밍 응답을 고려합니다.

### JSON-RPC 오류

**증상:** 구문 오류, 잘못된 요청 오류

**일반적인 원인:**

1. **서버가 stdout에 잘못 씁니다.**
   * stderr 대신 stdout으로 가는 디버그 출력
   * 불필요한 줄바꿈 또는 공백
   ```typescript
   // Wrong - pollutes stdout
   console.log("Debug info");

   // Correct - use stderr for debug
   console.error("Debug info");
   ```

2. **인코딩 문제:**
   * UTF-8 인코딩 확인
   * BOM 없음(바이트 순서 표시)

3. **메시지 프레이밍:**
   * 각 메시지는 완전한 JSON 개체여야 합니다.
   * 줄 바꿈으로 구분(줄당 하나의 메시지)

## 플랫폼별 문제

### Windows

#### .NET 콘솔 앱/도구

```csharp
// Correct configuration for .NET exe
["my-dotnet-server"] = new McpStdioServerConfig
{
    Command = @"C:\Tools\MyServer\MyServer.exe",  // Full path with .exe
    Args = new List<string>(),
    WorkingDirectory = @"C:\Tools\MyServer",  // Set working directory
    Tools = new List<string> { "*" },
}

// For dotnet tool (DLL)
["my-dotnet-tool"] = new McpStdioServerConfig
{
    Command = "dotnet",
    Args = new List<string> { @"C:\Tools\MyTool\MyTool.dll" },
    WorkingDirectory = @"C:\Tools\MyTool",
    Tools = new List<string> { "*" },
}
```

#### npx 명령

```csharp
// Windows needs cmd /c for npx
["filesystem"] = new McpStdioServerConfig
{
    Command = "cmd",
    Args = new List<string> { "/c", "npx", "-y", "@modelcontextprotocol/server-filesystem", "C:\\allowed\\path" },
    Tools = new List<string> { "*" },
}
```

#### 경로 문제

* 원시 문자열(`@"C:\path"`) 또는 슬래시(`"C:/path"`)를 사용하세요
* 가능하면 경로의 공백 방지
* 공백이 필요한 경우 올바르게 따옴표로 묶어야 합니다.

#### 바이러스 백신/방화벽

Windows Defender 또는 다른 AV는 다음을 차단할 수 있습니다.

* 새 실행 파일
* stdin/stdout을 통해 통신하는 프로세스

**솔루션:** MCP 서버 실행 파일에 대한 제외를 추가합니다.

### macOS

#### 게이트키퍼 차단

```bash
# If the server is blocked
xattr -d com.apple.quarantine /path/to/mcp-server
```

#### Homebrew 경로

```typescript
// GUI apps may not have /opt/homebrew in PATH
mcpServers: {
  "my-server": {
    command: "/opt/homebrew/bin/node",  // Full path
    args: ["/path/to/server.js"],
  },
}
```

### 리눅스

#### 권한 문제

```bash
chmod +x /path/to/mcp-server
```

#### 공유 라이브러리 누락

```bash
# Check dependencies
ldd /path/to/mcp-server

# Install missing libraries
apt install libfoo  # Debian/Ubuntu
yum install libfoo  # RHEL/CentOS
```

## 고급 디버깅

### 모든 MCP 트래픽 캡처

모든 통신을 기록하는 래퍼 스크립트를 만듭니다.

```bash
#!/bin/bash
# mcp-debug-wrapper.sh

LOG="./mcp-debug-$(date +%s).log"
ACTUAL_SERVER="$1"
shift

echo "=== MCP Debug Session ===" >> "$LOG"
echo "Server: $ACTUAL_SERVER" >> "$LOG"
echo "Args: $@" >> "$LOG"
echo "=========================" >> "$LOG"

# Tee stdin/stdout to log file
tee -a "$LOG" | "$ACTUAL_SERVER" "$@" 2>> "$LOG" | tee -a "$LOG"
```

사용하세요.

```typescript
mcpServers: {
  "debug-server": {
    command: "/path/to/mcp-debug-wrapper.sh",
    args: ["/actual/server/path", "arg1", "arg2"],
  },
}
```

### MCP 인스펙터로 검사

공식 MCP 검사기 도구를 사용합니다.

```bash
npx @modelcontextprotocol/inspector /path/to/your/mcp-server
```

다음과 같은 웹 UI를 제공합니다.

* 테스트 요청 보내기
* 응답 보기
* 도구 스키마 검사

### 프로토콜 버전 불일치

서버에서 SDK에서 사용하는 프로토콜 버전을 지원하는지 확인합니다.

```json
// In initialize response, check protocolVersion
{"result":{"protocolVersion":"2024-11-05",...}}
```

버전이 일치하지 않는 경우 MCP 서버 라이브러리를 업데이트합니다.

## 디버깅 검사 목록

문제를 열거나 도움을 요청할 때 다음을 수집합니다.

* [ ] SDK 언어 및 버전
* [ ] CLI 버전(`copilot --version`)
* [ ] MCP 서버 유형(Node.js, Python, .NET, Go, Rust 등)
* [ ] 전체 MCP 서버 구성(비밀 수정)
* [ ] 수동 `initialize` 테스트 결과
* [ ] 수동 `tools/list` 테스트 결과
* [ ] SDK에서 로그 디버그
* [ ] 모든 오류 메시지

## 참고하십시오

* [GitHub Copilot SDK에서 MCP 서버 사용](/ko/copilot/how-tos/copilot-sdk/features/mcp) - 구성 및 설정
* [디버깅 가이드](/ko/copilot/how-tos/copilot-sdk/troubleshooting/debugging) - SDK 전체 디버깅
* [MCP 사양](https://modelcontextprotocol.io/) - 공식 프로토콜 문서