以下是使用MCP Python SDK构建的SQLite浏览器的完整操作指南:
一、环境准备
- 安装依赖
bash
# 安装MCP SDK及SQLite支持
pip install mcp sqlite3
- 创建测试数据库
bash
sqlite3 test.db <<EOF
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT);
INSERT INTO users (name, email) VALUES ('Alice', '[email protected]');
INSERT INTO users (name, email) VALUES ('Bob', '[email protected]');
EOF
二、服务端开发
python
# sqlite_explorer.py
import sqlite3
from mcp.server.fastmcp import FastMCP, Context
# 初始化MCP服务器
mcp = FastMCP("SQLite Explorer")
@mcp.resource("schema://{database}")
def get_schema(database: str) -> str:
"""获取数据库模式"""
try:
conn = sqlite3.connect(f"{database}.db")
result = conn.execute("SELECT sql FROM sqlite_master").fetchall()
return "\n".join(row[0] for row in result if row[0])
except Exception as e:
return f"Error: {str(e)}"
@mcp.tool()
def execute_query(sql: str, ctx: Context) -> str:
"""安全执行SQL查询"""
try:
# 限制DELETE/UPDATE操作
if any(cmd in sql.upper() for cmd in ["DELETE", "UPDATE", "DROP"]):
return "Error: Write operations are disabled"
conn = sqlite3.connect("test.db")
cursor = conn.execute(sql)
# 返回格式化的结果
if cursor.description:
headers = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
return f"{headers}\n" + "\n".join(str(row) for row in rows)
return "Query executed successfully"
except Exception as e:
return f"Error: {str(e)}"
if __name__ == "__main__":
mcp.run()
三、服务启动与测试
- 启动服务器
bash
mcp dev sqlite_explorer.py
- 通过客户端交互
python
# client.py
from mcp.client.stdio import stdio_client
from mcp import ClientSession
async def main():
async with stdio_client() as (read, write):
async with ClientSession(read, write) as session:
# 获取数据库模式
schema = await session.read_resource("schema://test")
print("Schema:\n", schema)
# 执行查询
result = await session.call_tool("execute_query", {
"sql": "SELECT * FROM users LIMIT 2"
})
print("Query Result:\n", result)
asyncio.run(main())
四、核心功能说明
- 安全防护机制
- 自动拦截危险操作(DELETE/UPDATE/DROP)
- 限制最大返回行数(可在代码中添加
LIMIT
子句) - 使用参数化查询(示例中可扩展实现)
- 数据展示优化
python
# 在execute_query工具中优化输出格式
if cursor.description:
headers = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
max_width = 20
return (
"| " + " | ".join(h.ljust(max_width) for h in headers) + " |\n" +
"|-" + "-|-".join("-"*max_width for _ in headers) + "-|\n" +
"\n".join(
"| " + " | ".join(str(v).ljust(max_width)[:max_width] for v in row
) + " |"
for row in rows
)
)
五、高级功能扩展
- 数据库切换支持
python
@mcp.tool()
def switch_database(db_name: str) -> str:
global current_db
if not os.path.exists(f"{db_name}.db"):
return "Database not found"
current_db = f"{db_name}.db"
return f"Switched to {db_name}"
- 查询历史记录
python
from datetime import datetime
query_history = []
@mcp.resource("history://last10")
def get_history() -> str:
return "\n".join(
f"{ts} | {query}"
for ts, query in query_history[-10:]
)
# 在execute_query中记录历史
query_history.append((datetime.now().strftime("%Y-%m-%d %H:%M"), sql))
六、使用场景示例
- 自然语言查询转换
bash
用户请求 -> "显示最近注册的5个用户"
转换SQL -> "SELECT * FROM users ORDER BY id DESC LIMIT 5"
- 数据可视化对接
python
@mcp.tool()
def generate_chart(sql: str) -> Image:
data = execute_query(sql)
plt.figure()
# 生成图表逻辑
return Image(data=plot_to_bytes(), format="png")
通过以上实现,您已构建了一个具备完整CRUD功能、安全审计、历史追溯的SQLite浏览器服务。该服务可通过MCP协议无缝集成到各类LLM应用中,实现自然语言到结构化查询的安全转换。