MCP를 알아보자 (진짜 쉬움)

7 minute read

MCP 열풍 (?)

요즘은 어딜 가도 MCP다. 유튜브를 가도, 링크드인을 가도 다 ‘MCP’를 주제로 다룬 글이나 영상 천지다. 샘 알트만도 나서서 MCP를 지원하겠다고 이야기를 할 정도이니, 그 인기를 실감할 수 있다.

심지어 github star history를 기준으로 보면 그 상승세가 어마어마한데, 이 글을 작성하는 날 (2025.04.06) 을 기준으로 하면 벌써 30k를 넘었다.

오늘은 도대체 MCP가 뭐길래, 어떻게 쓰는거길래, 무슨 포텐셜이 있길래 사람들의 관심을 독차지 하고 있는지 알아보려고한다.

그게 뭔데?

MCP는 Model Context Protocol의 약자로, LLM (Large Language Model)이 세상과 소통하는 방법을 규격화한 것일 뿐이다.

현재 LLM은 RAG (Retrieval-Augmented Generation) 라는 방식을 통해, 학습 데이터를 벗어나는 질문들에 대한 답을 할 수 있다. 예컨대, 대한민국 대통령이 누구냐는 질문에 웹 검색 기록을 모델 입력부분에 첨부함으로써 현재 대통령이 없는 상태 (2025.04.06 기준) 라는 대답을 할 수 있게 하는 것이다. LLM을 학습할 당시의 학습 데이터에는 없는 정보였지만, 우리가 추가적인 정보들을 Web, DB, REST API 등 (세상) 을 통해서 첨부해주어 정확한 답변을 만들어내는 기술이라고 생각하면 된다.

MCP를 정의한 Anthropic 이라는 회사에서는 LLM이 세상과 소통하는 ‘방법’이라는 것을 규격화하였고, 사람들이 이 규격을 이용하여 LLM Agent를 개발하도록 독려하고 있는 것이다.

근데 그거 있는거 아닌가요?

하지만, MCP를 이해할 때 가장 헷갈리는 부분은 “엥? 그거 이미 있는거 아님?”이라는 의문이 생길 때이다. LLM Agent나 RAG와 익숙한 개발자라면 응당 이런 질문이 떠오를 것이다. 사실 Agent 를 개발할 때 가장 기본적은 langchain이라는 프레임워크를 사용한다면, 우리는 이러한 ‘세상과 소통하는 방법’을 아주 간단하게 구현할 수 있었다.

그냥 langchain에 정의돈 ‘툴’을 하나 가져와서 langchain의 model에다가 던져주면, LLM이 알아서 툴을 필요할 때 사용하게 만들 수 있다.

그리고 심지어, langchain이 필요한 것도 아니다. 개발자인 내가 스스로 툴을 함수로 정의하고, 모델 input에다가 꾸겨 넣어줘도 된다. 뿐만 아니라, ActionsGPT라고, 스펙을 맞춰서 ChatGPT에 전달하면 ChatGPT가 외부 세상과 소통하는 방식을 정의하는 것도 충분히 가능하다.

“아니 그러니까, 되는데 왜?” 라는 물음이 떠오를 수 있는 것이다. 하지만 여기서 중요한 점은 바로 규격화라는 점이다.

같은 Google Search 툴을 작성한다고 하자.

  • 내가 스스로 작성한 ‘함수’는 내가 만든 ‘Agent’에서만 사용할 수 있다.
  • langchain으로 작성한 ‘툴’은 langchain의 ‘Agent’에서만 사용할 수 있으며,
  • ActionsGPT로 작성한 스펙의 ‘Action’은 ‘ChatGPT’에서만 사용할 수 있다.

