본문 바로가기
  • 데이터에 가치를 더하다, 서영석입니다.
카테고리 없음

MCP 서버 직접 만들기 — AI가 DB를 직접 읽게 하는 법

by 꿀먹은데이터 2026. 3. 7.

지난 글에서 MCP가 "AI와 시스템 사이의 USB"라고 했다. 그 MCP를 직접 만들어보려고 한다.

Python으로 MCP 서버를 직접 만들고 AI가 데이터베이스를 읽게 하는 방법을 실습으로 알아본다.

  • SQLite DB (sales.db) — 고객/상품/주문 데이터
  • MCP 서버 (mcp_server.py) — 4개 Tool 보유
  • Claude Desktop — MCP 클라이언트 역할

핵심은 "Python 함수 하나를 AI Tool로 만들 수 있다." 이다.

STEP 0. MCP 라이브러리 설치

먼저 MCP 서버를 만들기 위한 라이브러리를 설치한다.

pip install fastmcp

STEP 1. 샘플 데이터베이스 만들기

실습을 위한 간단한 판매 데이터베이스를 만든다.

# setup_db.py
import sqlite3

conn = sqlite3.connect("sales.db")

conn.executescript("""
CREATE TABLE customers (
id INTEGER PRIMARY KEY, name TEXT, email TEXT, region TEXT);

CREATE TABLE products (
id INTEGER PRIMARY KEY, name TEXT, category TEXT, price REAL);

CREATE TABLE orders (
id INTEGER PRIMARY KEY, customer_id INT, product_id INT, quantity INT, order_date TEXT );
""")

conn.close()​

이 스크립트를 실행하면 다음 테이블이 생성된다.

테이블 설명
customers 고객 정보
products 상품 정보
orders 주문 정보

여기에 샘플 데이터를 몇 개 넣어두면 실습 준비가 끝난다.


STEP 2. MCP 서버 만들기

이제 본격적으로 MCP 서버를 만든다.

from mcp.server.fastmcp import FastMCP  
  mcp \= FastMCP("sales-db-server")

sales-db-server는 MCP 서버의 이름이다.


MCP의 핵심: @mcp.tool()

MCP에서 가장 중요한 부분은 @mcp.tool() 이다.
이 데코레이터 하나만 붙이면 Python 함수가 AI가 사용할 Tool이 된다.
예를 들어 DB 테이블 목록을 조회하는 Tool을 만들어보자.

@mcp.tool()  
def list\_tables() -> list\[str\]:  

 

DB 테이블 목록 반환

import sqlite3

with sqlite3.connect("sales.db") as conn:  
rows = conn.execute("SELECT name FROM sqlite\_master WHERE type='table'").fetchall()

return \[r\[0\] for r in rows\]

 

이제 Claude는 이 함수를 이렇게 사용할 수 있다. "이 데이터베이스에 어떤 테이블이 있어?" 그러면 Claude는 자동으로list_tables() Tool을 호출한다.

STEP 3. 실전 Tool 4개 만들기

실제 사용을 위해 다음과 같은 Tool을 만든다.

Tool 역할 클로드
list_tables() 테이블 목록 조회 데이터 구조 파악
describe_table() 테이블 컬럼 조회 SQL 작성 전 분석
query_sales() SQL 실행 자연어 → SQL
get_sales_summary() 매출 요약 리포트 생성

 

Tool 1 — 테이블 구조 확인

@mcp.tool()  
def describe\_table(table: str):

import sqlite3

with sqlite3.connect("sales.db") as conn:  
rows = conn.execute(  
f"PRAGMA table\_info({table})"  
).fetchall()

return rows

 

AI가 SQL을 작성하기 전에 테이블 구조를 먼저 확인할 수 있다.


Tool 2 — SQL 실행

AI가 자연어 질문을 받으면 SQL을 생성하고 이 Tool을 호출한다.

@mcp.tool()  
def query\_sales(sql: str):

import sqlite3

if not sql.strip().upper().startswith("SELECT"):  
return {"error": "SELECT 쿼리만 허용됩니다."}

with sqlite3.connect("sales.db") as conn:  
rows = conn.execute(sql).fetchall()

return rows

중요한 보안 처리

AI에게 DB 접근 권한을 줄 때 가장 중요한 것은 보안이다. AI가 실수로 이런 쿼리를 실행할 수도 있다.

DELETE FROM customers

그래서 우리는 다음과 같은 제한을 둔다.

if not sql.strip().upper().startswith("SELECT"):  
return {"error": "SELECT 쿼리만 허용됩니다."}

읽기 전용(Read Only) SQL만 허용한다. 이 한 줄이 실제 서비스에서도 매우 중요하다.

Tool 3 — 매출 요약

AI에게 리포트를 생성하는 Tool도 만들 수 있다.

@mcp.tool()  
def get\_sales\_summary():

import sqlite3

with sqlite3.connect("sales.db") as conn:

total\_orders = conn.execute(  
"SELECT COUNT(\*) FROM orders"  
).fetchone()\[0\]

total\_sales = conn.execute(  
"SELECT SUM(quantity \* price) FROM orders JOIN products ON orders.product\_id = products.id"  
).fetchone()\[0\]

return {  
"total\_orders": total\_orders,  
"total\_sales": total\_sales  
}

이제 Claude에게 "현재 매출 현황 요약해줘" 라고 물어볼 수 있다.

STEP 4. MCP 서버 실행

마지막으로 서버를 실행한다.

if \_\_name\_\_ == "\_\_main\_\_":  
mcp.run(transport="stdio")

 

stdio는 Claude Desktop 연결용 프로토콜이다.


STEP 5. Claude Desktop에 MCP 등록

Claude Desktop 설정 파일에 서버를 등록한다.

~/.config/claude/claude\_desktop\_config.json

{  
"mcpServers": {  
"sales-db": {  
"command": "python",  
"args": \["/path/to/mcp\_server.py"\]  
}  
}  
}

그리고 Claude Desktop을 재시작하면 끝이다.

실제 테스트 결과

실제로 실행하면 다음과 같이 동작한다.

테이블 조회 함수

Tool: list\_tables()
\['customers', 'products', 'orders'\]

매출 요약 쿼리

Tool: get\_sales\_summary()

 

전체 프로젝트 구조

최종 파일 구조는 매우 단순하다.

mcp\_demo/  
├── setup\_db.py  
├── mcp\_server.py  
└── sales.db

전체 코드 길이도 약 70줄 정도다.


왜 MCP가 중요한가

기업에서 AI 도입이 어려운 이유는 “우리 데이터에 AI를 어떻게 연결하지?” 이다.

마치며

기존 : API 개발 > 인증 처리 > 데이터 파이프라인 > 프롬프트 연결

"MCP 서버 : Python 함수 + @mcp.tool() 데코레이터"

기업 AI 도입의 가장 큰 벽이 "우리 데이터에 어떻게 연결하나"였다. MCP는 그 벽을 @mcp.tool() 한 줄로 허물어버린다.

반응형