AI 에이전트 시대, MCP(Model Context Protocol)를 직접 구축해보자
요즘 사내에서 AI 에이전트 도입 얘기가 나올 때마다 빠지지 않고 등장하는 단어가 하나 있다. 바로 MCP(Model Context Protocol)다. 처음 들었을 땐 또 새로운 벤더 용어겠거니 했는데, 막상 파보니 생각보다 훨씬 실용적이고 이미 여러 도구에서 표준처럼 자리잡고 있어서 이번 기회에 정리 겸 직접 서버를 하나 만들어봤다. 검색량도 최근 들어 꽤 늘어난 주제라 오늘은 이 MCP를 개념부터 실제 구축까지 다뤄보려 한다.
MCP가 뭔데 다들 이렇게 얘기하는 걸까
MCP는 Anthropic이 2024년 말에 공개한 오픈 프로토콜로, 한 마디로 정의하면 "LLM이 외부 데이터와 도구에 접근하는 방식을 표준화한 규격"이다. 예전에는 AI 모델이 파일 시스템을 읽거나, 사내 DB를 조회하거나, 슬랙 메시지를 보내려면 그때그때 커스텀 연동 코드를 짜야 했다. 문제는 이게 모델마다, 도구마다 제각각이라 N개의 모델과 M개의 도구를 연결하려면 이론상 N×M개의 연동 코드가 필요했다는 점이다.
MCP는 이 문제를 USB-C 같은 물리적 표준에 비유해서 설명하는 경우가 많은데, 실제로 딱 그런 역할을 한다. 도구를 만드는 쪽에서 MCP 서버 하나만 만들어두면, MCP를 지원하는 어떤 클라이언트(Claude Desktop, Claude Code, Cursor 등)에서든 별도 수정 없이 그 도구를 쓸 수 있다.
왜 하필 지금 MCP가 뜨는가
사실 표준화 시도 자체는 이전에도 여러 번 있었다. MCP가 다른 건 실제로 채택이 빠르게 이루어지고 있다는 점이다.
생태계 확산 속도
- Claude Desktop, Claude Code가 처음부터 네이티브로 지원
- Cursor, Windsurf 같은 AI 코딩 툴들이 잇따라 지원 추가
- 2025년 초 OpenAI도 자사 에이전트 SDK와 ChatGPT 데스크톱 앱에 MCP 지원을 공식 발표하면서 사실상 업계 표준으로 굳어지는 분위기
- Google DeepMind도 Gemini 계열 모델·SDK에 MCP 호환을 언급
즉 특정 회사의 폐쇄적인 스펙이 아니라 오픈소스로 공개된 프로토콜이다보니, 한 번 만들어둔 MCP 서버가 여러 벤더 생태계에서 재사용된다는 게 가장 큰 매력이다.
MCP의 기본 구조: Host - Client - Server
세 가지 구성요소
MCP 아키텍처는 크게 세 부분으로 나뉜다.
- Host — Claude Desktop, Claude Code처럼 사용자가 실제로 사용하는 AI 애플리케이션. 하나의 Host 안에 여러 MCP Client가 떠 있을 수 있다.
- Client — Host 내부에서 하나의 MCP Server와 1:1로 연결을 유지하는 커넥터. 프로토콜 메시지를 주고받는 실질적인 통신 담당자다.
- Server — 실제로 도구(Tool), 리소스(Resource), 프롬프트(Prompt)를 제공하는 프로그램. 로컬에서 실행되는 프로세스일 수도, 원격 HTTP 서버일 수도 있다.
통신은 JSON-RPC 2.0 기반이고, 로컬 서버는 보통 stdio(표준 입출력)로, 원격 서버는 HTTP(SSE 혹은 Streamable HTTP)로 통신한다. 결국 우리가 만들 건 이 중 Server 부분이다.
직접 만들어보기: 파이썬으로 MCP 서버 구축
이론은 이 정도로 하고, 실제로 간단한 MCP 서버 하나를 만들어서 Claude에 연결하는 과정을 그대로 따라가보자. 메모를 저장하고 조회하는 아주 단순한 도구를 예시로 잡았다.
1단계 — 개발 환경 준비
파이썬 3.10 이상이 설치되어 있어야 한다. 공식 SDK는 uv 사용을 권장하지만 pip로도 충분히 된다.
# uv를 쓰는 경우
uv init mcp-notes-server
cd mcp-notes-server
uv add "mcp[cli]"
# pip를 쓰는 경우
mkdir mcp-notes-server && cd mcp-notes-server
python -m venv .venv && source .venv/bin/activate
pip install "mcp[cli]"
2단계 — 서버 코드 작성
server.py 파일 하나에 아래 내용을 작성한다. FastMCP를 쓰면 함수에 데코레이터만 붙여도 자동으로 스키마가 생성돼서 보일러플레이트가 거의 없다.
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("notes-server")
# 아주 단순하게 메모리에 저장 (실제로는 파일/DB로 교체)
_notes: dict[str, str] = {}
@mcp.tool()
def save_note(title: str, content: str) -> str:
"""제목과 내용을 받아 메모를 저장한다."""
_notes[title] = content
return f"'{title}' 메모를 저장했습니다."
@mcp.tool()
def list_notes() -> list[str]:
"""저장된 모든 메모의 제목 목록을 반환한다."""
return list(_notes.keys())
@mcp.tool()
def read_note(title: str) -> str:
"""제목으로 메모 내용을 조회한다."""
return _notes.get(title, "해당 제목의 메모가 없습니다.")
if __name__ == "__main__":
mcp.run(transport="stdio")
도구(Tool) 함수의 docstring이 그대로 LLM에게 전달되는 설명이 되기 때문에, 이름과 docstring을 명확히 써주는 게 실제 사용성에 꽤 영향을 준다. 타입 힌트도 스키마 생성에 그대로 쓰이므로 빼먹지 않는 게 좋다.
3단계 — MCP Inspector로 먼저 테스트
Claude에 바로 연결하기 전에, 공식 제공되는 Inspector 도구로 로컬에서 먼저 동작을 확인하는 걸 추천한다.
mcp dev server.py
브라우저가 열리면서 Tool 목록, 입력 스키마, 실행 결과를 눈으로 바로 확인할 수 있다. 여기서 save_note, list_notes를 몇 번 호출해보고 정상 동작하면 다음 단계로 넘어간다.
4단계 — Claude에 연결하기
연결 방식은 사용하는 클라이언트에 따라 조금 다르다.
Claude Desktop을 쓴다면 설정 파일(claude_desktop_config.json)에 서버를 등록한다. macOS 기준 경로는 ~/Library/Application Support/Claude/claude_desktop_config.json, Windows는 %APPDATA%\Claude\claude_desktop_config.json이다.
{
"mcpServers": {
"notes-server": {
"command": "uv",
"args": [
"--directory",
"/절대경로/mcp-notes-server",
"run",
"server.py"
]
}
}
}
Claude Code를 쓴다면 설정 파일을 직접 건드릴 필요 없이 CLI 한 줄로 등록할 수 있어서 더 간편하다.
claude mcp add notes-server -- uv --directory /절대경로/mcp-notes-server run server.py
# 등록된 서버 확인
claude mcp list
등록 후 Claude Desktop은 완전히 재시작, Claude Code는 새 세션을 열면 도구가 인식된다. 대화창에서 "메모 목록 보여줘" 같은 요청을 하면 모델이 알아서 list_notes 도구를 호출하는 걸 확인할 수 있다.
실무에 적용할 때 주의할 점
몇 가지 함정들
- ❌ Tool 설명을 대충 쓰면 모델이 엉뚱한 상황에서 도구를 호출하거나, 반대로 필요할 때 호출하지 않는다. docstring 품질이 곧 사용성이다.
- ❌ 로컬 stdio 서버는 Host 프로세스와 생명주기가 묶여있다. 서버가 죽으면 Host 쪽 로그를 봐야 원인을 알 수 있는데, 클라이언트마다 로그 위치가 다르니 미리 확인해두는 게 좋다.
- ⭕ 원격 서비스(사내 API, DB 등)를 물릴 때는 stdio 대신 Streamable HTTP transport를 쓰고, 인증은 반드시 OAuth 등 정식 방식으로 처리한다. 토큰을 코드에 하드코딩하는 예제가 인터넷에 많은데 실무에서는 절대 금물이다.
- ⭕ 파괴적인 동작(삭제, 결제, 배포 등)을 하는 Tool은 실행 전 사용자 확인을 받도록 설계하는 게 안전하다. 대부분의 Host가 이런 confirm 단계를 지원한다.
마무리
직접 만들어보니 MCP의 진짜 가치는 프로토콜 자체의 정교함보다 "한 번 만들면 여러 곳에서 쓴다"는 생태계 효과에 있다는 걸 체감했다. 사내에 이미 있는 API나 DB를 MCP 서버로 한 번 감싸두면, 이후에 어떤 AI 툴을 도입하든 그 자산을 그대로 재활용할 수 있다는 게 특히 매력적이다.
공식 문서와 SDK는 계속 빠르게 업데이트되고 있으니, 실제로 붙일 때는 아래 공식 자료를 함께 참고하는 걸 추천한다.
- modelcontextprotocol.io — 공식 스펙 및 문서
- github.com/modelcontextprotocol — SDK 및 레퍼런스 서버 모음
* 위 내용은 작성 시점 기준이며, 프로토콜 스펙과 각 클라이언트의 지원 방식은 이후 변경될 수 있습니다.
댓글 0
로그인 후 댓글을 작성할 수 있습니다.