이제 무엇이 문제인지가 보인다. 특정 동작을 요구하는 LLM Agent을 만들기 위해서, 어떤 프레임워크를 사용하는가에 따라 매 번 툴을 거기에 맞게 새로 작성해야한다는 것이다. 극단적으로 현재 ‘여러가지 툴을 이용할 수 있는 LLM Agent’ 하나를 만들기 위해서 프레임워크(N개) 별로 각각 툴(M개) 을 작성해야하는 “N x M” 문제가 발생해버리고 있는 것이다.

바로 이러한 문제를 해결하고자 Anthropic에서는 “여러분 지금부터는 이렇게 툴을 작성합시다! 그러면 모든 프레임워크에서 사용될 수 있을 겁니다!” 라고 이야기한 것이다.


뿐만 아니라, Anthropic에서 이러한 프로토콜을 만든 것은 부가적인 장점이 존재한다. 바로 Official 한 Tool이 정의되고 서빙될 수 있다는 점이다. 지금까지 ‘Google Search’를 툴로 이용하기 위해서는 개발자가 Search API를 직접 Wrapping해야하거나, langchain에 맞게 툴을 정의하는 작업이 필요했다. 왜냐하면 그들이 제공하는 “REST API”는 본디 LLM을 위한 것이 아니었기 때문이다. 마찬가지로 DB 접근이나 추출 등 모든 것들이 이렇게 써드파티 “Wrapper” 개발에 의존하고 있었던 것이다. 이런 방법은 큰 한계점이 존재한다. 각종 API 에 버전 등의 의존성이 생기며, 중첩된 의존성의 경우에, 하나만 규격이 바뀌어도 내가 일일이 다 찾아서 수정해야하는 악몽이 시작되는 것이다.

하지만, MCP 라는 LLM에게 툴을 제공하는 ‘방법’이라는 것이 규격화 되었기 때문에, 이제는 Google과 같은 서비스 프로바이더가 공식적인 Tool을 제공, 공개할 수 있게 되었다. 즉 구글에서 “우리는 LLM을 위한 이러이러한 Tool을 공식적으로 지원합니다.” 라고 말하게 될 것이다. PayPal에서도 결제 인보이스 생성과 관련된 MCP 서버를 공식적으로 운영하는 등의 새로운 양상이 펼쳐질 수 있다는 것이다. 이는 모든 것을 개발자가 직접 Wrapping 하던 것과는 달리, **서비스 프로바이더들이 직접 버전을 관리하고 툴 서버를 운영하게 되는 것이므로, 우리같은 일반 개발자에겐 희소식이 아닐 수 없다.

MCP 컴포넌트

즉, MCP는 “규격화된” Wrapper 에 대한 “정의” 라고 생각하면 편하다. 그림을 보면 훨씬 이해하기 쉬운데,

원래 기존에 존재했던 Tool별로 MCP Server를 만들고, 해당 Tool을 이용하기 위한 MCP Client로 연결하는 방식이다.

내가 Arxiv 논문들과 각 논문들에 대한 Reddit의 반응을 정리하여 레포트를 만드는 LLM Agent 서비스를 만드는 개발자라고 가정하자.

이 때

  • Host 는 나의 LLM Agent 서버가 되고
  • MCP Servers 는 각 Tool들 (Arxiv 에서 논문을 긁어오는, Reddit 에 검색을 하는)에 대한 서버가 될 것이고,
  • MCP Clients 는 그 각 Tool 별로 연결을 담당하는 Connector 역할을 하게 되는 것이다.

여기서 MCP Servers의 경우 해당 기능을 공식적으로, 혹은 다른 개발자가 정의해놨다면 가져다가 쓰면 된다. 이렇게 MCP 를 사용하게 된다면, 내가 LLM Agent를 개발하는 프레임워크와 상관 없이, 이미 개발된 툴들을 갖다 쓰기만하면 되는 ‘편한’ 세상이 되는 것이다.


