< 返回版块

zhuxiujia 发表于 2025-06-22 10:12

Tags:使用 Rust + MCP 构建智能数据库服务:RBDC-MCP 实践分享

🦀 使用 Rust + MCP 构建智能数据库服务:RBDC-MCP 实践分享

前言

随着 AI 时代的到来,传统的数据库交互方式正在发生革命性的变化。今天我想和大家分享一个用 Rust 结合 Model Context Protocol (MCP) 构建的智能数据库服务项目 —— RBDC-MCP

这个项目展示了如何使用 Rust 的官方 MCP SDK (rmcp) 来构建一个能与 Claude AI 无缝集成的数据库服务,让用户通过自然语言与数据库交互。

项目地址: https://github.com/rbatis/rbdc-mcp

🏗️ 技术架构深度解析

1. 核心依赖与技术栈

项目采用了以下关键技术:

[dependencies]
# MCP 官方 Rust SDK
rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", 
         branch = "main", features = ["server", "transport-io"] }

# 异步运行时
tokio = { version = "1.0", features = ["full"] }

# RBDC 数据库生态系统
rbdc = { version = "4.6.0" }
rbdc-sqlite = { version = "4.6.0" }
rbdc-mysql = { version = "4.6.0" }
rbdc-pg = { version = "4.6.0" }
rbdc-mssql = { version = "4.6.0" }
rbdc-pool-fast = { version = "4.6.0" }

2. 模块化设计

项目采用清晰的模块化架构:

  • main.rs - 程序入口,负责参数解析和服务启动
  • db_manager.rs - 数据库连接管理和操作封装
  • handler.rs - MCP 协议处理和工具定义

3. 数据库管理器设计

pub struct DatabaseManager {
    pool: Arc<FastPool>,
    db_type: DatabaseType,
}

impl DatabaseManager {
    pub fn new(url: &str) -> Result<Self> {
        let db_type = DatabaseType::from_url(url)?;
        
        let driver: Box<dyn Driver> = match db_type {
            DatabaseType::SQLite => Box::new(rbdc_sqlite::SqliteDriver {}),
            DatabaseType::MySQL => Box::new(rbdc_mysql::MysqlDriver {}),
            DatabaseType::PostgreSQL => Box::new(rbdc_pg::PgDriver {}),
            DatabaseType::MSSQL => Box::new(rbdc_mssql::MssqlDriver {}),
        };

        let manager = ConnectionManager::new(driver, url)?;
        let pool = FastPool::new(manager)?;
        
        Ok(Self {
            pool: Arc::new(pool),
            db_type,
        })
    }
}

这里的设计亮点:

  • 统一抽象: 使用 Driver trait 统一不同数据库的接口
  • 连接池管理: 使用 FastPool 提供高性能的连接池
  • 类型安全: 通过 DatabaseType 枚举确保类型安全

🛠️ MCP 工具实现详解

1. 工具定义

项目使用 rmcp 库的宏来定义 MCP 工具:

#[tool(tool_box)]
impl RbdcDatabaseHandler {
    #[tool(description = "Execute SQL query and return results")]
    async fn sql_query(&self, #[tool(aggr)] SqlQueryParams { sql, params }: SqlQueryParams) 
        -> Result<CallToolResult, McpError> {
        // 实现逻辑
    }

    #[tool(description = "Execute SQL modification statements")]
    async fn sql_exec(&self, #[tool(aggr)] SqlExecParams { sql, params }: SqlExecParams) 
        -> Result<CallToolResult, McpError> {
        // 实现逻辑
    }

    #[tool(description = "Get database connection pool status")]
    async fn db_status(&self) -> Result<CallToolResult, McpError> {
        // 实现逻辑
    }
}

2. 参数转换处理

项目巧妙地处理了 JSON 参数到 RBS 参数的转换:

fn convert_params(&self, params: &[Value]) -> Vec<rbs::Value> {
    params.iter()
        .map(|v| serde_json::from_value(v.clone()).unwrap_or_default())
        .collect()
}

💡 丰富的实际应用场景

🎯 在 Cursor 中的开发场景

1. 从零构建 Rust HTTP 服务器

场景: 在 Cursor 中开发新项目时,需要快速搭建 HTTP 服务器和数据库

AI 对话示例:

开发者: "帮我创建一个用户管理的 HTTP API,包含用户注册、登录、查询功能"

AI: "我来帮你构建完整的用户管理系统。首先让我查看数据库结构..."

AI 会自动:

  • 查询现有数据库表结构
  • 分析字段类型和约束
  • 生成对应的 Rust 结构体
  • 创建完整的 Axum/Actix-web 路由
  • 实现数据库操作函数

生成的代码示例:

#[derive(Debug, Serialize, Deserialize)]
pub struct User {
    pub id: i64,
    pub username: String,
    pub email: String,
    pub created_at: DateTime<Utc>,
}

#[derive(Debug, Deserialize)]
pub struct CreateUserRequest {
    pub username: String,
    pub email: String,
    pub password: String,
}

// 自动生成的 HTTP 处理函数
async fn create_user(
    State(pool): State<Arc<Pool>>,
    Json(req): Json<CreateUserRequest>
) -> Result<Json<User>, ApiError> {
    // AI 生成的完整实现
}

2. 智能数据库结构体生成

场景: 已有数据库,需要生成对应的 Rust 结构体

AI 对话:

开发者: "根据 users 表生成 Rust 结构体,包含 Serde 序列化"

AI 执行: 
1. 查询表结构: "DESCRIBE users" 或 "PRAGMA table_info(users)"
2. 分析字段类型映射
3. 生成完整结构体定义

自动生成:

use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
    pub id: i64,
    pub username: String,
    pub email: String,
    pub password_hash: String,
    pub is_active: bool,
    pub created_at: DateTime<Utc>,
    pub updated_at: Option<DateTime<Utc>>,
}

#[derive(Debug, Deserialize)]
pub struct CreateUser {
    pub username: String,
    pub email: String,
    pub password: String,
}

#[derive(Debug, Deserialize)]
pub struct UpdateUser {
    pub username: Option<String>,
    pub email: Option<String>,
    pub is_active: Option<bool>,
}

3. 数据库访问层自动生成

AI 对话:

开发者: "为 User 结构体生成完整的数据库访问层,包含 CRUD 操作"

AI 自动生成:

use anyhow::Result;
use rbdc::pool::Pool;

pub struct UserRepository {
    pool: Arc<Pool>,
}

impl UserRepository {
    pub fn new(pool: Arc<Pool>) -> Self {
        Self { pool }
    }

