mcp-demo-server
MCP 데모 — Python 에이전트 도구를 처음부터 직접 구현하기
MCP란 무엇인가?
MCP (Model Context Protocol) 는 AI 애플리케이션이 하나의 일관된 인터페이스를 통해 외부 도구, 리소스, 프롬프트를 발견하고 사용할 수 있게 해주는 표준화된 프로토콜입니다.
모든 AI 프레임워크가 데이터베이스, API, 파일시스템, 내부 서비스마다 서로 다른 통합 방식을 발명하는 대신, MCP 호스트는 MCP 서버에 연결하여 동일한 프로토콜 표면을 사용할 수 있습니다.
MCP가 해결하는 문제
문제 | MCP 솔루션 |
벤더 종속 | 통합이 특정 모델 제공자나 에이전트 프레임워크에 묶이지 않고 MCP를 통해 기능을 노출함 |
비일관적인 도구 호출 | 도구가 기계가 읽을 수 있는 스키마와 표준화된 발견/호출 의미론을 가짐 |
컨텍스트 지속성 부재 | MCP가 컨텍스트/도구 제공자를 모델과 분리하여 장기 연결을 가능하게 함 |
동적 데이터 소스 | 데이터베이스, API, 파일, 내부 시스템이 구현을 모델 런타임에 내장하지 않고 MCP 리소스/도구로 래핑됨 |
네트워크 상에서 MCP는 JSON-RPC 2.0 메시지를 stdio 및 HTTP 기반 전송(SSE/Streamable HTTP)과 같은 전송 방식을 통해 사용합니다. 이 저장소는 stdio를 사용합니다: 클라이언트가 서버를 하위 프로세스로 실행하고, stdin을 통해 프로토콜 메시지를 보내며, stdout을 통해 응답을 받습니다.
Related MCP server: Weather MCP Server
아키텍처
flowchart TD
A[User: "What's the weather in London?"] --> B[AI Agent<br/>OpenAI Responses API]
B --> C[1. Discovers MCP tools]
B --> D[2. Decides whether to call]
B --> E[3. Emits function call]
E --> F[MCP Client<br/>ClientSession + stdio]
F --> G[initialize]
F --> H[tools/list]
F --> I[tools/call]
I --> J[JSON-RPC 2.0<br/>stdin/stdout]
J --> K[MCP Server subprocess]
K --> L[get_current_weather tool]
K --> M[greeting://{name} resource]공식 SDK를 사용하는 이유?
이 저장소는 프로토콜을 재구현하는 대신 공식 Python MCP SDK를 사용합니다. SDK는 다음을 제공합니다:
프로토콜 수명주기 및 검증
전송 추상화 (stdio, HTTP/SSE)
타입이 지정된 클라이언트/서버 API
애플리케이션 코드는 여전히 중요한 MCP 개념을 명시적으로 드러냅니다: 서버 등록, 도구 스키마, initialize, tools/list, tools/call, 리소스 읽기, stdio 프로세스 관리.
현재 SDK의 안정적인 v2 API는 서버 구축에
MCPServer를, stdio 클라이언트에ClientSession/stdio_client를 사용합니다.
프로젝트 구조
mcp-demo/
├── README.md
├── requirements.txt
├── .env.example
├── pyproject.toml
├── src/
│ ├── mcp_server/
│ │ ├── __init__.py
│ │ ├── server.py # MCP server entry point
│ │ ├── tools.py # Tool implementations
│ │ ├── handlers.py # Request handlers
│ │ └── utils.py # Shared utilities
│ ├── mcp_client/
│ │ ├── __init__.py
│ │ ├── client.py # MCP client wrapper
│ │ ├── agent.py # OpenAI agent integration
│ │ └── runner.py # Demo runner
│ └── shared/
│ ├── __init__.py
│ └── types.py # Shared Pydantic models
├── tests/
│ ├── test_server.py
│ └── test_client.py
├── examples/
│ └── demo.ipynb
└── scripts/
└── run_demo.sh요구 사항
Python 3.10 이상
OpenAI API 키 (AI 에이전트 데모용)
날씨 API 키 불필요 — 날씨 도구는 결정적 샘플 데이터를 사용하므로 MCP 경로가 오프라인에서도 작동합니다
빠른 시작
1. 가상 환경 생성
python -m venv .venv
source .venv/bin/activate # Linux/macOS
.venv\Scripts\Activate.ps1 # Windows PowerShell2. 의존성 설치
python -m pip install --upgrade pip
pip install -r requirements.txt3. OpenAI 구성
cp .env.example .env자격 증명으로 .env를 편집하세요:
OPENAI_API_KEY=your_api_key_here
OPENAI_MODEL=gpt-4.1-mini서버 자체는 OpenAI 키가 필요하지 않습니다.
데모 실행
저장소 루트에서
python src/mcp_client/runner.py러너가 수행하는 작업:
단계 | 설명 |
1️⃣ |
|
2️⃣ | MCP 초기화 핸드셰이크 수행 |
3️⃣ |
|
4️⃣ | 발견된 MCP 스키마 → OpenAI 함수 도구로 변환 |
5️⃣ | 모델에게 자연어 질문에 답하도록 요청 |
6️⃣ | 모델이 |
7️⃣ | MCP 결과를 모델에게 다시 전송 |
8️⃣ | 최종 답변 출력 |
9️⃣ | 서버를 깨끗하게 종료 |
대안: 셸 래퍼
bash scripts/run_demo.sh예상 출력
정확한 문구는 모델에 따라 다르지만, 로그 흐름은 다음과 같습니다:
INFO mcp_client.client: -> MCP initialize
INFO mcp_client.client: <- MCP initialize: server=mcp-demo-server
INFO mcp_client.client: -> MCP tools/list
INFO mcp_client.client: <- MCP tools/list: ["get_current_weather"]
INFO mcp_client.agent: User: What's the weather in London?
INFO mcp_client.agent: OpenAI requested tool: get_current_weather {"city":"London","units":"metric"}
INFO mcp_client.client: -> MCP tools/call name=get_current_weather arguments={"city":"London","units":"metric"}
INFO mcp_server.tools: weather lookup city=London units=metric
INFO mcp_client.client: <- MCP tools/call result={"city":"London","temperature":18.0,...}
INFO mcp_client.agent: Final: London is 18°C and partly cloudy.로그는 의도적으로 애플리케이션 경계에서 MCP 의미 메시지를 보여줍니다. SDK가 JSON-RPC 프레이밍을 내부적으로 처리합니다.
MCP 서버 단독 실행
python src/mcp_server/server.pystdio MCP 서버는 "멈춘" 것처럼 보입니다 — 이는 정상입니다. stdin에서 프로토콜 메시지를 기다리기 때문입니다. 호스트/클라이언트가 서버를 실행하고 stdio 파이프를 소유해야 합니다.
대화형 프로토콜 검사
pip install "mcp[cli]"
mcp dev src/mcp_server/server.py시연되는 MCP 메서드
공식 SDK가 JSON-RPC 수명주기를 처리합니다:
메서드 | 방향 | 목적 |
| 클라이언트 → 서버 | 핸드셰이크 및 기능 협상 |
| 클라이언트 → 서버 | 사용 가능한 도구 발견 |
| 클라이언트 → 서버 | 도구 호출 |
| 클라이언트 → 서버 | 사용 가능한 리소스 발견 |
| 클라이언트 → 서버 | 리소스 읽기 |
클라이언트는 기능을 나열하거나 호출하기 전에 명시적으로 initialize()를 호출합니다. 서버의 데코레이터는 Python 타입 어노테이션에서 도구/리소스 스키마를 생성합니다.
도구: get_current_weather
get_current_weather(
city: str,
units: Literal["metric", "imperial"] = "metric"
) -> WeatherResponse구조화된 Pydantic 기반 페이로드를 반환합니다:
{
"city": "London",
"temperature": 18.0,
"units": "metric",
"condition": "partly cloudy",
"humidity_percent": 72
}알 수 없는 도시는 서버를 중단시키는 대신 통제된 MCP 도구 오류로 실패합니다.
에이전트 통합 흐름
에이전트는 데모를 집중적으로 유지하기 위해 일반 OpenAI 함수 호출(추가 프레임워크 없음)을 사용합니다:
flowchart LR
A[MCP Tool Schema] --> B[OpenAI Function Tool]
B --> C[Model Chooses Function]
C --> D[MCP ClientSession.call_tool]
D --> E[MCP Server Executes Tool]
E --> F[Function Call Output]
F --> G[Final Model Answer]이것은 에이전트 프레임워크가 래핑하는 것과 동일한 패턴입니다: MCP 도구 발견 → 모델에 스키마 노출 → 선택된 호출을 MCP로 다시 라우팅 → 결과를 다음 모델 턴에 공급.
테스트
pytest -q테스트 스위트가 다루는 범위:
✅ 도구 실행 (미터법 날씨)
✅ 도구 실행 (야드파운드법 날씨)
✅ 검증/오류 동작 (알 수 없는 도시)
✅ 프로세스 내 MCP 클라이언트 발견 및 도구 호출
테스트는 가능한 경우 SDK의 인메모리 클라이언트를 사용합니다 — 실제 MCP 프로토콜 계층을 실행하면서 하위 프로세스 불안정성을 피합니다.
포맷팅 및 린팅
이 프로젝트는 Ruff 를 사용합니다:
# Check
ruff check .
ruff format --check .
# Format
ruff format .프로덕션 참고 사항
이 데모는 의도적으로 작지만 여러 프로덕션 고려 사항을 나타냅니다:
고려 사항 | 구현 |
stdout 규율 | 서버는 앱 로그를 stdout에 출력하지 않음 (MCP 전용); 로그는 |
타입이 지정된 I/O | Pydantic 모델이 애플리케이션 경계에서 도구 입력/출력 검증 |
통제된 실패 | 도구 예외 → MCP 오류 결과 (SDK), 프로세스 중단이 아님 |
하위 프로세스 수명주기 | SDK의 stdio 컨텍스트 관리자가 프로세스 시작/종료를 소유 |
최소 권한 환경 | MCP stdio 클라이언트가 하위 프로세스에 필요한 환경 변수만 명시적으로 전달 |
동적 발견 | 에이전트가 날씨 도구 스키마를 하드코딩하지 않고 |
실제 외부 데이터 소스의 경우: 결정적 날씨를 인증된 API/데이터베이스 호출로 대체하고, 타임아웃, 재시도, 속도 제한, 관찰 가능성, 비밀 관리를 추가하세요.
프로토콜 개념 모델
단순화된 JSON-RPC 시퀀스:
// Client -> Server
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{...}}
// Server -> Client
{"jsonrpc":"2.0","id":1,"result":{...}}
// Client -> Server
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}
// Server -> Client
{"jsonrpc":"2.0","id":2,"result":{"tools":[...]}}
// Client -> Server
{"jsonrpc":"2.0","id":3,"method":"tools/call",
"params":{"name":"get_current_weather","arguments":{"city":"London"}}}
// Server -> Client
{"jsonrpc":"2.0","id":3,"result":{"content":[...],"structuredContent":{...}}}정확한 프로토콜 스키마는 MCP 사양과 SDK가 유지 관리합니다. 위 내용은 교육 목적으로 의도적으로 단순화되었습니다.
참고 자료
공식 MCP Python SDK: https://py.sdk.modelcontextprotocol.io/
OpenAI 함수 호출: https://platform.openai.com/docs/guides/function-calling
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables AI agents to retrieve real-time weather conditions and forecasts via OpenWeatherMap API. Supports interactive weather queries and travel planning through MCP tools, resources, and prompts.2
- AlicenseNot gradedqualityDmaintenanceProvides weather data from OpenWeatherMap API through MCP tools and a REST API with OpenAPI support. Enables LLM agents to retrieve current weather, forecasts, and temperature ranges by city or coordinates.21MIT
- AlicenseNot gradedqualityCmaintenanceWraps the OpenWeatherMap API to provide weather data through MCP, enabling AI agents to query current conditions, forecasts, and other weather information via natural language.10MIT
- AlicenseNot gradedqualityCmaintenanceProvides weather data from WeatherAPI.com through MCP, enabling AI agents to query current conditions and forecasts via natural language.11MIT
Related MCP Connectors
Pocket Agent (aipocketagent.com) MCP server — read tools for personas, apps, and product info.
OpenWeather MCP — wraps the OpenWeatherMap API (openweathermap.org)
NOAA and ECMWF weather forecast MCP for discovery, validation, and GribStream OAuth queries.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mhamzanadeem/mcp-playground'
If you have feedback or need assistance with the MCP directory API, please join our Discord server