현재 MCP Server가 제공할 수 있는 기능은 크게 3가지로 Resource, Tool, Prompt가 있다.

  • Resource는 마치 GET Method 처럼 서버가 가진 Resource를 전달해주는 역할
  • Tool은 POST Method 처럼 서버가 가진 기능을 제공해주는 역할
  • Prompt는 해당 서비스를 적합하게 이용하기 위한 Pre-defined 프롬프트를 반환하는 형태이다.

보통 Resource와 Prompt는 개발자가 직접 이용하는 방식을 택하므로, 우리가 흔히 MCP 의 장밋빛 미래를 말할 때는 Tool 을 의미하는 것이긴 하다.

Python 예제

자, 그럼 컨셉은 이해됐으니 Python으로 작성하는 Server-Client 예제를 만들어보자.

여기서 아주 아주 아주 간단한 Tool을 정의하고 LLM Agent들이 이를 실제로 활용하는지를 확인해볼 것이다. 그 간단한 툴은 유저의 선호도를 입력 받아, 오늘의 메뉴를 추천해주는 Tool이다.

먼저 메뉴 추천 툴에 대한 MCP Server 코드이다. MCP Server는 아래 그림에서의 빨간 부분에 해당한다. Service Provider, 혹은 외부 개발자가 툴에 대해 작성해야할 부분이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from typing import List
from mcp.server.fastmcp import FastMCP

server = FastMCP("MCP Menu Recommender Server")

@server.tool()
def recommend_menu(preference: str) -> str:
    """
    Recommend a menu item based on user preference.

    Args:
        preference (str): User preference, must be one of {"vegetarian", "sweet", "none"}.
    """

    if "vegetarian" in preference:
        return (
            "Today, I recommend a Caesar Salad for a fresh, vegetarian-friendly option!"
        )
    elif "sweet" in preference:
        return "Today, I recommend a Tiramisu for a delicious sweet treat!"
    else:
        return "Today, I recommend a classic Margherita Pizza!"

if __name__ == "__main__":
    server.run()
  • line 4: MCP Server를 정의한다.
  • line 6~: 해당 Server에서 제공하는 Tool 중 하나의 기능이다. 이 글에서는 간단하게 단 1개의 툴만 제공한다.

중요한 것은 후에 LLM Agent가 적재적소에 이 서버의 Tool을 잘 선택할 수 있어야 한다. 따라서 Docstring을 잘 작성해주는 것이 중요하다. 보는 것처럼, 유저의 선호도를 String으로 입력받아, 그냥 if-else로 분기하여 메뉴를 추천하고 있다.

이제, 이 MCP Server를 이용하는 코드를 살펴보자.

자, ‘MCP’라는 것은 결국 ‘규격’이고, 이 ‘규격’을 통해서 Agent를 개발할 때 프레임워크별로 따로 툴 (Server) 을 규정할필요가 없게 된다는 것을 기억해보자.

먼저, Python으로 MCP Client를 만드는 예제는 아래와 같다. 사용자의 메세지를 입력으로 받아 One Word로 대답을 하는 Agent의 예제이다. 여기서는, 편하게 langchain-mcp-adapters라는 langchain에서 만든 라이브러리를 이용한다. 이 라이브러리는 MCP 로 구성된 Tool을 lanchain 프레임워크 안에서 사용할 수 있도록 한 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import os

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from langchain_mcp_adapters.tools import load_mcp_tools
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI

os.environ["OPENAI_API_KEY"] = "your-openai-api-key"

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

server_py = os.path.join(os.path.dirname(os.path.abspath(__file__)), "server.py")
server_params = StdioServerParameters(
    command="python",
    args=[server_py],
)

async def main():
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session: # Initialize the connection
            await session.initialize()

            # Get tools
            tools = await load_mcp_tools(session)

            # Create and run the agent
            agent = create_react_agent(
                model,
                tools,
                prompt="You are a helpful assistant. Answer the user's questions in one word.",
            )
            agent_response = await agent.ainvoke(
                {"messages": "I am a vegetarian. Can you recommend a menu for me?"}
            )
            print(agent_response)

