{"meta":{"title":"MCP 서버 디버깅 가이드","intro":"이 가이드에서는 Copilot SDK를 사용할 때 MCP(모델 컨텍스트 프로토콜) 서버와 관련된 디버깅 기술에 대해 설명합니다.","product":"GitHub Copilot","breadcrumbs":[{"href":"/ko/copilot","title":"GitHub Copilot"},{"href":"/ko/copilot/how-tos","title":"방법"},{"href":"/ko/copilot/how-tos/copilot-sdk","title":"코필로트 SDK"},{"href":"/ko/copilot/how-tos/copilot-sdk/troubleshooting","title":"Troubleshooting"},{"href":"/ko/copilot/how-tos/copilot-sdk/troubleshooting/mcp-debugging","title":"MCP 디버깅"}],"documentType":"article"},"body":"# MCP 서버 디버깅 가이드\n\n이 가이드에서는 Copilot SDK를 사용할 때 MCP(모델 컨텍스트 프로토콜) 서버와 관련된 디버깅 기술에 대해 설명합니다.\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n## 목차\n\n* [빠른 진단](#quick-diagnostics)\n* [독립적으로 MCP 서버 테스트](#testing-mcp-servers-independently)\n* [일반적인 문제](#common-issues)\n* [플랫폼별 문제](#platform-specific-issues)\n* [고급 디버깅](#advanced-debugging)\n\n## 빠른 진단\n\n### Checklist\n\n자세히 살펴보기 전에 다음 기본 사항을 확인합니다.\n\n* [ ] MCP 서버 실행 파일이 존재하며 실행 가능\n* [ ] 명령 경로가 올바르다(의심할 경우 절대 경로 사용)\n* [ ] 도구가 사용하도록 설정됨(`tools: [\"*\"]` 또는 특정 도구 이름)\n* [ ] 서버가 MCP 프로토콜을 올바르게 구현하여 `initialize`에 응답함\n* [ ] 프로세스를 차단하는 방화벽/바이러스 백신 없음(Windows)\n\n### MCP 디버그 로깅 사용\n\nMCP 서버 구성에 환경 변수를 추가합니다.\n\n```typescript\nmcpServers: {\n  \"my-server\": {\n    type: \"local\",\n    command: \"/path/to/server\",\n    args: [],\n    env: {\n      MCP_DEBUG: \"1\",\n      DEBUG: \"*\",\n      NODE_DEBUG: \"mcp\",  // For Node.js MCP servers\n    },\n  },\n}\n```\n\n## MCP 서버를 독립적으로 테스트\n\n항상 먼저 SDK 외부에서 MCP 서버를 테스트합니다.\n\n### 수동 프로토콜 테스트\n\nstdin을 통해 `initialize` 요청을 보냅니다.\n\n```bash\n# Unix/macOS\necho '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"test\",\"version\":\"1.0\"}}}' | /path/to/your/mcp-server\n\n# Windows (PowerShell)\n'{\"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\n```\n\n**예상 응답:**\n\n```json\n{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{\"tools\":{}},\"serverInfo\":{\"name\":\"your-server\",\"version\":\"1.0\"}}}\n```\n\n### 테스트 도구 목록\n\n초기화 후 도구 목록을 요청합니다.\n\n```bash\necho '{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\",\"params\":{}}' | /path/to/your/mcp-server\n```\n\n**예상 응답:**\n\n```json\n{\"jsonrpc\":\"2.0\",\"id\":2,\"result\":{\"tools\":[{\"name\":\"my_tool\",\"description\":\"Does something\",\"inputSchema\":{...}}]}}\n```\n\n### 대화형 테스트 스크립트\n\nMCP 서버를 대화형으로 디버그하는 테스트 스크립트를 만듭니다.\n\n```bash\n#!/bin/bash\n# test-mcp.sh\n\nSERVER=\"$1\"\n\n# Initialize\necho '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"test\",\"version\":\"1.0\"}}}'\n\n# Send initialized notification\necho '{\"jsonrpc\":\"2.0\",\"method\":\"notifications/initialized\"}'\n\n# List tools\necho '{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\",\"params\":{}}'\n\n# Keep stdin open\ncat\n```\n\n사용법:\n\n```bash\n./test-mcp.sh | /path/to/mcp-server\n```\n\n## 일반적인 문제\n\n### 서버가 시작되지 않음\n\n**증상:** 도구가 표시되지 않고 로그에 오류가 없습니다.\n\n**원인 및 솔루션:**\n\n| 원인                                 | 해결 방법                             |\n| ---------------------------------- | --------------------------------- |\n| 잘못된 명령 경로                          | 절대 경로 사용: `/usr/local/bin/server` |\n| 실행 권한이 없습니다.                       |                                   |\n| `chmod +x /path/to/server`을 실행합니다. |                                   |\n| 누락된 종속성                            | Linux를 사용하여 확인하거나 수동으로 실행         |\n| 작업 디렉터리 문제                         | 구성에서 `cwd`을 설정하세요.                |\n\n**수동으로 실행하여 디버그:**\n\n```bash\n# Run exactly what the SDK would run\ncd /expected/working/dir\n/path/to/command arg1 arg2\n```\n\n### 서버가 시작되지만 도구가 표시되지 않음\n\n**증상:** 서버 프로세스가 실행되지만 사용할 수 있는 도구는 없습니다.\n\n**원인 및 솔루션:**\n\n1. **구성에서 사용하도록 설정되지 않은 도구:**\n\n   ```typescript\n   mcpServers: {\n     \"server\": {\n       // ...\n       tools: [\"*\"],  // Must be \"*\" or list of tool names\n     },\n   }\n   ```\n\n2. **서버는 도구를 노출하지 않습니다.**\n   * `tools/list` 요청을 수동으로 테스트\n   * 서버가 `tools/list` 메서드를 구현하는지 확인\n\n3. **초기화 핸드셰이크가 실패합니다.**\n   * 서버가 `initialize` 올바르게 응답해야 합니다.\n   * 서버에서 처리해야 합니다. `notifications/initialized`\n\n### 도구가 나열되었지만 호출되지 않았습니다.\n\n**증상:** 도구는 디버그 로그에 표시되지만 모델은 이를 사용하지 않습니다.\n\n**원인 및 솔루션:**\n\n1. **프롬프트에는 도구가 명확하게 필요하지 않습니다.**\n\n   ```typescript\n   // Too vague\n   await session.sendAndWait({ prompt: \"What's the weather?\" });\n\n   // Better - explicitly mentions capability\n   await session.sendAndWait({ \n     prompt: \"Use the weather tool to get the current temperature in Seattle\" \n   });\n   ```\n\n2. **도구 설명 불분명:**\n\n   ```typescript\n   // Bad - model doesn't know when to use it\n   { name: \"do_thing\", description: \"Does a thing\" }\n\n   // Good - clear purpose\n   { name: \"get_weather\", description: \"Get current weather conditions for a city. Returns temperature, humidity, and conditions.\" }\n   ```\n\n3. **도구 스키마 문제:**\n   * 유효한 JSON 스키마인지 확인 `inputSchema`\n   * 필수 필드는 배열에 있어야 합니다.`required`\n\n### 시간 제한 오류\n\n**증상:**`MCP tool call timed out` 오류.\n\n**솔루션:**\n\n1. **시간 제한 늘리기:**\n\n   ```typescript\n   mcpServers: {\n     \"slow-server\": {\n       // ...\n       timeout: 300000,  // 5 minutes\n     },\n   }\n   ```\n\n2. **서버 성능 최적화:**\n   * 병목 상태를 식별하기 위한 진행률 로깅 추가\n   * 비동기 작업을 고려하세요\n   * 차단 I/O가 있는지 확인\n\n3. **장기 실행 도구의 경우** 지원되는 경우 스트리밍 응답을 고려합니다.\n\n### JSON-RPC 오류\n\n**증상:** 구문 오류, 잘못된 요청 오류\n\n**일반적인 원인:**\n\n1. **서버가 stdout에 잘못 씁니다.**\n   * stderr 대신 stdout으로 가는 디버그 출력\n   * 불필요한 줄바꿈 또는 공백\n   ```typescript\n   // Wrong - pollutes stdout\n   console.log(\"Debug info\");\n\n   // Correct - use stderr for debug\n   console.error(\"Debug info\");\n   ```\n\n2. **인코딩 문제:**\n   * UTF-8 인코딩 확인\n   * BOM 없음(바이트 순서 표시)\n\n3. **메시지 프레이밍:**\n   * 각 메시지는 완전한 JSON 개체여야 합니다.\n   * 줄 바꿈으로 구분(줄당 하나의 메시지)\n\n## 플랫폼별 문제\n\n### Windows\n\n#### .NET 콘솔 앱/도구\n\n```csharp\n// Correct configuration for .NET exe\n[\"my-dotnet-server\"] = new McpStdioServerConfig\n{\n    Command = @\"C:\\Tools\\MyServer\\MyServer.exe\",  // Full path with .exe\n    Args = new List<string>(),\n    WorkingDirectory = @\"C:\\Tools\\MyServer\",  // Set working directory\n    Tools = new List<string> { \"*\" },\n}\n\n// For dotnet tool (DLL)\n[\"my-dotnet-tool\"] = new McpStdioServerConfig\n{\n    Command = \"dotnet\",\n    Args = new List<string> { @\"C:\\Tools\\MyTool\\MyTool.dll\" },\n    WorkingDirectory = @\"C:\\Tools\\MyTool\",\n    Tools = new List<string> { \"*\" },\n}\n```\n\n#### npx 명령\n\n```csharp\n// Windows needs cmd /c for npx\n[\"filesystem\"] = new McpStdioServerConfig\n{\n    Command = \"cmd\",\n    Args = new List<string> { \"/c\", \"npx\", \"-y\", \"@modelcontextprotocol/server-filesystem\", \"C:\\\\allowed\\\\path\" },\n    Tools = new List<string> { \"*\" },\n}\n```\n\n#### 경로 문제\n\n* 원시 문자열(`@\"C:\\path\"`) 또는 슬래시(`\"C:/path\"`)를 사용하세요\n* 가능하면 경로의 공백 방지\n* 공백이 필요한 경우 올바르게 따옴표로 묶어야 합니다.\n\n#### 바이러스 백신/방화벽\n\nWindows Defender 또는 다른 AV는 다음을 차단할 수 있습니다.\n\n* 새 실행 파일\n* stdin/stdout을 통해 통신하는 프로세스\n\n**솔루션:** MCP 서버 실행 파일에 대한 제외를 추가합니다.\n\n### macOS\n\n#### 게이트키퍼 차단\n\n```bash\n# If the server is blocked\nxattr -d com.apple.quarantine /path/to/mcp-server\n```\n\n#### Homebrew 경로\n\n```typescript\n// GUI apps may not have /opt/homebrew in PATH\nmcpServers: {\n  \"my-server\": {\n    command: \"/opt/homebrew/bin/node\",  // Full path\n    args: [\"/path/to/server.js\"],\n  },\n}\n```\n\n### 리눅스\n\n#### 권한 문제\n\n```bash\nchmod +x /path/to/mcp-server\n```\n\n#### 공유 라이브러리 누락\n\n```bash\n# Check dependencies\nldd /path/to/mcp-server\n\n# Install missing libraries\napt install libfoo  # Debian/Ubuntu\nyum install libfoo  # RHEL/CentOS\n```\n\n## 고급 디버깅\n\n### 모든 MCP 트래픽 캡처\n\n모든 통신을 기록하는 래퍼 스크립트를 만듭니다.\n\n```bash\n#!/bin/bash\n# mcp-debug-wrapper.sh\n\nLOG=\"./mcp-debug-$(date +%s).log\"\nACTUAL_SERVER=\"$1\"\nshift\n\necho \"=== MCP Debug Session ===\" >> \"$LOG\"\necho \"Server: $ACTUAL_SERVER\" >> \"$LOG\"\necho \"Args: $@\" >> \"$LOG\"\necho \"=========================\" >> \"$LOG\"\n\n# Tee stdin/stdout to log file\ntee -a \"$LOG\" | \"$ACTUAL_SERVER\" \"$@\" 2>> \"$LOG\" | tee -a \"$LOG\"\n```\n\n사용하세요.\n\n```typescript\nmcpServers: {\n  \"debug-server\": {\n    command: \"/path/to/mcp-debug-wrapper.sh\",\n    args: [\"/actual/server/path\", \"arg1\", \"arg2\"],\n  },\n}\n```\n\n### MCP 인스펙터로 검사\n\n공식 MCP 검사기 도구를 사용합니다.\n\n```bash\nnpx @modelcontextprotocol/inspector /path/to/your/mcp-server\n```\n\n다음과 같은 웹 UI를 제공합니다.\n\n* 테스트 요청 보내기\n* 응답 보기\n* 도구 스키마 검사\n\n### 프로토콜 버전 불일치\n\n서버에서 SDK에서 사용하는 프로토콜 버전을 지원하는지 확인합니다.\n\n```json\n// In initialize response, check protocolVersion\n{\"result\":{\"protocolVersion\":\"2024-11-05\",...}}\n```\n\n버전이 일치하지 않는 경우 MCP 서버 라이브러리를 업데이트합니다.\n\n## 디버깅 검사 목록\n\n문제를 열거나 도움을 요청할 때 다음을 수집합니다.\n\n* [ ] SDK 언어 및 버전\n* [ ] CLI 버전(`copilot --version`)\n* [ ] MCP 서버 유형(Node.js, Python, .NET, Go, Rust 등)\n* [ ] 전체 MCP 서버 구성(비밀 수정)\n* [ ] 수동 `initialize` 테스트 결과\n* [ ] 수동 `tools/list` 테스트 결과\n* [ ] SDK에서 로그 디버그\n* [ ] 모든 오류 메시지\n\n## 참고하십시오\n\n* [GitHub Copilot SDK에서 MCP 서버 사용](/ko/copilot/how-tos/copilot-sdk/features/mcp) - 구성 및 설정\n* [디버깅 가이드](/ko/copilot/how-tos/copilot-sdk/troubleshooting/debugging) - SDK 전체 디버깅\n* [MCP 사양](https://modelcontextprotocol.io/) - 공식 프로토콜 문서"}