Skip to content

oscka/mcp_example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MCP Example

개요

해당 소스는 Infrastructure Provisioning 자동화를 위한 MCP Server 예제입니다.

Streamable HTTP 프로토콜을 통해 다양한 Client에 연결하여 자연어 기반으로 Infrastructure를 관리할 수 있는 기능을 제공합니다.

Proxmox 환경 기준으로 작성되었으나 Public Cloud 및 Multi Cloud 환경에서도 사용이 가능하도록 설계되었습니다.

WSO2 APIM 등 API Gateway와 연동하여 사용하는 것을 권장합니다.

테스트에 필요한 사전 환경 요구사항은 다음과 같습니다.

  • 컨테이너 배포용 환경
  • Proxmox 환경
  • MCP 프로토콜을 지원하는 Client(Steramable HTTP로 연결해야 합니다.)

Architecture 정의

MCP Server에 도구를 쉽게 추가/제거하고 코드 종속성을 줄이기 위해 Modular Monolithic Architecture 및 Microkernel Architecture를 적용하였습니다.

Architecture에 대한 세부 정의는 다음과 같습니다.

Interface Architecture

Resource Provisioner MCP Tools과 같은 비즈니스 로직과 인프라 제어 로직(Terraform/Ansible) 사이의 규격을 저의하는 추상화 인터페이스입니다.

설계 목적

  • 인프라 추상화: Client(User, Agent 등)가 Proxmox, AWS 등 특정 플랫폼에 종속되지 않고 명령을 내릴 수 있도록 격리합니다.
  • 작업 일관성: 리소스 종류와 관계 없이 동일한 작업 흐름을 보장합니다.
  • 확장성: 새로운 인프라 자산 또는 기능이 추가되어도 기존 소스 코드 수정 없이 새 모듈만 구현하면 즉시 통합할 수 있습니다.

Sequence Architecture

Sequence Architecture는 다음과 같습니다.

  1. 요청 수신: MCP Client가 MCP Tool을 호출하면, MCP Server가 이를 수신한다.
  2. 리소스 등록: 데이터베이스에 새로운 리소스 정보를 기록하고 상태를 PENDING으로 마킹합니다.
  3. 프로비저너 할당: ProvisionerRegistry(ResoruceProvisioner 인터페이스의 구현체들을 관리하는 클래스)가 리소스 타입을 확인 후, Provisioner 객체를 생성합니다.
  4. 비동기 실행: Server는 Terraform 프로세스를 비동기 Subprocess로 실행하고 제어권을 반환할 준비를 합니다.
  5. 상태 스트리밍:
  • Terraform 코드가 실행되면서 중간 상태를 POST 요청으로 Terraform 백엔드로 전송합니다.
  • Terraform 백엔드는 이를 수신하여 데이터베이스의 tf_state 테이블을 실시간으로 갱신합니다.
  1. 완료 처리: Terraform 프로세스가 종료되면, 서버는 Terraform 반환 결과를 파싱하여 DB에 기록하고 리소스 상태를 RUNNING으로 변경합니다.

Sequence Architecture

Provisioning Workflow

Provisioning Workflow는 리소스 생성 시의 Lifecycle을 정의합니다. 데이터베이스의 state 컬럼이 변하는 규칙이며, 시스템의 가시성을 결정합니다.

리소스 상태 정의 및 전이 조건

상태 (Status) 의미 (Meaning) 전이 조건 (Trigger)
PENDING 생성 요청 수신 Database 레코드 최초 생성 시
PROVISIONING 인프라 리소스 할당 중 Terraform 프로세스(apply) 시작 시
CONFIGURING SW 및 환경 설정 중 Terraform 프로세스 완료 후 Ansible Playbook 시작 시
RUNNING 리소스 사용 가능 모든 프로비저닝 로직이 성공적으로 종료되었을 때
ERROR 작업 실패 작업 도중 예외 발생 또는 프로세스 에러 반환 시
DESTROYING 리소스 삭제 리소스 삭제 작업 수행 시

핵심 워크플로우 로직

  • 인프라 레이어 (Phase 1): Terraform을 통해 Proxmox 노드에 리소스를 할당합니다.
  • 설정 레이어 (Phase 2): 동적으로 Ansible Inventory를 생성하고 Ansible이 동적 Inventory 정보를 이용해 SSH 접속을 시도합니다. 예제에서는 Base Package 설치 및 보안 설정을 수행합니다.
  • 데이터 동기화: 각 Phase가 끝날 때마다 infra_state.db의 정보를 갱신하여 사용자가 언제든 진행상황을 확인할 수 있게 합니다.

