컴퓨터/AI

Custom GPT + MCP 서버 구축으로 ChatGPT 파일 시스템 제어하기

아보다 2025. 7. 9.
반응형

Custom GPT + MCP 서버 구축으로 ChatGPT 파일 시스템 제어하기 ChatGPT가 이제 파일 시스템도 제어한다면? 가장 쉬운 방법으로 나만의 MCP 서버를 구축해보세요.

얼마 전, 갑자기 Claude에서 썼던 MCP라는 게 생각났어요. 그때는 그냥 pip으로 설치해서 쓰는 간단한 패키지 정도로만 알았는데, 이번에 다시 찾아보니 ChatGPT의 Custom GPT 기능과 연결하면 진짜 서버처럼 활용할 수 있다는 걸 알게 됐죠. 저는 이걸 테스트 삼아 직접 MCP 서버를 만들고, Custom GPT랑 연동해서 파일 시스템을 제어하는 구조를 짜봤어요. 원래 FastAPI도 잘 몰랐고, Render도 처음이었는데... 역시 ChatGPT가 도와주니 훨씬 수월했어요. 이번 글에서는 저처럼 처음 MCP를 접하거나 Custom GPT를 활용해보고 싶은 분들을 위해 가장 쉽고 저렴하게 설정할 수 있는 방법을 공유해보려 해요.

Custom GPT + MCP 서버 구축으로 ChatGPT 파일 시스템 제어하기

Custom GPT + MCP 서버 구축으로 ChatGPT 파일 시스템 제어하기
Custom GPT + MCP 서버 구축으로 ChatGPT 파일 시스템 제어하기

MCP란 무엇이고 왜 필요한가?

MCP라는 단어만 보면 뭔가 복잡한 서버 시스템 같지만, 사실상 그냥 FastAPI로 구현된 파일 시스템 제어용 API 모음이라고 보면 돼요. 저도 처음엔 'MCP 서버'라는 이름 때문에 Docker나 Kubernetes처럼 뭔가 무거운 인프라를 상상했는데, 알고 보니 그냥 Python 코드 몇 줄이면 작동하는 거더라구요. 단순히 pip 설치만으로 끝나는 건 아니고, Custom GPT에서 실제로 외부 시스템을 호출하려면 HTTP로 응답을 받는 실서버가 필요하죠. 그래서 '서버'라는 말이 붙은 거예요.

FastAPI로 GitHub에 MCP 서버 구성하기

반응형

MCP 서버를 만들기 위해 GitHub에 새로운 저장소를 생성했어요. 핵심 구성은 단 3개의 파일입니다. FastAPI를 사용하면 아주 간단하게 HTTP API를 만들 수 있거든요. 아래는 각 파일의 구성입니다.

FastAPI로 GitHub에 MCP 서버 구성하기
FastAPI로 GitHub에 MCP 서버 구성하기
Custom GPT + MCP 서버 구축으로 ChatGPT 파일 시스템 제어하기
Custom GPT + MCP 서버 구축으로 ChatGPT 파일 시스템 제어하기

파일명 설명
main.py MCP API 기능 구현 (파일 쓰기, 읽기, 삭제 등)
render.yaml Render 배포 설정 정보
requirements.txt FastAPI, uvicorn 등 필요한 패키지 명시

# main.py
from fastapi import FastAPI, HTTPException, Query
from pydantic import BaseModel
import uvicorn
import os

app = FastAPI()

BASE_PATH = "/tmp/gpt_mcp"

class FileRequest(BaseModel):
    filename: str
    content: str

class FolderRequest(BaseModel):
    foldername: str

@app.get("/ping")
def ping():
    return {"status": "awake"}

@app.post("/create-folder")
def create_folder(req: FolderRequest):
    path = os.path.join("/tmp", req.foldername)
    os.makedirs(path, exist_ok=True)
    return {"message": f"Folder created at {path}"}

