MCP Server 처음부터 개발하기: AI 도구 호출 능력 완전 가이드

2026년 현재 MCP 생태계에는 10,000개 이상의 Server가 등록되어 있으며, Cursor, Claude Desktop, VS Code가 네이티브로 지원합니다. 본 글은 프로토콜 원리부터 Tools / Resources / Prompts 3대 역량, HTTP 원격 배포개인 지식베이스 실습까지 다루며, 프로덕션 수준의 MCP Server를 독립적으로 구현할 수 있도록 안내합니다.

대규모 언어 모델이 아무리 강력해도 사용자 DB를 직접 조회하거나 내부 API를 호출하고 로컬 파일을 읽는 것은 불가능합니다. 결국 필요한 것은 표준화된 도구 호출 채널입니다. MCP(Model Context Protocol)는 Anthropic이 오픈소스로 공개한 개방 프로토콜로, Claude / GPT / Cursor가 동일한 JSON-RPC 체계로 여러분이 작성한 Server를 발견하고 호출할 수 있게 합니다. 본 글은 Python 또는 TypeScript 기초를 갖춘 백엔드·AI 엔지니어를 대상으로 합니다. ① MCP 프로토콜 아키텍처와 통신 메커니즘 이해, ② 개발 환경 구축과 Hello World 작성, ③ Tools·Resources·Prompts 3대 역량 개발, ④ HTTP 전송과 프로덕션 배포 심화, ⑤ 개인 지식베이스 실습 프로젝트 완료. 프로토콜 배경은 MCP 심층 해설, Cursor Agent Skills 가이드와 함께 읽으면 좋습니다.

00AI에 MCP가 필요한 이유: Function Calling에서 개방 프로토콜까지

기존 AI 모델이 「똑똑하지 못한」 근본 원인은 외부 도구와 실시간 데이터에 접근할 수 없기 때문입니다. Claude가 DB를 조회하고, GPT가 API를 호출하고, Cursor가 파일 시스템을 다루게 하려는 요구가 바로 MCP가 풀려는 문제입니다. 도구 호출 능력은 Function Calling → Plugins → MCP로 진화했습니다. Function Calling은 단일 벤더에 묶이고, Plugins 생태계는 폐쇄적이며, MCP는 크로스 모델·크로스 클라이언트 개방 표준을 제공합니다.

Anthropic은 2024년 11월 MCP를 설계했으며, 핵심 목표는 AI와 외부 도구 간 통신 프로토콜 표준화로 N개 모델 × M개 도구 = N×M 커스텀 통합 지옥을 해소하는 것입니다. 본 글을 마치면 프로덕션 수준의 MCP Server를 독립적으로 개발·배포할 수 있습니다.

고충MCP 없을 때 도구 통합이 얼마나 고통스러운가

  • 반복 구현: Cursor, Claude Desktop, VS Code 각각에 파일 시스템 연동 로직을 따로 작성해야 합니다.
  • 모델 교체 시 전면 재작성: Claude에서 GPT로 옮기면 통합 계층을 처음부터 다시 짜야 합니다.
  • 리소스·프롬프트 표준 부재: Function Calling은 「함수 호출」만 다루며, 읽기 전용 리소스와 재사용 Prompt 템플릿을 네이티브로 노출하지 못합니다.
  • 디버깅 블랙박스: 도구 호출 실패 시 통합 Inspector와 JSON-RPC 로그가 없어 원인 추적이 어렵습니다.

01MCP 프로토콜 아키텍처: Client, Server와 3대 역량

Client는 AI 모델 측(Claude Desktop, Cursor, 커스텀 클라이언트)이고, Server는 여러분이 개발하는 역량 제공자입니다. 양측은 JSON-RPC 2.0으로 통신하며, 전송 방식은 stdio(로컬 프로세스)와 HTTP + SSE(원격 서비스)를 지원합니다. 수명 주기는 초기화 핸드셰이크 → 역량 협상 → 요청/응답 → 종료 순입니다.

Server가 노출하는 3대 핵심 역량은 다음과 같습니다.

  • Tools: AI가 호출하는 함수(검색, 계산, DB 조회)
  • Resources: AI가 읽는 리소스(파일, URL, 데이터 스트림)
  • Prompts: 사전 정의된 프롬프트 템플릿
비교 항목MCPOpenAI Function CallingLangChain Tools
표준화 수준개방 프로토콜 표준벤더 전용프레임워크 종속
전송 방식stdio / HTTPHTTPHTTP
크로스 모델지원미지원부분 지원
리소스/프롬프트네이티브 지원미지원미지원
생태계급성장(10,000+ Server)성숙성숙

