반응형
바이브 코딩을 위한 스킬, 서브에이전트 등의 필요한 지침을 만들다 나에 대한 지침은 무엇일까? 엉뚱한 생각을 해봤다.
친구에게 큰 돈을 빌려주지 않는다 등의 원칙들은 있지만, 이것들은 큰 차원의 지침인것 같고 딱히 없는 것 같다. 몇몇 습관들은 지침이 만든 결과일수 있겠지만, 사소하다.
AI 는 프롬프트 엔지니어링에서 하네스 엔지니어링으로 진화하면서, 출력의 품질이 점점 개선된다. 입장을 바꿔서 나라는 사람이 더 생산성을 내거나 좋은 출력물을 만들어내려면, 엔지니어링기법이 적용된 어떤 지침들이 필요하지 않을까?
딥러닝이 뇌 신경망 구조를 컨셉으로 만들어졌듯, AI 기술들이 인간의 성질과 속성을 모방하는 방향으로 진화하고 있다. 짐깐 주체를 나로 바꿔보는 것도 재밌을 것 같다.
인생이 내 맘대로 잘 풀리지 않는다면, 나에 대한 지침이 무엇인가를 고민해봐야 하는 시점이다

반응형
반응형

 

요즘 AI 가 발달하면서 생겨난 일명 "바이브 코딩" 이라는 기술로, 아이디어만 있으면, 누구나 개발이 가능한 환경이 갖춰졌다.

 

나 역시도 마찬가지로 바이브 코딩으로 하고 싶었던 주제로 서비스를 만들어보기도 하고, 툴을 만들면서 내 업무의 생산성을 높이고 있다.

 

오늘 다룰 Github Action 이라는 주제와 맞지 않는 서문일 수 있지만, 우리가 만든 개발물은 결국 Git 을 통해 형상관리를 해줘야 손이 덜 가게 된다는 것을 느낄 것이다.

 

Github 는 Git 을 온라인 호스팅으로 서비스하고 있는 솔루션으로 보면 되고, 마이크소프트 산하의 제품이다.

 

Github 든 GitLab 이던 Repository 를 만들어 코드를 관리하고 있다면, 매번 새로운 Commit, Merge 가 일어날 때마다 서버에 진입하며 코드를 최신화 ($ git pull) 하고 서비스를 재시작 해야 할 것이다.

 

보통은 이 과정들을 Script 로 만들고, Jenkins , GoCD 와 같은 CI/CD 서비스 를 이용하여 Git 에 커밋이 발생할 때 자동으로 배포하게 만든다.

 

Github Action 도 비슷한 기능이 있어, 아래 소개한다.

  • 준비
    • 서비스 자동화 스크립트
    • 서비스 자동화 스크립트가 배포된 EC2 서버
  • 시나리오
    • 서비스 서버에 배포용 SSH 키페어를 생성한다.
    • 생성된 공개키를 서버의 authorized_keys 에 추가한다.
    • Github Secrets 설정에서 원격 서버의 정보를 저장한다.
    • workflow yaml 파일을 작성한다.
    • Git Action 에서 워크플로우를 실행한다.

전체 과정

1. SSH 키 생성 및 설정

 

 

먼저 로컬에서 SSH 키 페어를 생성

ssh-keygen -t ed25519 -C "github-actions"

 

생성된 공개키(id_ed25519.pub)를 서버의 ~/.ssh/authorized_keys에 추가, 개인키(id_ed25519)는 일단 복사한다.

2. GitHub Secrets 설정

Repository → Settings → Secrets and variables → Actions에서 다음 정보들을 등록

  • SSH_PRIVATE_KEY: SSH 개인키 내용 (1번 과정에서 복사한 개인키를 복사해서 붙여넣는다.)
  • SERVER_HOST: 서버 IP 또는 도메인
  • SERVER_USER: SSH 접속 유저명
  • SERVER_PORT: SSH 포트 (기본값 22)

3. GitHub Actions Workflow 파일 생성

.github/workflows/deploy.yml 파일을 생성합니다:## 더 간단한 방법: marketplace action 사용

SSH 액션을 직접 작성하는 대신, 검증된 marketplace action을 사용할 수도 있습니다:

  1. 코드 푸시: 워크플로우 파일을 커밋하고 main 브랜치에 푸시
  2. Actions 탭 확인: GitHub Repository의 Actions 탭에서 실행 상태 확인
  3. 로그 확인: 각 step의 실행 로그를 확인하여 성공/실패 여부 파악
    name: Test Workflow (여기 이름이 워크플로우 목록에 뜸)
    
    on:
      # 수동 실행 가능하도록 설정 (테스트용)
      workflow_dispatch:
      
      # push할 때도 실행 (원하면 주석 해제)
      # push:
      #   branches:
      #     - main
    
    jobs:  #워크플로우에서 실행할 작업(job)들을 정의합
      test-workflow: # 작업(job)의 고유한 이름입니다. 여기서는 '연결 테스트' 역할
        runs-on: ubuntu-latest
        # 이 작업이 실행될 환경을 지정. 최신 버전의 Ubuntu 가상 머신에서 실행
        steps:
        - name: Checkout code 
          uses: actions/checkout@v4 # GitHub 저장소의 코드를 가상 환경으로 가져오는(체크아웃하는) 공식 액션(v4 버전)을 사용
      
        - name: SSH Connection Test 
          uses: appleboy/ssh-action@v1.0.0 # SSH를 통해 원격 서버에 명령을 실행하는 서드파티 액션(v1.0.0 버전)을 사용
          with:
            host: ${{ secrets.SERVER_HOST }}
            username: ${{ secrets.SERVER_USER }}
            key: ${{ secrets.SSH_PRIVATE_KEY }}
            port: 22
            script: |
              echo "SSH Connection Test Success"
              [여기에 자동화 스크립트 실행 명령어를 넣으면 된다.]

 

