지난 포스팅에 이어서
2025.06.03 - [코딩/Python_AI] - langchain_mcp_adapters 를 이용해 Langchain 과 MCP 연동하기
이번 포스팅에서는 Streamlit 으로 채팅 화면을 만드는 방법을 알아봅니다.
MCP 서버를 통해 수학 계산, 날씨 조회 등의 외부 도구를 직접 호출하는 구조를 기반으로 하며 모두 외부서버로 떠 있어야합니다.
weather server (8010)
from typing import List
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Weather", port=8010)
@mcp.tool()
async def get_weather(location: str) -> str:
"""해당 지역의 날씨를 알려줍니다."""
return "날씨는 맑음입니다."
if __name__ == "__main__":
mcp.run(transport="streamable-http")
math server (8020)
# math_server.py
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Math", port=8020)
@mcp.tool()
def add(a: int, b: int) -> int:
"""두 수를 더합니다."""
return a + b
@mcp.tool()
def multiply(a: int, b: int) -> int:
"""두 수를 곱합니다."""
return a * b
if __name__ == "__main__":
# mcp.run(transport="stdio")
mcp.run(transport="streamable-http")
streamlit 을 이용한 app 코드입니다.
mcp 도구를 체크 박스로 사용여부를 설정할 수 있습니다.
# pip install streamlit langchain-openai langchain langchain-mcp-adapters
# pip install nest_asyncio
import streamlit as st
import os
from dotenv import load_dotenv
import asyncio
import nest_asyncio
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from langchain_mcp_adapters.client import MultiServerMCPClient
nest_asyncio.apply()
load_dotenv()
# OpenAI API 키 로드
openai_key = os.getenv("OPENAI_API_KEY")
if not openai_key:
st.error("❌ OPENAI_API_KEY 가 .env에 설정되어 있지 않습니다.")
st.stop()
# MCP 서버 정의 (토글용)
default_mcp_servers = {
"math": {
"url": "http://localhost:8020/mcp",
"transport": "streamable_http",
"enabled": True
},
"weather": {
"url": "http://localhost:8010/mcp",
"transport": "streamable_http",
"enabled": True
}
}
st.title("🔧 LangChain MCP 채팅")
st.markdown("OpenAI GPT-4o + MCP 도구 연동")
# 세션 상태 초기화
if "chat_history" not in st.session_state:
st.session_state.chat_history = []
if "mcp_config" not in st.session_state:
st.session_state.mcp_config = default_mcp_servers.copy()
# MCP 도구 토글 UI
st.sidebar.title("🧩 MCP 도구 설정")
for name, config in st.session_state.mcp_config.items():
config["enabled"] = st.sidebar.checkbox(name, value=config["enabled"])
# 사용자 입력
user_input = st.chat_input("질문을 입력하세요...")
# 메인 비동기 처리
async def handle_query(query):
# 사용 중인 MCP 도구만 필터링
active_tools = {
name: {k: v for k, v in config.items() if k != "enabled"}
for name, config in st.session_state.mcp_config.items() if config["enabled"]
}
client = MultiServerMCPClient(active_tools)
tools = await client.get_tools()
model = ChatOpenAI(openai_api_key=openai_key, model="gpt-4o", temperature=0)
agent = create_react_agent(model=model, tools=tools)
response = await agent.ainvoke({"messages": [{"role": "user", "content": query}]})
tool_used = None
final_answer = None
for message in response.get("messages", []):
if hasattr(message, "tool_calls") and message.tool_calls:
for tool_call in message.tool_calls:
tool_used = tool_call.get("name")
if hasattr(message, "content") and message.content:
final_answer = message.content
return tool_used, final_answer
# 채팅 처리
if user_input:
st.session_state.chat_history.append(("user", user_input))
tool, answer = asyncio.run(handle_query(user_input))
tool_msg = f"🔧 MCP 도구 사용됨: `{tool}`" if tool else "🧠 도구 사용 없이 응답함"
st.session_state.chat_history.append(("assistant", f"{tool_msg}\n\n{answer}"))
# 채팅 UI 렌더링
for sender, message in st.session_state.chat_history:
with st.chat_message(sender):
st.markdown(message)
위 코드를 보면 알수 있듯이 도구를 사용한 경우는 어떤 도구를 사용했는지 알려주면 도구를 사용하지 않은 경우도 표시해 줍니다.
일반적인 대화도 가능하지만 mcp 도구가 필요한 경우 도구를 활용해 응답하게 됩니다.
* .env 파일에 OPEN API KEY 가 설정되어있어야 합니다.
결과
LangChain 을 이용한 Streamlit 채팅에 Smithery MCP 추가하기 (1) | 2025.06.07 |
---|---|
OpenWebUI 사용하기 (0) | 2025.06.03 |
langchain_mcp_adapters 를 이용해 Langchain 과 MCP 연동하기 (0) | 2025.06.03 |
A2A 샘플 실행해 보기 (0) | 2025.05.31 |
vLLM 사용하기 (0) | 2025.05.26 |