02개발 환경 준비: Python 중심, TypeScript 대조

Python(초보자 권장): 공식 SDK mcp, 문법이 단순하고 입문이 쉽습니다. TypeScript(프론트/풀스택 권장): 공식 SDK @modelcontextprotocol/sdk. 본 글은 Python을 주로 다루고 TypeScript는 대조 설명으로 제공합니다.

환경 구축
# Python
python -m venv .venv
source .venv/bin/activate
pip install mcp

# TypeScript (대조)
npm init -y
npm install @modelcontextprotocol/sdk

권장 프로젝트 구조는 다음과 같습니다.

my-mcp-server/
my-mcp-server/
├── server.py
├── tools/
│   ├── calculator.py
│   └── web_search.py
├── resources/
│   └── file_reader.py
├── prompts/
│   └── templates.py
├── tests/
│   └── test_tools.py
├── pyproject.toml
└── README.md

디버깅 도구: MCP Inspector(공식 디버그 UI), Claude Desktop 로컬 연동, Cursor.cursor/mcp.json 설정. 공식 문서는 modelcontextprotocol.io를 참고하세요.

03첫 MCP Server: Hello World

server.py
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("my-first-server")

@mcp.tool()
def say_hello(name: str) -> str:
    """지정한 사람에게 인사합니다"""
    return f"Hello, {name}! 첫 MCP 도구입니다."

if __name__ == "__main__":
    mcp.run()
실행 및 검증
python server.py
npx @modelcontextprotocol/inspector python server.py

Cursor.cursor/mcp.json 또는 Claude Desktopclaude_desktop_config.jsoncommand + argspython server.py를 지정하고 재시작한 뒤, 도구가 AI 컨텍스트에 나타나는지 확인하세요.

04Tools: AI가 호출할 도구 개발

도구의 기본 구조는 함수 시그니처가 곧 문서입니다. 파라미터 타입, 반환 타입, docstring이 MCP에서 JSON Schema로 변환되어 모델이 이해합니다. 이름은 snake_case를 쓰고, 오류는 예외를 그대로 던지지 말고 구조화된 정보로 반환하세요.

Pydantic 입력 파라미터
from pydantic import BaseModel, Field

class SearchInput(BaseModel):
    query: str = Field(description="검색 키워드")
    max_results: int = Field(default=5, description="최대 결과 수")
    language: str = Field(default="ko", description="결과 언어")

@mcp.tool()
def web_search(input: SearchInput) -> list[dict]:
    """웹 검색을 실행하고 관련 결과 목록을 반환합니다"""
    ...

다섯 가지 실용 도구를 연습 체크리스트로 권장합니다.

  • 계산기: 수식 평가(eval은 샌드박스 제한 필요)
  • 파일 읽기/쓰기: 허용 디렉터리 내 로컬 파일 처리
  • HTTP 요청: 외부 REST API 호출
  • DB 조회: 읽기 전용 SQL 실행
  • 시간 도구: 현재 시각, 타임존 변환
비동기 도구
import httpx

@mcp.tool()
async def fetch_url(url: str) -> str:
    """지정 URL의 내용을 가져옵니다"""
    async with httpx.AsyncClient() as client:
        response = await client.get(url)
        return response.text

오류 처리 권장 사항: 구조화된 오류 정보 반환, 타임아웃 설정(권장 30초), Server 계층 권한 검증. 자격 증명은 클라이언트 설정에 흩뿌리지 말고 Server에서 관리하세요.

05Resources: AI가 동적 콘텐츠를 읽게 하기

Resource와 Tool의 차이: Resource는 데이터 제공자(읽기 전용), Tool은 동작 실행자입니다. URI로 접근합니다: file://, http://, custom://.

정적·동적 리소스
@mcp.resource("config://app-settings")
def get_app_settings() -> str:
  return json.dumps({"version": "1.0", "env": "production"})

@mcp.resource("user://{user_id}/profile")
def get_user_profile(user_id: str) -> str:
    user = db.query_user(user_id)
    return json.dumps(user)

리소스 유형은 텍스트(text/plain, application/json), 바이너리(이미지, PDF), 스트리밍(실시간 데이터)을 포함합니다. 파일 시스템 리소스 Server는 디렉터리 목록, 파일 읽기, 변경 감시(리소스 구독)를 구현할 수 있습니다.

06Prompts: 재사용 가능한 프롬프트 템플릿 정의