Provisioning Workflow

Database Schema 정의

Terraform 사용 시 PostgreSQL 등 지원하는 Backend를 사용하는 것이 일반적이지만 본 예제에서는 Terraform의 HTTP Backend를 이용하여 SQLite에 저장하도록 구현되었습니다.

1. resource Table

이 테이블은 관리 대상인 모든 인프라 자원의 메타데이터와 현재 상태를 추적합니다.

컬럼명 타입 제약 조건 설명
resource_id TEXT PK 고유 식별자 (예: provider-name)
name TEXT UNIQUE, NOT NULL 리소스 이름
provider TEXT NOT NULL Cloud Provider (AWS, GCP, Proxmox 등)
type TEXT NOT NULL 리소스 타입 (VM, Container, Network 등)
state TEXT NOT NULL 리소스 상태 (PENDING, RUNNING 등)
metadata TEXT NOT NULL Cloud Provider별 상세 식별 데이터 (JSON 등)
created_at DATETIME DEFAULT CURRENT_TIMESTAMP 생성 시간
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP 갱신 시간

2. tf_state Table

Terraform의 상태 파일(tfstate)을 관리하며, 동시성 제어를 위한 락(Lock) 정보를 포함합니다. 리소스 단위로 상태관리가 이뤄지게 됩니다.

컬럼명 타입 제약 조건 설명
resource_id TEXT PK, FK 고유 식별자 (resource 테이블 참조)
data TEXT - Terraform State 원본 데이터 (JSON 문자열)
is_locked BOOLEAN DEFAULT 0 잠금 여부 (0: 해제, 1: 잠금)
lock_info TEXT - Terraform Lock 상세 정보 (JSON)
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP 생성 및 최종 갱신 시간

배포 방법

docker-compose.yml을 통해 배포하여 관리할 수 있습니다.

services:
  mcp-example:
    build: .
    container_name: mcp-example
    ports:
      - "8000:8000"
    environment:
      - TZ=Asia/Seoul
    env_file:
      - ./secrets/.env
    volumes:
      - ./data:/app/data
      - ./terraform:/app/terraform
      - ./ansible:/app/ansible
      - ./secrets:/app/secrets
    extra_hosts:
      - "host.docker.internal:host-gateway"
    restart: unless-stopped  

.env 작성 예제

##############
# Ansible Envs
##############
PROXMOX_URL="https://<host>:<port>"
PROXMOX_USER="ansible@pve"
PROXMOX_TOKEN_ID="ansible-inventory"
PROXMOX_TOKEN_SECRET="<proxmox-terraform-api-token-sercret>"
PM_VMID_MIN=20000
PM_VMID_MAX=30000

################
# Terraform Envs
################
TF_VAR_pm_api_url="https://<host>:<port>/api2/json"
TF_VAR_pm_api_token_id="terraform@pve!terraform-provider"
TF_VAR_pm_api_token_secret="<proxmox-terraform-api-token-sercret>"
TF_VAR_pool="agentpool"
TF_VAR_target_node="<proxmox node name>"
TF_VAR_template_id=10000
TF_VAR_storage_pool="local-lvm"
TF_VAR_disk_size="32G"
TF_VAR_bridge_name = "vlan50"
TF_VAR_nameserver = "<nameserver>"
TF_VAR_searchdomain = "<dns>"

MCP Tool 사용 예제

# User Prompt(VM 생성)
sandbox-01 1대를 생성해줘.

# System
`sandbox-01` VM 생성이 시작되었습니다!

**생성 정보:**
- **VM 이름:** sandbox-01
- **리소스 ID:** pm-sandbox-01
- **사양 (flavor):** small
- **용도 (purpose):** sandbox

VM의 기초 환경 구성이 진행 중입니다. 생성이 완료되면 VM을 사용할 준비가 됩니다.

# User Prompt(VM 목록 조회)
현재 vm 목록을 조회해줘.

# System
현재 Proxmox 노드의 VM 목록은 다음과 같습니다:

## VM 목록 조회 결과