결과 

이 방법으로 코드가 푸시될 때마다 자동으로 서버에 배포하거나 특정 작업을 실행할 수 있다.

 


결론

  • 배포 자동화는 사실 구성하기 귀찮다. 손도 많이가고, 시간도 많이 소요된다.
  • 그런데 한 번 구성해놓으면, 그 후는 정말 편하다.
  • 서비스 배포를 한동안 안하다가 오랜만에 하면 까먹고, 다시 기억해내려면 시간이 또 걸리거든.

 

반응형
반응형

잡담.

MCP 서버를 내가 외부에 제공한다고 했을 때, 여러 방법이 있을 것 같다.

가장 먼저 생각나는 건 서버 코드를 공유하고 stdio 실행 방식으로 제공하는 방식, 그리고 또 다른 방법은 웹서버를 띄워 StreamableHTTP 방식으로 제공하는 것이다.

MCP 서버를 직접 운영하면서 오픈한다는 의미는 인증과 인가를 붙이겠다는 의미일 것 같다.

AWS Lambda 환경에서 MCP 서버를 배포할 경우 아래의 장점이 있다.
- 인프라 관리가 불필요하여, 서버 운영 부담이 없다.
- 사용한 만큼 비용이 지불되기 때문에 비용 효율성이 높다.
- 자동으로 스케일링이 되기 때문에 트래픽에 따라 h/w 자원을 동적으로 변경할 수 있다.
- 보안 및 권한 관리가 쉽고, 도메인 주소관리, SSL 관리 등의 네트워크 리소스 운영 작업이 편하다.

단점도 있다.
- 최대 실행시간과 메모리 제한이 있고, 로깅과 제어가 제한적이다.

이 포스팅의 목적은 비교적 최근에 나온 MCP 서버를 AWS Lambda 환경에서 MCP 배포가 가능할지 확인해보기 위함이다.


그럼 시작해보자.

 

 


AWS Lambda 에서 MCP 서버 구축 해보기

A) 사전 준비

  • fastMCP 로 구현한 mcp server 코드
  • 컨테이너 이미지 로 생성할 Dockerfile 코드
  • requirements.txt 패키지 설치 파일

B) 시나리오 

1. teams webhook 을 이용해 message 를 발송하는 MCP 서버 구축
2. mcp 서버를 컨테이너 이미지로 생성하고, ECR 레포지토리에 업로드
3. aws lambda 를 생성하고 ecr 에 업로드 된 이미지를 이용하여 배포 
4. 아래 두 가지 방식으로 MCP Server 테스트를 한다.

  a. Lambda 의 FunctionURL 을 이용해 MCP Client 로 연결하여 Teams 채널로 메세지를 전송해본다.
(LLM 모델은 로컬에서 테스트를 위해 Ollama 모델을 활용)
  b. cursor 의 MCP tool 로 등록해서 Teams 채널로 메세지를 전송해본다.

 

C) Step by Step

MCP 서버 코드 

from fastmcp import FastMCP
import os
import requests
import json
from typing import Optional, Dict, Any
WEBHOOK_URL = "웹훅 주소"
mcp = FastMCP("MCP-TEST-SERVER")

@mcp.tool()
async def get_my_info() -> str:
    """ 안녕하세요. 저는 러닝을 좋아하는 jssvs 입니다."""
    return f""

@mcp.tool()
async def get_weather() -> str:
    """현재 날씨를 조회합니다"""
    return f"오늘 날씨는 맑습니다."


