MCP·Skill 운영 실습 예시
연결 장애 진단부터 트리거 디버깅, 보안 감사 후 팀 배포까지 — 운영 단계에서 실제로 마주치는 문제를 난이도순으로 따라가며 익힌다. | ← 레퍼런스 문서로 돌아가기
claude mcp add로 로컬 stdio 서버를 방금 등록했는데, 대화 중에 그 서버의 도구가 전혀 호출되지 않는다. 등록은 됐는지, 프로세스가 제대로 떠 있는지, 어디서 막혔는지 확인하고 싶다. 추측 대신 상태 → 직접 실행 → 로그 순서로 좁혀 나간다.
-
등록 상태와 연결 여부 확인
먼저
claude mcp list로 등록된 서버 목록과 연결 상태를 본다. 이름이 보이지 않으면 등록 자체가 실패한 것이고, 이름은 있으나 연결에 실패했다면 명령·인자·전송 방식 문제다.claude mcp get <name>으로 실제 등록된 command/args/scope를 확인한다.claude mcp list claude mcp get my-server
-
MCP Inspector로 서버를 직접 실행해 테스트
Claude를 거치지 않고 서버를 단독으로 띄워 본다. Inspector는 등록 정보와 똑같은 실행 명령을 받아 서버를 기동하고,
tools/list·resources·prompts를 직접 호출해 응답을 보여 준다. 여기서 도구 목록이 정상적으로 나오면 서버는 멀쩡하고 등록 설정 쪽이 문제다.npx @modelcontextprotocol/inspector python my_server.py
-
로그를 tail로 따라가며 실패 지점 확인
Inspector에서도 서버가 죽거나 응답이 없다면 로그를 본다. macOS에서 Claude Desktop의 MCP 로그는
~/Library/Logs/Claude/에mcp*.log로 쌓인다. 실행 중 새로 들어오는 줄을 보려고tail -f로 따라가며 다시 연결을 시도해, 초기화 단계에서 어떤 오류가 나는지 잡아낸다.tail -f ~/Library/Logs/Claude/mcp*.log
initialize 요청/응답으로 protocolVersion과 capabilities를 협상한 뒤에야 tools/list로 도구 목록을 받아 온다. 이 초기화 핸드셰이크가 실패하면 도구는 하나도 노출되지 않는다. 그래서 "상태 → 단독 실행 → 로그" 순서로 보면, 협상 단계와 서버 자체 동작을 분리해 어느 쪽이 깨졌는지 가려낼 수 있다.
command가 PATH에 없거나, 가상환경 밖의 인터프리터를 가리키거나, 상대 경로를 써서 실행 디렉터리에 따라 깨지는 경우가 흔하다. claude mcp get에 찍힌 명령을 터미널에 그대로 붙여 손으로 실행해 보면 원인이 빠르게 드러난다.
.claude/skills/에 SKILL.md를 두고 작업을 시켰는데, 분명 해당 Skill이 다뤄야 할 요청인데도 Claude가 그 절차를 쓰지 않고 그냥 일반적으로 답한다. 파일은 인식됐는지, description이 발화와 맞물리는지, 호출 자체는 되는지를 하나씩 분리해 확인한다.
-
description에 사용자 발화 키워드가 들어 있는지 점검
Skill 자동 호출은 frontmatter의
description만 보고 결정된다. 본문은 트리거된 뒤에야 로드되므로, "무엇을 + 언제 사용"이 description에 없으면 절대 불려 나오지 않는다. 사용자가 실제로 쓰는 표현(예: "보고서를 엑셀로", "PR 리뷰")이 description에 3인칭으로 구체적으로 담겼는지 확인한다.--- name: excel-report description: Generates .xlsx spreadsheets from tabular data. Use when the user asks to export results to Excel, build a report sheet, or convert a table into a spreadsheet. ---
-
claude --debug로 YAML 파싱 확인
description이 멀쩡해 보여도 frontmatter YAML이 깨졌으면 Skill은 메타데이터 단계에서 아예 로드되지 않는다.
claude --debug로 띄우면 Skill을 읽어 들이는 과정과 YAML 파싱 결과가 로그에 찍힌다. 들여쓰기 오류, 누락된---구분선, 64자/1024자 제한 위반 등을 여기서 잡는다.claude --debug
-
직접 호출로 격리 테스트
로드는 됐지만 자동 트리거가 안 되는지, 아니면 Skill 본문 자체에 문제가 있는지 가르려면 슬래시 명령으로 직접 불러 본다. 직접 호출에서는 잘 동작하는데 자연어로는 안 불려 나온다면 원인은 본문이 아니라 description의 트리거 표현에 있다.
/excel-report 분기 매출 표를 스프레드시트로 만들어줘
-
description 수정 후 재확인
격리 테스트로 "본문은 정상, 트리거가 문제"임이 확인되면 description을 손본다. 사용자가 실제로 쓰는 동사·명사를 더 넣고, 모호한 일반어 대신 구체적인 상황을 적는다. 수정 후 같은 발화로 자동 호출이 되는지 다시 검증한다.
description: ... Use when the user mentions Excel, xlsx, spreadsheet, 매출표, 보고서 시트, or asks to export a table to a workbook.
name에 예약어인 anthropic·claude를 쓰거나 64자·1024자 제한을 넘기면 로드 자체가 막힌다. 키워드는 "이 Skill이 진짜 담당하는 상황"으로 한정해 추가한다.
.mcp.json과 플러그인 경로로 일괄 배포한다.
-
번들 코드와 도구 설명을 직접 검토
MCP 서버 소스와 Skill의 SKILL.md·
scripts/를 사람이 읽어 본다. tool 설명(inputSchema 포함)에 숨은 악성 지시가 없는지(prompt injection), 외부 URL로 데이터를 빼돌리는 호출이 없는지, 파일 삭제·셸 실행 등 권한 상승 동작이 없는지 확인한다. 임의 코드가 들어갈 수 있는 스크립트는 한 줄씩 본다.grep -rEn "https?://|curl|wget|subprocess|os\.system|eval|exec" server/ skill/
-
비밀키를 env로 분리
API 키·토큰을 소스나 인자에 박지 않고 환경변수로 주입한다. 원격 HTTP 전송 서버는 인증 토큰을
--header(예:Authorization: Bearer $TOKEN)로 분리하고, stdio 서버의 경우에만env블록에 키를 두어 각자의 셸 환경이나 비밀 관리 도구에서 값을 채운다. 그래야 공유 설정 파일(.mcp.json)을 git에 올려도 비밀이 새지 않는다.claude mcp add --transport http team-api https://api.internal.example.com \ --header "Authorization: Bearer $TEAM_API_TOKEN"
-
SSRF·injection 등 공격 표면 점검
원격 HTTP 서버라면 SSRF를 막는다. 내부 IP 대역과 클라우드 메타데이터 주소(
169.254.169.254)로의 요청을 차단하는지 확인한다. 더불어 OAuth confused deputy, 비결정적 session id를 통한 세션 하이재킹, tool 설명을 통한 prompt injection도 점검 항목에 넣는다. 실행 전 동의 프롬프트를 끄지 않는다.curl -s http://169.254.169.254/latest/meta-data/ # 서버 경유 시 차단되어야 정상
-
.mcp.json과 플러그인으로 배포
감사를 통과한 MCP 서버는 프로젝트 루트의
.mcp.json에 넣어 git으로 공유하면 팀원이 같은 설정으로 연결된다. Skill 번들은 마켓플레이스 등록 후 플러그인으로 설치하거나.claude/skills/에 커밋해 배포한다./plugin marketplace add our-org/claude-tools /plugin install team-skills@our-org
Claude Docs · Claude Code 2026-06 기준 (MCP 스펙 2025-11-25 / 프로토콜 2025-06-18) | 2026년 6월 27일 작성
← 운영 레퍼런스