| VM 이름 | 리소스 ID | 상태 | 사양 | VM ID | 생성일 | 업데이트일 |
|--------|----------|------|------|------|--------|-----------|
| **sandbox-01** | pm-sandbox-01 | RUNNING | small | 20000 | 2026-04-22 04:40:00 | 2026-04-22 04:40:55 |

### 요약
- **총 VM 수:** 1 대
- **생성된 VM:** sandbox-01
- **상태:** 정상 동작 중 (RUNNING)
- **리소스 사양:** small
- **용도:** sandbox

VM이 성공적으로 생성되어 현재 실행 중입니다.

# User Prompt(VM 업데이트)
sandbox-01의 사양을 medium으로 변경해줘.

# System
`sandbox-01` VM 의 사양이 `small`에서 `medium`으로 변경되었습니다.

**변경 정보:**
- **VM 이름:** sandbox-01
- **기존 사양:** small
- **새로운 사양:** medium
- **용도:** sandbox (유지)

사양 변경이 완료되었으며, 더 많은 리소스를 사용할 수 있게 되었습니다.

# User Prompt(VM 삭제)
`sandbox-01` VM 삭제 프로세스가 성공적으로 시작되었습니다!

**삭제 정보:**
- **VM 이름:** sandbox-01
- **상태:** 삭제 진행 중
- **결과:** 성공

VM의 데이터와 리소스는 이제 해제가 될 예정입니다. 삭제 작업이 완료되면 더 이상 해당 VM을 사용할 수 없으니 참고하시기 바랍니다.

Appendix

프로젝트 디렉토리 구조

/mcp_example           
├─ mcp_server/                        # MCP/API 소스 코드
│  ├─ main.py                        # 실행 엔드포인트 (FastAPI + MCP)
│  ├─ database.py                    # SQLite 초기화 및 CRUD 공통 로직
│  ├─ utils.py                       # 유틸리티 로직
│  ├─ api/                           # 외부 통신 레이어
│  │  ├─ mcp/                       # MCP Tool 정의
│  │  │  └─ proxmox.py
│  │  ├─ mcp_router.py              # MCP Tool Router
│  │  └─ tf_backend.py              # Terraform HTTP Backend
│  ├─ core/                          # 프레임워크 코어 로직
│  │  ├─ base.py                    # 추상 베이스 클래스 집합
│  │  ├─ registry.py                # Provisioner 구현체의 생명주기를 관리하는 클래스 집합
│  │  ├─ constants.py               # 시스템 전역 상수 및 리소스 상태(Enum) 정의
│  │  └─ executor/                  # Ansible, Terraform 등 도구 실행 라이브러리
│  │     ├─ terraform.py
│  │     └─ ansible.py
│  ├─ provisioners/                  # 리소스 별 구현체 집합
│  │  └─ proxmox/                   # Proxmox Provisioners
│  │     └─ vm.py
│  └─ schemas/                       # 스키마 정의
│     ├─ base.py
│     └─ proxmox.py
│
├─ terraform/                         # Terraform 코드
│  └─ proxmox/                       # Proxmox Provider
│     ├─ main.tf                  
│     ├─ outputs.tf                    
│     ├─ provider.tf                   
│     └─ variables.tf 
│
├─ ansible/                           # Ansible 코드
│  ├─ inventory/                    
│  │  └─ group_vars/                
│  │  │  └─ all.yml             
│  │  └─ sandbox.proxmox.yml        
│  ├─ playbooks/                    
│  │  └─ base.yml                   
│  └─ ansible.cfg    
│
├─ scripts/                         
│  └─ entrypoint.sh                  # 초기 셋업용 스크립트
│
├─ secrets/                           # .env 및 .ssh 등 프로젝트 내에서 관리되어야 하는 Secret 파일 또는 값의 집합
│  ├─ .env                         
│  └─ .ssh/                        
│     ├─ agent_key                 
│     ├─ agent_key.pub             
│     └─ admin_key.pub
│
├─ data/                             # 데이터 보관 장소
│  └─ infra_state.db                # Infra의 상태를 저장하는 SQLite 파일
│
├─ requirements.txt                  # 의존성 목록
├─ Dockerfile
├─ docker-compose.yml
├─ .dockerignore
└─ .gitignore

About

MCP Server Example for Infrastructure Provisioning

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors