LLM, AI 도구 / / 2025. 4. 8. 07:15

MCP Client 개발 - Langchain

이전에 만든 MCP Server 용 프로그램을 Langchain에서도 사용할 수 있다.
원래는 Langchain에서 도구를 사용할 때 @tool을 사용하여 도구를 각기 정의를 하던가, builtin tool를 가져다가 사용을 했었는데 이제는 Langchain 전용 도구가 아니라 MCP 도구를 사용할 수 있게 되었다.

그럼 Langchain에서 이전에 만든 MCP Server를 사용할 수 있도록 Client를 한번 만들어보자.

Client를 만드는 방법은 아래 주소에 잘 설명되어 있고 따라서 만들면 된다.

https://github.com/langchain-ai/langchain-mcp-adapters

대신 github에서 알려주는 코드 방식이 아니라 mcp_config.json이라는 파일 내에 mcp 설정정보를 모아두고 추가하면 langchain에서 자동으로 연결하여 사용할 수 있도록 만들어보았다. (cursor와 비슷하게)

패키지 설치

pip install langchain-mcp-adapters

# 혹은
uv add langchain-mcp-adapters

langchain_client.py내에 client 코드를 작성하였다.

같은 경로의 mcp_config.json을 로딩해서 실행한다. langchain 코드에서 연결해서 사용하면 된다.

아래와 같이 stdio, sse 방식 모두 지원하도록 했다.

import json

from dotenv import load_dotenv
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

load_dotenv()

model = ChatOpenAI(model="gpt-4o-mini")


def load_mcp_config():
    """현재 디렉토리의 MCP 설정 파일을 로드합니다."""
    try:
        with open("./mcp_config.json", "r") as f:
            return json.load(f)
    except Exception as e:
        print(f"설정 파일을 읽는 중 오류 발생: {str(e)}")
        return None


def create_server_config():
    """MCP 서버 설정을 생성합니다."""
    config = load_mcp_config()
    server_config = {}

    if config and "mcpServers" in config:
        for server_name, server_config_data in config["mcpServers"].items():
            # command가 있으면 stdio 방식
            if "command" in server_config_data:
                server_config[server_name] = {
                    "command": server_config_data.get("command"),
                    "args": server_config_data.get("args", []),
                    "transport": "stdio",
                }
            # url이 있으면 sse 방식
            elif "url" in server_config_data:
                server_config[server_name] = {
                    "url": server_config_data.get("url"),
                    "transport": "sse",
                }

    return server_config


async def main():
    server_config = create_server_config()
    async with MultiServerMCPClient(server_config) as client:
        agent = create_react_agent(model, client.get_tools())

        query = "서울 날씨 어때?"
        response = await agent.ainvoke({"messages": query})
        print(f"도구 호출 결과")
        print(f"{response['messages'][-1].content}")


if __name__ == "__main__":
    import asyncio

    asyncio.run(main())

실제 호출은 main함수로 테스트로 호출해보도록 했고, client를 Langgraph나 Langchain에서 가져다가 사용을 하면 된다.

아래는 mcp_config.json 의 내용이며 weather는 이전에 만든 날씨정보 조회하는 기능이다.

그리고 smithery(https://smithery.ai/) 같은데서 다른 MCP 설정을 가져다가 아래에 추가로 넣으도 동일하게 실행이 된다.

여기서는 desktop-commander라고 os 명령어를 실행하는 도구를 넣었고 실행해보면 langchain에서도 동일하게 실행이 된다.

{
    "mcpServers": {
        "weather": {
            "command": "uv",
            "args": [
                "--directory",
                "/Users/rudaks/mcp/server/weather",
                "run",
                "server_local.py"
            ]
        },
        "desktop-commander": {
            "command": "npx",
            "args": [
                "-y",
                "@smithery/cli@latest",
                "run",
                "@wonderwhy-er/desktop-commander",
                "--key",
                "xxxx"
            ]
        }
    }
}
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유