이전 포스팅에서 Langchain 과 내가 구축한 MCP 연결하여 Streamlit 로 채팅창을 만들었습니다.
2025.06.03 - [코딩/Python_AI] - LangChain MCP 와 Streamlit 으로 채팅창 만들기
이번에는 Smithery에서 제공하는 다양한 MCP 도구를 연결하는 방법을 다루겠습니다.
Smithery는 여러 유용한 MCP 도구를 모아둔 공개 레지스트리로, 예를 들어 code-mcp, text-enhancer, filesystem 등의 도구를 제공합니다. 이 MCP들은 LangChain과 호환되며, npx 명령어를 통해 로컬에서 실행 가능합니다.
Smithery의 MCP 도구를 로컬에서 npx 명령으로 실행하는 구성하는 경우 LangChain MCP에서 stdio 기반의 MCP 도구 실행 방식과 연결됩니다.
전제조건은
이전 포스팅의 코드에서 아래 코드를 추가하면됩니다.
smithery_mcp_servers = {
"code-mcp": {
"command": "npx",
"args": [
"-y",
"@smithery/cli@latest",
"run",
"@block/code-mcp",
"--key",
"4b***-***-***"
],
"transport": "stdio",
"enabled": False
},
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"C:\\Users\\junij\\Downloads\\pic"
],
"transport": "stdio",
"enabled": False
}
}
# 모든 MCP 서버 병합: 기본 + Smithery
if "mcp_config" not in st.session_state:
st.session_state.mcp_config = {
**smithery_mcp_servers
}
아래는 전체 코드입니다.
MCP 도구 선택 UI를 사이드바로 구성했고, 체크박스를 통해 실행할 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
import sys
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from langchain_mcp_adapters.client import MultiServerMCPClient
nest_asyncio.apply()
load_dotenv()
# Windows 운영체제 호환성을 위한 이벤트 루프 정책 설정
if sys.platform == "win32":
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
# 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()
smithery_mcp_servers = {
"code-mcp": {
"command": "npx",
"args": [
"-y",
"@smithery/cli@latest",
"run",
"@block/code-mcp",
"--key",
"4bf83a94-4b96-4dc1-b052-fad63748ccff"
],
"transport": "stdio",
"enabled": False
},
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"C:\\Users\\junij\\Downloads\\pic"
],
"transport": "stdio",
"enabled": False
}
}
# 모든 MCP 서버 병합: 기본 + Smithery
if "mcp_config" not in st.session_state:
st.session_state.mcp_config = {
**default_mcp_servers,
**smithery_mcp_servers
}
# 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)
아래는 filesystem 을 이용해 로컬 파일의 내용을 변경해 본 결과 입니다.

filesystem MCP를 사용하면 로컬 디렉터리 내의 파일을 분석하거나 조작할 수 있습니다. 예를 들어, 특정 폴더 내의 이미지 파일을 불러오고 설명을 생성하는 작업이 가능합니다.
왼쪽에 체크박스를 해제하면 해당 mcp 는 사용하지 않습니다.
Smithery - Model Context Protocol Registry
@isnow890/naver-search-mcp A MCP server based on Naver Search API. Enables searching various content types (news, cafe, blogs, shopping, web search, etc.) and analyzing search/shopping trends via DataLab API. Shopping analytics provide consumer behavior pa
smithery.ai
https://github.com/langchain-ai/langchain
GitHub - langchain-ai/langchain: 🦜🔗 Build context-aware reasoning applications
🦜🔗 Build context-aware reasoning applications. Contribute to langchain-ai/langchain development by creating an account on GitHub.
github.com
| LiteLLM으로 여러 AI 모델을 한 번에 사용하기 (0) | 2025.08.11 |
|---|---|
| vLLM으로 API 서버 실행하기 (0) | 2025.07.08 |
| LangChain MCP 와 Streamlit 으로 채팅창 만들기 (0) | 2025.06.03 |
| OpenWebUI 사용하기 (0) | 2025.06.03 |
| langchain_mcp_adapters 를 이용해 Langchain 과 MCP 연동하기 (0) | 2025.06.03 |