디버깅

디버깅 (Debugging)

Model Context Protocol(MCP) 통합을 디버깅하는 종합 가이드예요. MCP 서버를 개발하거나 애플리케이션에 통합할 때 효과적인 디버깅은 필수이죠. 이 가이드는 MCP 생태계에서 사용 가능한 디버깅 도구와 접근 방식을 다룹니다.

출처: 문서

본문

MCP 서버를 개발하거나 애플리케이션에 통합할 때 효과적인 디버깅은 필수입니다. 이 가이드는 MCP 생태계에서 사용 가능한 디버깅 도구와 접근 방식을 다룹니다.

디버깅 도구 개요

MCP는 서로 다른 수준에서 디버깅하기 위한 여러 도구를 제공해요.

  1. MCP Inspector: 상호작용적이고 전송에 구애받지 않는 테스트 UI예요. stdio 또는 Streamable HTTP 서버에 연결하고, 도구, 프롬프트, 리소스를 호출하며 알림 스트림을 관찰할 수 있어요. 가장 먼저 사용해야 하는 도구입니다.
  2. 서버 로깅: stderr(stdio 전송) 또는 OpenTelemetry(모든 전송)를 통한 구조화된 로그예요. 프로토콜을 통한 로깅(notifications/message)은 프로토콜 버전 2026-07-28부터 폐기 예정입니다.
  3. 클라이언트 개발자 도구: 대부분의 MCP 클라이언트는 로그와 연결 상태를 노출해요. 아래의 Claude Desktop에서 디버깅을 예로 보거나 클라이언트 문서를 확인하세요.

로깅 구현하기

서버 측 로깅

로컬 stdio 전송을 사용하는 서버를 만들 때, stderr(표준 오류)에 기록한 모든 메시지는 호스트 애플리케이션이 자동으로 캡처해요.

로컬 MCP 서버는 stdout(표준 출력)에 로그 메시지를 기록해서는 안 됩니다. 프로토콜 동작을 방해하기 때문이에요.

Streamable HTTP 전송을 사용하는 서버의 경우 stderr는 클라이언트가 캡처하지 않아요. 로그에는 자체 서버 측 로그 집계나 OpenTelemetry를 사용하고, 요청과 SSE 스트림을 검사하려면 표준 HTTP 도구(curl, 브라우저 DevTools Network 패널)를 사용하세요.

아래의 notifications/message 메커니즘은 프로토콜 버전 2026-07-28부터 폐기 예정이에요. 폐기 기간 동안에는 계속 사용할 수 있습니다.

모든 전송에서 서버가 실행 중에 무엇을 하는지 기록하세요.

import logging

from mcp.server import MCPServer

logger = logging.getLogger(__name__)

mcp = MCPServer("reports")


@mcp.tool()
async def fetch_report(report_id: str) -> str:
    """Fetch a report by id."""
    logger.info("Fetching report %s", report_id)
    return f"Report {report_id} is ready."
await server.sendLoggingMessage({
  level: "info",
  data: "Server started successfully",
});

MCP는 여덟 가지 RFC 5424 심각도 수준(debug부터 emergency까지)을 정의해요. 클라이언트는 요청의 _meta에서 io.modelcontextprotocol/logLevel 필드를 설정해 요청별로 로그 메시지를 선택적으로 받습니다. 서버는 이 필드를 생략한 요청에 대해 notifications/message를 보내면 안 됩니다.

기록할 중요한 이벤트:

  • 시작 단계
  • 리소스 접근
  • 도구 실행
  • 오류 조건
  • 성능 지표

흔한 문제

아래 예시는 Claude Desktop의 claude_desktop_config.json을 사용해요. 같은 원칙이 어떤 stdio 기반 MCP 클라이언트에도 적용됩니다.

작업 디렉터리

MCP 클라이언트가 stdio 서버를 실행할 때:

  • 클라이언트의 설정을 통해 실행된 서버의 작업 디렉터리는 정의되지 않을 수 있어요(macOS의 /처럼). 클라이언트가 어디서든 시작될 수 있기 때문이죠.
  • 안정적인 동작을 보장하려면 구성과 .env 파일에 항상 절대 경로를 사용하세요.
  • 명령줄로 서버를 직접 테스트할 때는 작업 디렉터리가 명령을 실행한 위치가 돼요.

예를 들어 claude_desktop_config.json에서:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/username/data"
      ]
    }
  }
}

./data 같은 상대 경로 대신 이렇게 하세요.

환경 변수

stdio로 실행되는 MCP 서버는 제한된 환경 변수 부분집합만 자동으로 상속해요(정확한 집합은 플랫폼에 따라 다름).

기본 변수를 덮어쓰거나 직접 제공하려면 claude_desktop_config.json에 env 키를 지정할 수 있어요.

{
  "mcpServers": {
    "myserver": {
      "command": "mcp-server-myapp",
      "env": {
        "MYAPP_API_KEY": "some_key"
      }
    }
  }
}

서버 시작

