이 글은 Gemini 기반 MCP 서버 및 클라이언트를 개발하는 방법을 간략히 보여준다.
MCP의 개념과 상세한 동작 방식은 다음 글을 참고한다.
개요
MCP는 클라이언트-서버 구조를 따른다. 클라이언트는 서버의 MCP 도구를 사용하는 AI 앱이나 LLM을 의미한다. 서버는 MCP 도구를 공급하고, API, 데이터소스 인터페이스를 제공한다.
MCP를 통해 LLM이 해결하지 못하는 작업은 외부 시스템과 연결해 서비스 받을 수 있다.
MCP서버는 파일 시스템 조작, 웹 검색, 데이터베이스 조작, 버전 관리 등 다양한 도구를 제공할 수 있다.
제미니 LLM 기반 MCP 구조
다음은 제미니 LLM 기반 MCP 구조 예시를 보여준다. 이 예는 비행기 예약 유스케이스를 구현한다.
- MCP 호스트가 사용자 명령 입력. 예) 내일 인천에서 애틀란타 가는 비행편 찾기
- 클라이언트 스크립트가 입력을 처리(CLIENT.PY)
- 클라이언트가 MCP 서버 프로세스 시작(MCP-FLIGHT-SEARCH). STDIO 통신 채널 연결 및 관련 도구 검색
- 클라이언트가 사용자 명령에 대한 함수 호출 방법을 수신함
- 클라리언트가 함수 호출 방법에 대한 정확한 함수 호출 형식을 GEMINI에서 획득. 함수 호출 형식에 부합하는 적절한 MCP 도구를 서버에 호출. 서버의 도구 함수 호출 결과를 리턴
- MCP 서버가 구글 항공편 검색을 위한 SerpAPI를 호출. 구글 항공편 데이터 질의.
- 구글 항공편 정보 리턴
- 서버에서 클라이언트로 해당 정보 리턴
- 클라이언트가 호스로 해당 정보 전달
개발 환경
개발을 위한 최소한의 환경은 파이썬 3.8+이다. 이외 다음을 준비한다.- Claude 데스크탑 설치
- Google Cloud 에서 Project 생성
- Google Gemini API 키 획득
- SerpAPI 키 획득
다음 종속성을 터미널에서 설치한다. google-genai는 google 생성AI 라이브러리이며, mcp는 MCP 서버 통신을 위한 파이썬 SDK이다.
pip install google-genai mcp
환경변수를 설정한다.
export GEMINI_API_KEY="your-google-api-key"
export SERP_API_KEY="your-serpapi-key"
항공편 검색 MCP 서버 설치
MCP 프로토콜 공개 이후로 많은 MCP 서버가 개발되었다. 우리는 항공편 검색 MCP 서버 오픈소스인 mcp-flgiht-search 를 사용한다. 다음을 설치한다.
pip install mcp-flight-search
코딩해보기
다음과 같이 client.py를 코딩한다.
import os, sys, time, asyncio
from google import genai
from google.genai import types
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from dotenv import load_dotenv
load_dotenv()
gemini_api_key = os.getenv("GEMINI_API_KEY")
serp_api_key = os.getenv("SERP_API_KEY")
client = genai.Client(api_key=gemini_api_key)
server_params = StdioServerParameters(
command="mcp-flight-search",
args=["--connection_type", "stdio"],
env={"SERP_API_KEY": serp_api_key},
)
async def run():
async with stdio_client(server_params) as (read, write): # 항공 예약 검색 도구 등록
async with ClientSession(read, write) as session:
prompt = f"Find Flights from Atlanta to Las Vegas 2025-08-15" # 사용자 질의 명령
await session.initialize()
mcp_tools = await session.list_tools() # 도구 리스트 획득
tools = [
types.Tool(
function_declarations=[
{
"name": tool.name,
"description": tool.description,
"parameters": {
k: v
for k, v in tool.inputSchema.items()
if k not in ["additionalProperties", "$schema"]
},
}
] # 해당 도구 함수 선언 생성
)
for tool in mcp_tools.tools
]
response = client.models.generate_content(
model="gemini-2.5-pro-exp-03-25",
contents=prompt,
config=types.GenerateContentConfig(
temperature=0,
tools=tools,
), # LLM 모델에 프롬프트 전달.
)
if response.candidates[0].content.parts[0].function_call:
function_call = response.candidates[0].content.parts[0].function_call # 함수호출정보
result = await session.call_tool(
function_call.name, arguments=dict(function_call.args)
) # 도구 함수 호출
print("--- Formatted Result ---") # Add header for clarity
try:
flight_data = json.loads(result.content[0].text)
print(json.dumps(flight_data, indent=2))
except json.JSONDecodeError:
print("MCP server returned non-JSON response:")
print(result.content[0].text)
except (IndexError, AttributeError):
print("Unexpected result structure from MCP server:")
print(result)
else:
print("No function call was generated by the model.")
if response.text:
print("Model response:")
print(response.text)
asyncio.run(run()) # 클라이언트 실행
실행한다. 그럼 프롬프트에 대해 LLM이 적절한 도구와 파라메터를 확인해 함수 호출 정보를 생성한다. 이를 call_tool로 호출한 결과가 표시된다
레퍼런스
- Introducing Graphite — An Event Driven AI Agent Framework | by Craig Li, Ph.D | Binome | Apr, 2025 | Medium
- Model Context Protocol(MCP) with Google Gemini 2.5 Pro - Deep Dive , Google Cloud Gen AI | Google Cloud - Community
- Model Context Protocol (MCP) with Gemini 2.5 Pro. Convert conversational queries into flight searches using Gemini's function calling capabilities and MCP's flight search tools
댓글 없음:
댓글 쓰기