Skip to main content
Glama
zerogon1203

MCP Database Server

by zerogon1203
README.md
# πŸ—„οΈ MCP Database Server

> **λ³΄μ•ˆ κ°•ν™”λœ 닀쀑 λ°μ΄ν„°λ² μ΄μŠ€ 지원 MCP μ„œλ²„** - Cursor IDE 및 Claude와 연동 κ°€λŠ₯ν•œ Model Context Protocol μ„œλ²„

MySQL, PostgreSQL을 μ§€μ›ν•˜λŠ” **μ—„κ²©ν•œ λ³΄μ•ˆ μ •μ±…**을 μ μš©ν•œ λ°μ΄ν„°λ² μ΄μŠ€ 뢄석 및 μ‹œκ°ν™” λ„κ΅¬μž…λ‹ˆλ‹€.

## ✨ μ£Όμš” κΈ°λŠ₯

### πŸ”’ **λ³΄μ•ˆ κΈ°λŠ₯ (NEW!)**
- **읽기 μ „μš© λͺ¨λ“œ κ°•μ œ** - SELECT 쿼리만 ν—ˆμš©
- **SQL Injection λ°©μ§€** - 닀쀑 λ¬Έμž₯ μ‹€ν–‰ 및 κΈˆμ§€ 동사 차단
- **μ‹λ³„μž ν™”μ΄νŠΈλ¦¬μŠ€νŠΈ** - ν…Œμ΄λΈ”/컬럼λͺ… 검증
- **νŒŒλΌλ―Έν„° 바인딩 κ°•μ œ** - μ•ˆμ „ν•œ 쿼리 μ‹€ν–‰
- **MySQL/PostgreSQL μœ„ν—˜ κΈ°λŠ₯ 차단** - INTO OUTFILE, COPY λ“±

### 🎯 **닀쀑 λ°μ΄ν„°λ² μ΄μŠ€ 지원**
- **MySQL/MariaDB** - μ™„μ „ 지원 (λ³΄μ•ˆ κ°•ν™”)
- **PostgreSQL** - μ™„μ „ 지원 (λ³΄μ•ˆ κ°•ν™”)
- **SQLite** - κΈ°λ³Έ 지원 (μ€€λΉ„ 쀑)

### πŸ“Š **μ‹œκ°ν™” 도ꡬ**
- **Mermaid ERD 생성** - λ°μ΄ν„°λ² μ΄μŠ€ μŠ€ν‚€λ§ˆλ₯Ό Mermaid λ‹€μ΄μ–΄κ·Έλž¨μœΌλ‘œ
- **λ§ˆν¬λ‹€μš΄ ν…Œμ΄λΈ” μš”μ•½** - ν…Œμ΄λΈ” 정보λ₯Ό κΉ”λ”ν•œ ν‘œλ‘œ 정리
- **ASCII μ„±λŠ₯ 차트** - ν…Œμ΄λΈ” 크기와 인덱슀 νš¨μœ¨μ„±μ„ μ‹œκ°μ μœΌλ‘œ

### πŸ” **뢄석 κΈ°λŠ₯**
- μŠ€ν‚€λ§ˆ 뢄석 및 쑰회
- ν…Œμ΄λΈ”λ³„ 톡계 정보
- μ„±λŠ₯ 병λͺ© 지점 탐지
- 인덱슀 μ΅œμ ν™” μ œμ•ˆ
- 쿼리 μ‹€ν–‰ κ³„νš 뢄석

## πŸ“¦ μ„€μΉ˜

```bash
git clone <this-repo-url>
cd db-mcp-server
python -m venv venv
source venv/bin/activate  # λ˜λŠ” venv\Scripts\activate (Windows)
pip install -r requirements.txt
```

## βš™οΈ μ„€μ •

### πŸ”’ λ³΄μ•ˆ μ„€μ • (μ€‘μš”!)

**ν”„λ‘œλ•μ…˜ ν™˜κ²½μ—μ„œλŠ” λ°˜λ“œμ‹œ λ‹€μŒ 섀정을 μ μš©ν•˜μ„Έμš”:**

```env
# 읽기 μ „μš© λͺ¨λ“œ κ°•μ œ
READ_ONLY=true
STRICT_READONLY=true

# λ³΄μ•ˆ κ°•ν™”λœ λ°μ΄ν„°λ² μ΄μŠ€ 계정 μ‚¬μš©
DB_USER=readonly_user
DB_PASSWORD=secure_password
```

### ν™˜κ²½λ³€μˆ˜ μ„€μ •

`.env` νŒŒμΌμ„ μƒμ„±ν•˜κ³  λ°μ΄ν„°λ² μ΄μŠ€ 정보λ₯Ό μ„€μ •ν•˜μ„Έμš”:

```bash
cp .env.example .env
```

### MySQL/MariaDB μ„€μ • (λ³΄μ•ˆ κ°•ν™”)
```env
DB_TYPE=mysql
DB_HOST=localhost
DB_USER=readonly_user  # 읽기 μ „μš© 계정 μ‚¬μš©
DB_PASSWORD=your_password
DB_NAME=your_database
DB_CHARSET=utf8mb4
DB_PORT=3306
```

