ai

MCP 서버 연동하기 vs MCP서버 만들기

MCP서버를 만드는것
MCP 서버를 만들 때는 API의 각 엔드포인트를 처리하는 함수를 작성하고, 그 함수를 AI 에이전트가 인식할 수 있도록 "tool" 형태로 등록합니다. 에이전트는 작업을 처리하면서 해당 MCP 서버에 어떤 tool이 있는지 보고, 그중 무엇을 쓸지 스스로 판단해서 사용합니다.

이미 존재하는 MCP서버에 연동하기 (기업에서 제공)
MCP 서버 연동 자체는 설정 몇 줄이면 끝나고, tool(함수)들도 이미 상대 서버 쪽에 다 준비되어 있는 경우가 많습니다. 이 경우 에이전트가 하는 일은 그 서버에 있는 tool 중 무엇을 쓸지 결정하는 것뿐입니다.

에이전트란?
여기서 "에이전트"란, 내가 LLM에게 질문했을 때 그 질문을 해결하기 위해 필요한 일련의 행동(웹 검색, 파일 분석 등)을 알아서 수행해주는 비서 같은 존재를 말합니다.

들어가며

MCP(Model Context Protocol)를 처음 접하면 **"서버를 만든다"와 "서버에 연동한다"**를 같은 작업으로 생각하기 쉽다. 하지만 이 둘은 완전히 다른 역할이다.

이 글에서는 MCP 서버를 직접 만드는 것과 기존 MCP 서버를 연동하는 것의 차이를 정리하고, 실제로 연동한 이후 에이전트(LLM)가 해당 서버의 도구를 어떻게 사용하는지 설명한다.


1. MCP 서버를 "만든다"는 것

서버를 만든다는 것은 특정 기능이나 데이터를 제공하는 프로그램을 직접 구현하는 것이다.

직접 코드를 작성하고 MCP 프로토콜 규격에 맞춰 도구를 외부에 노출해야 한다.

Python에서는 보통 FastMCP와 같은 고수준 라이브러리를 사용한다. MCP 프로토콜의 저수준 처리(JSON-RPC, 스키마 정의, 세션 관리 등)를 직접 구현하지 않아도 되기 때문에, 함수에 데코레이터를 붙이는 것만으로도 간단하게 도구를 만들 수 있다.

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("weather")

@mcp.tool()
def get_weather(city: str) -> str:
    """도시의 날씨를 반환합니다."""
    return f"{city} 날씨: 맑음, 22도"

if __name__ == "__main__":
    mcp.run()

이 서버는 get_weather라는 하나의 도구를 제공한다.

실제 프로젝트에서는 날씨 조회뿐만 아니라 데이터베이스 조회, GitHub 조작, 파일 검색, API 호출 등 다양한 기능을 도구로 만들어 제공할 수 있다.

즉, MCP 서버를 만든다는 것은 AI가 사용할 수 있는 도구를 직접 개발하는 작업이라고 생각하면 된다.


2. MCP 서버에 "연동한다"는 것

연동은 이미 만들어진 MCP 서버를 Claude Desktop, Claude Code 등의 MCP 클라이언트에 등록하는 작업이다.

서버를 직접 개발할 필요 없이, 설정 파일이나 CLI 명령어를 통해 MCP 서버를 어떻게 실행할지만 알려주면 된다.

예를 들어 Claude Code에서는 다음과 같이 등록할 수 있다.

claude mcp add weather -- python /path/to/weather_server.py

또는 설정 파일에 직접 추가할 수도 있다.

{
  "mcpServers": {
    "weather": {
      "command": "python",
      "args": ["/path/to/weather_server.py"]
    }
  }
}

여기서 중요한 점은 이 서버가 내가 직접 만든 서버인지, 다른 사람이 만든 서버인지와 관계없이 기본적인 연동 개념은 동일하다는 것이다.

즉,

  • 만들기 → 개발자가 MCP 서버와 도구를 구현하는 작업

  • 연동하기 → 만들어진 MCP 서버를 클라이언트에 연결하는 작업

이라고 이해하면 된다.

구분하는 일필요한 것서버 만들기도구/기능을 코드로 구현프로그래밍, MCP SDK서버 연동만들어진 서버를 클라이언트에 등록설정 파일 또는 CLI 명령서버 사용AI가 필요한 도구를 호출에이전트의 판단


3. 연동한 이후 — 에이전트는 도구를 어떻게 쓰는가

