본문 바로가기
2026년 5월 13일2분 읽기

Claude Code에 MCP 서버 등록은 됐는데 도구가 호출되지 않습니다

김
김영삼
조회 1024댓글 4

회사 내부 도구를 Claude Code에 통합하려고 MCP 서버를 만들었는데, 등록은 됐는데 호출이 안 되는 상태입니다.

환경: Claude Code 1.0 GA, macOS 15, MCP SDK @modelcontextprotocol/sdk 1.4, Node 24

현재 상태:

  • ~/.claude/mcp.json에 등록 ✅
  • Claude Code 시작 시 콘솔에 "Loaded MCP server: my-jira-bridge" 로그 ✅
  • /mcp 명령으로 보면 my-jira-bridge가 connected ✅
  • 도구 목록(list_tools)도 정상: create_jira_ticket, search_jira 두 개
  • 그런데 "진행 중인 버그를 Jira에 티켓으로 만들어줘" 같은 요청을 해도 Claude가 그냥 텍스트로만 답합니다
  • 도구가 호출되는 흔적 없음

mcp.json:

{
  "mcpServers": {
    "my-jira-bridge": {
      "command": "node",
      "args": ["/Users/me/work/jira-mcp/dist/index.js"],
      "env": { "JIRA_TOKEN": "..." }
    }
  }
}

도구 정의 (서버 코드):

server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: 'create_jira_ticket',
      description: '새 Jira 티켓을 생성합니다',
      inputSchema: { type: 'object', properties: { title: { type: 'string' } } },
    },
  ],
}))

다른 MCP 서버(filesystem, github)는 잘 호출되는데 제가 만든 것만 안 부릅니다. 무엇을 확인해야 할까요?

댓글 4

김김영삼5개월 전

등록·연결까지 됐는데 모델이 도구를 안 쓰는 패턴은 거의 항상 inputSchema 또는 description 문제입니다. 4가지 순서대로 점검하세요.


1) inputSchema의 required 누락


JSON Schema에서 required가 없으면 LLM이 "어떤 인자가 필수인지" 못 알아서 호출 자체를 회피합니다. 표시된 코드에 빠져있네요.


inputSchema: {
type: 'object',
properties: {
title: { type: 'string', description: '티켓 제목' },
description: { type: 'string', description: '본문' },
priority: { type: 'string', enum: ['low', 'medium', 'high'] },
},
required: ['title'], // ← 필수
additionalProperties: false, // ← 권장
}

2) description이 너무 짧음


"새 Jira 티켓을 생성합니다"만으로는 LLM이 "이걸 언제 써야 하는가"를 판단하기 어렵습니다. "어떤 상황에서 사용", "어떤 정보가 필요한가", "결과로 무엇이 반환되는가"를 명시하세요.


description: `Jira에 새 이슈를 생성합니다. 사용자가 "버그를 티켓으로", "이 이슈를 추적해줘", "Jira에 등록해줘" 같은 의도를 표현하면 이 도구를 사용하세요. title은 필수, description·priority는 선택. 결과로 생성된 티켓의 키(예: PROJ-123)와 URL을 반환합니다.`

LLM이 도구 선택 시 description을 가장 우선시합니다.


3) Claude Code의 도구 허용 권한


Claude Code 1.0 GA부터는 보안 강화로 MCP 도구가 기본적으로 prompt 표시 후 사용자가 허용해야 합니다. 처음 호출 시 권한 요청이 떴는데 무시하거나 거부한 적 없는지 확인하세요.


# 설정 확인
cat ~/.claude/settings.json | jq .permissions

# 또는 명시적 허용
{
"permissions": {
"allowedMcpTools": ["my-jira-bridge:*"]
}
}

4) MCP debug 로그


가장 확실한 진단법입니다. 디버그 모드로 실행하면 모든 MCP 메시지가 stderr로 나옵니다.


# Claude Code 실행 시
claude --mcp-debug

# 또는 환경변수
MCP_DEBUG=1 claude

# 별도 터미널에서 서버 로그도
tail -f ~/.claude/logs/mcp-my-jira-bridge.log

여기서 보통 (a) tools/list 요청이 왔는지, (b) 실제 tools/call이 발생했는지, (c) 발생했다면 어떤 인자로 호출됐는지 명확히 보입니다. 호출 자체가 안 일어나면 description 문제, 호출 후 에러면 inputSchema나 핸들러 문제로 분기됩니다.


