MCP API Documentation System

MCP API Documentation System

A fully automated system that analyzes Django REST Framework ViewSets to generate accurate OpenAPI 3.0 specification documentation without manual configuration.

Category
访问服务器

README

MCP API 문서 자동화 시스템

Django REST Framework ViewSet을 자동으로 분석하여 OpenAPI 3.0 스펙의 API 문서를 생성하는 완전 자동화 시스템입니다.

📋 목차

🎯 프로젝트 개요

목적

  • Django 프로젝트의 ViewSet을 자동으로 탐지하고 분석
  • 실제 serializer 필드를 기반으로 정확한 OpenAPI 3.0 스펙 생성
  • Request/Response 파라미터, 헤더, 바디 정보 완전 자동화
  • Swagger UI를 통한 직관적인 API 문서 제공

핵심 특징

  • 완전 자동화: 수동 설정 없이 ViewSet 자동 탐지
  • 정확한 스키마: 실제 serializer 필드 1:1 반영
  • 125개 엔드포인트: 모든 ViewSet CRUD 작업 지원
  • 실시간 생성: 코드 변경 시 즉시 문서 업데이트
  • JavaScript 호환: Swagger UI 완벽 지원

🏗️ 시스템 아키텍처

┌─────────────────┐    HTTP Request    ┌─────────────────┐
│   MCP Server    │ ──────────────────► │ Python Parser   │
│  (Spring Boot)  │                    │   (FastAPI)     │
│   Port: 8080    │                    │   Port: 8009    │
└─────────────────┘                    └─────────────────┘
         │                                       │
         │                                       │
         ▼                                       ▼
┌─────────────────┐                    ┌─────────────────┐
│   Swagger UI    │                    │ Django Project  │
│  API Docs HTML  │                    │  ViewSet Files  │
│  /api-docs/html │                    │  /shared_repos/ │
└─────────────────┘                    └─────────────────┘

컴포넌트 설명

  1. Python Parser (FastAPI)

    • Django ViewSet 자동 탐지 및 분석
    • OpenAPI 3.0 스펙 생성
    • 실제 serializer 필드 추출
  2. MCP Server (Spring Boot)

    • Swagger UI 제공
    • JSON API 문서 서빙
    • 프록시 역할
  3. Django Project

    • 분석 대상 ViewSet 파일들
    • 실제 serializer 정의

🚀 주요 기능

1. ViewSet 자동 탐지

  • app/ 디렉토리 내 모든 앱 스캔
  • views.py 또는 views/ 폴더 내 파일 분석
  • class \w+ViewSet 패턴 자동 발견

2. Serializer 필드 추출

  • serializer_class 속성 자동 감지
  • 실제 필드 타입, nullable, required 정보 추출
  • 중첩 serializer 지원

3. OpenAPI 3.0 스펙 생성

  • Request 파라미터 (쿼리, 헤더, 바디)
  • Response 스키마 (상태 코드별)
  • 인증 정보 (Authorization 헤더)
  • Pagination, Search, Filtering 지원

4. CRUD 엔드포인트 자동 생성

  • GET /api/v1/{resource}/ - 목록 조회
  • POST /api/v1/{resource}/ - 생성
  • GET /api/v1/{resource}/{id}/ - 상세 조회
  • PUT /api/v1/{resource}/{id}/ - 수정
  • DELETE /api/v1/{resource}/{id}/ - 삭제

🛠️ 기술 스택

Backend

  • Python 3.12.2: 메인 파싱 로직
  • FastAPI: Python Parser 서버
  • Django: 분석 대상 프로젝트
  • Django REST Framework: ViewSet 분석

Frontend

  • Spring Boot: MCP 서버
  • Swagger UI: API 문서 인터페이스
  • Thymeleaf: HTML 템플릿

개발 도구

  • Gradle: Spring Boot 빌드
  • uvicorn: FastAPI 서버
  • watchfiles: 자동 리로드

📁 프로젝트 구조

