"Claude Code에서 내가 만든 함수를 AI가 직접 호출하게 할 수 있다고?"
저도 처음 MCP 개념을 접했을 때 반신반의했습니다. 근데 실제로 해보니까 생각보다 훨씬 간단했어요. Python 파일 하나, 명령어 한 줄이면 됩니다. 이 글에서는 MCP 서버가 뭔지 짧게 짚고, Python으로 서버를 만든 다음 Claude Code에 연결하는 전체 과정을 순서대로 정리했습니다. 중간에 막히는 포인트도 같이 다룹니다.
MCP가 뭔지 30초만에 이해하기
MCP(Model Context Protocol)는 Anthropic이 2024년 오픈소스로 공개한 프로토콜입니다. 공식 문서에서 "AI용 USB-C 포트"라고 표현하는데, 딱 맞는 비유예요. USB-C가 노트북이든 폰이든 어댑터 없이 꽂히듯, MCP는 Claude Code가 어떤 외부 도구든 같은 방식으로 연결하게 해줍니다.
구조는 세 계층입니다.
- MCP Host: AI 앱 자체. Claude Code, Claude Desktop, VS Code 같은 것들.
- MCP Client: Host 내부에서 서버와 1:1로 붙는 컴포넌트. SDK가 알아서 처리해줘서 신경 안 써도 됩니다.
- MCP Server: 여러분이 만들 프로그램. 도구(Tools), 리소스(Resources), 프롬프트(Prompts)를 Claude에 제공하는 역할.
2026년 현재 공개된 MCP 서버가 13,000개를 넘겼고, Claude·ChatGPT·VS Code·Cursor 등 주요 플랫폼이 전부 지원합니다. 이미 사실상의 표준이 됐습니다.
Python으로 MCP 서버 만들기 (FastMCP)
환경 준비
Python 3.10 이상이 필요합니다. 패키지 매니저는 uv를 씁니다. pip보다 빠르고, MCP 공식 문서도 uv를 기본으로 안내합니다.
# uv 설치 (Windows PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# 프로젝트 생성
uv init my-mcp-server
cd my-mcp-server
uv venv
.venv\Scripts\activate # Windows
# source .venv/bin/activate # macOS/Linux
uv add "mcp[cli]"
SDK 버전은 stable 기준 1.x입니다. 2.0.0a3 같은 pre-release 버전은 프로덕션에서 쓰지 마세요.
가장 간단한 서버: 두 수를 더하는 도구
# server.py
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("my-server")
@mcp.tool()
def add(a: int, b: int) -> int:
"""두 정수를 더한다."""
return a + b
if __name__ == "__main__":
mcp.run(transport="stdio")
@mcp.tool() 데코레이터 하나로 함수가 도구로 등록됩니다. Python 타입 힌트와 docstring으로 JSON 스키마가 자동 생성되기 때문에, 스키마를 손으로 작성할 필요가 없어요. FastMCP가 다 해줍니다.
외부 API를 쓰는 서버 예시
실제로 쓸 만한 건 HTTP 요청이 들어갑니다. httpx를 추가로 설치하면 됩니다.
uv add httpx
# weather.py
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("weather")
NWS_API_BASE = "https://api.weather.gov"
async def make_nws_request(url: str) -> dict[str, Any] | None:
headers = {"User-Agent": "weather-app/1.0", "Accept": "application/geo+json"}
async with httpx.AsyncClient() as client:
try:
response = await client.get(url, headers=headers, timeout=30.0)
response.raise_for_status()
return response.json()
except Exception:
return None
@mcp.tool()
async def get_alerts(state: str) -> str:
"""미국 주별 기상 경보 조회. state: 두 글자 주 코드 (예: CA, NY)"""
url = f"{NWS_API_BASE}/alerts/active/area/{state}"
data = await make_nws_request(url)
if not data or "features" not in data:
return "경보 정보를 가져올 수 없습니다."
if not data["features"]:
return "해당 주에 활성 경보 없음."
return f"{len(data['features'])}개 경보 발견"
def main():
mcp.run(transport="stdio")
if __name__ == "__main__":
main()
서버 실행: uv run weather.py
Claude Code에 MCP 서버 연결하기
서버 파일을 만들었으면 Claude Code에 등록해야 합니다. 명령어 한 줄입니다.
# 로컬 stdio 서버 등록
claude mcp add my-server -- python /절대경로/server.py
# uv로 실행하는 경우
claude mcp add my-server -- uv --directory /절대경로/프로젝트 run server.py
# 등록 확인
claude mcp list
절대경로를 써야 한다는 점이 중요합니다. MCP 클라이언트가 서버를 시작할 때 작업 디렉터리가 예측 불가능해서, 상대경로(./server.py)로 쓰면 연결에 실패할 수 있어요.
스코프 설정: 나만 쓸지, 팀이랑 쓸지
# 내 모든 프로젝트에서 사용 (user 스코프)
claude mcp add --scope user my-server -- python /절대경로/server.py
# 팀 전체와 공유 (project 스코프 → .mcp.json 생성 → git 커밋)
claude mcp add --scope project my-server -- python /절대경로/server.py
| 스코프 | 저장 위치 | 적용 범위 |
|---|---|---|
| local (기본) | ~/.claude.json |
나, 현재 프로젝트만 |
| user | ~/.claude.json |
나, 모든 프로젝트 |
| project | .mcp.json (프로젝트 루트) |
git 커밋하면 팀 전체 |
초보자가 반드시 알아야 할 실수 3가지
1. STDIO 서버에서 print() 쓰기 (가장 흔한 실수)
STDIO 트랜스포트는 표준 입출력 스트림으로 통신합니다. print()로 stdout에 뭔가를 출력하는 순간 JSON-RPC 스트림이 오염되고, 연결이 끊깁니다. 공식 문서도 명시적으로 경고하는 내용입니다.
# 잘못된 방법
print("처리 중...") # stdout → 프로토콜 파괴
# 올바른 방법
import sys
print("처리 중...", file=sys.stderr) # stderr로만 출력
import logging
logging.info("처리 중...") # logging은 기본적으로 stderr 사용
저도 처음에 이거 때문에 한참 헤맸습니다. 연결은 되는데 도구 호출하면 계속 오류 나는 상황이면 일단 print()부터 확인하세요.
2. 코드 수정 후 재시작 안 하기
server.py를 수정하고 Claude Code를 그냥 두면 변경사항이 반영되지 않습니다. MCP 클라이언트(Claude Code)를 완전히 재시작해야 해요. 창만 닫는 게 아니라 프로세스 종료 후 재실행까지 해야 합니다.
3. 환경 변수 빠뜨리기
API 키 같은 환경 변수는 STDIO 서버에 자동 상속되지 않습니다. .mcp.json에 명시적으로 넣어줘야 해요.
{
"mcpServers": {
"my-server": {
"command": "python",
"args": ["/절대경로/server.py"],
"env": {
"MY_API_KEY": "실제_키값"
}
}
}
}
만든 서버, 어디서 디버깅하나
개발 중엔 MCP Inspector를 씁니다. 브라우저에서 서버를 직접 테스트할 수 있어요.
npx @modelcontextprotocol/inspector uv run server.py
연결 상태는 Claude Code 세션 안에서 /mcp 명령으로 확인합니다. ✓ Connected면 정상, ✗ Failed to connect면 서버 명령어를 직접 터미널에서 실행해서 오류 메시지를 확인하세요.
서버를 완성했다면, 다음 단계는
혼자 쓸 도구면 .mcp.json에 등록해서 git으로 팀과 공유하면 됩니다. 공개 배포까지 생각하면 npm 패키지(npx로 설치 없이 실행)나 PyPI 패키지(uvx로 실행) 형태로 만드는 게 편합니다.
2026년 6월 기준으로 Smithery(smithery.ai)에는 7,300개 이상의 MCP 서버가 등록돼 있고, 월 43만 명의 개발자가 사용 중입니다. 원격 HTTP 서버를 만들어 배포하려면 VPS가 필요한데, Vultr처럼 저렴하게 시작할 수 있는 옵션을 쓰는 개발자들이 많습니다.
FastMCP로 10줄짜리 서버 하나 만들어보는 게 이 모든 것의 시작입니다. 직접 해보면 "이게 이렇게 간단했어?" 싶을 거예요.
관련해서 읽어볼 글
- Claude Code 기본 사용법 정리
- MCP 공식 레지스트리에서 도구 찾는 법
'AI활용' 카테고리의 다른 글
| Claude Code Teleport 완전 정리: 웹 세션을 로컬로 가져오는 법 (0) | 2026.07.02 |
|---|---|
| Cursor iOS 앱 완벽 가이드 — 모바일에서 AI 코딩 에이전트 굴리는 법 (0) | 2026.07.01 |
| Cursor Rules vs CLAUDE.md — AI 지시 파일 완전 비교 2026 (0) | 2026.06.29 |
| Claude Code Skills 완벽 가이드 2026 — 슬래시 커맨드로 반복 작업 자동화하기 (0) | 2026.06.29 |
| CLAUDE.md 완벽 가이드 2026 — AI가 내 규칙을 기억하게 만드는 법 (0) | 2026.06.29 |