if __name__ == "__main__":
    import asyncio

    asyncio.run(main())
  • line 21~22: MCP Client Session을 구성한다.
  • line 26~34: MCP Server로 떠있는 Tool 들을 langchain의 툴 형태로 로드한다.
  • line 35: 기존과 똑같이 langchain Agent를 실행한다.

전체 소스코드 및 실행 예제는 아래 깃헙에서 찾아볼 수 있다. https://github.com/zzaebok/mcp-example

이렇게 코드를 실행하고 나면,

{
    "messages": [
        HumanMessage(
            content="I am a vegetarian. Can you recommend a menu for me?",
        ),
        AIMessage(
            content="",
            tool_calls=[
                {
                    "name": "recommend_menu",
                    "args": {"preference": "vegetarian"},
                    "type": "tool_call",
                }
            ],
        ),
        ToolMessage(
            content="Today, I recommend a Caesar Salad for a fresh, vegetarian-friendly option!",
            name="recommend_menu",
        ),
        AIMessage(
            content="Caesar Salad.",
        ),
    ]
}

위와 같은 형태로 LLM Agent Output이 출력되는 것을 확인할 수 있다. 우리가 원했던 대로, 메뉴 추천을 하는 MCP Tool을 호출하여 메뉴 추천을 받고 이를 정제하여 최종 답변을 출력하는 걸 볼 수 있다.


자, 이건 Python Client의 예제였다. MCP 는 프레임워크를 가리지 않는 ‘규격’이다. 따라서 이번에는 Python Client가 아니라, Claude Desktop App 에 MCP Tool을 연결해보도록 한다.

MCP Tool을 Claude Desktop App Config에 등록을 해주고, 서버를 가동시키면 아래와 같이 사용 가능한 Tool을 확인할 수 있다.

그리고 아까와 같은 질문을 던지면

이처럼 Claude Desktop App이 MCP Server 툴을 이용하여 메뉴를 제대로 추천해준 것을 확인할 수 있다.

MCP Registry

그럼 이제 남은 것은 뭘까? 바로 각종 서비스 프로바이더들이 자신들의 서비스를 MCP Server로 제공해주는 일이다. Google Search, Naver Maps 등등 지금까지는 개발자들이 알아서 Wrapper를 한땀한땀 프레임워크에 맞게 가공해왔다면, 이제부터는 공식 Tool Server가 출시되어야 하는 것이다.

지금 각 개발자들이 만든 MCP Server들은 아래 두 곳에서 크게 확인할 수 있다. 먼저, MCP 공식 깃헙에서 README.md 에 리스트를 정리하고 있는 곳이 있으며,

Smithery 라고 해서, 각 MCP Server 리스트들을 보여주고, 호스트까지 해주는 서비스도 있는 것으로 보인다.

서비스 프로바이더들 중에 오피셜 Integration으로는 Grafana, JetBrains, Neo4j, Qdrant 등 기존에 Tool로 사용되던 아주 다양한 컴포넌트들이 “활발히” 참여하고 있다.

앞으로 이러한 MCP Server를 제공하는 프로바이더들은 점점 더 증가할 것이고, 어떤 프레임워크를 쓰던 이러한 툴을 사용하는 LLM Agent 개발은 쉬워질 것이다.

References

  • https://docs.anthropic.com/en/docs/agents-and-tools/mcp
  • https://huggingface.co/blog/Kseniase/mcp
  • https://thefocus.ai/posts/exposing-services-with-mcp/
  • https://www.youtube.com/watch?v=7j_NE6Pjv-E
  • https://platform.openai.com/docs/actions/getting-started
  • https://github.com/langchain-ai/langchain-mcp-adapters
  • https://medium.com/@nimritakoul01/the-model-context-protocol-mcp-a-complete-tutorial-a3abe8a7f4ef
  • https://dytis.tistory.com/114

Categories: ,

Updated:

Leave a comment