Claude Code에 파일 검색·번역·내부 API 같은 내 도구를 붙이고 싶은데 방법이 막막할 겁니다. MCP는 스펙 변화가 잦아 오래된 블로그로 MCP 서버 만들기를 따라 하면 깨진 import·구 SSE 방식으로 시간만 날립니다.
Claude Code에 여러 도구를 붙여 써온 관점에서 현재(1.29.0 기준) 동작하는 최소 코드만 정리했습니다. 이 순서대로 가면 최소 MCP 서버 하나를 만들어 Claude Code에서 직접 호출하는 것까지 끝납니다.

1. MCP가 뭐고 왜 직접 만드나
MCP(Model Context Protocol)는 AI 클라이언트와 외부 도구 사이의 USB-C 같은 표준 규격입니다. Claude Code든 Claude Desktop이든 규격만 맞으면 같은 서버를 그대로 꽂아 씁니다. 직접 만드는 이유는 하나입니다. 남이 만든 서버로는 안 되는 내 파일·내 API·내 워크플로를 AI가 직접 만지게 하려는 겁니다.
서버가 노출할 수 있는 요소는 세 가지입니다.
| 요소 | 역할 | 읽기전용 | 예시 |
|---|---|---|---|
| Tools | AI가 호출해 동작 실행 | 아니오 | 파일 쓰기, API 호출, 번역 |
| Resources | AI가 읽어가는 데이터 | 예 | 문서, DB 스냅샷, 로그 |
| Prompts | 재사용 프롬프트 템플릿 | 예 | 리뷰 요청, 요약 지시 |
대부분은 Tools 하나만 만들어도 충분합니다. Resources·Prompts는 AI에게 읽을거리·정형 지시를 미리 심어둘 때만 손대면 됩니다. 그래서 MCP 서버 만들기는 Tool 하나짜리 최소 서버로 시작하는 게 가장 빠릅니다.
2. 준비 + 최소 서버 코드
MCP 서버 만들기의 준비물은 Node.js 18 이상 하나입니다. 패키지 두 개를 깔면 됩니다.
npm install @modelcontextprotocol/sdk zod
@modelcontextprotocol/sdk가 공식 TypeScript SDK고, zod는 입력 스키마 검증용 peer dependency입니다. 아래가 greet라는 tool 하나를 가진 최소 서버 전체 코드입니다.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({ name: "my-server", version: "1.0.0" });
server.registerTool(
"greet",
{ title: "인사", description: "이름을 받아 인사말 반환", inputSchema: { name: z.string() } },
async ({ name }) => ({ content: [{ type: "text", text: `안녕하세요, ${name}님!` }] })
);
const transport = new StdioServerTransport();
await server.connect(transport);
registerTool의 3번째 인자가 실제 동작이고, 반환은 { content: [{ type: "text", text }] } 형태로 고정입니다. Resources는 registerResource, Prompts는 registerPrompt로 같은 패턴을 씁니다. StdioServerTransport는 Claude Code가 이 서버를 자식 프로세스로 실행해 표준입출력으로 통신한다는 뜻입니다.
3. Claude Code에 등록·호출
TypeScript는 실행 전에 빌드가 필요합니다. tsc로 컴파일한 뒤 나온 JS 파일의 전체 경로(absolute path)를 등록합니다.
claude mcp add my-server -- node /full/path/to/dist/server.js
-- 뒤가 서버 실행 명령입니다. stdio가 기본이라 별도 플래그는 없고, 환경변수는 -e KEY=value로 넘깁니다. 등록 스코프는 세 가지입니다.
| 스코프 | 저장 위치 | 공유 범위 | git |
|---|---|---|---|
| local (기본) | ~/.claude.json (프로젝트별) |
나만, 이 프로젝트 | 안 됨 |
project (-s project) |
.mcp.json |
팀 전체 | 커밋 |
user (-s user) |
전역 설정 | 나, 모든 프로젝트 | 안 됨 |
등록 후 claude mcp list로 목록을 보고, Claude Code 안에서 /mcp를 치면 연결 상태와 승인을 확인합니다. 여기까지 초록불이면 대화창에서 "greet로 규니한테 인사해줘"처럼 시키면 tool이 실제로 불립니다. Claude Code를 붙여 쓸 때 놓치기 쉬운 기본 세팅은 Claude Code 필수 설정 가이드에 정리해뒀습니다.