MCP Prompt는 사전 정의된 프롬프트 조각으로, 동적 파라미터 주입을 지원하여 일관성과 유지보수성을 높입니다. userassistant를 포함한 다중 턴 템플릿을 정의할 수 있으며, 코드 리뷰, 면접 시뮬레이션, 디버깅 어시스턴트 등에 적합합니다.

코드 리뷰 Prompt
from mcp.types import PromptMessage, TextContent

@mcp.prompt()
def code_review_prompt(language: str, code: str) -> list[PromptMessage]:
    return [
        PromptMessage(
            role="user",
            content=TextContent(
                type="text",
                text=f"다음 {language} 코드를 리뷰해 주세요..."
            )
        )
    ]

07심화: HTTP 전송 모드(원격 MCP Server)

특성stdioHTTP + SSE
배포 방식로컬 프로세스원격 서버
지연매우 낮음네트워크 의존
다중 클라이언트미지원지원
적합 시나리오로컬 도구SaaS / 팀 공유
HTTP 모드 시작
mcp = FastMCP("remote-server", transport="streamable-http")

if __name__ == "__main__":
    mcp.run(host="0.0.0.0", port=8000)

프로덕션에서는 Bearer Token 인증, API Key 검증 미들웨어, CORS, 요청 빈도 제한을 구성해야 합니다. 자격 증명은 각 클라이언트에 분산하지 말고 Server 계층에서 일원화하세요.

참고 데이터 1: 2026년 현재 MCP 생태계에는 10,000개 이상의 Server가 등록되어 있습니다.

참고 데이터 2: 기업이 MCP를 도입한 뒤 도구 통합 개발 비용이 약 38–55% 감소했다는 업계 조사 구간이 보고되었습니다.

참고 데이터 3: MCP Python SDK의 PyPI 월간 다운로드는 2026년 Q2500만 건을 넘었습니다.

08디버깅과 테스트

MCP Inspector로 디버그 UI를 띄우고 Tools 호출을 테스트하고 JSON-RPC 요청/응답 로그를 확인하며 오류 시나리오를 시뮬레이션할 수 있습니다. 단위 테스트는 Server를 서브프로세스로 띄우고 ClientSession으로 호출합니다.

pytest 스모크 테스트
from mcp.client.session import ClientSession
from mcp.client.stdio import StdioServerParameters, stdio_client

async with stdio_client(StdioServerParameters(
    command="python", args=["server.py"]
)) as (read, write):
    async with ClientSession(read, write) as session:
        await session.initialize()
        result = await session.call_tool("calculate", {"expression": "2 + 2"})
        assert result.content[0].text == "4"
오류원인해결
AI에 도구가 안 보임설정 경로 오류config.json 경로와 command 확인
JSON 직렬화 실패반환 타입 미지원문자열 또는 dict로 변환
타임아웃 끊김도구 실행 지연비동기 + 타임아웃 제어 추가
권한 거부파일 경로 제한허용 디렉터리 화이트리스트 설정

09프로덕션 배포: Docker, 클라우드와 가시성

Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "server.py"]

배포 옵션: Railway / Render(개인 프로젝트 원클릭), AWS Lambda / Google Cloud Run(Serverless), 자체 VPS(Nginx 리버스 프록시). 모니터링 권장: 구조화된 요청 로그, Prometheus 도구 호출 지표, Sentry 오류 알림, 헬스 체크 엔드포인트. 버전 관리 시 MCP 프로토콜 버전을 명시하고 하위 호환 도구 업그레이드 전략을 따르세요.

10실습 프로젝트: 개인 지식베이스 MCP Server

요구사항: AI가 로컬 Markdown 노트를 검색하고, 의미 검색(벡터 검색)을 지원하고, 노트를 생성·갱신할 수 있게 합니다.

기술 스택: 로컬 벡터 DB ChromaDB / Qdrant; 임베딩 모델 text-embedding-3-small; 파일 감시 watchfiles.

  • 노트 인덱싱 도구: 디렉터리 스캔, 청크 임베딩 후 벡터 DB 저장
  • 의미 검색 도구: query로 Top-K 관련 조각 반환
  • 노트 쓰기 도구: Markdown 파일을 생성하거나 갱신합니다
  • 파일 리소스 서비스: Resource URI로 노트 전문 노출

데모: Cursor에서 「지난주 MCP에 대해 기록한 내용이 뭐였지?」라고 물으면 AI가 MCP 검색 도구를 호출해 관련 노트 조각을 반환합니다.

