AI 에이전트를 위한 안전한 데이터베이스 액세스: SQLatte를 사용한 MCP 서버 구축
요약
SQLatte는 Anthropic의 MCP(Model Context Protocol)를 활용하여 AI 에이전트가 데이터베이스에 안전하게 접근할 수 있도록 돕는 오픈 소스 MCP 서버입니다. 보안 계층, 감사 로깅, 비용 최적화 기능을 통해 SQL 인젝션 방지 및 컴플라이언스 문제를 해결하며, 사용자가 제어권을 유지한 채 AI가 데이터를 쿼리할 수 있는 환경을 제공합니다.
핵심 포인트
- MCP(Model Context Protocol)를 통해 AI 모델과 외부 데이터베이스 간의 안전한 상호작용 표준 제공
- SQL 인젝션 방지, 감사 로깅(Audit logging), 비용 최적화를 포함한 4단계 보안 계층 구축
- 자연어를 SQL로 변환하는 SQL Generator와 스마트 LLM 라우팅을 통한 효율적인 데이터 접근
- Trino, BigQuery, PostgreSQL, MySQL 등 다양한 데이터베이스 엔진 지원
요약(TL;DR): SQLatte를 사용하여 기업급 보안, 감사 로깅(Audit logging), 비용 최적화를 갖춘 MCP (Model Context Protocol)를 통해 Claude 및 기타 AI 에이전트에게 데이터베이스에 대한 제어된 액세스 권한을 부여하는 방법을 배워보세요.
🤔 문제점
Claude와 같은 AI 에이전트가 데이터베이스에 직접 쿼리하기를 원하지만, 다음과 같은 문제가 있습니다:
❌ 직접적인 데이터베이스 액세스는 보안 측면에서 악몽과 같습니다
❌ 감사 추적(Audit trail)이 없으면 컴플라이언스(Compliance) 문제가 발생합니다
❌ 제어되지 않는 LLM 호출은 예상치 못한 비용 청구로 이어집니다
❌ AI가 생성한 쿼리로 인한 SQL 인젝션(SQL injection) 위험이 있습니다
해결책은 무엇일까요?
MCP 서버 + SQLatte = 안전하고 감사 가능한 AI-데이터베이스 브릿지
🔌 MCP란 무엇인가?
MCP (Model Context Protocol)는 AI 모델이 외부 시스템과 안전하게 상호작용할 수 있도록 하는 Anthropic의 오픈 표준입니다.
MCP가 없을 때:
사용자 → Claude → "여기 SQL 코드가 있습니다" → 사용자 복사 → 수동 실행
MCP가 있을 때:
사용자 → Claude → [MCP 서버] → 데이터베이스 → 즉시 결과 반환
✨ 핵심 이점: 사용자가 완전한 제어권을 유지하면서 AI가 데이터를 쿼리할 수 있습니다.
🏗️ SQLatte 아키텍처
SQLatte는 AI와 데이터베이스 사이에 안전한 게이트웨이를 제공하는 오픈 소스 MCP 서버입니다:
┌─────────────────┐
│ Claude Desktop │
│ 또는 API │
└────────┬────────┘
│ MCP 프로토콜 (SSE) ▼
┌─────────────────────────┐
│ SQLatte MCP 서버 │
│ ┌──────────────────┐ │
│ │ 감사 로거 (Audit Logger) │◄──┼─ 모든 쿼리 기록 │
│ └──────────────────┘ │
│ ┌──────────────────┐ │
│ │ 비용 최적화 도구 (Cost Optimizer) │◄──┼─ 스마트 LLM 라우팅 │
│ └──────────────────┘ │
│ ┌──────────────────┐ │
│ │ SQL 생성기 (SQL Generator) │◄──┼─ 자연어(NL) → SQL 변환 │
│ └──────────────────┘ │
│ ┌──────────────────┐ │
│ │ 보안 계층 (Security Layer) │◄──┼─ 인젝션 방지 │
│ └──────────────────┘ │
└──────────┬──────────────┘
│ ▼
┌───────────────┐
│ Trino │
│ BigQuery │
│ PostgreSQL │
│ MySQL │
│ ClickHouse │
└───────────────┘
GitHub : osmanuygar/sqlatte
🔐 보안: 4단계 보호 계층
1.
SQL Injection (SQL 인젝션) 방지 # 다층 검증 (Multi-layer validation)
class SecurityValidator :
def validate_sql ( self , sql : str ) -> tuple [ bool , str ] :
# 계층 1: 키워드 블랙리스트 (Keyword blacklist)
dangerous_keywords = [ " DROP ", " TRUNCATE ", " DELETE FROM " ]
# 계층 2: 구문 분석 (Syntax parsing)
parsed = sqlparse . parse ( sql )
# 계층 3: 위험 점수 산정 (Risk scoring)
risk_score = self . calculate_risk ( parsed )
# 계층 4: 고위험군에 대한 관리자 승인 (Admin approval for high-risk)
if risk_score > 0.7 :
return False , " 관리자 승인이 필요합니다 "
return True , " 안전함 "
2. 속도 제한 (Rate Limiting)
config.yaml
security :
rate_limiting :
enabled : true
requests_per_minute : 60
requests_per_hour : 1000
per_user : true
data_limits :
max_bytes_per_query : 10737418240 # 10 GB
max_rows_returned : 100000
- 사용자 기반 액세스 제어 (User-Based Access Control)
사용자별 제한 (Per-user restrictions)
user_access :
osmanuygar :
allowed_databases : [ " analytics" , " staging" ]
allowed_schemas : [ " public" , " reports" ]
max_query_cost : 10.00 # USD
daily_quota : 500
- 감사 로그 (Audit Logging)
모든 쿼리는 전체 컨텍스트와 함께 기록됩니다:
{
"timestamp" : "2025-05-20T14:30:45Z",
"user" : "data_analyst",
"session_id" : "sess_abc123",
"intent_type" : "sql_generation",
"input" : "매출 기준 상위 10명 고객 보여줘",
"generated_sql" : "SELECT customer, SUM(amount)...",
"model_used" : "claude-sonnet-4-20250514",
"execution_time_ms" : 1243,
"rows_returned" : 10,
"data_scanned_bytes" : 2147483648,
"cost" : 0.015,
"success" : true
}
컴플라이언스 감사(SOC2, GDPR)를 위해 CSV로 내보낼 수 있습니다.
💰 비용 최적화: 70% 절감
작업 기반 모델 라우팅 (Task-Based Model Routing)
모든 쿼리에 비용이 많이 드는 모델이 필요하지는 않습니다.
SQLatte는 스마트하게 라우팅합니다:
model_routing : enabled : true
tasks :
저렴하고 빠른 의도 탐지 (intent_detection)
intent_detection :
model : "claude-haiku-3-5-20241022"
max_tokens : 500
cost_per_call : ~$0.0003
정확하고 신뢰할 수 있는 SQL 생성 (sql_generation)
sql_generation :
model : "claude-sonnet-4-20250514"
max_tokens : 4096
cost_per_call : ~$0.015
균형 잡힌 인사이트 (insights)
insights :
model : "claude-sonnet-4-20250514"
max_tokens : 2000
cost_per_call : ~$0.012
| 실제 비용 비교 시나리오 | 라우팅 미사용 시 | 라우팅 사용 시 | 절감액 |
|---|---|---|---|
| 월 10만 건의 쿼리 | $3,600 | $1,012 | 72% |
작동 방식:
- 모든 쿼리는 먼저 Haiku를 거칩니다 (의도 탐지, intent detection)
- 오직 50%만이 Sonnet을 필요로 합니다 (복잡한 SQL 생성)
- 오직 10%만이 인사이트를 필요로 합니다 (분석)
결과: 막대한 비용 절감 💰
🛠️ MCP 도구: 3가지 간단한 API
SQLatte는 sqlatte_mcp_server.py를 통해 3가지 도구를 노출합니다:
-
ask_database - 자연어 쿼리 (Natural Language Query)
@server.tool ()
async def ask_database ( question : str ) -> str :
"""
데이터베이스에 자연어 쿼리를 실행합니다.
예시: "지난달 매출 기준 상위 10개 제품을 보여줘"
반환값: 결과가 포함된 포맷팅된 테이블
""" -
list_tables - 스키마 탐색 (Discover Schema)
@server.tool ()
async def list_tables ( schema : str = None ) -> str :
"""
데이터베이스의 모든 테이블을 나열합니다.
반환값: 행(row) 수가 포함된 테이블 이름
""" -
get_schema - 테이블 구조 (Table Structure)
@server.tool ()
async def get_schema ( table : str ) -> str :
"""
정확한 SQL 생성을 위해 컬럼 상세 정보를 가져옵니다.
반환값: 컬럼 이름, 타입, 샘플 값
"""
왜 도구가 3개뿐인가요?
MCP를 단순하게 유지하기 위해서입니다. 고급 기능(대시보드, 스케줄링)은 웹 UI(web UI)에서 제공됩니다.
🚀 5분 만에 설정하기
1단계: git 설치 및 클론
git clone https://github.com/osmanuygar/sqlatte.git<br>cd sqlatte<br>pip install -r requirements.txt<br>pip install mcp httpx<br><br>2단계: 설정 구성<br>파일 config/config.yaml을 편집합니다.<br>yaml database : provider : "trino" # 또는 bigquery, postgres, mysql trino : host : "your-host.com" port : 443 user : "your-username" password : "your-password" catalog : "hive" schema : "default" llm : provider : "anthropic" anthropic : api_key : "sk-ant-your-key" model : "claude-sonnet-4-20250514" model_routing : enabled : true <br><br>3단계: 서버 실행<br>python app.py<br># 서버는 http://localhost:8000에서 실행됩니다.<br><br>4단계: Claude Desktop 설정 구성<br>macOS: ~/Library/Application Support/Claude/claude_desktop_config.json<br>Windows: %APPDATA%\Claude\claude_desktop_config.json<br>```json
{ "mcpServers" : { "sqlatte" : { "command" : "python3" , "args" : [ "/absolute/path/to/sqlatte/sqlatte_mcp_server.py" ], "env" : { "SQLATTE_URL" : "http://localhost:8000" , "TRINO_HOST" : "your-host" , "TRINO_PORT" : "443" , "TRINO_USER" : "username" , "TRINO_PASSWORD" : "password" , "TRINO_CATALOG" : "hive" , "TRINO_SCHEMA" : "default" , "TRINO_HTTP_SCHEME" : "https" } } } }
🎉 📊 실제 사용 사례: Claude Desktop 사용자의 자연어에서 SQL 변환<br>사용자: "2025년 1분기 매출 기준 상위 10명 고객을 보여줘" (Show me our top 10 customers by revenue in Q1 2025)<br><br>내부 동작 과정:<br>의도 탐지 (Intent Detection) (Haiku - 50ms, $0.0003)<br>분류 (Classification): QUERY<br>SQL 생성 (SQL Generation) (Sonnet - 1.2s, $0.015)<br>```sql
SELECT customer_name , SUM ( order_amount ) as total_revenue FROM orders WHERE order_date >= '2025-01-01' AND order_date < '2025-04-01' GROUP BY customer_name ORDER BY total_revenue DESC LIMIT 10
실행 (Execution) (Trino - 250ms)<br>10개의 행 반환, 2.3 GB 스캔됨<br>감사 로그 (Audit Log) 생성<br>```json
{ "user" : "data_analyst" , "models_used" : [ "haiku" , "sonnet" ] , "total_cost" : "$0.0153" , "execution_time_ms" : 1500 }
Claude의 응답:<br>2025년 1분기 매출 기준 상위 10명 고객입니다:<br>| 고객명 | 총 매출 |<br>|---------------------|----------------|<br>| ACME Corporation | $1,234,567 |<br>| TechCorp Inc | $987,654 |<br>| Global Solutions | $765,432 |<br>...<br><br>🎯 주요 기능<br>✅ 멀티 데이터베이스 지원 (Multi-Database Support)<br>설정으로 데이터베이스 전환:<br>```yaml
database :
provider : " bigquery " # 또는 trino, postgres, mysql, clickhouse
```<br>✅ 시맨틱 레이어 (Semantic Layer)<br>비즈니스 용어를 데이터베이스 스키마 (Schema)에 매핑하여 LLM의 환각 (Hallucination) 방지:<br>```yaml
semantic_layer :
entities :
- name : " Customer"
table : " customer_master"
columns :
cust_id : " Customer ID"
full_name : " Customer Name"
ltv : " Lifetime Value"
```<br>이제 다음과 같이 질문해 보세요: "생애 가치 (Lifetime Value)가 높은 고객을 보여줘"<br>SQLatte는 `ltv` 컬럼을 자동으로 인식합니다!<br><br>✅ 대시보드 시스템 (Dashboard System)<br>쿼리를 자동 생성된 차트와 함께 재사용 가능한 대시보드로 저장합니다.<br><br>✅ 쿼리 스케줄러 (Query Scheduler)<br>이메일 전송 기능이 포함된 정기 보고서를 예약합니다:<br>```yaml
schedule :
name : " Daily Sales Report"
frequency : " 0 9 * * * " # 매일 오전 9시
recipients : [ " [email protected]" ]
```<br><br>🔍 관리자 패널 (Admin Panel)<br>/admin에서 다음 기능에 접속할 수 있습니다:<br>- 감사 로그 (Audit Logs): 사용자, 날짜, 의도 유형별 필터링<br>- 비용 추적 (Cost Tracking): 사용자별 LLM 지출 분석<br>- 시맨틱 레이어 (Semantic Layer): 엔티티/관계 시각적 빌더<br>- 쿼리 히스토리 (Query History): 모든 SQL 실행 내역 검토<br>- 속도 제한 설정 (Rate Limit Config): 보안 설정 조정<br>- 컴플라이언스(Compliance)를 위한 감사 로그 CSV 내보내기<br><br>🧪 프로덕션 모범 사례 (Production Best Practices)<br>1.
항상 감사 로그 (Audit Logging)를 활성화하세요<br>analytics : enabled : true # 쿼리 이력을 위한 PostgreSQL<br><br>2. 속도 제한 (Rate Limits)을 보수적으로 시작하세요<br>rate_limiting : requests_per_minute : 10 # 낮게 시작<br>requests_per_hour : 100 # 사용량에 따라 증가<br><br>3. 시맨틱 레이어 (Semantic Layer)를 사용하세요<br>LLM 환각 (Hallucinations)을 70% 이상 방지합니다 : semantic_layer : enabled : true<br>auto_discovery : true # 제안을 위해 DB 스캔<br><br>4. 비용을 모니터링하세요<br>매일 감사 로그를 확인하세요<br>SELECT user_id, DATE ( timestamp ) as date , SUM ( total_tokens ) as tokens, COUNT ( * ) as queries FROM audit_logs GROUP BY user_id, date<br><br>5. 읽기 전용 (Read-Only) 사용자로 테스트하세요<br>-- 읽기 전용 데이터베이스 사용자 생성<br>CREATE USER sqlatte_ro WITH PASSWORD 'secure_password' ;<br>GRANT SELECT ON ALL TABLES IN SCHEMA public TO sqlatte_ro ;<br><br>🚧 일반적인 과제 및 해결책 (Common Challenges & Solutions)<br><br>과제 1: LLM이 잘못된 컬럼 이름을 생성함<br>문제 : 컬럼명이 username일 때 AI가 user_name이라고 환각을 일으킴<br>해결책 : 항상 스키마 컨텍스트 (Schema Context) + 시맨틱 레이어를 제공하세요<br># get_schema 도구가 정확한 컬럼 이름을 반환함<br>system_prompt = f """ Available columns: { get_schema ( ' users ' ) } Use ONLY these exact column names. """<br><br>과제 2: 비용이 많이 드는 쿼리<br>문제 : 사용자가 모호한 질문을 하면 LLM이 테이블 전체를 스캔함<br>해결책 : 설정에 데이터 제한을 추가하세요<br>security : max_bytes_per_query : 10737418240 # 10 GB 제한<br><br>과제 3: 속도 제한의 오탐 (False Positives)<br>문제 : 정당한 파워 유저가 차단됨<br>해결책 : 사용자별 할당량 (Quotas) 설정<br>users : power_analyst : requests_per_hour : 500 # 더 높은 제한<br>regular_user : requests_per_hour : 100 # 표준 제한<br><br>📈 무엇이 SQLatte를 프로덕션 환경에 적합하게(Production-Ready) 만드는가?
✅ 보안 (Security)
- SQL 인젝션 (SQL injection) 방지 (다중 계층)
- 사용자별 속도 제한 (Rate limiting)
- 감사 로그 (Audit logging) (100% 커버리지)
- 사용자 기반 액세스 제어 (User-based access control)
✅ 비용 제어 (Cost Control)
- 태스크 기반 LLM 라우팅 (Task-based LLM routing) (70% 절감)
- 사용자별 비용 추적 (Per-user cost tracking)
- 쿼리 비용 추정 (Query cost estimation)
- 설정 가능한 할당량 (Configurable quotas)
✅ 신뢰성 (Reliability)
- 커넥션 풀링 (Connection pooling)
- 비동기 FastAPI 아키텍처 (Async FastAPI architecture)
- 우아한 오류 처리 (Graceful error handling)
- 자동 재시도 (Automatic retries)
✅ 관찰 가능성 (Observability)
- 상세한 감사 로그 (Detailed audit logs)
- 토큰 사용량 추적 (Token usage tracking)
- 성능 지표 (Performance metrics)
- 분석을 위한 CSV 내보내기 (CSV export for analysis)
🤝 오픈 소스 및 MIT 라이선스 (Open Source & MIT Licensed)
SQLatte는 완전히 무료이며 오픈 소스입니다:
# 기여하기 (Contribute)
git clone https://github.com/osmanuygar/sqlatte.git
cd sqlatte
git checkout -b feature/your-feature
# 변경 사항 적용, 커밋, 푸시, PR(Pull Request) 진행!
다음과 같은 기여를 환영합니다:
🐛 버그 수정 (Bug fixes)
✨ 새로운 데이터베이스 제공자 (New database providers)
📖 문서 개선 (Documentation improvements)
🌍 번역 (Translations)
💭 왜 MCP + SQLatte인가?
직접적인 데이터베이스 액세스 (Direct Database Access)와 비교 시
✅ 보안 (Security): 직접 액세스 대비 다중 계층 보호
✅ 감사 (Audit): 기록이 없는 경우 대비 전체 로깅 제공
✅ 비용 (Cost): 통제되지 않는 비용 대비 최적화된 라우팅
커스텀 API (Custom API)와 비교 시
✅ 표준 (Standard): 독자적인 방식 대비 MCP 프로토콜 사용
✅ 멀티 AI (Multi-AI): Claude, ChatGPT, Gemini와 모두 호환
✅ 커뮤니티 (Community): 공유된 툴링 생태계 활용
BI 도구 (BI Tools)와 비교 시
✅ 대화형 (Conversational): 클릭 위주의 UI 대비 자연어 사용
✅ 유연성 (Flexible): 경직된 대시보드 대비 애드혹(Ad-hoc) 쿼리 가능
✅ 속도 (Fast): 긴 설정 과정 대비 즉각적인 답변
🚀 시작하기 (Get Started)
# 1. 클론 (Clone)
git clone https://github.com/osmanuygar/sqlatte.git
cd sqlatte
# 2. 설치 (Install)
pip install -r requirements.txt
pip install mcp httpx
# 3. 설정 (Configure)
cp config/config.yaml.example config/config.yaml
# 데이터베이스 자격 증명으로 편집하세요
# 4. 실행 (Run)
python app.py
# 5. Claude Desktop 설정
# (위의 설정 지침을 참조하세요)
# 6. Claude에게 질문하기!
"모든 테이블 목록 표시" 📚 리소스 GitHub : osmanuygar/sqlatte 문서(Documentation) : osmanuygar.github.io/sqlatte-docs MCP 프로토콜(Protocol) : modelcontextprotocol.io Anthropic Claude : anthropic.com 🎯 핵심 요약(Key Takeaways) MCP는 안전한 AI-데이터베이스 연결을 가능하게 합니다. 감사 로깅(Audit logging)은 운영 환경(Production)에서 타협할 수 없는 필수 사항입니다. 작업 기반 라우팅(Task-based routing)은 LLM 비용을 70% 이상 절감합니다. 시맨틱 레이어(Semantic layers)는 AI의 환각(Hallucinations) 현상을 방지합니다. SQLatte는 기업용으로 즉시 사용 가능한 구성 요소들을 기본적으로 제공합니다. Made with ❤️ and ☕ 안전하고, 감사 가능하며, 비용 효율적인 AI 데이터베이스 액세스. 질문이 있으신가요? GitHub에 이슈(Issue)를 생성해 주세요. 도움이 되셨나요? ⭐️ 리포지토리(Repo)에 별(Star)을 눌러주시고 팀원들과 공유해 주세요! 태그(Tags) : #ai #mcp #python #database #security #anthropic #claude #sql #opensource #llm
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기