数据库只读查询服务

dbsage是一个MCP服务器,允许LLMs探索数据库模式、理解业务上下文并运行验证查询,而无需担心写入数据库的风险。

  • by MihirLathiya510
  • Python
  • 本地部署
  • 3 星标
  • 更新于
在 GitHub 查看 MihirLathiya510/dbsage

使用说明

Dbsage

AI工具的安全、只读数据库访问。

dbsage是一个MCP服务器,它允许LLM探索模式、理解业务上下文并运行经过验证的查询,而不会有任何写入数据库的风险。

为什么选择dbsage

大多数团队都希望人工智能帮助回答数据问题,但他们不愿意让它访问原始数据库。直接访问意味着写入风险、无上限查询以及敏感表周围没有防护措施。

dbsage位于AI和数据库之间。它在查询级别强制执行只读访问,注入行限制和超时,隐藏您标记为禁止的表,并返回LLM可以清晰推理的结构化输出。你也可以用简单的语言描述你的模式,这样人工智能就可以带着业务上下文到达,而不是每次都从头开始。

它在实践中是什么样子的

一位队友问,按类型分组,有多少交易正在进行中。dbsage加载数据库上下文,然后运行:

SELECT dt.name AS deal_type, COUNT(d.id) AS count
FROM Deals d
JOIN DealTypes dt ON d.dealType_id = dt.id
GROUP BY dt.id
ORDER BY count DESC;
deal_type             count
Bridge Loan             142
Construction Loan        89
Permanent Financing      34
Mezzanine                12

4 rows in 28ms

因为语义配置映射 deal 对于正确的表,不需要猜测表名或联接路径。

在发布版本之前,您可能需要检查暂存是否仍与生产相匹配:

Schema comparison: prod to staging

Tables only in prod:
  audit_log
  feature_flags

Tables only in staging:
  none

Tables in both: 147

或者比较不同环境中的行数:

orders
  prod       4.3M
  replica    4.3M
  staging    18.4k

命名连接配置文件从一个地方处理所有这些,无需切换VPN或打开单独的客户端。

快速开始

一旦发布到PyPI,您只需要:

uvx dbsage

客户端配置:

{
  "mcpServers": {
    "dbsage": {
      "command": "uvx",
      "args": ["dbsage"],
      "env": {
        "DBSAGE_DB_HOST": "your-host.rds.amazonaws.com",
        "DBSAGE_DB_NAME": "your_database",
        "DBSAGE_DB_USER": "readonly_user",
        "DBSAGE_DB_PASSWORD": "your_password",
        "DBSAGE_DB_TYPE": "mysql"
      }
    }
  }
}

PyPI的发布仍在进行中。要从源代码运行,请执行以下操作:

git clone https://github.com/your-org/dbsage.git
cd dbsage
cp .env.example .env
uv sync

然后将您的客户指向本地项目:

{
  "mcpServers": {
    "dbsage": {
      "command": "uv",
      "args": ["run", "--directory", "/absolute/path/to/dbsage", "dbsage"]
    }
  }
}

工具

dbsage有23个工具。完整参考 docs/tools.md.

发现和模式

list_tables 和 search_tables 让您按名称或关键字查找表,包括行数。

describe_table 返回列名、类型、可空性和外键引用。 table_relationships 映射表在整个数据库或特定表中的连接方式。 schema_summary 将它们合并为一个包含大小和行数的单一概述。 show_create_view 返回视图的完整SQL定义。

采样

sample_table 提取一小部分行,以便人工智能能够理解数据的实际外观。 sample_column_values 返回列的不同值和计数,这对分类字段很有用。 table_row_count 返回一个快速的近似计数 information_schema. inspect_json_column pretty打印JSON或JSONB列中的示例。

查询执行

run_read_only_query 在强制限制和超时的情况下验证、重写和执行SELECT查询。 explain_query 返回执行计划,以便在运行任何昂贵的程序之前检查完整扫描。

语义上下文

get_database_context 从语义配置中返回域、词汇表和分析注释。 get_table_semantics 返回特定表的业务描述和列含义。 search_schema_by_meaning 允许您按业务术语而不是确切名称查找表和列。

连接

list_connections 显示配置的配置文件和 ping_connections 检查它们之间的连接性和延迟。 add_connection 和 remove_connection 允许您在运行时添加或删除配置文件,而无需重新启动服务器。 compare_query_across_connections 在多个数据库中运行相同的查询, diff_schema 比较环境之间的表结构, find_table_across_connections 检查哪些连接具有给定的表,以及 compare_row_counts 为您提供快速的跨环境计数比较。

语义配置

语义配置将原始模式细节转化为AI可以实际使用的东西。与每次对话都从表发现和猜测开始不同,您只需记录一次域,每次调用都可以使用它。

