
MCP 서버 통신에 대한 개념적인 내용을 더 숙지하고 싶으시면 이전 글을 읽어주시면 될거 같습니다. 여기에서는 서버 구축에 집중하여 글을 작성하도록 하겠습니다.

# 프로젝트를 위한 새 file 생성
uv init
# 가상 환경 생성 및 활성화
uv venv
source .venv/bin/activate
# 의존성 설치
uv add "mcp[cli]" httpx
# Python 3.13.5 기반 이미지 사용
FROM python:3.13.5-slim
# 작업 디렉토리 설정
WORKDIR /app
# 프로젝트 파일 복사
COPY main.py .
COPY pyproject.toml .
COPY uv.lock .
# uv 설치
RUN pip install uv
# 의존성 설치
RUN uv sync
# 서버 실행
CMD ["uv", "run", "python3", "main.py"]

Python 버전을 3.10 이상으로 환경 구성하지 않으면 위와 같은 오류가 발생합니다.
Local 로 환경 셋팅을 할 수도 있지만, 그러면 개발자간의 일관적인 개발환경에서 개발하기 어렵기 때문에 도커 기준으로 설명하겠습니다.
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("mcp_project")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b
if __name__ == "__main__":
import sys
print("Starting MCP server...", file=sys.stderr)
mcp.run()
print("Server stopped", file=sys.stderr)
위와 같이 mcp.run() 을 하면 기본적으로 Stdio 로 동작하게 됩니다. mcp.run(transport='stdio') 로 명시적으로 구현 할 수도 있습니다. 잘 구축이 되었는지 테스트는 Claude Desktop 에서 구현 tool 의 기능을 확인하거나 MCP Inspector 를 통해서 확인 할 수 있습니다. 각각의 방법에 대해서 Claude Desktop 은 아래 5번으로 가시면 따로 설명이 있습니다.
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b
@mcp.tool() Annotation 을 통해서 클라이언트가 서버에서 호출 할 tool 을 등록할 수 있습니다.
$ docker build -t mcp_server_stdio .
이후 MCP 서버를 subprocess 로 실행 할 때는 claude_desktop_config.json 에서 도커 명령어를 설정해서 Claude Desktop 에서 실행 하거나, MCP Inspector 에서 도커를 실행하면 됩니다.
import uvicorn
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("mcp_project")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b
if __name__ == "__main__":
print("Starting MCP server...")
uvicorn.run(mcp.sse_app(), host="0.0.0.0", port=8000, log_level="info")
uvicorn.run(mcp.sse_app(), host="0.0.0.0", port=8000, log_level="info") 하면 sse 로 서버를 구축할 수 있습니다. 내부에 다양한 함수들이 있어서 위 방법 말고도 다른 방법으로도 구축할 수 있지만, 여기서는 기본만 다루겠습니다.
host="0.0.0.0" 으로 해서 외부 프로그램 및 브라우저에서 접근 가능하게 합니다.
$ docker build -t mcp_server_sse .
도커 이미지를 빌드 합니다.
$ docker run -it -p 8000:8000 mcp_server_sse
빌드한 도커 이미지를 실행합니다. 이후 Claude Desktop 에서 Json 포멧을 mcp-remote 에 맞추어서 SSE 로 통신을 진행하면 됩니다.
import uvicorn
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("mcp_project")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b
if __name__ == "__main__":
print("Starting MCP server...")
uvicorn.run(mcp.streamable_http_app(), host="0.0.0.0", port=8000, log_level="info")
uvicorn.run(mcp.streamable_http_app(), host="0.0.0.0", port=8000, log_level="info") 하면 Streamable Http 로 서버를 구축할 수 있습니다. 내부에 다양한 함수들이 있어서 위 방법 말고도 다른 방법으로도 구축할 수 있지만, 여기서는 기본만 다루겠습니다.
host="0.0.0.0" 으로 해서 외부 프로그램 및 브라우저에서 접근 가능하게 합니다.
$ docker build -t mcp_server_http .
도커 이미지를 빌드 합니다.
$ docker run -it -p 8000:8000 mcp_server_http
빌드한 도커 이미지를 실행합니다. 이후 Claude Desktop 에서 Json 포멧을 mcp-remote 에 맞추어서 Streamable Http 로 통신을 진행하면 됩니다.

구성 편집 버튼을 누르면 claude_desktop_config.json 파일이 있는 디렉토리로 이동을 하게 됩니다. claude_desktop_config.json 에 알맞은 json data 를 넣어주면 Claude Desktop 을 재시작하면 적용되게 됩니다. json 포맷의 경우 아래에 따로 상세히 설명하겠습니다.
{
"mcpServers": {
"mcp_project": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"mcp_server_stdio:latest"
]
}
}
}
"command": "docker" 를 통해서 docker 환경에서 실행하는 것을 알 수 있습니다.
{
"mcpServers": {
"mcp_project": {
"command": "npx",
"args": [
"mcp-remote",
"http://127.0.0.1:8000/sse"
]
}
}
}
{
"mcpServers": {
"mcp_project": {
"command": "npx",
"args": [
"mcp-remote",
"http://127.0.0.1:8000/mcp"
]
}
}
}

연결이 되어 있는것을 확인할 수 있습니다.
https://github.com/modelcontextprotocol
https://modelcontextprotocol.io/introduction
https://thetechnomist.com/p/standardizing-ai-value-the-tech-and