mcp-docs-server-final/
├── python-parser/                    # Python Parser 서버
│   ├── main.py                      # FastAPI 서버 진입점
│   ├── src/
│   │   ├── application/             # 애플리케이션 레이어
│   │   │   └── use_cases/
│   │   │       └── generate_api_docs_use_case.py
│   │   ├── domain/                  # 도메인 레이어
│   │   │   └── entities/
│   │   │       ├── api_documentation.py
│   │   │       ├── api_endpoint.py
│   │   │       └── api_parameter.py
│   │   ├── infrastructure/          # 인프라 레이어
│   │   │   ├── generators/
│   │   │   │   └── api_documentation_generator.py
│   │   │   └── parsers/
│   │   │       └── python_parser.py
│   │   └── presentation/            # 프레젠테이션 레이어
│   │       └── controllers/
│   │           └── api_docs_controller.py
│   ├── generated_docs/              # 생성된 API 문서
│   │   └── ucms-be_api_docs.json
│   └── requirements.txt
├── shared_repos/                    # 분석 대상 Django 프로젝트
│   └── ucms-be/
│       └── app/
│           ├── account/
│           ├── revenue/
│           ├── content/
│           └── ... (기타 앱들)
├── src/                             # Spring Boot MCP 서버
│   └── main/
│       ├── java/
│       │   └── com/odk/
│       │       └── controller/
│       │           └── ApiDocsController.java
│       └── resources/
│           ├── templates/
│           │   └── swagger-viewer.html
│           └── static/
│               └── openapi/
├── build.gradle                     # Spring Boot 빌드 설정
└── docker-compose.override.yml      # Docker 설정

🔧 로컬 환경 설정

1. Python 환경 설정

# Python 3.12.2 설치 (pyenv 사용)
pyenv install 3.12.2
pyenv local 3.12.2

# 가상환경 생성 및 활성화
cd python-parser
python -m venv venv
source venv/bin/activate  # macOS/Linux
# 또는
venv\Scripts\activate     # Windows

2. Python 의존성 설치

cd python-parser
pip install -r requirements.txt

3. Spring Boot 환경 설정

# Java 17 이상 필요
java -version

# Gradle 빌드
./gradlew build

🚀 실행 방법

1. Python Parser 서버 시작

cd python-parser
python main.py

서버 정보:

  • URL: http://localhost:8009
  • 자동 리로드: 활성화
  • Django 환경: 자동 설정

2. Spring Boot MCP 서버 시작

# 프로젝트 루트에서
./gradlew bootRun

서버 정보:

  • URL: http://localhost:8080
  • Swagger UI: http://localhost:8080/api-docs/html
  • JSON API: http://localhost:8080/api-docs/json

3. API 문서 생성

# Python Parser 서버가 실행 중인 상태에서
curl -X POST "http://localhost:8009/api/v1/docs/generate/ucms-be?base_url=http://localhost:8009&save_to_file=true"

📖 API 사용법

1. API 문서 생성 엔드포인트

POST /api/v1/docs/generate/{project_name}

