한 줄 요약: MCP 서버(MCP Server)란, Model Context Protocol을 구현해 AI 모델(클라이언트)이 특정 리소스나 도구에 표준화된 방식으로 접근할 수 있도록 인터페이스를 제공하는 서버 프로세스이다.


1. MCP 서버란 무엇인가?

번역 앱을 생각해 보세요. 번역 앱(AI 클라이언트)은 여러 번역 API(서버)에 연결할 수 있습니다. Google 번역, Papago, DeepL 등 다양한 서버가 있지만, 모두 HTTP 표준 프로토콜로 통신합니다.

MCP 서버는 이와 유사합니다. AI 에이전트(Claude 등)가 파일 시스템, GitHub, Slack, 데이터베이스 등 다양한 외부 서비스에 접근할 때 MCP 프로토콜이라는 표준으로 통신합니다. MCP 서버는 이 프로토콜을 구현한 중간 레이어입니다.

MCP 서버의 역할:

  • AI ↔ 외부 세계 사이의 표준 통신 레이어
  • 리소스(데이터), 도구(함수), 프롬프트 제공
  • 인증, 권한, 에러 처리 캡슐화

2. 핵심 개념 이해하기

MCP 아키텍처에서의 서버 위치

┌─────────────────────────────────────────┐
│       MCP 호스트 (Claude Desktop 등)     │
│  ┌───────────────────────────────────┐  │
│  │         MCP 클라이언트             │  │
│  └───────────────┬───────────────────┘  │
└──────────────────┼──────────────────────┘
                   │ JSON-RPC 2.0
        ┌──────────┼──────────┐
        ↓          ↓          ↓
   ┌─────────┐ ┌─────────┐ ┌─────────┐
   │  파일   │ │ GitHub  │ │ Slack   │
   │ MCP 서버│ │ MCP 서버│ │ MCP 서버│
   └─────────┘ └─────────┘ └─────────┘
        ↓          ↓          ↓
   파일시스템   GitHub API  Slack API

서버가 제공하는 세 가지 기능

# 1. Resources: AI가 읽을 수 있는 데이터
@server.list_resources()
async def list_resources():
    return [Resource(uri="file:///data/report.pdf", name="분기 보고서")]

# 2. Tools: AI가 실행할 수 있는 함수
@server.list_tools()
async def list_tools():
    return [Tool(name="send_email", description="이메일 전송")]

# 3. Prompts: 재사용 가능한 프롬프트 템플릿
@server.list_prompts()
async def list_prompts():
    return [Prompt(name="code_review", description="코드 리뷰 템플릿")]

공식 MCP 서버 목록 (Anthropic 제공)

서버 기능
@modelcontextprotocol/server-filesystem 로컬 파일 시스템 접근
@modelcontextprotocol/server-github GitHub API (이슈, PR, 코드)
@modelcontextprotocol/server-postgres PostgreSQL 쿼리 실행
@modelcontextprotocol/server-slack Slack 메시지/채널 관리
@modelcontextprotocol/server-puppeteer 웹 브라우저 자동화

3. 실무 적용 예시

날씨 API를 제공하는 커스텀 MCP 서버 구현입니다.

import asyncio
import aiohttp
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp import types

app = Server("weather-server")

WEATHER_API_KEY = "your_api_key"

@app.list_tools()
async def list_tools() -> list[types.Tool]:
    return [
        types.Tool(
            name="get_weather",
            description="도시의 현재 날씨 정보를 가져옵니다",
            inputSchema={
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "도시 이름 (영문)"
                    },
                    "units": {
                        "type": "string",
                        "enum": ["metric", "imperial"],
                        "default": "metric"
                    }
                },
                "required": ["city"]
            }
        )
    ]

@app.call_tool()
async def call_tool(name: str, arguments: dict) -> list[types.TextContent]:
    if name == "get_weather":
        city = arguments["city"]
        units = arguments.get("units", "metric")

        async with aiohttp.ClientSession() as session:
            url = f"https://api.openweathermap.org/data/2.5/weather"
            params = {"q": city, "appid": WEATHER_API_KEY, "units": units}
            async with session.get(url, params=params) as resp:
                data = await resp.json()

        if data.get("cod") != 200:
            return [types.TextContent(type="text", text=f"오류: {data.get('message')}")]

        temp = data["main"]["temp"]
        desc = data["weather"][0]["description"]
        humidity = data["main"]["humidity"]
        unit_symbol = "°C" if units == "metric" else "°F"

        result = f"{city} 현재 날씨: {temp}{unit_symbol}, {desc}, 습도 {humidity}%"
        return [types.TextContent(type="text", text=result)]

    raise ValueError(f"Unknown tool: {name}")

async def main():
    async with stdio_server() as (read_stream, write_stream):
        await app.run(read_stream, write_stream, app.create_initialization_options())

if __name__ == "__main__":
    asyncio.run(main())

Claude Desktop 등록:

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

4. MCP 서버 vs 유사 개념 비교

구분 MCP 서버 REST API 플러그인
표준화 ✅ MCP 프로토콜 개별 설계 플랫폼별 상이
AI 특화 ✅ 컨텍스트 인식 ❌ 범용 부분
재사용성 ✅ 모든 MCP 호스트 ❌ 클라이언트별 구현 ❌ 특정 플랫폼만
양방향 제한적 제한적
오픈 생태계 혼합

5. 마치며

MCP 서버는 AI 에이전트 시대의 핵심 인프라입니다. 한 번 MCP 서버를 만들면 Claude Desktop, Cursor, Zed, 그리고 MCP를 지원하는 모든 AI 도구에서 재사용할 수 있습니다. 플러그인 시스템(Plugin System)툴 콜링(Tool Calling)을 함께 이해하면 MCP 생태계를 완전히 활용할 수 있습니다.

참고 자료

함께 읽으면 좋은 용어

이 개념과 함께 알아두면 이해가 깊어지는 관련 용어들입니다.

댓글 남기기