최근 AI 에이전트를 구축할 때, 다양한 외부 도구를 손쉽게 연결하고 확장할 수 있는 MCP (Model Context Protocol) 아키텍처가 주목받고 있습니다.
🧩 MCP란?
**MCP(Model Context Protocol)**는 LLM 기반 AI 에이전트가 다양한 외부 도구를 유연하게 호출할 수 있도록 설계된 개방형 프로토콜이며, 여러 기업 및 개발자들이 이를 활용한 프로젝트를 진행 중이다.
✔️ MCP의 주요 특징
- 유연한 통신: 다양한 클라이언트/서버 구성에서 사용 가능
- 빠른 도구 연동: 도구를 데코레이터 한 줄로 노출 가능
- 빠른 개발 및 프로토타이핑에 최적
- 낮은 진입 장벽: LangChain Adapter + FastMCP로 바로 시작 가능
🧱 아키텍처 구성 개요

MCP 시스템은 크게 3가지 요소로 구성됩니다.
- MCP Host
- 유저가 사용하는 인터페이스 (예: ChatGPT, LangGraph, 웹 UI 등)
- MCP 도구를 호출하는 클라이언트이자 실행 환경
- MCP Client
- 도구 목록을 MCP 서버에 요청하고, 메시지를 전송하는 중계자
- LangChain MCP Adapter로 쉽게 구현 가능
- MCP Server
- 실제 도구를 실행하는 서버
- 도구들은 함수 기반으로 정의되어 있으며, FastMCP로 간단하게 구성 가능
🌐 SSE 방식이란?
우리는 SSE(Server-Sent Events) 방식으로 MCP 서버를 구동합니다. 이 방식은 HTTP 기반의 실시간 이벤트 스트리밍을 지원하며, 다음과 같은 장점이 있습니다:
- 실시간 업데이트: 서버에서 클라이언트로 실시간 데이터 푸시
- HTTP 기반: 방화벽/프록시 우회가 쉬워 운영 환경에 적합
- 경량 통신: WebSocket보다 단순하고 빠르게 구성 가능
🚀 FastMCP로 MCP 서버 만들기
MCP SSE Remote사용하기
최근 AI 업계에서는 모델 컨텍스트 프로토콜(MCP) 이 주요 이슈로 떠오르고 있다. MCP는 애플리케이션이 대형 언어 모델(LLM)에 컨텍스트를 제공하는 방식을 표준화하는 개방형 프로토콜이며, 여러
hyeong9647.tistory.com
이전 글쓰기를 참조해서 MCP를 Remote SSE환경에서 띄어서 사용해보자
from typing import List
from mcp.server.fastmcp import FastMCP
# FastMCP 인스턴스 생성 및 'Weather' 도구 추가
mcp = FastMCP("Weather")
@mcp.tool()
async def get_weather(location: str) -> str:
"""지정된 위치의 날씨 정보를 반환"""
return f"It's always sunny in {location}"
# SSE 방식으로 MCP 서버 실행
if __name__ == "__main__":
mcp.run(transport="sse")
위 코드를 app.py로 저장한 후, 다음 명령어를 실행하여 SSE 서버를 시작할 수 있다.
🎯 랭체인 코드 실행
간단한 create_react_agent를 만들어서 똑같은 동작을 구현하려고 한다.
MCP는 전부 비동기를 사용해야되서 디버그가 쉽지 않지만 나쁘지 않게 해볼만하다.
import asyncio
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI
from langchain_mcp_adapters.client import SingleServerMCPClient
async def main():
# OpenAI 모델 초기화
model = ChatOpenAI(model="gpt-4o-mini", openai_api_key=api_key)
# FastMCP에서 제공하는 Weather 도구에 연결 (SSE)
async with SingleServerMCPClient(
url="http://localhost:8000/sse", # FastMCP 서버 포트와 일치해야 함
transport="sse"
) as client:
tools = client.get_tools()
print("Available tools:", tools)
# MCP 도구로 React Agent 생성
agent = create_react_agent(model, tools)
# 메시지를 통한 도구 호출
response = await agent.ainvoke({"messages": "서울의 날씨를 알려줘"})
print("Agent response:", response)
# 비동기 실행
asyncio.run(main())
🌐 랭그래프 코드 실행
연결하는 방법은 어렵지 않다 기존의 코드에서 tool만 client에서 받아와서 사용하면 똑같이 기존코드를 사용할수 있다.
import asyncio
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode, tools_condition
from langchain_core.runnables import RunnableConfig
from langchain_openai import ChatOpenAI
from langchain_mcp_adapters.client import SingleServerMCPClient
# ✅ 상태 정의
class State(TypedDict):
messages: Annotated[list, add_messages]
memory = MemorySaver()
# ✅ FastMCP용 클라이언트 생성 함수
async def create_client():
return SingleServerMCPClient(
url="http://localhost:8000/sse", # FastMCP 서버 포트에 맞춰 설정
transport="sse"
)
# ✅ MCP Graph 생성 함수
def mcp_graph(client):
tools = client.get_tools()
print("🔧 MCP Tools:", tools)
# LLM 설정
api_key = openai_api_key()
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0, openai_api_key=api_key)
llm_with_tools = llm.bind_tools(tools)
# 챗봇 노드 정의
def chatbot(state: State):
return {"messages": [llm_with_tools.invoke(state["messages"])]}
# 상태 그래프 정의
graph_builder = StateGraph(State)
# 노드 구성
graph_builder.add_node("chatbot", chatbot)
tool_node = ToolNode(tools=tools)
graph_builder.add_node("tools", tool_node)
graph_builder.add_conditional_edges("chatbot", tools_condition)
graph_builder.add_edge("tools", "chatbot")
# 시작과 종료 정의
graph_builder.add_edge(START, "chatbot")
graph_builder.add_edge("chatbot", END)
# 그래프 컴파일
return graph_builder.compile(checkpointer=memory)
# ✅ 메인 함수
async def main():
config = RunnableConfig(
recursion_limit=10,
configurable={"thread_id": "1"},
tags=["my-tag"]
)
async with await create_client() as client:
agent = mcp_graph(client)
response = await agent.ainvoke(
{"messages": "서울 날씨 알려줘"}, # 메시지를 MCP 도구에 맞게 조정
config=config
)
print("📨 Agent Response:", response)
# ✅ 실행
asyncio.run(main())
'코딩 > LLM' 카테고리의 다른 글
MCP SSE Remote사용하기 (2) | 2025.04.03 |
---|---|
vLLM으로 임베딩 모델 서빙 (0) | 2025.04.03 |
랭체인 VLLMOpenAI를 사용할때 모델에 맞는 형식의 프롬프트 전달 방법 (0) | 2025.02.03 |
EXAONE 3.0 7.8B 모델의 llamafied과 파인튜닝 (0) | 2024.08.08 |
LLM2Vec 디코더 전용 LLM을 텍스트 인코더로 변환하는 방법 (0) | 2024.08.08 |