파라미터:

  • project_name: 프로젝트 이름 (예: ucms-be)
  • base_url: 기본 URL (예: http://localhost:8009)
  • save_to_file: 파일 저장 여부 (true/false)

응답:

{
  "success": true,
  "message": "API documentation generated successfully",
  "data": {
    "endpoints_count": 125,
    "file_path": "generated_docs/ucms-be_api_docs.json"
  }
}

2. 생성된 문서 확인

  • Swagger UI: http://localhost:8080/api-docs/html
  • JSON 파일: http://localhost:8080/api-docs/json
  • 로컬 파일: python-parser/generated_docs/ucms-be_api_docs.json

🔍 구현 상세 내용

1. ViewSet 자동 탐지 로직

def discover_viewsets(django_app_path: str) -> List[Tuple[str, str]]:
    """
    Django 앱 디렉토리에서 ViewSet 클래스 자동 탐지

    Args:
        django_app_path: Django 앱 경로

    Returns:
        List[Tuple[앱명.ViewSet명, URL경로]]
    """
    viewsets = []

    # app/ 디렉토리 내 모든 앱 스캔
    for app_dir in os.listdir(django_app_path):
        app_path = os.path.join(django_app_path, app_dir)

        if os.path.isdir(app_path):
            # views.py 파일 확인
            views_file = os.path.join(app_path, "views.py")
            if os.path.exists(views_file):
                viewsets.extend(extract_viewsets_from_file(views_file, app_dir))

            # views/ 폴더 확인
            views_dir = os.path.join(app_path, "views")
            if os.path.isdir(views_dir):
                for file in os.listdir(views_dir):
                    if file.endswith(".py"):
                        file_path = os.path.join(views_dir, file)
                        viewsets.extend(extract_viewsets_from_file(file_path, f"{app_dir}/views/{file[:-3]}"))

    return viewsets

2. Serializer 필드 추출 로직

def extract_serializer_from_viewset(viewset_class, viewset_name: str) -> Dict[str, Any]:
    """
    ViewSet에서 실제 사용하는 serializer 필드 추출

    Args:
        viewset_class: ViewSet 클래스
        viewset_name: ViewSet 이름

    Returns:
        Dict[str, Any]: 필드 정보 딕셔너리
    """
    try:
        # 1. serializer_class 속성 확인
        if hasattr(viewset_class, 'serializer_class'):
            serializer_class = viewset_class.serializer_class
            return extract_serializer_fields(serializer_class)

        # 2. get_serializer_class 메서드 확인
        if hasattr(viewset_class, 'get_serializer_class'):
            serializer_class = viewset_class.get_serializer_class()
            return extract_serializer_fields(serializer_class)

        # 3. 소스 코드 분석으로 serializer 패턴 찾기
        return extract_serializer_from_source(viewset_class, viewset_name)

    except Exception as e:
        print(f"[문서 자동화] {viewset_name}에서 serializer 필드 추출 실패: {e}")
        return None

3. OpenAPI 스펙 생성 로직

def generate_openapi_for_viewset(
    viewset_name: str,
    file_path: str,
    base_url: str,
    model_name: str = None,
) -> List[ApiEndpoint]:
    """
    ViewSet에서 OpenAPI 엔드포인트 생성

    Args:
        viewset_name: ViewSet 클래스명
        file_path: ViewSet 파일 경로
        base_url: 기본 URL
        model_name: 모델명 (선택사항)

    Returns:
        List[ApiEndpoint]: 생성된 엔드포인트 목록
    """
    # 1. ViewSet 클래스 import
    viewset_class = import_viewset_class(file_path, viewset_name)

    # 2. Serializer 필드 추출
    serializer_fields = extract_serializer_from_viewset(viewset_class, viewset_name)

    # 3. URL 경로 생성
    resource_name = model_name or viewset_name.replace('ViewSet', '').lower()
    base_path = f"/api/v1/{resource_name}/"

    # 4. CRUD 엔드포인트 생성
    endpoints = []

    # GET /api/v1/{resource}/ - 목록 조회
    endpoints.append(ApiEndpoint(
        path=base_path,
        method=HttpMethod.GET,
        summary=f"Get {resource_name} list",
        description=f"Retrieve a list of {resource_name}",
        parameters=generate_list_parameters(),
        responses=generate_list_responses(serializer_fields)
    ))

    # POST /api/v1/{resource}/ - 생성
    endpoints.append(ApiEndpoint(
        path=base_path,
        method=HttpMethod.POST,
        summary=f"Create {resource_name}",
        description=f"Create a new {resource_name}",
        parameters=generate_create_parameters(),
        request_body=generate_request_body(serializer_fields),
        responses=generate_create_responses(serializer_fields)
    ))

    # 기타 CRUD 엔드포인트들...

    return endpoints

🧪 테스트 방법

1. 단위 테스트

cd python-parser
python -m pytest tests/

2. 통합 테스트

# 1. Python Parser 서버 시작
cd python-parser
python main.py

# 2. API 문서 생성 요청
curl -X POST "http://localhost:8009/api/v1/docs/generate/ucms-be?base_url=http://localhost:8009&save_to_file=true"

# 3. 생성된 파일 확인
ls -la generated_docs/
cat generated_docs/ucms-be_api_docs.json | jq '.paths | keys | length'

3. Swagger UI 테스트

# 1. Spring Boot 서버 시작
./gradlew bootRun

# 2. 브라우저에서 확인
open http://localhost:8080/api-docs/html

4. 엔드포인트별 테스트

# Revenue API 테스트
curl -X GET "http://localhost:8080/api-docs/json" | jq '.paths | keys | grep revenue'

# AdminUser API 테스트
curl -X GET "http://localhost:8080/api-docs/json" | jq '.paths | keys | grep adminuser'

📊 생성된 API 문서 예시

1. Revenue API 엔드포인트

{
  "/api/v1/revenues/": {
    "get": {
      "summary": "Get revenues list",
      "description": "Retrieve a list of revenues",
      "tags": ["revenue"],
      "parameters": [
        {
          "name": "Authorization",
          "in": "header",
          "required": true,
          "description": "Bearer token for authentication",
          "schema": { "type": "string" }
        },
        {
          "name": "page",
          "in": "query",
          "required": false,
          "description": "Page number for pagination",
          "schema": { "type": "integer" }
        }
      ],
      "responses": {
        "200": {
          "description": "Successful response",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": { "type": "integer" },
                  "amount": { "type": "number", "format": "decimal" },
                  "currency": { "type": "string" },
                  "created_at": { "type": "string", "format": "date-time" },
                  "updated_at": { "type": "string", "format": "date-time" }
                }
              }
            }
          }
        }
      }
    }
  }
}