1번부터 3번까지 점검하고 그래도 안 되면 4번 로그로 정확한 원인 잡으세요.

데데이터사이언스현5개월 전

저도 사내 MCP 서버 만들면서 비슷한 경험 — 추가로 두 가지 자주 빠뜨리는 포인트:


도구 이름 컨벤션



  • 소문자 + 언더스코어 (snake_case): create_jira_ticket ✅

  • 대문자·하이픈·점·공백 금지: CreateJiraTicket, create-jira-ticket, jira.create ❌

  • 64자 한도

  • 도구 간 이름 충돌: 다른 MCP 서버가 같은 이름의 도구를 노출하면 Claude가 헷갈려서 둘 다 호출 회피합니다. my_jira_create처럼 prefix를 두는 게 안전


stdio vs http transport


command 방식(stdio)으로 등록하셨네요. stdio는 단순하지만 stderr를 출력하면 그게 stdout과 섞여서 MCP 프로토콜이 깨지는 경우가 있습니다. 서버 코드에서 console.log를 절대 쓰지 마시고, console.error(stderr)로만 로깅하세요. 또는 처음부터 SSE/HTTP transport로 만들면 logging이 분리되어 편합니다.


// stdio용 안전한 logging
console.error('[mcp] tools/call received:', JSON.stringify(req))
// ❌ console.log는 절대 금지 — stdout은 MCP 프로토콜 전용
MMCP실험중(guest)5개월 전
OP입니다. 1·2번 적용하니 create_jira_ticket은 잘 호출됩니다! 감사합니다.
그런데 또 다른 도구 search_jira는 여전히 호출이 안 됩니다. inputSchema·description 모두 비슷하게 적었는데요. search_jira는 인자가 JQL 쿼리 문자열 하나뿐인데, 이름 때문일까요? 아니면 도구 두 개가 비슷해서 헷갈리는 걸까요? 디버그 로그에는 tools/list만 보이고 tools/call이 안 옵니다.
김김영삼5개월 전

좋은 후속입니다. "비슷한 도구가 여러 개일 때"의 흔한 함정이 있습니다.


원인 추정 — 도구 선택 모호성


Claude는 "사용자 의도 → 도구 매칭"을 description으로 판단하는데, create_jira_ticket과 search_jira의 description이 비슷한 표현을 쓰면 어느 쪽을 부를지 confidence가 낮아져서 둘 다 호출하지 않고 그냥 텍스트로 답하는 경향이 있습니다.


해결은 description을 명확히 구분되게 작성하는 것:


{
name: 'search_jira',
description: `기존 Jira 이슈를 JQL로 검색합니다.
사용자가 "Jira에서 찾아줘", "X 관련 티켓 보여줘", "이번 주 만든 이슈 리스트" 같은 의도를 표현할 때 사용하세요.
새 티켓 생성이 아닌 조회 전용입니다.
결과로 매칭된 이슈 키·제목·상태의 배열을 반환합니다.`,
inputSchema: {
type: 'object',
properties: {
jql: {
type: 'string',
description: 'JQL 쿼리 (예: "project = PROJ AND status = Open AND created >= -7d")',
},
max_results: { type: 'integer', default: 20, minimum: 1, maximum: 100 },
},
required: ['jql'],
},
}

핵심은 두 도구 description의 첫 문장에서 "생성" vs "검색"이 명확히 구분되는 것. 그리고 "사용자가 ~ 할 때 사용하세요"라는 트리거 문장이 차별화되면 매칭률이 크게 올라갑니다.


tools/list만 오고 tools/call이 안 오는 경우 추가 확인



  • 대화에서 명시적으로 "search_jira 도구로 X 검색해줘"라고 시켜보세요 — 이러면 100% 호출됩니다. 호출되면 description 매칭 문제 확정

  • 여전히 안 되면 inputSchema 검증 실패 가능성 — Claude는 schema 검증 실패 시 silently bail합니다. AJV로 schema 자체 검증해보세요

  • ~/.claude/logs/mcp-*.log에 "Tool schema validation failed" 같은 메시지가 있는지 확인


이 두 도구 패턴이 잡히면 향후 MCP 서버 만들 때 한 번에 통과될 겁니다.

Ctrl+Enter로 등록