Skip to main content

MCP 서버 디버깅 가이드

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

목차

빠른 진단

Checklist

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

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

MCP 디버그 로깅 사용

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

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 요청을 보냅니다.

# 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

예상 응답:

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

테스트 도구 목록

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

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

예상 응답:

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

대화형 테스트 스크립트

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

#!/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

사용법:

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

일반적인 문제

서버가 시작되지 않음

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

원인 및 솔루션:

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

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

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

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

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

원인 및 솔루션:

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

    mcpServers: {
      "server": {
        // ...
        tools: ["*"],  // Must be "*" or list of tool names
      },
    }
    
  2. 서버는 도구를 노출하지 않습니다.

    • tools/list 요청을 수동으로 테스트
    • 서버가 tools/list 메서드를 구현하는지 확인
  3. 초기화 핸드셰이크가 실패합니다.

    • 서버가 initialize 올바르게 응답해야 합니다.
    • 서버에서 처리해야 합니다. notifications/initialized

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

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

원인 및 솔루션:

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

    // 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. 도구 설명 불분명:

    // 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. 시간 제한 늘리기:

    mcpServers: {
      "slow-server": {
        // ...
        timeout: 300000,  // 5 minutes
      },
    }
    
  2. 서버 성능 최적화:

    • 병목 상태를 식별하기 위한 진행률 로깅 추가
    • 비동기 작업을 고려하세요
    • 차단 I/O가 있는지 확인
  3. 장기 실행 도구의 경우 지원되는 경우 스트리밍 응답을 고려합니다.

JSON-RPC 오류

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

일반적인 원인:

  1. 서버가 stdout에 잘못 씁니다.

    • stderr 대신 stdout으로 가는 디버그 출력
    • 불필요한 줄바꿈 또는 공백
    // Wrong - pollutes stdout
    console.log("Debug info");
    
    // Correct - use stderr for debug
    console.error("Debug info");
    
  2. 인코딩 문제:

    • UTF-8 인코딩 확인
    • BOM 없음(바이트 순서 표시)
  3. 메시지 프레이밍:

    • 각 메시지는 완전한 JSON 개체여야 합니다.
    • 줄 바꿈으로 구분(줄당 하나의 메시지)

플랫폼별 문제

Windows

.NET 콘솔 앱/도구

using GitHub.Copilot;

public static class McpDotnetConfigExample
{
    public static void Main()
    {
        var servers = new Dictionary<string, McpServerConfig>
        {
            ["my-dotnet-server"] = new McpStdioServerConfig
            {
                Command = @"C:\Tools\MyServer\MyServer.exe",
                Args = new List<string>(),
                WorkingDirectory = @"C:\Tools\MyServer",
                Tools = new List<string> { "*" },
            },
            ["my-dotnet-tool"] = new McpStdioServerConfig
            {
                Command = "dotnet",
                Args = new List<string> { @"C:\Tools\MyTool\MyTool.dll" },
                WorkingDirectory = @"C:\Tools\MyTool",
                Tools = new List<string> { "*" },
            }
        };
    }
}
// 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 명령

using GitHub.Copilot;

public static class McpNpxConfigExample
{
    public static void Main()
    {
        var servers = new Dictionary<string, McpServerConfig>
        {
            ["filesystem"] = new McpStdioServerConfig
            {
                Command = "cmd",
                Args = new List<string> { "/c", "npx", "-y", "@modelcontextprotocol/server-filesystem", "C:\\allowed\\path" },
                Tools = new List<string> { "*" },
            }
        };
    }
}
// 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

게이트키퍼 차단

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

Homebrew 경로

import { MCPStdioServerConfig } from "@github/copilot-sdk";

const mcpServers: Record<string, MCPStdioServerConfig> = {
  "my-server": {
    command: "/opt/homebrew/bin/node",
    args: ["/path/to/server.js"],
    tools: ["*"],
  },
};
// GUI apps may not have /opt/homebrew in PATH
mcpServers: {
  "my-server": {
    command: "/opt/homebrew/bin/node",  // Full path
    args: ["/path/to/server.js"],
  },
}

리눅스

권한 문제

chmod +x /path/to/mcp-server

공유 라이브러리 누락

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

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

고급 디버깅

모든 MCP 트래픽 캡처

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

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

LOG="/tmp/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"

사용하세요.

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

MCP 인스펙터로 검사

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

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

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

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

프로토콜 버전 불일치

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

// 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에서 로그 디버그
  • 모든 오류 메시지

참고하십시오