MCP SQLite Server (Read-Only)
MCP SQLite Server (읽기 전용)
프로덕션 준비가 완료된 Model Context Protocol 서버로, AI 에이전트에게 SQLite 데이터베이스(shop.db)에 대한 안전한 읽기 전용 액세스를 제공합니다. 공식 mcp Python SDK와 stdio 전송을 사용하여 구축되었습니다.
기능
3가지 MCP 도구:
list_tables,describe_table,query_database다층 방어(Defense-in-depth) 읽기 전용 안전성: SQLite URI 읽기 전용 모드 +
PRAGMA query_only+ SQL 검증기 + EXPLAIN opcode 검사쿼리 검증:
INSERT/UPDATE/DELETE/DROP/ALTER/CREATE/REPLACE/TRUNCATE/ATTACH/DETACH, 다중 문 쿼리(;), SQL 주석(--,/* */) 및 수정형PRAGMA를 거부합니다 — 문자열 리터럴에 대한 오탐(false positive) 없이페이지네이션: 기본 행 제한(100),
limit/offset매개변수, 잘림 출력 플래그stderr 전용 로깅: 모든 로그/트레이스백은
sys.stderr로 전송됩니다.stdout은 JSON-RPC 전용으로 예약됩니다.전체 타입 힌트:
mypy --strict클린TDD: 보안, DB 계층, MCP 도구, 8가지 벤치마크 쿼리, stderr 가드를 포함한 105개 테스트
Related MCP server: sqlite-mcp-server
빠른 시작
사전 요구 사항
Python 3.10+
SQLite 데이터베이스 파일(기본값:
./shop.db)
로컬 설정
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"구성
.env.example을 복사하고 데이터베이스 경로를 설정합니다:
cp .env.example .env
# Edit DATABASE_PATH to point to your SQLite file또는 환경 변수를 직접 설정합니다:
export DATABASE_PATH=/abs/path/to/shop.db서버 실행
python -m mcp_server.server서버는 MCP stdio 전송을 사용하여 stdin/stdout을 통해 통신합니다. 직접 상호작용할 필요는 없습니다 — MCP 클라이언트(예: Claude Desktop, AI 에이전트)가 연결합니다.
MCP 클라이언트 구성
표준 Python
MCP 클라이언트 구성(예: Claude Desktop의 claude_desktop_config.json)에 다음을 추가합니다:
{
"mcpServers": {
"sqlite-shop": {
"command": "python",
"args": ["-m", "mcp_server.server"],
"env": {
"DATABASE_PATH": "/abs/path/to/shop.db"
}
}
}
}Docker
먼저 이미지를 빌드합니다:
docker build -t mcp-shop:latest .그런 다음 MCP 클라이언트를 구성합니다:
{
"mcpServers": {
"sqlite-shop": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-v", "/abs/path/to/shop.db:/app/shop.db",
"-e", "DATABASE_PATH=/app/shop.db",
"mcp-shop:latest"
]
}
}
}Docker Compose
docker compose up -d도구
list_tables
데이터베이스의 모든 사용자 테이블과 뷰를 나열합니다(내부 sqlite_* 테이블 제외).
매개변수: 없음
반환값:
{
"tables": ["customers", "orders", "order_items", "products"],
"count": 4
}describe_table
테이블의 스키마를 설명합니다: 열, 외래 키, 행 수 및 CREATE 문.
매개변수:
table(문자열, 필수): 설명할 테이블의 이름.
반환값:
{
"table": "customers",
"columns": [
{"cid": 0, "name": "id", "type": "INTEGER", "notnull": 0, "default": null, "pk": 1},
{"cid": 1, "name": "first_name", "type": "TEXT", "notnull": 1, "default": null, "pk": 0}
],
"foreign_keys": [],
"row_count": 150,
"sql": "CREATE TABLE customers (...)"
}query_database
페이지네이션을 지원하는 읽기 전용 SQL 쿼리를 실행합니다.
매개변수:
sql(문자열, 필수): 단일 읽기 전용 SQL 문(SELECT,WITH,EXPLAIN또는 읽기 전용PRAGMA).limit(정수, 선택): 반환할 최대 행 수. 기본값: 100. 최대: 1000.offset(정수, 선택): 건너뛸 행 수. 기본값: 0.
반환값:
{
"columns": ["id", "first_name"],
"rows": [{"id": 1, "first_name": "Alice"}, {"id": 2, "first_name": "Bob"}],
"row_count": 2,
"truncated": false,
"limit": 100,
"offset": 0
}truncated가 true이면 더 많은 행이 존재합니다 — offset을 늘려 다음 페이지를 가져옵니다.
보안
서버는 읽기 전용 액세스를 보장하기 위해 다층 방어를 구현합니다:
계층 1: SQLite 연결(URI 읽기 전용 모드)
데이터베이스는 file:<path>?mode=ro로 열리며, SQLite 엔진 수준에서 쓰기를 방지합니다. 또한 모든 연결에 PRAGMA query_only = ON이 설정됩니다.
계층 2: SQL 쿼리 검증기(security.py)
모든 쿼리가 SQLite에 도달하기 전에 다단계 검증기를 통과합니다:
문자열 리터럴 제거: 문자열 리터럴(
'...',"...")은 플레이스홀더로 대체되어 데이터 내부의 키워드(예: "Deleted Item"이라는 제품)가 오탐을 유발하지 않도록 합니다.주석 감지: SQL 주석(
--,/* */)은 주석 기반 우회를 방지하기 위해 거부됩니다.다중 문 거부: 세미콜론(
;)은 스택 쿼리를 방지하기 위해 거부됩니다.키워드 분석: 첫 번째 실제 문 키워드는
SELECT,WITH,EXPLAIN또는PRAGMA여야 합니다. 파괴적 키워드(INSERT,UPDATE,DELETE,DROP,ALTER,CREATE,REPLACE,TRUNCATE,ATTACH,DETACH,VACUUM등)는 차단됩니다.PRAGMA 검증: 읽기 전용 PRAGMA(
table_info,database_list등)는 허용됩니다. 할당(=)이 있거나 변경형 PRAGMA 블록리스트(journal_mode,synchronous,foreign_keys등)에 포함된 PRAGMA는 거부됩니다.
계층 3: EXPLAIN Opcode 검사
최종 방어선으로, 쿼리는 EXPLAIN <query>를 통해 SQLite 자체 파서로 실행됩니다. 결과 opcode 스트림에서 쓰기 opcode(OpenWrite, Insert, Delete, Create, Drop 등)와 쓰기 트랜잭션 플래그를 검사합니다. 발견되면 쿼리가 거부됩니다.
계층 4: 정화된 오류 메시지
클라이언트에 반환되는 모든 오류는 정화됩니다 — 파일 시스템 경로와 내부 세부 정보는 정보 유출을 방지하기 위해 제거됩니다.
테스트
테스트는 임시/인메모리 데이터베이스만 사용합니다 — 프로덕션 shop.db는 절대 사용하지 않습니다.
# Run all tests
python -m pytest
# Run with verbose output
python -m pytest -v
# Run a specific test file
python -m pytest tests/test_security.py테스트 커버리지
테스트 파일 | 커버리지 |
| 76개 테스트: 유효한 쿼리, 파괴적 문 거부, PRAGMA 검증, 다중 문 거부, 주석 우회 방지, 문자열 리터럴 처리 |
| 20개 테스트: 읽기 전용 강제, 테이블 나열, 스키마 설명, 페이지네이션, 잘림, 8가지 벤치마크 쿼리 전체 |
| 9개 테스트: MCP 도구 검색, SDK 클라이언트를 통한 도구 호출, 파괴적 쿼리 거부, 페이지네이션, 도구를 통한 7가지 벤치마크 쿼리, stderr/stdout 오염 방지 가드 |
정적 분석
# Type checking
python -m mypy
# Linting
python -m ruff check src/ tests/프로젝트 구조
.
├── .env.example # Environment variable template
├── Dockerfile # Docker containerization
├── docker-compose.yml # Docker Compose config
├── pyproject.toml # Package config, deps, tool settings
├── README.md # This file
├── shop.db # The SQLite database (not included in tests)
├── src/mcp_server/
│ ├── __init__.py
│ ├── config.py # Configuration (DATABASE_PATH, limits, URI builder)
│ ├── db.py # Read-only Database class with introspection + query
│ ├── security.py # SQL validator (multi-layer defense-in-depth)
│ ├── server.py # MCP server entrypoint (stdio transport)
│ ├── tools.py # MCP tool definitions and handlers
│ └── py.typed # PEP 561 marker
└── tests/
├── __init__.py
├── test_db.py # Database layer + benchmark tests
├── test_security.py # Query validator tests
└── test_server.py # MCP server/tool tests벤치마크 작업
서버의 도구를 통해 AI 에이전트는 다음 분석 작업을 수행할 수 있습니다(통제된 픽스처 데이터베이스에 대한 테스트로 검증됨):
테이블 검색:
list_tables+describe_table— 모든 테이블을 나열하고 스키마를 설명합니다.필터링된 개수:
SELECT COUNT(*) FROM customers WHERE country = 'Germany'를 사용한query_database.국가 집계:
SELECT country, COUNT(*) ... GROUP BY country ORDER BY ... DESC LIMIT 1.고객 LTV:
customers+orders조인,SUM(total_amount), 합계 기준 정렬.제품 성과:
order_items+products조인, 수량과 매출로 집계,LIMIT 5.카테고리 집계:
order_items→products→category탐색, 매출 집계,LIMIT 3.날짜 필터링:
SUM(total_amount) WHERE substr(order_date,1,4) = '2025'.주문 집계:
customers+orders조인,COUNT(o.id), 개수 기준 정렬.
구성
환경 변수 | 기본값 | 설명 |
|
| SQLite 데이터베이스 파일 경로 |
|
| 쿼리 결과의 기본 행 제한(최대 1000) |
라이선스
이 프로젝트는 데모 목적으로 있는 그대로 제공됩니다.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceExposes a SQLite database to AI assistants with structured, read-safe access. Includes five tools for schema exploration, querying, and sampling data.
- AlicenseNot gradedqualityCmaintenanceA read-only MCP server that enables LLMs to safely explore and query any SQLite database via natural language. It exposes tools for listing tables, describing schemas, and executing SELECT/WITH queries with built-in safety guards like write prevention and row limits.MIT
- FlicenseNot gradedqualityCmaintenanceExposes any SQLite database as read-only MCP tools for AI assistants, enabling listing tables, describing schemas, and running SELECT queries with filtering, ordering, and pagination.
- FlicenseNot gradedqualityBmaintenanceEnables AI agents to query a SQLite database using natural language through the Model Context Protocol (MCP). Includes security guardrails that block destructive SQL operations.
Related MCP Connectors
Explore, query, and inspect SQLite databases with ease. List tables, preview results, and view det…
Read-only MCP server for Muovi, Argentina's trust-first local services marketplace (6 tools).
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ilyassakhanov/my-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server