흔한 시작 문제:

  1. 경로 문제

    • 잘못된 서버 실행 파일 경로
    • 필수 파일 누락
    • 권한 문제
    • command에 절대 경로를 사용해 보세요
  2. 구성 오류

    • 잘못된 JSON 문법
    • 필수 필드 누락
    • 타입 불일치
  3. 환경 문제

    • 환경 변수 누락
    • 잘못된 변수 값
    • 권한 제한

연결 문제

서버가 연결에 실패할 때:

  1. 클라이언트 로그 확인
  2. 서버 프로세스가 실행 중인지 확인
  3. Inspector로 독립 테스트
  4. 프로토콜 호환성 확인: server/discover를 호출해 서버가 지원하는 프로토콜 버전을 확인하세요. UnsupportedProtocolVersionError(-32022)는 data 필드에 서버가 지원하는 버전을 나열해요.
  5. 요청별 _meta 필드 확인: 모든 요청은 io.modelcontextprotocol/protocolVersion과 io.modelcontextprotocol/clientCapabilities를 담아야 하며, 클라이언트는 io.modelcontextprotocol/clientInfo도 포함해야 해요. 필수 필드 중 하나가 없으면 -32602(Invalid params) 오류로 거부되는데, 이는 다른 많은 잘못된 입력에서도 반환되는 코드예요. 서버가 요청의 clientCapabilities가 선언하지 않은 기능(elicitation 같은)을 필요로 하면, 누락된 기능을 이름 붙인 MissingRequiredClientCapabilityError(-32021)를 반환합니다. 요청의 _meta와 server/discover 응답을 검사해 양쪽이 기대하는 것을 선언했는지 확인하세요.

Claude Desktop에서 디버깅

Claude Desktop은 여러 MCP 클라이언트 중 하나예요. macOS와 Windows에서 사용할 수 있습니다.

서버 상태 확인

채팅 입력의 "Add files, connectors, and more" 더하기 아이콘을 클릭한 다음 Connectors 메뉴 위에 마우스를 올려 연결된 서버와 사용 가능한 도구를 확인하세요.

로그 보기

로그 파일은 다음 위치에 기록됩니다.

  • macOS: ~/Library/Logs/Claude
  • Windows: %APPDATA%\Claude\logs
tail -n 20 -F ~/Library/Logs/Claude/mcp*.log
type "$env:AppData\Claude\logs\mcp*.log"

로그는 다음을 캡처해요.

  • 서버 연결 이벤트
  • 구성 문제
  • 런타임 오류
  • 메시지 교환

Chrome DevTools 사용하기

Claude Desktop 안에서 Chrome 개발자 도구에 접근해 클라이언트 측 오류를 조사할 수 있어요.

  1. allowDevTools를 true로 설정한 developer_settings.json 파일을 만드세요.
echo '{"allowDevTools": true}' > ~/Library/Application\ Support/Claude/developer_settings.json
'{"allowDevTools": true}' | Set-Content "$env:AppData\Claude\developer_settings.json"
  1. DevTools 열기: Command-Option-I(macOS) 또는 Ctrl+Alt+I(Windows)

참고: 두 개의 DevTools 창이 보일 거예요.

  • 메인 콘텐츠 창
  • 앱 타이틀 바 창

Console 패널로 클라이언트 측 오류를 검사하세요.

Network 패널로 다음을 검사하세요.

  • 메시지 페이로드
  • 연결 타이밍

디버깅 워크플로

개발 주기

  1. 초기 개발

    • 기본 테스트에 Inspector 사용
    • 핵심 기능 구현
    • 로깅 지점 추가
  2. 통합 테스트

    • 대상 MCP 클라이언트에서 테스트
    • 로그 모니터링
    • 오류 처리 확인

변경 테스트

변경을 효율적으로 테스트하려면:

  • 구성 변경: MCP 클라이언트 다시 시작
  • 서버 코드 변경: 클라이언트 다시 시작(Claude Desktop에서는 완전히 종료 후 다시 열어야 해요. 창을 닫는 것만으로는 부족해요)
  • 빠른 반복: 개발 중 Inspector 사용

모범 사례

로깅 전략

  1. 구조화된 로깅

    • 일관된 형식 사용
    • 컨텍스트 포함
    • 타임스탬프 추가
    • 요청 ID 추적
  2. 오류 처리

    • 스택 트레이스 기록
    • 오류 컨텍스트 포함
    • 오류 패턴 추적
    • 복구 모니터링
  3. 성능 추적

    • 작업 타이밍 기록
    • 리소스 사용 모니터링
    • 메시지 크기 추적
    • 지연 시간 측정

보안 고려 사항

디버깅할 때:

  1. 민감한 데이터

    • 로그 정리
    • 자격 증명 보호
    • 개인 정보 마스킹
  2. 접근 통제

    • 권한 확인
    • 인증 확인
    • 접근 패턴 모니터링

MCP 공격 벡터와 완화책의 전체 설명은 보안 모범 사례를 참고하세요.

도움 얻기

문제가 발생하면:

  1. 첫 단계

    • 서버 로그 확인
    • Inspector로 테스트
    • 구성 검토
    • 환경 확인
  2. 지원 채널

  3. 정보 제공

    • 로그 발췌
    • 구성 파일
    • 재현 단계
    • 환경 세부 사항

더 알아보기 (Learn more)