### PostgreSQL μ„€μ •
```env
DB_TYPE=postgresql
DB_HOST=localhost
DB_USER=postgres
DB_PASSWORD=your_password
DB_NAME=your_database
DB_PORT=5432
DB_SCHEMA=public
```

### SQLite μ„€μ •
```env
DB_TYPE=sqlite
DB_PATH=./database.sqlite
```

## πŸš€ μ‚¬μš©λ²•

### Cursor IDE 연동

`MCP Server` μΆ”κ°€ β†’ `Transport: stdio` β†’ `Command: python main.py`

**ν™˜κ²½λ³€μˆ˜ κ°œλ³„ μ„€μ •:**
```json
{
  "mcpServers": {
    "db-mcp-server": {
      "transport": "stdio",
      "command": "/path/to/venv/bin/python",
      "args": ["/path/to/db-mcp-server/main.py"],
      "env": {
        "DB_TYPE": "postgresql",
        "DB_NAME": "your_db_name",
        "DB_HOST": "localhost"
      }
    }
  }
}
```

## πŸ”’ λ³΄μ•ˆ

### λ³΄μ•ˆ μ •μ±…

이 μ„œλ²„λŠ” μ—„κ²©ν•œ λ³΄μ•ˆ 정책을 μ μš©ν•©λ‹ˆλ‹€:

- **읽기 μ „μš© λͺ¨λ“œ**: SELECT 쿼리만 ν—ˆμš©
- **SQL Injection λ°©μ§€**: 닀쀑 λ¬Έμž₯ μ‹€ν–‰ 및 κΈˆμ§€ 동사 차단
- **μ‹λ³„μž 검증**: ν…Œμ΄λΈ”/컬럼λͺ… ν™”μ΄νŠΈλ¦¬μŠ€νŠΈ 검증
- **νŒŒλΌλ―Έν„° 바인딩**: λͺ¨λ“  μ‚¬μš©μž μž…λ ₯은 μ•ˆμ „ν•œ λ°©μ‹μœΌλ‘œ 처리

### λ³΄μ•ˆ μ„€μ •

μžμ„Έν•œ λ³΄μ•ˆ 섀정은 [SECURITY.md](SECURITY.md)λ₯Ό μ°Έμ‘°ν•˜μ„Έμš”.

### λ°μ΄ν„°λ² μ΄μŠ€ 계정 κΆŒν•œ

**μ€‘μš”**: ν”„λ‘œλ•μ…˜ ν™˜κ²½μ—μ„œλŠ” λ°˜λ“œμ‹œ 읽기 μ „μš© 계정을 μ‚¬μš©ν•˜μ„Έμš”:

```sql
-- MySQL μ˜ˆμ‹œ
CREATE USER 'mcp_readonly'@'%' IDENTIFIED BY 'secure_password';
GRANT SELECT ON your_database.* TO 'mcp_readonly'@'%';

-- PostgreSQL μ˜ˆμ‹œ
CREATE USER mcp_readonly WITH PASSWORD 'secure_password';
GRANT CONNECT ON DATABASE your_database TO mcp_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_readonly;
```

## πŸ› οΈ μ‚¬μš© κ°€λŠ₯ν•œ 도ꡬ듀

### πŸ“‹ **μŠ€ν‚€λ§ˆ 도ꡬ** 
- `get_schema` - 전체 λ°μ΄ν„°λ² μ΄μŠ€ μŠ€ν‚€λ§ˆ 쑰회
- `get_table_stats` - ν…Œμ΄λΈ”λ³„ 톡계 정보
- `get_sample_data` - μƒ˜ν”Œ 데이터 쑰회
- `get_column_stats` - μ»¬λŸΌλ³„ 상세 톡계

### πŸ” **뢄석 도ꡬ**
- `execute_query` - μ•ˆμ „ν•œ 읽기 μ „μš© 쿼리 μ‹€ν–‰
- `explain_query` - 쿼리 μ‹€ν–‰ κ³„νš 뢄석
- `optimize_query` - 쿼리 μ΅œμ ν™” μ œμ•ˆ
- `get_db_status` - λ°μ΄ν„°λ² μ΄μŠ€ μƒνƒœ 정보
- `get_table_size` - ν…Œμ΄λΈ”λ³„ 크기 정보
- `get_index_usage` - 인덱슀 μ‚¬μš© 톡계
- `analyze_performance` - μ„±λŠ₯ 병λͺ© 지점 뢄석
- `suggest_indexes` - 인덱슀 생성 μ œμ•ˆ
- `optimize_tables` - ν…Œμ΄λΈ” μ΅œμ ν™” μ œμ•ˆ

### 🎨 **μ‹œκ°ν™” 도ꡬ**
- `generate_schema_mermaid` - Mermaid ERD λ‹€μ΄μ–΄κ·Έλž¨ 생성
- `generate_tables_summary` - λ§ˆν¬λ‹€μš΄ ν…Œμ΄λΈ” μš”μ•½
- `generate_performance_report` - μ„±λŠ₯ 뢄석 리포트 (ASCII 차트 포함)