创建 config/semantic_schema.json:

{
  "database": {
    "name": "your_db",
    "description": "What this database is for",
    "domain": "e-commerce",
    "core_workflow": "User places Order, Items added, Payment processed, Shipped"
  },
  "vocabulary": {
    "customer": "users",
    "purchase": "orders"
  },
  "tables": {
    "users": {
      "description": "Registered customer accounts",
      "columns": {
        "id": "Unique user identifier UUID",
        "email": "Login email address"
      }
    }
  }
}

您可以包含一个简单的语言数据库描述、业务词汇映射、核心工作流、表和列描述以及常见的查询模式。完整指南 docs/semantic.md.

多个连接

每个面向数据库的工具都接受一个可选 connection 将调用路由到命名配置文件的参数。将其留空以使用默认值。

复制 config/connections.example.json 到 config/connections.json 并填写您的个人资料。对于本地开发,内联密码是可以的:

{
  "connections": {
    "dev": {
      "host": "dev-db.example.com",
      "database": "app_db",
      "user": "readonly",
      "password": "your_password_here",
      "db_type": "mysql"
    }
  }
}

用于生产,使用 password_env 并设置 requires_confirmation: true。来自该连接的响应将包括一个警告横幅,密码永远不会出现在配置或日志中:

{
  "connections": {
    "prod": {
      "host": "prod-db.example.com",
      "database": "app_db",
      "user": "readonly",
      "password_env": "PROD_DB_PASSWORD",
      "db_type": "mysql",
      "requires_confirmation": true
    }
  }
}

如果两者都有 password 和 password_env 被设置, password 优先。你也可以收紧 max_query_rows 和 query_timeout_ms 根据个人资料。连接组允许您同时定位多个配置文件:

{
  "default": "primary",
  "groups": {
    "all-prod": ["prod-us", "prod-eu"]
  },
  "connections": {}
}

完整指南 docs/multiconnection.md.

配置

所有环境变量都使用 DBSAGE_ 前缀。

变量 默认值 注释
DBSAGE_DB_HOST localhost
DBSAGE_DB_PORT 3306
DBSAGE_DB_NAME 必填
DBSAGE_DB_USER 必填
DBSAGE_DB_PASSWORD 必填
DBSAGE_DB_TYPE mysql mysql, postgresql,或 mssql
DBSAGE_MAX_QUERY_ROWS 100 查询无时的默认LIMIT
DBSAGE_MAX_QUERY_ROWS_HARD_CAP 500 明确限制的上限
DBSAGE_QUERY_TIMEOUT_MS 3000
DBSAGE_SLOW_QUERY_THRESHOLD_MS 2000 日志查询速度比这慢
DBSAGE_DEFAULT_SAMPLE_LIMIT 10 默认行 sample_table
DBSAGE_CACHE_TTL_SECONDS 300 架构元数据缓存TTL
DBSAGE_BLACKLISTED_TABLES [] 对所有工具隐藏的表
DBSAGE_DEV_MODE false 人类可读日志

您还可以在中管理隐藏表 config/blacklist_tables.json。启动时,那里的值与环境变量合并。

安全

dbsage在每个查询到达数据库之前对其进行验证。INSERT、UPDATE、DELETE、DROP、ALTER、TRUNCATE、CREATE、GRANT和REVOKE被彻底阻止,以及间接突变路径,如 SELECT INTO OUTFILE, LOAD DATA INFILE,以及 CREATE TEMP TABLE.

密码存储为 SecretStr 这样它们就不会出现在日志、堆栈跟踪或repr输出中。每个查询都有超时运行,如果不包括超时,则会得到默认的行限制,并且上限为 DBSAGE_MAX_QUERY_ROWS_HARD_CAP 即使呼叫者要求更多。黑名单表从每个工具响应中删除。

为了获得最强的保证,请创建一个仅具有SELECT权限的数据库用户。dbsage在应用程序层强制执行只读,但仅限SELECT的凭据添加了无法绕过的第二层。

发展

git clone https://github.com/your-org/dbsage.git
cd dbsage
uv sync --extra dev

uv run pytest
uv run ruff check src/
uv run mypy src/

276次测试,覆盖率约为96%。严格的mypy和ruff安全检查在每次通过Lefthok提交时都会运行。

贡献指南 docs/contributing.md.

需求

Python 3.12+、uv和MySQL 5.7+、PostgreSQL 13+或SQL Server 2017+。对于MSSQL,还要安装Microsoft ODBC驱动程序并运行 uv sync --extra mssql.

curl -LsSf https://docs.astral.sh/uv/install.sh | sh

许可证

麻省理工学院