    pub async fn create(&self, user: CreateUser) -> Result<User> {
        let mut conn = self.pool.get().await?;
        let sql = r#"
            INSERT INTO users (username, email, password_hash, created_at)
            VALUES (?, ?, ?, ?)
            RETURNING id, username, email, password_hash, is_active, created_at, updated_at
        "#;
        
        let password_hash = hash_password(&user.password)?;
        let now = Utc::now();
        
        let result = conn.fetch_one(sql, vec![
            user.username.into(),
            user.email.into(),
            password_hash.into(),
            now.into(),
        ]).await?;
        
        Ok(User::from_row(result)?)
    }

    pub async fn find_by_id(&self, id: i64) -> Result<Option<User>> {
        // AI 生成的完整实现
    }

    pub async fn find_by_email(&self, email: &str) -> Result<Option<User>> {
        // AI 生成的完整实现
    }

    pub async fn update(&self, id: i64, updates: UpdateUser) -> Result<User> {
        // AI 生成的动态 SQL 更新逻辑
    }

    pub async fn delete(&self, id: i64) -> Result<bool> {
        // AI 生成的删除逻辑
    }
}

🔍 数据库设计与验证场景

4. 数据库设计验证

场景: 检查数据库设计的合理性

AI 对话:

开发者: "帮我分析这个电商数据库设计是否合理,检查表关系和索引"

AI 自动执行:
1. 查询所有表结构
2. 分析外键关系
3. 检查索引配置
4. 提供优化建议

AI 分析结果:

数据库设计分析报告:

✅ 优点:
- users 表主键设计合理
- 订单表包含必要的时间戳
- 外键约束设置正确

⚠️ 建议优化:
- users.email 字段建议添加唯一索引
- orders.created_at 建议添加索引提升查询性能  
- products.category_id 建议添加外键约束

🔧 推荐的 SQL 优化:
```sql
CREATE UNIQUE INDEX idx_users_email ON users(email);
CREATE INDEX idx_orders_created_at ON orders(created_at);
ALTER TABLE products ADD CONSTRAINT fk_products_category 
    FOREIGN KEY (category_id) REFERENCES categories(id);

5. 数据库迁移脚本生成

AI 对话:

开发者: "我需要为用户表添加 phone 字段,生成迁移脚本"

AI 自动生成迁移脚本:
```rust
// migrations/20241201_add_phone_to_users.sql
-- Up
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
CREATE INDEX idx_users_phone ON users(phone);

-- Down  
DROP INDEX idx_users_phone;
ALTER TABLE users DROP COLUMN phone;

📊 数据分析与报表场景

6. 智能数据分析

AI 对话:

开发者: "分析最近一个月的用户注册趋势,按天统计"

AI 自动执行复杂查询:
```sql
SELECT 
    DATE(created_at) as date,
    COUNT(*) as registrations,
    COUNT(*) - LAG(COUNT(*)) OVER (ORDER BY DATE(created_at)) as daily_change
FROM users 
WHERE created_at >= DATE('now', '-30 days')
GROUP BY DATE(created_at)
ORDER BY date;

7. 性能监控与优化

AI 对话:

开发者: "检查慢查询并提供优化建议"

AI 分析:
1. 查询执行计划
2. 识别全表扫描
3. 推荐索引优化
4. 生成优化后的 SQL

🧪 测试数据生成场景

8. 测试数据自动生成

AI 对话:

开发者: "为用户表生成100条测试数据"

AI 自动生成:
```sql
INSERT INTO users (username, email, password_hash, created_at) VALUES
('user_001', 'user001@example.com', '$2b$12$...', '2024-11-01 10:00:00'),
('user_002', 'user002@example.com', '$2b$12$...', '2024-11-01 11:00:00'),
-- ... 继续生成98条数据

🔄 数据同步与转换场景

9. 数据库间同步

AI 对话:

开发者: "将 MySQL 的用户数据同步到 PostgreSQL"

AI 生成同步脚本:
1. 读取源数据库结构
2. 生成目标数据库 DDL
3. 创建数据转换逻辑
4. 处理数据类型差异

10. API 数据验证

场景: 验证 API 返回的数据与数据库一致性

AI 对话:

开发者: "验证 /api/users/{id} 接口返回的数据是否与数据库一致"

AI 自动:
1. 查询数据库中的用户数据
2. 对比 API 响应格式
3. 验证字段完整性
4. 检查数据类型匹配

🛡️ 安全性检查场景

11. SQL 注入检测

AI 帮助:

  • 分析 SQL 查询的安全性
  • 检查参数化查询的使用
  • 识别潜在的注入风险
  • 提供安全编码建议

12. 数据敏感性分析

AI 分析:

  • 识别包含敏感信息的字段
  • 建议数据加密策略
  • 检查访问权限设置
  • 提供合规性建议

🚀 技术亮点与创新

1. 多数据库统一支持

  • 支持 SQLite、MySQL、PostgreSQL、MSSQL
  • 统一的 API 接口,切换数据库只需改变连接字符串

2. 高性能异步处理

  • 基于 Tokio 异步运行时
  • 使用连接池避免频繁连接开销
  • 支持并发请求处理

3. 类型安全的参数处理

  • 使用 schemars 生成 JSON Schema
  • 强类型的参数定义
  • 自动参数验证

4. 优雅的错误处理

match self.db_manager.execute_query(&sql, rbs_params).await {
    Ok(results) => {
        let json_str = serde_json::to_string_pretty(&results)
            .map_err(|e| McpError::internal_error(format!("Result serialization failed: {}", e), None))?;
        Ok(CallToolResult::success(vec![Content::text(json_str)]))
    }
    Err(e) => Err(McpError::internal_error(format!("SQL query failed: {}", e), None))
}

🔧 部署与使用

1. 编译安装

cargo install --git https://github.com/rbatis/rbdc-mcp.git

2. Claude Desktop 配置

{
  "mcpServers": {
    "rbdc-mcp": {
      "command": "rbdc-mcp",
      "args": ["--database-url", "sqlite://./database.db"]
    }
  }
}

3. Cursor IDE 配置

在 Cursor 中,你可以直接通过 AI 助手与数据库交互,无需手动编写 SQL。

🎯 实际开发效率提升

使用 RBDC-MCP 后,开发效率的显著提升:

  1. 减少 90% 的样板代码编写时间
  2. 自动生成类型安全的数据库操作代码
  3. 智能数据库设计验证和优化建议
  4. 一键生成测试数据和迁移脚本
  5. 实时性能监控和优化建议

🎯 总结与展望

这个项目展示了 Rust 在构建 MCP 服务方面的强大能力:

  1. 性能优异: Rust 的零成本抽象和内存安全
  2. 生态丰富: RBDC 提供完善的数据库支持
  3. 类型安全: 编译时保证类型正确性
  4. 易于扩展: 模块化设计便于添加新功能

未来可能的改进方向:

  • 支持更多数据库类型
  • 添加数据库 Schema 分析功能
  • 实现更智能的 SQL 优化建议
  • 支持批量操作和事务处理
  • 集成数据库版本控制
  • 添加可视化数据分析功能

🔗 相关资源

  • 项目地址: https://github.com/rbatis/rbdc-mcp
  • MCP 官方文档: https://modelcontextprotocol.io/
  • RBDC 生态: https://github.com/rbatis/rbdc

希望这个项目能为大家在 Rust + MCP 开发道路上提供一些参考和灵感!特别是在 Cursor 等 AI 驱动的开发环境中,这种工具能够极大地提升开发效率。如果你也在探索 AI 时代的数据库交互,欢迎交流讨论! 🚀


Ext Link: https://github.com/rbatis/rbdc-mcp

评论区

写评论

还没有评论

1 共 0 条评论, 1 页