MCP 클라이언트 빌드 (코어)

MCP 클라이언트 빌드 (코어)

이 페이지는 공식 튜토리얼에서 핵심 내용을 추출하여 최소 실행 구현(플랜 A)에 집중합니다. 모든 예제와 코드는 공식 문서에서 가져왔습니다.

권장 선행 학습: /docs/quickstart/server/ (클라이언트-서버 통신 모델 이해)

시스템 요구 사항 (Python)

  • macOS 또는 Windows
  • 최신 Python 버전
  • uv 설치됨

프로젝트 초기화 (Python)

uv init mcp-client
cd mcp-client
uv venv
source .venv/bin/activate
uv add mcp anthropic python-dotenv
rm main.py
touch client.py

API 키 설정 (Anthropic)

echo "ANTHROPIC_API_KEY=<your key here>" > .env
echo ".env" >> .gitignore

클라이언트 스켈레톤 (공식 예제)

import asyncio
from typing import Optional
from contextlib import AsyncExitStack

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

from anthropic import Anthropic
from dotenv import load_dotenv

load_dotenv()

class MCPClient:
    def __init__(self):
        self.session: Optional[ClientSession] = None
        self.exit_stack = AsyncExitStack()
        self.anthropic = Anthropic()
    # methods will go here

MCP 서버 연결 (공식 예제)

async def connect_to_server(self, server_script_path: str):
    is_python = server_script_path.endswith('.py')
    is_js = server_script_path.endswith('.js')
    if not (is_python or is_js):
        raise ValueError("Server script must be a .py or .js file")

    command = "python" if is_python else "node"
    server_params = StdioServerParameters(
        command=command,
        args=[server_script_path],
        env=None
    )

    stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
    self.stdio, self.write = stdio_transport
    self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))

    await self.session.initialize()

    response = await self.session.list_tools()
    tools = response.tools
    print("\nConnected to server with tools:", [tool.name for tool in tools])

질의 처리 (공식 발췌)

async def process_query(self, query: str) -> str:
    messages = [{"role": "user", "content": query}]
    response = await self.session.list_tools()
    available_tools = [{
        "name": tool.name,
        "description": tool.description,
        "input_schema": tool.inputSchema
    } for tool in response.tools]
    response = self.anthropic.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=1000,
        messages=messages,
        tools=available_tools
    )

다음 단계

  • 도구 실행과 결과 집계 추가
  • 공식 튜토리얼과 동일한 TypeScript 버전 추가
  • 오류 처리와 재시도 로직 추가
  • /specification/draft/basic/authorization/ 과 일치하도록 OAuth 토큰 통합