그렇다면 MCP 서버를 연동한 이후에는 실제로 어떤 일이 일어날까?

MCP 서버를 연결하면 클라이언트는 서버에게 **"어떤 도구를 가지고 있어?"**라고 요청한다.

이때 list_tools 등을 통해 서버가 제공하는 도구의 이름, 설명, 입력값의 스키마 등의 정보를 받아온다.

예를 들어 서버가 다음과 같은 도구를 제공한다고 하자.

get_weather
설명: 도시의 현재 날씨를 조회합니다.
입력값: city (string)

이러한 도구 정보가 에이전트가 사용할 수 있는 컨텍스트에 제공된다.

그 이후 사용자가

"서울 날씨 알려줘"

라고 질문하면 에이전트는 등록되어 있는 도구들을 확인하고, 현재 요청에 필요한 도구가 있는지 판단한다.

그리고 get_weather가 적절하다고 판단하면 다음과 같이 도구를 호출한다.

get_weather("서울")

MCP 서버는 요청을 처리하고 결과를 반환한다.

서울 날씨: 맑음, 22도

에이전트는 이 결과를 바탕으로 최종 답변을 생성한다.

전체 흐름을 단순화하면 다음과 같다.

사용자
  ↓
"서울 날씨 알려줘"
  ↓
에이전트(LLM)
  ↓
사용 가능한 MCP Tool 확인
  ↓
get_weather 선택
  ↓
MCP 서버에 Tool 호출
  ↓
날씨 정보 반환
  ↓
에이전트가 결과를 이용해 답변

여기서 중요한 점은 사람이 매번 "get_weather를 사용해"라고 지정할 필요가 없다는 것이다.

도구의 이름과 설명, 입력 스키마 등을 바탕으로 LLM이 현재 상황에 적절한 도구를 사용할지 판단한다.


4. 에이전트가 도구를 선택할 때 주의할 점

다만 LLM이 항상 정확하게 도구를 선택하는 것은 아니다.

도구 설명이 중요하다

LLM은 도구의 이름과 설명을 보고 어떤 상황에서 해당 도구를 사용해야 하는지 판단한다.

따라서 도구의 목적과 사용 조건을 명확하게 작성하는 것이 중요하다.

예를 들어

search()

보다는

GitHub Issue에서 키워드와 일치하는 Issue를 검색합니다.
기존 Issue를 찾을 때 사용합니다.

처럼 구체적으로 설명하는 것이 좋다.

MCP 서버가 많아질수록 복잡해질 수 있다

여러 MCP 서버를 동시에 연결하면 사용할 수 있는 도구의 수도 많아진다.

예를 들어

GitHub MCP
 ├─ search_issue
 ├─ create_issue
 └─ create_pr

Database MCP
 ├─ search_user
 └─ execute_query

Slack MCP
 ├─ search_message
 └─ send_message

처럼 수많은 도구가 존재할 수 있다.

도구가 너무 많아지면 에이전트가 어떤 도구를 사용해야 하는지 판단하는 과정이 복잡해질 수 있고, 컨텍스트 부담도 커질 수 있다.

도구 호출은 항상 보장되는 것은 아니다

MCP에 도구가 등록되어 있다고 해서 LLM이 반드시 그 도구를 호출하는 것은 아니다.

최종적으로 어떤 도구를 사용할지, 또는 도구를 사용하지 않을지는 에이전트의 판단에 달려 있다.

따라서 도구를 설계할 때는 명확한 이름과 설명, 적절한 입력 스키마를 제공하는 것이 중요하다.


정리

MCP를 이해할 때는 다음 세 가지를 구분하면 쉽다.

  • 서버 만들기 = AI가 사용할 수 있는 도구를 코드로 구현하는 개발 작업

  • 서버 연동 = 이미 만들어진 MCP 서버를 클라이언트에 등록하는 설정 작업

  • 도구 사용 = 에이전트(LLM)가 대화의 맥락을 보고 필요한 도구를 선택해서 호출하는 과정

결국 MCP 서버는 **"AI가 사용할 수 있는 도구를 제공하는 곳"**이고, 에이전트는 그중에서 현재 상황에 어떤 도구가 필요한지 판단하는 역할을 한다.

쉽게 비유하면 MCP 서버는 도구 창고이고, 에이전트는 그 창고에서 어떤 도구를 언제 꺼내 사용할지 결정하는 사람이라고 생각하면 된다.