내 시스템을 Claude 에 연결하기 | Custom MCP 서버 만들기
MCP Builder Skill 로 날씨 API 를 감싸는 MCP 서버를 직접 만들고, Tool 정의의 핵심 구조를 이해합니다
Overview
앞 레슨에서 Claude in Chrome 과 Figma MCP 를 붙여봤습니다. 공개된 MCP 는 대부분 이렇게 설치만으로 바로 쓸 수 있습니다. 그런데 사내 API 나 자체 데이터베이스 처럼 세상에 공개된 MCP 서버가 없는 경우는 어떻게 할까요?
이번 레슨은 Anthropic 의 MCP Builder Skill 로 MCP 서버 프로젝트를 자동 생성하고, 생성된 Tool 정의를 읽어보며 MCP 서버의 세 가지 핵심 원칙을 체득합니다. 실습 대상은 API 키 없이 쓸 수 있는 Open-Meteo 날씨 API 라, MCP 서버 구조 자체에 집중 할 수 있습니다.
학습 목표
- MCP Builder Skill 로 MCP 서버 프로젝트를 생성할 수 있습니다
- Tool 정의의 세 요소 (이름 · description · 입력 스키마) 를 읽고 이해합니다
- 직접 만든 MCP 서버를 Claude Code 에 연결하고 동작을 확인합니다
시작하기 전 확인사항
- Node.js 20 이상 + Bun 설치 (
bun --version) - Claude Code 인증 완료 (
claude --version) - 이 실습은 기존 강의 프로젝트와 무관한 독립 프로젝트 로 시작합니다. 새 폴더에서 진행합니다
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 - 터미널에서
pwd로 경로가.../weather-mcp로 끝나는지 확인
이제 이 폴더에서 MCP Builder Skill 설치와 Claude Code 실행을 이어갑니다.
Step 2: MCP Builder Skill 설치하기
MCP Builder 는 Anthropic 이 공식 제공하는 Skill 입니다. VS Code 터미널에서 다음 명령어를 실행합니다.
npx skills add anthropics/skills --skill mcp-builder이 명령어는 .claude/skills/mcp-builder/ 에 Skill 폴더를 설치합니다. 이후 Claude Code 에서 /mcp-builder 로 호출할 수 있습니다.
Step 3: MCP 서버 프로젝트 생성 요청하기
터미널에서 claude 로 Claude Code 를 시작하고 다음과 같이 요청합니다.
/mcp-builder 도시 이름을 입력하면 현재 날씨 정보 (기온, 풍속, 습도) 를 반환하는 MCP 서버를 TypeScript 로 만들어줘. 프로젝트 폴더명은 weather-mcp-server 로 해줘. Open-Meteo API 를 사용하고 API 키 없이 동작해야 해.MCP Builder Skill 의 지침을 따라 프로젝트가 자동 생성됩니다. 결과 구조는 대략 이렇습니다.
weather-mcp/
└── weather-mcp-server/
├── package.json
├── src/
│ └── index.ts # MCP 서버 메인 파일
└── README.md결과가 매번 다를 수 있습니다
AI 가 생성하는 코드는 실행마다 세부 사항이 달라질 수 있습니다. 파일 구조나 변수 이름이 아래 예시와 달라도 정상입니다. 핵심 구조(Tool 정의 · 입출력 스키마 · 서버 연결)가 동일한지가 중요합니다.
Step 4: 생성된 Tool 정의 읽기
src/index.ts 의 Tool 정의 부분이 MCP 서버의 심장입니다.
server.registerTool(
"get-weather",
{
title: "Get Weather",
description: "도시 이름으로 현재 날씨를 조회합니다",
inputSchema: {
city: z.string().describe("도시 이름 (예: Seoul, Tokyo, New York)"),
},
},
async ({ city }) => {
// 1. 도시 이름 → 좌표 변환 (Geocoding)
// 2. 좌표 → 날씨 데이터 조회
// 3. content 배열로 결과 반환
}
);Tool 이름
Claude 가 이 도구를 식별하는 ID
동사 + 명사 형태로 명확하게
설정 객체
Claude 의 선택 근거와 입력 계약
description 이 가장 중요
실행 함수
실제 API 호출 · 데이터 가공
{ content: [...] } 표준 형식 반환
server.registerTool() 의 세 인자가 Tool 의 품질을 결정합니다server.registerTool() 은 세 개의 인자를 받습니다.
| 인자 | 역할 |
|---|---|
| 이름 | Claude 가 이 도구를 식별하는 ID (get-weather) |
| 설정 객체 | title · description · inputSchema 를 담은 메타데이터 |
| 실행 함수 | 실제 동작. API 호출, 데이터 가공 후 결과 반환 |
Tool 정의의 세 요소가 품질을 결정합니다.
description: 이 Tool 을 언제 호출할지 알려주는 한 줄 설명. "데이터를 가져옵니다" 처럼 모호하면 잘못된 선택을 유도합니다. "도시 이름으로 현재 날씨를 조회합니다" 처럼 구체적이어야 합니다inputSchema: Tool 이 받을 입력 형태를 미리 선언하는 필드. Zod 로 정의합니다..describe()에 예시까지 넣으면 Claude 가 자연어에서 올바른 값을 더 잘 추출합니다- 실행 함수의 반환: 반드시
{ content: [{ type: "text", text: "..." }] }형식. 이 표준 형식 덕분에 모든 MCP 서버의 응답을 Claude Code 가 같은 방식으로 처리합니다
Step 5: Claude Code 에 MCP 서버 등록하기
MCP 서버 파일을 만들었지만, Claude Code 는 아직 이 파일의 존재를 모릅니다. 한 번 등록해두면, Claude Code 가 시작될 때마다 .mcp.json 에 적힌 명령어로 이 파일을 백그라운드에서 자동으로 실행 해 둡니다. 이후 Tool 을 호출할 때 Claude 가 이 프로세스에 요청을 보내고, 돌려받은 응답을 사용합니다. Claude in Chrome · Figma MCP 같은 공개 MCP 와 작동 원리는 같고, 차이는 내 로컬 파일이라는 점 하나입니다.
다음과 같이 등록합니다.
claude mcp add weather -s project -- bun run "$(pwd)/weather-mcp-server/src/index.ts"
위 명령어로 현재 프로젝트에 MCP 서버를 등록해줘.명령어가 6 개 부분으로 나뉩니다.
| 부분 | 의미 |
|---|---|
claude mcp add | Claude Code 에 MCP 서버를 등록하는 명령 |
weather | 서버 이름. /mcp 에 이 이름으로 표시됨 |
-s project | 스코프. project = 현재 프로젝트 루트의 .mcp.json 에 저장 |
-- | 구분자. 이 뒤가 서버 실행 명령어 |
bun run | Bun 런타임으로 파일 실행. TypeScript 를 컴파일 없이 바로 돌림 |
"$(pwd)/weather-mcp-server/src/index.ts" | 서버 소스 파일 절대 경로 ($(pwd) 는 현재 폴더로 치환) |
Claude 가 명령어를 실행하면 .mcp.json 에 서버 정보가 저장됩니다.
Step 6: 연결 확인하고 날씨 조회 테스트하기
MCP 설정은 Claude Code 가 시작될 때 한 번 읽습니다. /exit 로 나가서 다시 claude 를 실행합니다.
/mcpweather 서버가 "Connected" 상태면 성공입니다. 연결에 실패하면 경로가 절대 경로인지, bun 이 PATH 에 있는지, package.json 에 "type": "module" 이 있는지 확인합니다.
이제 Claude 에게 날씨를 물어봅니다.
서울 날씨 어때?Claude 가 get-weather Tool 을 호출해서 Open-Meteo API 에서 실시간 데이터를 가져옵니다. 응답에 기온·풍속·습도가 포함되면 성공입니다.
한 단계 더 나아가 여러 도시를 비교합니다.
도쿄랑 뉴욕 날씨 비교해줘Claude 가 get-weather 를 두 번 호출해 두 도시 결과를 가져오고 비교합니다. MCP 서버는 데이터만 가져오고, 비교·판단·표현은 Claude 가 담당합니다. 이것이 MCP 서버의 역할 경계입니다.
좋은 MCP 서버의 세 가지 원칙
직접 만들어 보고 나면 원칙이 보입니다.
description 이 Tool 선택을 결정하기
Claude 는 사용자 질문과 여러 Tool 의 description 을 비교해서 무엇을 호출할지 판단합니다. 내가 만든 get-weather 도 내장 Tool · 다른 MCP 의 Tool 과 같은 목록에서 함께 경쟁합니다. "날씨" 라는 단어가 없으면 "서울 날씨 어때?" 에 이 Tool 을 선택하지 않습니다. 모호한 설명은 곧 잘못된 Tool 선택으로 이어집니다.
입력 스키마: Claude 와의 계약
z.string().describe("도시 이름") 이라고 정의하면, Claude 는 사용자의 자연어에서 도시 이름을 추출해 문자열로 전달합니다. 스키마가 명확할수록 추출 정확도가 올라갑니다. .describe("도시 이름 (예: Seoul, Tokyo)") 처럼 예시까지 넣으면 추출 정확도가 더 올라갑니다.
복잡성은 서버 안에 숨기기
날씨 MCP 는 내부적으로 API 를 두 번 호출합니다 (Geocoding → Weather). 그러나 Claude 가 보는 인터페이스는 city 하나뿐입니다. 좋은 MCP 서버는 외부 시스템의 복잡성(좌표 변환 · 호출 순서 · 에러 처리)을 감추고 Claude 에게 단순한 인터페이스만 노출합니다.
핵심 포인트 정리
- MCP Builder Skill 로 자동 생성: 만들고 싶은 서버를 설명하면 Claude 가 프로젝트 구조 · SDK 설정 · Tool 정의까지 전체를 만듭니다. 개발자는 설계 의도만 전달하면 됩니다.
- Tool 정의의 세 요소:
description(Claude 선택 근거) ·inputSchema(Claude 와의 계약) ·content배열 출력(MCP 표준 형식) 이 셋이 명확할수록 Claude 의 호출 정확도가 올라갑니다. claude mcp add한 줄로 연결: 절대 경로로 등록하고 새 세션에서 확인합니다..mcp.json에 저장되므로 팀원이 저장소를 받으면 같은 설정이 즉시 동작합니다.
FAQ
-
Q: MCP Builder Skill 없이 직접 코드를 작성해도 되나요?
- A: 가능합니다.
@modelcontextprotocol/sdk패키지를 설치하고 직접 작성할 수 있습니다. MCP Builder Skill 은 반복 코드(프로젝트 구조 · SDK 설정 · 의존성)를 자동화할 뿐, 핵심 로직은 어느 쪽이든 개발자가 설계해야 합니다.
- A: 가능합니다.
-
Q: 하나의 MCP 서버에 Tool 을 여러 개 넣을 수 있나요?
- A: 가능합니다.
server.registerTool()을 여러 번 호출하면 됩니다. 다만 Tool 이 많아질수록 설명이 Context 를 더 소비하고, Claude 의 선택 정확도가 떨어질 수 있습니다. 관련된 기능만 하나의 서버에 묶습니다.
- A: 가능합니다.
-
Q: API 키가 필요한 서비스를 감싸려면 어떻게 하나요?
- A: 환경 변수로 전달합니다.
claude mcp add에-e API_KEY=your-key옵션을 붙이면 서버 프로세스에 환경 변수가 주입됩니다. 코드에서는process.env.API_KEY로 읽습니다. API 키를 코드에 직접 넣으면.mcp.json을 공유할 때 유출될 수 있으므로 주의합니다.
- A: 환경 변수로 전달합니다.
-
Q: 직접 만든 MCP 와 공개 MCP 의 차이가 있나요?
- A: 기술적으로 동일합니다. Claude Code 입장에서 같은 MCP 프로토콜을 따르므로 구분이 없습니다. 직접 만드는 이유는 사내 시스템 · 자체 API 처럼 공개 서버가 없는 경우뿐입니다.
이어서 배울 내용
CLI, MCP, Custom MCP 로 외부 시스템에 닿는 세 가지 길을 다 배웠습니다. 그런데 도구에 접근할 수 있는 것과, 그 도구를 매번 같은 방식으로 쓰는 것 은 다른 문제입니다. 다음 레슨에서는 외부 도구에 Skill 을 결합해서 반복 워크플로우를 일관되게 만드는 방법을 배웁니다.
- 도구 (Capability) 와 사용법 (Procedure) 의 분리
- CLI + Skill 결합 워크플로우 사례
- MCP + Skill 결합 워크플로우 사례