4. 함정 — 여기서 대부분 막힙니다
MCP 서버 만들기에서 사람들이 가장 자주 걸리는 지점은 import 경로입니다. 처음 만들 때 옛 블로그를 따라 @modelcontextprotocol/server를 import 했다가 설치 자체가 안 돼서 한참 헤맸습니다. 그건 미출시 패키지고, 정확한 경로는 @modelcontextprotocol/sdk/server/mcp.js입니다. import 문부터 위 코드 그대로 복사하는 게 안전합니다.
증상: claude mcp add는 됐는데 /mcp에서 서버가 failed로 뜬다.
원인: 90%는 실행 경로 문제입니다. 빌드를 안 했거나, 상대경로를 넣었거나, tsx로 개발하던 감각으로 .ts 경로를 그대로 등록한 경우.
해결: tsc로 빌드한 뒤 dist의 .js 전체 경로를 등록합니다. stderr 로그는 claude --debug mcp로 봅니다.
Windows에서 npx 패키지를 붙일 때는 한 겹 더 감싸야 합니다. claude mcp add my-server -- cmd /c npx -y <패키지>처럼 cmd /c로 래핑하지 않으면 프로세스가 안 뜹니다. 또 원격 서버를 붙일 땐 transport로 Streamable HTTP를 쓰세요. 구 SSE 방식은 deprecated라 예제로 남은 코드를 따라가면 시간만 버립니다. 로컬 개인 도구는 stdio가 정답이고, HTTP는 팀에 서버를 공유할 때만 꺼내는 카드입니다.
Q&A — 자주 보는 질문 5개
Q. Python으로도 만들 수 있나요?
A. 됩니다. mcp 패키지(1.28.1, Python 3.10+)의 FastMCP를 쓰면 됩니다. 개념과 등록 방식은 동일하고 서버 코드 문법만 다릅니다.
Q. mcp add 했는데 Claude Code에 안 붙어요.
A. claude mcp list로 등록 여부, /mcp로 연결 상태를 먼저 확인하세요. stderr는 claude --debug mcp로 봅니다. 90%는 빌드 안 함·상대경로 같은 실행 경로 문제입니다.
Q. stdio랑 HTTP 중 뭘 써야 하나요?
A. 내 PC에서 혼자 쓰는 로컬 도구는 stdio가 정답입니다. 팀·원격 공유가 필요할 때만 Streamable HTTP를 씁니다. 구 SSE는 deprecated니 쓰지 마세요.
Q. 팀원과 서버를 공유하려면요?
A. -s project로 등록하면 .mcp.json 파일이 생깁니다. 이 파일을 git에 커밋하면 팀원이 clone 후 바로 같은 서버를 씁니다.
Q. Claude Desktop에서도 되나요?
A. 됩니다. 서버 코드는 그대로 두고 등록 방법만 다릅니다. Desktop은 설정 파일에 서버를 적는 방식입니다. Claude Code 자체 활용 팁은 Claude Code 활용법 정리를 참고하세요.
MCP 서버 만들기의 핵심은 결국 정확한 import 경로와 빌드된 JS의 전체 경로 등록, 이 둘입니다. 같은 환경이면 위 순서대로 따라가도 무리 없습니다.
설치 환경: Node.js 24, @modelcontextprotocol/sdk 1.29.0
'AI 활용법 > Claude 시리즈' 카테고리의 다른 글
| Claude Code 플러그인 만들기 — 스킬·훅·MCP를 하나로 묶어 배포하기 (0) | 2026.07.21 |
|---|---|
| Claude Code에 MCP 서버 연동하기 — 노션·GitHub·Sentry 붙이는 법 (0) | 2026.07.10 |
| Claude Code Hooks 실전 — 포맷·위험 명령 차단·알림 자동화 5가지 (0) | 2026.07.09 |
| Claude Sonnet 5 vs Opus 4.8 — 기본 모델 바뀌었는데 Opus 계속 써도 되나 (0) | 2026.07.07 |
| Claude Code 서브에이전트 실전 배치 — 역할 분리부터 병렬 3~5개 스윗스팟까지 (0) | 2026.07.06 |
IT 기술과 개발 내용을 포스팅하는 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!