## πŸ“Š μ‚¬μš© μ˜ˆμ‹œ

### μŠ€ν‚€λ§ˆ μ‹œκ°ν™”
```
😊 μ‚¬μš©μž: "λ°μ΄ν„°λ² μ΄μŠ€ μŠ€ν‚€λ§ˆλ₯Ό ERD둜 λ³΄μ—¬μ€˜"
πŸ€– AI: generate_schema_mermaid() μ‹€ν–‰ β†’ Mermaid λ‹€μ΄μ–΄κ·Έλž¨ 제곡
```

### μ„±λŠ₯ 뢄석
```
😊 μ‚¬μš©μž: "μ„±λŠ₯ λ¬Έμ œκ°€ μžˆλŠ”μ§€ λΆ„μ„ν•΄μ€˜"  
πŸ€– AI: analyze_performance() β†’ generate_performance_report() μ‹€ν–‰
     β†’ ASCII μ°¨νŠΈμ™€ ν•¨κ»˜ μƒμ„Έν•œ μ„±λŠ₯ 리포트 제곡
```

### ν…Œμ΄λΈ” ν˜„ν™© μš”μ•½
```
😊 μ‚¬μš©μž: "ν…Œμ΄λΈ”λ“€ ν˜„ν™©μ„ μš”μ•½ν•΄μ€˜"
πŸ€– AI: generate_tables_summary() μ‹€ν–‰ β†’ λ§ˆν¬λ‹€μš΄ ν…Œμ΄λΈ” μš”μ•½ 제곡
```

## πŸ—οΈ ν”„λ‘œμ νŠΈ ꡬ쑰

```
db-mcp-server/
β”œβ”€β”€ main.py                 # MCP μ„œλ²„ 메인 파일
β”œβ”€β”€ .env.example            # ν™˜κ²½λ³€μˆ˜ μ˜ˆμ‹œ 파일
β”œβ”€β”€ requirements.txt        # Python μ˜μ‘΄μ„±
β”œβ”€β”€ adapters/               # λ°μ΄ν„°λ² μ΄μŠ€ μ–΄λŒ‘ν„°
β”‚   β”œβ”€β”€ __init__.py        
β”‚   β”œβ”€β”€ base.py            # 베이슀 μ–΄λŒ‘ν„° 클래슀
β”‚   β”œβ”€β”€ mysql.py           # MySQL/MariaDB μ–΄λŒ‘ν„°
β”‚   └── postgresql.py      # PostgreSQL μ–΄λŒ‘ν„°
└── tools/                 # MCP 도ꡬ λͺ¨λ“ˆ
    β”œβ”€β”€ __init__.py
    β”œβ”€β”€ schema_tools.py     # μŠ€ν‚€λ§ˆ κ΄€λ ¨ 도ꡬ
    β”œβ”€β”€ analysis_tools.py   # 뢄석 κ΄€λ ¨ 도ꡬ
    └── visualization_tools.py # μ‹œκ°ν™” κ΄€λ ¨ 도ꡬ
```

## πŸš€ ν™•μž₯μ„±

### μƒˆλ‘œμš΄ λ°μ΄ν„°λ² μ΄μŠ€ μΆ”κ°€

1. `adapters/` 폴더에 μƒˆ μ–΄λŒ‘ν„° 클래슀 생성
2. `DatabaseAdapter` 베이슀 클래슀 상속
3. ν•„μš”ν•œ λ©”μ„œλ“œλ“€ κ΅¬ν˜„
4. `adapters/__init__.py`의 νŒ©ν† λ¦¬ ν•¨μˆ˜μ— μΆ”κ°€

### μƒˆλ‘œμš΄ 도ꡬ μΆ”κ°€

1. ν•΄λ‹Ή μΉ΄ν…Œκ³ λ¦¬μ˜ `tools/` λͺ¨λ“ˆμ— ν•¨μˆ˜ μΆ”κ°€
2. `@mcp.tool()` λ°μ½”λ ˆμ΄ν„°λ‘œ 등둝
3. μ–΄λŒ‘ν„°μ˜ λ©”μ„œλ“œλ₯Ό ν™œμš©ν•˜μ—¬ κ΅¬ν˜„

## πŸ“‹ μš”κ΅¬μ‚¬ν•­

- **Python 3.8+**
- **λ°μ΄ν„°λ² μ΄μŠ€**:
  - MySQL/MariaDB 5.7+
  - PostgreSQL 12+
  - SQLite 3.x

## 🀝 κΈ°μ—¬ν•˜κΈ°

1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request

## πŸ“„ λΌμ΄μ„ΌμŠ€

이 ν”„λ‘œμ νŠΈλŠ” MIT λΌμ΄μ„ΌμŠ€ ν•˜μ— μžˆμŠ΅λ‹ˆλ‹€. μžμ„Έν•œ λ‚΄μš©μ€ `LICENSE` νŒŒμΌμ„ μ°Έμ‘°ν•˜μ„Έμš”.