빅데이타 & 머신러닝/생성형 AI (ChatGPT etc)

MCP (Model Context Protocol) 2. 서버 개발하기

Terry Cho 2025. 4. 6. 08:57

조대협 (http://bcho.tistory.com)

지난 글을 통해서 MCP의 개념에 대해서 간략하게 이해해봤다. 이번글에서는 그러면 어떻게 MCP 서버를 실제로 구현하는지에 대해서 알아보도록 한다.

MCP Local server & remote server

MCP server 는 구동 위치에 따라서, 로컬 서버와 리모트 서버로 분리된다. 

아래는 Anthropic 의 아키텍처 다이어그램이다. 

 

 

로컬 서버의 경우, MCP 애플리케이션 호스트 프로세스가 기동되는 로컬 데스크탑에서 실행되는 서버이고, 리모트 서버는 클라우드나 기타 네트워크로 접속될 수 있는 환경에서 기동되는 서버이다. 

로컬 서버의 경우에는 같은 데스크탑에서 실행되기 때문에, 로컬 자원, 즉 데스크탑의 파일 등에 접근할 수 있다.

(노트 : 이는 보안적으로 매우 위험할 수 있다. MCP 서버 애플리케이션이 악의적으로 로컬 파일을 전송하거나 또는 로컬에 파일을 인스톨하여 실행함으로써, 정보를 해킹하거나, Malware등의 소프트웨어를 설치할 수 있기 때문이다. 그래서 로컬 MCP 서버를 다운로드 받아서 사용할 경우에는, 반드시 인증이 되고 증명이 된 서버만 사용하기 바란다.)

 

로컬 MCP 서버의 경우에는 stdio input을 사용한다. Linux 파이프 (|)와 같이 콘솔 input/output을 이용하여 input/ouput을 받는다는 이야기이다. 리모트 MCP 서버의 경우에는 HTTP/JSON-RPC를 이용해서, 통신한다. 

아래는 본 내용을 정리한 유투브 비디오 입니다.

 

 

MCP Server 구현

MCP Server를 구현하려면 SDK를 사용해야 하는데, 현재는 Python, Typescript , Java, Kotlin, C#을 지원한다.

이 예제에서는 Python을 이용해보도록 하겠다. 

파이썬 SDK https://github.com/modelcontextprotocol/python-sdk

파이썬 SDK는 FastMCP라는 MCP로, 파이썬의 FastAPI와 유사하고 사용법이 단순하다.

 

먼저 파이썬 환경을 설정하자

uv init mcp-server-tutorial

uv venv

source .venv/bin/activate

# Install dependencies

uv add "mcp[cli]"

  • uv init 로, 기본 프로젝트 폴더를 생성한다.
  • uv venv로, 파이썬 가상 환경을 설정한다. 
  • uv add를 이용하여 mcp 파이썬 라이브러리를 설치한다. 

 

이제 MCP 서버를 구현해보자. 이 서버는 get_weather라는 툴 하나를 가지고 있는 서버로, 도시의 이름을 넣으면, 응답으로 “{도시이름} weather is good” 이라는 문자열을 리턴한다. MCP 서버 구현 방법을 설명하기 때문에, 복잡한 로직은 구현하지 않았다. 

from mcp.server.fastmcp import FastMCP # Parameter is not strictly needed now, but good practice to keep if you add more complex params later

# Create the FastMCP instance with stdio transport
mcp = FastMCP()

# Define the tool using the @mcp.tool() decorator
@mcp.tool()
def get_weather(city: str) -> str:
   """
   Returns weather of the city

   :param city: The city to get the weather for
   """
   return f"{city} weather is good"

# The tool is automatically added to the mcp instance by the decorator

# Run the server if the script is executed directly
if __name__ == "__main__":
   print("Starting MCP server...")
   mcp.run(transport="stdio")

 

<코드 .  main.py> 

 

  • 먼저 FastMCP()로 mcp 서버 인스턴스를 생성한다. 
  • 툴을 정의하려면 @mcp.tool() 이라는 데코레이터를 이용하여, tool에 사용할 함수를 정의한다. 
  • 다음으로 “”” “”” 주석으로, 해당 tool에 대해서 설명을 한다. Tool에 대한 설명과, 입력/출력값에 대해서 정의를 해주면 된다. 이 주석의 내용은 나중에 MCP 클라이언트가 서버에 접속했을때, 어떤 툴들이 있고, 툴의 사용방법이 어떻게 되는지를 클라이언트에게 알려줄 수 있다. 

MCP 애플리케이션과 연결

서버를 구현 하였으며, 작동이 제대로 되는지를 확인하기 위해서, MCP 호스트 애플리케이션에 연동해보자.

Anthropic의 클로드 데스크탑 (https://claude.ai/download) 이 사용이 편리하다. 먼저 데스크탑을 다운로드 받아서 설치한다.

MCP 서버 연결 설정

다음으로 클로드 데스크탑 앱에, 이 MCP Server를 연결해야 하는데, MCP Server 연결 설정은 json 파일에 등록해야 한다.

Mac의 경우에는 “~/Library/Application Support/Claude/claude_desktop_config.json” 파일이다. 해당 파일에 아래 내용을 붙여 넣는다.

 

{

 "mcpServers": {

   "weather": {

     "command": "uv",

     "args": [

       "--directory",

       "{앞서 작성한 mcp server 파일이 있는 디렉토리 경로}",

       "run",

       "main.py"

     ]

   }

 }

}




이 파일의 내용은 앞서 작성한 main.py를 uv 명령어를 이용해서 실행하는 명령어 이다. 이렇게 실행된 서버는 stdio를 통하여 클로드 데스크탑과 연결이 된다. 

파일이 생성되었으면 클로드 데스크 탑을 재 실행한다. 

실행하면 MCP Server가 등록되었으면 아래 그림과 같이 “망치” 모양의 아이콘이 나타나고, 연결된 MCP 서버의 수가 숫자로 표현된다. 

 

해당 버튼을 누르면 아래와 같이 tool의 목록과 사용법이 표시된다. 

자, 그러면 MCP Server와 잘 통신이 되는지 확인해보자. 

서울의 날씨를 질의하였다. 

클로드는 현재 서울 날씨에 대한 정보를 알 수 없기 때문에, 외부 도구를 통해서 찾을 수 있을지 생각을 하고, 우리가 등록한 weather 도구가 날씨 정보를 제공할 수 있다는 것을 알고 있기 때문에, weather mcp server에서 “get_weather” 툴을 수행하려고 한다. 보안상 클로드는 로컬 mcp 호출을 하기 위해서 사용자에게 로컬 mcp server를 호출해야 하는지 사용자에게 아래와 같이 질의한다. 

 

“Allow for this chat”으로 이번 채팅에서 사용할 수 있게 해주면, 아래와 같이 우리가 mcp server tools에서 정의한것처럼 “Seoul weather is good”이라는 정보를 클로드 데스크탑에 전달하고, 클로드는 이 메시지를 가공하여 “The current weather in Seoul is good”이라는 메시지를 최종으로 출력하게 된다. 

 

MCP 서버 설정

이미 많은 MCP 서버들이 나와 있으며, MCP 서버를 모아놓은 대표적인 디렉토리 사이트들은 다음과 같다.  

 

해당 사이트에 들어가서 검색을 하고 MCP server를 선택하면, 서버마다, 서버를 실행할 수 있는 JSON config 파일을 가이드하고 있다. 

MCP 서버 확인

만약 클로드등의 클라이언트 없이 MCP 서버가 제대로 작동하는지 확인하고 싶으면, MCP Inspector라는 것을 사용할 수 있다. 

https://modelcontextprotocol.io/docs/tools/inspector

 

npx 명령을 이용해서 구동할 수 있는데,

npx @modelcontextprotocol/inspector {mcp 서버 구동 명령어}

식으로 사용하면 된다. 우리가 개발한 서버는 main.py 이기 때문에, 아래 명령어로 구동한다. 

 

npx @modelcontextprotocol/inspector uv run main.py

서버가 구동이 되면 아래와 같이 localhost에서 접속할 수 있는 URL http://127.0.0.1:6274 가 출력된다. 

해당 사이트에 접속하면 아래와 같이 MCP server를 접속할 수 있는 Connect 버튼이 나온다. 

서버에 Connect를 하면 해당 MCP Server가 제공하는 Tool list나 기타 resource, prompt에 대한 정보를 볼 수 있다. (이 글에서는 resource나 prompt는 다루지 않았다. )

Tools를 선택하여, list tools를 해보면 우리가 구현한 get_weather tool이 나오는 것을 확인할 수 있고, 이를 테스트하기 위해서, 툴을 선택하면 우측에 입력값을 넣을 수 있는 창이 나온다. 아래와 같이 “Mountain view”를 입력하면, 결과 값으로 “Mountain view weather is good”이라는 응답이 나오는 것을 확인할 수 있다. 

 

이 글에서는 간단하게 mcp server를 fastmcp sdk로 구현하는 방법에 대해서 알아보았다. 다음글에서는 mcp client를 직접 구현하는 방법에 대해서 알아보도록 하겠다.