2. 생성된 엔드포인트 통계

  • 총 엔드포인트: 125개
  • ViewSet 개수: 25개
  • 주요 ViewSet:
    • Revenue (16개 필드)
    • RevenueShare (16개 필드)
    • AdminUser (8개 필드)
    • UserActionHistory (12개 필드)
    • VideoSource (23개 필드)
    • Series (18개 필드)
    • Content (다양한 필드)
    • 기타 모든 ViewSet

🔧 트러블슈팅

1. Django 환경 설정 문제

문제: DJANGO_SETTINGS_MODULE 미설정

Error: No module named 'django'

해결책:

def setup_django_environment(django_app_path: str):
    """Django 환경 설정"""
    import os
    import sys
    import django

    # Django 설정 모듈 환경변수 설정
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')

    # 프로젝트 및 앱 경로를 Python 경로에 추가
    project_root = os.path.dirname(django_app_path)
    sys.path.insert(0, project_root)
    sys.path.insert(0, django_app_path)

    # Django 설정
    django.setup()

2. ViewSet Import 실패

문제: 상대 import 오류

Error: attempted relative import with no known parent package

해결책:

def import_viewset_class(file_path: str, viewset_name: str):
    """ViewSet 클래스 import"""
    try:
        # 1. 직접 import 시도
        module_name = get_module_name_from_path(file_path)
        module = importlib.import_module(module_name)
        return getattr(module, viewset_name)
    except ImportError:
        # 2. fallback: 파일 파싱
        return parse_viewset_from_file(file_path, viewset_name)

3. Serializer 필드 추출 실패

문제: cached_property 오류

Error: 'cached_property' object has no attribute 'get_fields'

해결책:

def extract_serializer_fields(serializer_class):
    """Serializer 필드 추출"""
    try:
        # Serializer 인스턴스 생성
        serializer = serializer_class()

        # fields 속성에 안전하게 접근
        if hasattr(serializer, 'fields'):
            fields = serializer.fields
            return {name: extract_field_schema(field) for name, field in fields.items()}
    except Exception as e:
        print(f"Serializer 필드 추출 실패: {e}")
        return None

4. JavaScript 호환성 문제

문제: Swagger UI에서 Object.keys() 오류

TypeError: Cannot convert undefined or null to object

해결책:

def to_openapi_dict(self) -> Dict[str, Any]:
    """OpenAPI 3.0 형식으로 변환"""
    endpoint_dict = {
        "summary": endpoint.summary,
        "description": endpoint.description,
        "tags": endpoint.tags,
        "deprecated": endpoint.deprecated,
        "parameters": [...],
    }

    # null 값 제거로 JavaScript 호환성 확보
    if endpoint.request_body is not None:
        endpoint_dict["requestBody"] = endpoint.request_body

    if endpoint.responses is not None:
        endpoint_dict["responses"] = endpoint.responses

    return endpoint_dict

📈 성능 최적화

1. 캐싱 전략

  • ViewSet 클래스 import 결과 캐싱
  • Serializer 필드 추출 결과 캐싱
  • 파일 변경 감지로 부분 업데이트

2. 병렬 처리

  • 여러 ViewSet 동시 분석
  • 파일 I/O 비동기 처리

3. 메모리 최적화

  • 불필요한 객체 생성 방지
  • 가비지 컬렉션 최적화

🔮 향후 개선 계획

1. 기능 확장

  • [ ] GraphQL 스키마 생성 지원
  • [ ] API 버전 관리
  • [ ] 커스텀 필터링/정렬 지원
  • [ ] API 테스트 코드 자동 생성

2. 성능 개선

  • [ ] Redis 캐싱 도입
  • [ ] 배치 처리 최적화
  • [ ] 메모리 사용량 모니터링

3. 사용성 개선

  • [ ] 웹 인터페이스 추가
  • [ ] 실시간 문서 업데이트
  • [ ] API 문서 버전 관리

📞 지원 및 문의

프로젝트 관련 문의사항이나 버그 리포트는 이슈를 통해 제출해 주세요.


개발자: AI Assistant
최종 업데이트: 2024년 12월
버전: 1.0.0

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选