@mcp.tool()
def send_teams_message(
    message: str,
    title: str = None,
) -> bool:
    """
    Microsoft Teams 채널에 webhook을 통해 메시지를 전송합니다.
    
    Args:
        message (str): 전송할 메시지 내용
        title (str, optional): 메시지 제목
    Returns:
        bool: 전송 성공 여부
    Example:
        send_teams_message(message="안녕하세요!", title="알림")
    """
    color = "00FF00"
    # MessageCard 형식으로 페이로드 구성
    payload = {
        "@type": "MessageCard",
        "@context": "https://schema.org/extensions",
        "summary": title or "알림",
        "sections": [{
            "activityTitle": title,
            "text": message
        }]
    }
    
    # 색상이 지정된 경우 추가
    if color:
        payload["themeColor"] = color
    
    # 제목이 없는 경우 섹션에서 제거
    if not title:
        del payload["sections"][0]["activityTitle"]
    
    try:
        response = requests.post(
            WEBHOOK_URL,
            headers={"Content-Type": "application/json"},
            data=json.dumps(payload)
        )
        
        # 성공 여부 확인
        if response.status_code == 200:
            print(f"✓ 메시지 전송 성공")
            return True
        else:
            print(f"✗ 메시지 전송 실패: {response.status_code}")
            print(f"응답: {response.text}")
            return False
            
    except Exception as e:
        print(f"✗ 오류 발생: {str(e)}")
        return False

def main():
    host = os.environ.get("HOST","0.0.0.0")
    port = int(os.environ.get("PORT",8080))
    print(f"Starting FastMCP HTTP Server on {host}:{port}")
    print("Available tools:")
    print("- get_bdp_team_info: Returns BDP team information")
    print("- get_weather: Returns weather information")
    print(f"Server accessible at: http://{host}:{port}")
    mcp.run(transport="http",host=host, port=port, stateless_http=True)

if __name__ == "__main__":
    main()

requirements.txt

fastmcp>=0.1.0
requests

 

Dockerfile

FROM python:3.12-slim
WORKDIR /app

# ### Environment Variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1


# Install the specified packages
COPY requirements.txt .
RUN pip install --no-cache-dir --upgrade pip && \
    pip install --no-cache-dir -r requirements.txt

# MCP 서버 코드 복사
COPY mcp_server.py .

# 환경 변수 설정
ENV PORT=8080
ENV AWS_LWA_INVOKE_MODE=response_stream
ENV AWS_LWA_READINESS_CHECK_PORT=8080
ENV AWS_LWA_READINESS_CHECK_PATH=/health

# === Lambda Web Adapter ===
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.7.0 /lambda-adapter /opt/extensions/lambda-adapter

# 서버 시작 명령어
CMD ["python", "mcp_server.py"]

 

D) 참고해야 할 부분 !

1) Lambda 설정 시 참고 
-> 환경변수에 2개의 값 추가 (Dockerfile 에 ENV 에 추가해줬다면 생략해도 된다.)

2) 기본 TImeout 값으로는 MCP tool 호출이 되기 전에 호출이 종료되기 때문에 값을 조정한다.

 

 

 

E) 테스트 해보기

 

 

A) Strands Agent 코드를 작성하여 테스트 발송

from strands import Agent
from strands.models.ollama import OllamaModel
from strands.tools.mcp.mcp_client import MCPClient
from mcp.client.streamable_http import streamablehttp_client


client = MCPClient(
    lambda: streamablehttp_client(
        # url = "http://127.0.0.1:8080/mcp"
        url = "https://LambdaFunctinURL 주소.lambda-url.ap-northeast-2.on.aws/mcp"
    )
)
with client:
    tools = client.list_tools_sync()
    
    base_model = OllamaModel(
        host = "http://localhost:11434",
        model_id = "llama3.1:8b",
        temperature = 0.1
        )
    agent = Agent(tools = tools, model = base_model)
    # print(agent.tool.get_weather())
    result = agent("teams 채널에 아래 메세지를 전송해줘 \n message : Lambda 에서 구축한 MCP 서버 테스트 \n title : MCP 서버 테스트")
    print(result)

 

 

 

B) Cursor MCP 툴 연동하여 테스트 발송

 

 

결론

  • lambda 의 장점은 서버리스, 즉 물리 서버를 운용하지 않으면서 서비스를 배포하는데 있다. 그렇다면 MCP 서버 역시 이런 장점을 누릴 수 있다.
  • 내가 테스트한 부분은 운영 버전용으로 활용할 수 는 없다. 운영 버전까지 고려할 때는 보안을 위해 VPC 안에서 배포를 한다던지, 앞단에 Gateway 의 셋팅, 동시성 테스트 등 다양한 준비가 필요하다.
  • 그리고 Dockerfile 을 보면 알겠지만, lambda web adapter 를 멀티스테이지 빌드를 사용하여 로드한 부분이 있는데, lambda 의 extension 기능으로 붙인 것이다. 즉 기능 추가, 의존성 등의 확장에 있어 제한이 있을 수 있음을 의미한다.

참고

[1] Welcome to FastMCP 2.0 - https://gofastmcp.com/getting-started/welcome 
[2] GitHub - awslabs/aws-lambda-web-adapter - https://github.com/awslabs/aws-lambda-web-adapter 
[3] Deploy MCP Server on AWS Lambda | Step-by-Step Guide - https://www.youtube.com/watch?v=JncV8hXuyRg&t=341s 
[4] 컨테이너 이미지로 Python Lambda 함수 배포 - Python용 AWS 기본 이미지 사용 - https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/python-image.html#python-image-instructions

반응형

+ Recent posts