시작하기 전에: 3가지 흔한 딜레마

저는 올해 초 이커머스 플랫폼 AI 고객 서비스 봇을 운영하면서 극적인 트래픽 변화를 경험했습니다. 블랙프라이데이 시즌이 다가오자 기존 서버 기반 MCP Server가 분당 500건에서 5,000건으로 요청량이 폭증했고, 저는 급히 확장성을 갖춘 서버리스 아키텍처로 마이그레이션해야 했습니다.

이 튜토리얼은 다음 상황을 해결합니다:

MCP Server 서버리스 아키텍처 개요

AWS Lambda + API Gateway 조합은 MCP Server 배포에 최적화된 서버리스 스택입니다. 이 조합의 핵심 장점은 다음과 같습니다:

사전 준비 사항

1단계: 프로젝트 구조 설정

먼저 프로젝트 디렉토리를 생성하고 필요한 패키지를 설치합니다.

# 프로젝트 디렉토리 생성
mkdir mcp-server-lambda && cd mcp-server-lambda
npm init -y

필수 의존성 설치

npm install @modelcontextprotocol/sdk npm install @aws-lambda-powertools/logger npm install @aws-lambda-powertools/metrics npm install aws-xray-sdk

개발 의존성

npm install -D typescript @types/node npx tsc --init

2단계: Lambda 핸들러 구현

MCP Server의 핵심 로직을 Lambda 함수로 구현합니다. 여기서는 HolySheep AI API를 사용하여 AI 응답 생성을 처리합니다.

import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { SSECClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import { Logger } from '@aws-lambda-powertools/logger';
import { Metrics } from '@aws-lambda-powertools/metrics';

const logger = new Logger();
const metrics = new Metrics();

// HolySheep AI API 설정
const HOLYSHEEP_API_KEY = process.env.HOLYSHEEP_API_KEY || '';
const HOLYSHEEP_BASE_URL = 'https://api.holysheep.ai/v1';

interface MCPRequest {
  jsonrpc: string;
  id: string | number;
  method: string;
  params?: {
    name?: string;
    arguments?: Record<string, unknown>;
  };
}

export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
  const requestId = event.requestContext.requestId;
  
  try {
    // POST 요청 처리 (MCP 도구 호출)
    if (event.httpMethod === 'POST') {
      const body: MCPRequest = JSON.parse(event.body || '{}');
      
      if (body.method === 'tools/call' && body.params) {
        const toolName = body.params.name;
        const args = body.params.arguments || {};
        
        logger.info(MCP Tool Call: ${toolName}, { requestId, toolName, args });
        
        // 도구별 처리 로직
        const result = await handleToolCall(toolName, args, requestId);
        
        metrics.addMetric('ToolCalls', 'Count', 1);
        
        return {
          statusCode: 200,
          headers: {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*',
          },
          body: JSON.stringify({
            jsonrpc: '2.0',
            id: body.id,
            result: result,
          }),
        };
      }
    }
    
    // GET 요청 처리 (헬스체크)
    if (event.httpMethod === 'GET' && event.path === '/health') {
      return {
        statusCode: 200,
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ status: 'healthy', timestamp: Date.now() }),
      };
    }
    
    return {
      statusCode: 400,
      body: JSON.stringify({ error: 'Invalid request' }),
    };
    
  } catch (error) {
    logger.error('MCP Handler Error', { requestId, error });
    metrics.addMetric('Errors', 'Count', 1);
    
    return {
      statusCode: 500,
      body: JSON.stringify({ error: 'Internal server error' }),
    };
  }
};

async function handleToolCall(toolName: string, args: Record<string, unknown>, requestId: string) {
  // HolySheep AI를 사용한 AI 응답 생성
  const response = await fetch(${HOLYSHEEP_BASE_URL}/chat/completions, {
    method: 'POST',
    headers: {
      'Authorization': Bearer ${HOLYSHEEP_API_KEY},
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'gpt-4.1',
      messages: [
        {
          role: 'system',
          content: '당신은 도움이 되는 AI 어시스턴트입니다.'
        },
        {
          role: 'user',
          content: args.prompt || '인사를 해주세요.'
        }
      ],
      temperature: 0.7,
      max_tokens: 1000,
    }),
  });
  
  if (!response.ok) {
    throw new Error(HolySheep API Error: ${response.status});
  }
  
  const data = await response.json();
  
  return {
    content: [
      {
        type: 'text',
        text: data.choices[0].message.content,
      },
    ],
    isError: false,
  };
}

3단계: Terraform로 인프라 배포

인프라를 코드로 관리하기 위해 Terraform 설정 파일을 작성합니다. 이 설정은 Lambda 함수, API Gateway, IAM 역할을 자동으로 프로비저닝합니다.

# terraform/main.tf

terraform {