@app.post("/write-file")
def write_file(req: FileRequest):
    os.makedirs(BASE_PATH, exist_ok=True)
    filepath = os.path.join(BASE_PATH, req.filename)
    try:
        with open(filepath, "w") as f:
            f.write(req.content)
        return {"message": f"File written to {filepath}"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/list-files")
def list_files():
    if not os.path.exists(BASE_PATH):
        return {"files": []}
    files = os.listdir(BASE_PATH)
    return {"files": files}

@app.get("/read-file")
def read_file(filename: str = Query(...)):
    filepath = os.path.join(BASE_PATH, filename)
    if not os.path.exists(filepath):
        raise HTTPException(status_code=404, detail="File not found")
    try:
        with open(filepath, "r") as f:
            content = f.read()
        return {"filename": filename, "content": content}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.delete("/delete-file")
def delete_file(filename: str = Query(...)):
    filepath = os.path.join(BASE_PATH, filename)
    if not os.path.exists(filepath):
        raise HTTPException(status_code=404, detail="File not found")
    try:
        os.remove(filepath)
        return {"message": f"Deleted {filename}"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.post("/clear-folder")
def clear_folder():
    if not os.path.exists(BASE_PATH):
        return {"message": "Folder does not exist, nothing to clear"}
    try:
        for f in os.listdir(BASE_PATH):
            path = os.path.join(BASE_PATH, f)
            if os.path.isfile(path):
                os.remove(path)
        return {"message": "All files deleted"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

# 로컬 실행용 코드 (Render 배포 시 필요 없음)
if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=10000)
# render.yaml
services:
  - type: web
    name: mcp-server
    env: python
    buildCommand: ""
    startCommand: uvicorn main:app --host 0.0.0.0 --port 10000
# requirements.txt
fastapi
uvicorn

Render를 활용한 무료 배포 방법

Render는 GitHub 저장소를 연동해서 자동으로 웹 애플리케이션을 배포할 수 있는 아주 편리한 서비스예요. 무료로 월 750시간까지 쓸 수 있어서 MCP 테스트에는 딱이죠. 설정 방법은 다음과 같아요.

Custom GPT + MCP 서버 구축으로 ChatGPT 파일 시스템 제어하기
Custom GPT + MCP 서버 구축으로 ChatGPT 파일 시스템 제어하기

https://render.com/

 

Cloud Application Platform | Render

On Render, you can build, deploy, and scale your apps with unparalleled ease – from your first user to your billionth.

render.com

  1. Render 계정 생성 후 로그인
  2. "+ New > Web Service" 클릭
  3. Public Git Repository에 GitHub URL 입력
  4. Start Command에 uvicorn main:app --host 0.0.0.0 --port 10000 입력
  5. 요금제는 Free 선택, "Deploy Web Service" 클릭

Custom GPT + MCP 서버 구축으로 ChatGPT 파일 시스템 제어하기
Custom GPT + MCP 서버 구축으로 ChatGPT 파일 시스템 제어하기

Custom GPT에서 MCP 연동 설정

이제 MCP 서버가 배포되었으니, 본격적으로 ChatGPT의 Custom GPT 기능을 통해 연동해볼 차례예요. 이 기능은 Free 요금제에서는 안 되고, 반드시 Plus 요금제 이상에서만 활성화돼요. GPT 설정 화면에서 "구성" 탭으로 이동해서 작업을 추가하고 OpenAPI 스키마를 붙여 넣으면 됩니다. 특히 스키마 작성은 처음엔 어렵게 느껴질 수 있는데, MCP 서버에 있는 FastAPI 코드 구조만 이해하면 의외로 간단해요.

OpenAPI 스키마 작성 가이드

Custom GPT가 MCP 서버의 기능을 호출하려면, MCP API 구조를 명세하는 OpenAPI 스키마가 필요해요. 아래는 주요 엔드포인트와 요청 방식, 필수 파라미터를 간략히 정리한 표입니다.

엔드포인트 요청 방식 기능 요약
/create-folder POST 폴더 생성
/write-file POST 파일 쓰기
/list-files GET 폴더 내 파일 목록 조회

실제 파일 제어 테스트 예시

Custom GPT + MCP 서버 구축으로 ChatGPT 파일 시스템 제어하기
Custom GPT + MCP 서버 구축으로 ChatGPT 파일 시스템 제어하기

설정이 완료되었다면 이제 실제로 파일을 만들거나 읽는 테스트를 할 수 있어요. 아래는 ChatGPT에게 자연어로 요청하고, MCP 서버가 실제로 처리한 테스트 예시들입니다.

  • "/tmp/test" 폴더 만들어줘 → 폴더 생성
  • "hello.txt에 안녕이라고 써줘" → 파일 작성
  • "hello.txt 내용 보여줘" → 파일 읽기l
Q MCP 서버 없이도 Custom GPT 설정이 가능한가요?

불가능합니다. Custom GPT가 외부 시스템과 상호작용하려면 실제 서버가 있어야 하며, 그 서버는 OpenAPI 기반 API를 제공해야 합니다.

Q MCP 서버는 로컬에서 테스트할 수 있나요?

네, uvicorn으로 로컬 서버를 실행하면 동일한 API 테스트가 가능합니다. 단, Custom GPT와 연결하려면 외부에 노출된 주소가 필요합니다.

Q Render 무료 요금제의 제약은 어떤 게 있나요?

슬립 상태로 진입해 첫 요청 시 딜레이가 생길 수 있습니다. 또한, 월 750시간 사용 제한이 있으므로 장시간 서비스 운영에는 적합하지 않습니다.

Q OpenAPI 스키마는 반드시 JSON이어야 하나요?

Custom GPT에서는 JSON 형식으로 스키마를 정의하는 것이 가장 안정적이며, 시각적인 GUI에서 오류 없이 작동합니다.

Q MCP 외에도 Custom GPT에 연동할 수 있는 예시가 있나요?

물론입니다. 날씨 API, Google Calendar, Notion, OpenAI Functions 등 다양한 API를 연결하여 자신만의 도우미를 구성할 수 있습니다.

Q MCP 서버 API가 변경되면 Custom GPT도 다시 설정해야 하나요?

네, 엔드포인트나 파라미터가 바뀌면 OpenAPI 스키마도 수정해야 하며, GPT 작업 설정에서도 업데이트가 필요합니다.

여기까지 따라오셨다면 이제 여러분도 MCP 서버를 구축하고 Custom GPT로 제어할 수 있는 도우미를 직접 만들 수 있게 되셨을 거예요. 저도 처음엔 막막했는데 하나하나 시도하다 보니 생각보다 어렵지 않더라고요. 이 경험을 통해 얻은 가장 큰 깨달음은, 결국 중요한 건 '시도'라는 거예요. 누군가가 만들어둔 GPT를 쓰는 것도 좋지만, 나만의 GPT를 만들고 직접 제어할 수 있다는 자유도 엄청난 매력이 있답니다. 혹시 따라하면서 막히는 부분이 있었다면 댓글이나 커뮤니티에서 함께 해결해봐요!

태그: Custom GPT, MCP 서버, FastAPI, Render 무료 배포, ChatGPT 외부 API 연동, OpenAPI 스키마, GPT 플러그인, ChatGPT 파일 시스템, FastAPI 서버 배포, ChatGPT 도우미 설정

2025.03.16 - [분류 전체보기] - MCP(Model Context Protocol)란 무엇인가?

반응형

댓글

💲 추천 글