지난 글에서 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() 한 줄로 허물어버린다.