내 시스템을 Claude에 연결하기 | Custom MCP 서버 만들기
MCP Server Development Plugin으로 날씨 API를 감싸는 MCP 서버를 만들고, Tool 정의의 핵심 구조를 이해합니다
마지막 업데이트: 2026. 8. 13.
Overview
앞 Lesson에서는 Claude in Chrome을 연결해 이미 만들어진 MCP 서버를 사용했습니다. 사내 API나 자체 데이터베이스처럼 공개된 서버가 없는 시스템은 직접 MCP 서버로 만들어 연결해야 합니다.
Anthropic의 MCP Server Development Plugin으로 MCP 서버 프로젝트를 생성하고, 생성된 Tool 정의를 읽은 뒤 Claude Code에 연결합니다.
학습 목표
- MCP Server Development Plugin으로 로컬 stdio MCP 서버 프로젝트를 생성할 수 있습니다
- Tool 정의의 세 요소 (이름 · description · 입력 스키마) 를 읽고 이해합니다
- 직접 만든 MCP 서버를 Claude Code에 연결하고 동작을 확인합니다
시작하기 전 확인사항
- Node.js 20 이상 + Bun 설치 (
bun --version) - Claude Code 인증 완료 (
claude --version) - MCP 연결 Lesson의 Server·Client·Host 구조 이해
- 이 실습은 기존 강의 프로젝트와 무관한 독립 프로젝트로 시작합니다. 새 폴더에서 진행합니다
Step 1: 프로젝트 폴더 준비하기
MCP 서버는 자체 package.json 과 의존성을 갖춘 독립 프로세스입니다. 지금까지 쓰던 강의 프로젝트 (Todo 앱) 와 분리된 새 폴더에서 시작합니다.
- 찾기 쉬운 위치에
weather-mcp폴더 생성- macOS: Finder에서 홈 디렉토리 · 바탕화면 등에
⌘+⇧+N으로 새 폴더 - Windows: 탐색기에서 우클릭 → 새 폴더
- macOS: Finder에서 홈 디렉토리 · 바탕화면 등에
- VS Code에서 폴더 열기:
File > Open Folder(단축키: macOS⌘+O, WindowsCtrl+K Ctrl+O) → 방금 만든weather-mcp폴더 선택 - VS Code 터미널 열기:
⌃+(백틱) 또는 메뉴의Terminal > New Terminal
이제 이 폴더에서 MCP Server Development Plugin 설치와 Claude Code 실행을 이어갑니다.
Step 2: MCP Server Development Plugin 설치하기
mcp-server-dev는 Anthropic 공식 마켓플레이스에서 설치하는 MCP 서버 개발용 Plugin입니다.
/plugin install mcp-server-dev@claude-plugins-official설치 결과에 Plugin이 활성화됐다고 나오면 바로 사용할 수 있습니다. /reload-plugins를 실행하라는 안내가 나올 때만 Plugin을 다시 불러옵니다.
이 Plugin은 원격 HTTP 서버와 로컬 stdio 서버 제작을 모두 안내합니다. 이번 실습에서는 내 컴퓨터에서 실행하는 로컬 stdio 서버를 만듭니다.
Step 3: MCP 서버 프로젝트 생성 요청하기
터미널에서 claude 로 Claude Code를 시작하고 다음과 같이 요청합니다.
/mcp-server-dev:build-mcp-server 도시 이름을 입력하면 현재 날씨 정보 (기온, 풍속, 습도) 를 반환하는 로컬 stdio MCP 서버를 TypeScript 로 만들어줘. 프로젝트 폴더명은 weather-mcp-server 로 해줘. Open-Meteo API 를 사용하고 API 키 없이 동작해야 해.MCP Server Development Skill이 지침을 따라 프로젝트를 만듭니다. 결과 구조는 대략 이렇습니다.
src/index.ts가 MCP 서버 메인 파일입니다.
결과가 매번 다를 수 있습니다
AI가 생성하는 코드는 실행마다 세부 사항이 달라질 수 있습니다. 파일 구조나 변수 이름이 아래 예시와 달라도 정상입니다. 핵심 구조(Tool 정의 · 입출력 스키마 · 서버 연결)가 동일한지가 중요합니다.
Step 4: 생성된 Tool 정의 읽기
src/index.ts 의 Tool 정의가 MCP 서버의 핵심입니다.
server.registerTool(
"get-weather",
{
title: "Get Weather",
description: "도시 이름으로 현재 날씨를 조회합니다",
inputSchema: z.object({
city: z.string().describe("도시 이름 (예: Seoul, Tokyo, New York)"),
}),
},
async ({ city }) => {
// 1. 도시 이름 → 좌표 변환 (Geocoding)
// 2. 좌표 → 날씨 데이터 조회
// 3. content 배열로 결과 반환
}
);Tool 이름
Claude Code가 Tool을 식별하는 ID
역할이 드러나는 이름
설정 객체
Tool의 용도와 입력 계약
title은 선택적 표시명
실행 함수
실제 API 호출 · 데이터 가공
{ content: [...] } 표준 형식 반환
server.registerTool() 의 세 인자로 Tool 인터페이스를 정의합니다server.registerTool() 은 세 개의 인자를 받습니다.
| 인자 | 역할 |
|---|---|
| 이름 | Claude가 이 도구를 식별하는 ID (get-weather) |
| 설정 객체 | title · description · inputSchema 를 담은 메타데이터 |
| 실행 함수 | 실제 동작. API 호출, 데이터 가공 후 결과 반환 |
Tool 정의의 세 요소가 품질을 결정합니다.
description: 이 Tool을 언제 호출할지 알려주는 한 줄 설명입니다. "데이터를 가져옵니다" 처럼 모호하면 Claude가 잘못된 Tool을 고릅니다. "도시 이름으로 현재 날씨를 조회합니다" 처럼 구체적이어야 합니다.inputSchema: Tool이 받을 입력 형태를 미리 선언하는 필드입니다. Zod는 TypeScript에서 입력값의 형태를 코드로 정의하고 검사하는 라이브러리입니다..describe()에 예시까지 넣으면 Claude가 자연어에서 올바른 값을 더 잘 추출합니다.- 실행 함수의 반환: 가장 단순한 예시는
{ content: [{ type: "text", text: "..." }] }처럼 텍스트를 반환하는 형태입니다. 필요하면 이미지·오디오·리소스·structuredContent도 함께 반환할 수 있습니다.
Step 5: Claude Code에 MCP 서버 등록하기
MCP 서버 파일을 만들었지만, Claude Code는 아직 이 파일의 존재를 모릅니다. 한 번 등록해두면, Claude Code가 시작될 때마다 .mcp.json 에 적힌 명령어로 이 파일을 백그라운드에서 자동으로 실행해 둡니다. 이후 Tool을 호출할 때 Claude가 이 프로세스에 요청을 보내고, 돌려받은 응답을 사용합니다. Claude in Chrome 같은 공개 MCP와 작동 원리는 같고, 차이는 내 로컬 파일이라는 점 하나입니다.
다음과 같이 등록합니다.
claude mcp add --scope project weather -- bun run '${CLAUDE_PROJECT_DIR:-.}/weather-mcp-server/src/index.ts'
위 명령어로 현재 프로젝트에 MCP 서버를 등록해줘.명령어가 6 개 부분으로 나뉩니다.
| 부분 | 의미 |
|---|---|
claude mcp add | Claude Code에 MCP 서버를 등록하는 명령 |
weather | 서버 이름. /mcp 에 이 이름으로 표시됨 |
--scope project | 스코프. project = 현재 프로젝트 루트의 .mcp.json 에 저장 |
-- | 구분자. 이 뒤가 서버 실행 명령어 |
bun run | Bun 런타임으로 파일 실행. TypeScript를 컴파일 없이 바로 돌림 |
'${CLAUDE_PROJECT_DIR:-.}/weather-mcp-server/src/index.ts' | .mcp.json이 있는 프로젝트 루트를 기준으로 찾는 서버 파일 경로 |
Claude가 명령어를 실행하면 .mcp.json 에 서버 정보가 저장됩니다.
Step 6: 연결 확인하고 날씨 조회 테스트하기
/mcp를 열어 프로젝트 MCP를 승인하고, weather 서버를 선택해 Reconnect를 실행합니다. 그래도 새 설정이 보이지 않을 때만 Claude Code를 다시 시작합니다.
/mcpweather 서버가 "Connected" 상태면 성공입니다.
이제 Claude에게 날씨를 물어봅니다.
서울 날씨 어때?Claude가 get-weather Tool을 호출해서 Open-Meteo API에서 실시간 데이터를 가져옵니다. 응답에 기온·풍속·습도가 포함되면 성공입니다.
한 단계 더 나아가 여러 도시를 비교합니다.
도쿄랑 뉴욕 날씨 비교해줘Claude가 get-weather 를 두 번 호출해 두 도시 결과를 가져오고 비교합니다. MCP 서버는 데이터만 가져오고, 비교·판단·표현은 Claude가 담당합니다. 이것이 MCP 서버의 역할 경계입니다.
좋은 MCP 서버의 세 가지 원칙
구체적인 Tool 정의로 선택 돕기
Claude는 Tool의 이름·description·입력 스키마와 현재 대화를 함께 보고 무엇을 호출할지 판단합니다. 내가 만든 get-weather도 내장 Tool·다른 MCP의 Tool과 같은 목록에 놓입니다. 역할이 드러나는 이름과 구체적인 설명이 올바른 Tool 선택을 돕습니다.
입력 스키마: Claude 와의 계약
z.string().describe("도시 이름")이라고 정의하면 Claude는 사용자의 자연어에서 도시 이름을 찾아 문자열로 전달하고, 서버는 입력이 문자열인지 검사합니다. .describe("도시 이름 (예: Seoul, Tokyo)")처럼 의미와 예시를 제공하면 Claude가 올바른 인자를 만드는 데 도움이 됩니다.
복잡성은 서버 안에 숨기기
날씨 MCP는 내부적으로 API를 두 번 호출합니다 (Geocoding → Weather). 그러나 Claude가 보는 인터페이스는 city 하나뿐입니다. 좋은 MCP 서버는 외부 시스템의 복잡성(좌표 변환 · 호출 순서 · 에러 처리)을 감추고 Claude에게 단순한 인터페이스만 노출합니다.
핵심 포인트 정리
- MCP Server Development Plugin으로 생성: 만들고 싶은 서버와 전송 방식(stdio 또는 HTTP)을 설명하면 Claude가 프로젝트 구조 · SDK 설정 · Tool 정의를 만듭니다.
- Tool 정의의 세 요소:
description(Claude 선택 근거) ·inputSchema(Claude와의 계약) · 실행 함수의 결과가 명확할수록 Claude가 Tool을 안정적으로 사용합니다. - 프로젝트 스코프로 연결: 프로젝트 상대 경로로
.mcp.json에 등록하면 서버 정의를 팀과 공유할 수 있습니다. 각 팀원은 연결 승인과 의존성·환경 변수·인증을 따로 준비합니다.
FAQ
이어서 배울 내용
CLI로 외부 명령을 실행하고, 공개 MCP를 연결하고, 필요한 MCP 서버를 직접 만드는 방법까지 배웠습니다. 하지만 Tool을 사용할 수 있다고 해서 코드 리뷰나 버그 조사를 매번 같은 순서와 기준으로 수행하는 것은 아닙니다. 다음 Lesson에서는 CLI·MCP에 Skill을 결합해 반복 작업의 절차를 정합니다.
- 도구가 제공하는 가능성과 Skill이 정하는 절차 구분하기
- CLI + Skill, MCP + Skill 워크플로우 설계하기