11MCP 생태계와 향후 전망

우수 커뮤니티 Server: mcp-server-filesystem(파일 시스템), mcp-server-github(GitHub 저장소), mcp-server-brave-search(웹 검색), mcp-server-postgres(DB), mcp-server-slack(Slack 메시지).

2026년 동향: OpenAI, Google, Microsoft가 MCP 지원을 발표했고, 거버넌스는 Linux Foundation AAIF로 이관되었습니다. MCP Marketplace가 급성장하고, 기업급 보안 표준(OAuth 2.1)이 로드맵에 포함되었습니다.

다음 학습 경로: MCP 프로토콜 규격 심화; 공개 MCP Server 개발·배포; MCP + Agent 조합 탐색; 오픈소스 생태계 기여(Python SDK, TypeScript SDK, Inspector).

126단계 Runbook: 클라우드 Mac에서 MCP Server 7×24 운영

  1. 01
    전송 모드 결정: 로컬 개발은 stdio; 팀 공유나 원격 Claude Code 호출은 HTTP+SSE. API Key는 Server 계층에서 일원 관리합니다.
  2. 02
    콘솔에서 클라우드 Mac 프로비저닝: NUKCLOUD 콘솔에 로그인해 16 GB+ 메모리(다중 Server 병렬 시 32 GB 권장)를 선택합니다. 요금 페이지에서 시간 과금으로 시험할 수 있습니다.
  3. 03
    Python 3.12 + mcp 설치: SSH 로그인 후 pip install mcp httpx pydantic; MCP Inspector로 로컬 스모크 테스트를 수행합니다.
  4. 04
    HTTP Server 배포 및 포트 노출: mcp.run(host="0.0.0.0", port=8000); Bearer Token 미들웨어와 CORS를 구성합니다.
  5. 05
    클라이언트 연결 검증: Cursor .cursor/mcp.json에 클라우드 URL을 지정하고 tools/listtools/call 스모크가 통과하는지 확인합니다.
  6. 06
    launchd 상시 운영과 월간 임대 고정: LaunchAgents plist로 7×24 실행을 유지합니다. 파일럿 통과 후 주문 페이지에서 스펙을 고정합니다. 자세한 내용은 NUKCLOUD 프로덕션 Runbook을 참고하세요.

로컬 노트북이나 공유 VPS에서 HTTP MCP Server를 돌리면 덮개 닫기로 세션 중단, 대역폭 변동으로 SSE 끊김, 다수 개발자가 한 프로세스를 두고 경합하는 문제가 흔합니다. Cursor Background Agents나 개인 지식베이스 Server를 7×24 안정적으로 서비스해야 할 때 NUKCLOUD 다지역 베어메탈 Mac / 클라우드 Mac 노드는 전용 테넌트 경계와 스펙 탄력성 측면에서 MCP 워크플로와 더 잘 맞습니다.

13자주 묻는 질문

MCP Server는 Python과 TypeScript 중 무엇으로 작성해야 합니까?
초보자는 Python + FastMCP를 권장합니다. 데코레이터 문법이 가장 단순합니다. 프론트/풀스택 팀은 TypeScript SDK를 선택하면 Node 생태계와 일치합니다. 둘 모두 공식 유지보수되며 프로토콜 계층은 완전 호환입니다.
Tools, Resources, Prompts는 어떻게 나누어 쓰면 됩니까?
Tools는 동작 실행(DB 쓰기, API 호출), Resources는 읽기 전용 데이터(설정, 파일 내용), Prompts는 재사용 프롬프트 템플릿을 제공합니다. 셋이 상호 보완하여 Agent에 필요한 컨텍스트 확장을 모두 커버합니다.
stdio와 HTTP는 어떻게 선택합니까?
개인 로컬 개발, Cursor 단일 사용자는 stdio; 팀 공유, SaaS화, 다중 클라이언트 원격 접속은 HTTP+SSE입니다. 본문 7절 비교표를 참고하세요.
기존 MCP 프로토콜 해설 글과 무엇이 다릅니까?
MCP 심층 해설은 프로토콜 본질과 HTTP 비유에 집중합니다. 본 글은 처음부터 개발하는 실습 튜토리얼로, 전체 코드, 배포, 개인 지식베이스 프로젝트를 포함합니다.
MCP로 어떤 도구를 만들 계획이신가요?
댓글로 MCP Server 아이디어를 공유해 주세요. MCP는 AI 도구화의 표준 프로토콜이며, 2026년 AI 엔지니어의 핵심 역량 중 하나입니다.