Skip to main content
Glama
nusduck

biz-db-mcp

by nusduck

biz-db-mcp

面向 UPRC 智能体平台的 MySQL MCP Server:按调用者机构隔离的只读查询、经 MCP 返回文件的导出,以及白名单内的产物导入。

v0.3 平台接入:Streamable HTTP + Bearer、宿主参数 instituteid、表替换式行级隔离、DBPM 原生 TCP 取密、config.yaml 配置、导出改为 embedded resource、新增 import_rows。迁移说明见文末。

设计边界

  • 机构隔离:所有工具都有顶层必填字符串参数 instituteid,由平台按登录用户注入(模型看不到、改不了)。服务端按平台同一规则归一(0800001000 → 00001000),未知机构直接拒绝。

  • 行级过滤:模型写的 SELECT 用 sqlglot 解析,每个基表引用替换为 (SELECT * FROM 表 WHERE 机构列 IN (...)) AS 别名,对 JOIN、OR、外连接、聚合、子查询、UNION、CTE 同样成立。非公共表必须有机构列(isolation.column_candidates 中第一个存在的列)或显式配置,否则视为不存在。

  • SQL 准入:只允许单条 SELECT(含 WITH / UNION);含任何注释、锁定读、INTO、变量、未知/危险函数、系统库的语句一律拒绝。

  • 只读:读连接使用最小权限读账号并设置 SESSION TRANSACTION READ ONLY;行数、序列化字节、执行时间都有上限,截断会标明原因。

  • 导出:生成 Parquet/CSV/JSONL 后以 MCP embedded resource(base64)返回,平台写入会话工作区。本服务不调用 Sandbox、不持有 Sandbox 凭据。超限整体失败,不截断。

  • 导入:import_rows 默认关闭;只能写运维白名单内的表与列,机构列由服务端写入,单事务、持久幂等账本防重复写入。

  • 通用 DML:execute / execute_many 仅供本地 stdio 开发,HTTP 部署下拒绝启动。

  • 审计:stderr 输出 JSON 行,只含工具、机构码、库/表、SQL 摘要与长度、状态、错误码和耗时;不含 SQL 原文、参数、凭据、文件内容或结果数据。

Related MCP server: MySQL ReadOnly MCP Server

目录结构

biz_db_mcp/
  config.py        # config.yaml 加载与严格校验
  institution.py   # 机构号校验与归一
  policy.py        # 机构范围、表策略
  sql_guard.py     # SELECT 准入与表替换改写(另含开发用 DML 守卫)
  db.py            # 连接、元数据、隔离查询、导出流
  credentials.py   # 启动时一次性取齐数据库口令
  dbpm.py          # DBPM 原生 TCP 协议客户端
  export.py        # 固定 schema 的流式文件生成
  mcp_files.py     # 文件 → embedded resource
  import_rows.py   # 产物导入:校验、类型检查、事务写入
  import_ledger.py # 幂等账本
  limits.py        # 并发槽与机构速率
  transport.py     # HTTP Bearer 鉴权与请求体上限
  errors.py        # 稳定错误码
  audit.py         # 结构化审计日志
  server.py        # MCP 工具与启动入口
migrations/        # DBA 执行的账本 DDL 与授权模板
tests/

配置

全部可信配置放在一个 YAML 文件里,启动时加载一次,修改后重启生效。查找顺序:--config 参数 → $BIZDB_CONFIG → 当前目录 config.yaml。复制 config.example.yaml 为 config.yaml(已被 git 忽略)后修改。未知键会直接报错,避免拼写错误被悄悄忽略。

文件里不放秘密:

秘密

来源

MCP Bearer token

server.auth_token_env 指定的环境变量(默认 BIZDB_MCP_TOKEN,平台 authTokenRef 用同名)

数据库口令

DBPM(dbpm.enabled: true),启动时取一次,只在内存中

本地开发口令

仅 stdio 且 DBPM 关闭时,databases.<id>.password_env 指定的环境变量

DSN 中带口令会被拒绝。主要配置块:

块

作用

server

transport(stdio / streamable-http)、host、port、auth_token_env、allowed_hosts、max_request_bytes、tool_deadline_seconds

limits

query / export / import 的行数、字节、时间上限;concurrency 并发槽;rate 每机构速率。均为每实例预算

dbpm

两个 host:port 端点与连接/单端点/总预算超时

databases

连接目录:无口令 DSN、DBPM 条目名、allow_reads、allow_imports、独立 import_credential、按库覆盖的上限

institutions

归一机构码 → scope: self / institutions / all、ids、allow_imports。键必须加引号,否则 YAML 会丢前导零

isolation

column_candidates、public_tables、按表显式 tables(column、value_format: code / raw)

imports

总开关与白名单表:modes、columns、key_columns、institution_column、max_rows

writes

仅本地 stdio 的通用 DML 开关

logging

level、stderr;audit / app 两个文件各自的 path、max_bytes、backup_count(按大小轮转,backup_count ≥ 1)

storage

temp_dir 导出暂存目录、stale_temp_seconds 启动时清理残留的阈值

文件中的相对路径都相对配置文件所在目录解析。

存储占用

位置

内容

上限

logging.audit.path

审计 JSON 行

(backup_count + 1) × max_bytes,默认 60 MiB

logging.app.path

服务/SDK 日志

同上,示例 40 MiB;不配置路径则只写 stderr

storage.temp_dir

导出文件生成到返回之间的暂存,返回后立即删除

同时导出数(limits.concurrency.export,默认 1)× limits.export.max_bytes(20 MiB);崩溃残留在下次启动时清理

进程内存

导出 base64(约 1.33 × 文件)、导入解码字节与解析后的行、查询结果

导出约 27 MiB + JSON;导入 10 MiB 文件及最多 5 万行;查询 1 MiB

MySQL 账本表 bizdb_import_ledger

每次成功导入一行(约 300 B)

不自动清理;服务账号无 DELETE 权限,按需由 DBA 定期清理很久以前的记录(清理后同一文件可再次导入)

服务本身不写其他文件:DBPM 口令只在内存,MCP 无状态模式不存会话,速率桶按已配置的机构数有界。

工具

工具

说明

list_databases

本机构可读的库

list_tables

本机构可读的表/视图,pattern 为 LIKE

describe_table

列元数据

query

隔离后的只读 SELECT;limit/offset 分页,dry_run 只做校验与授权解析

explain

隔离后 SELECT 的执行计划

export

结果文件以 embedded resource 返回;超限报 TOO_LARGE

import_rows

imports.enabled 时注册;白名单产物导入,dry_run 默认 true

execute / execute_many

仅本地 stdio 且 writes.enabled 时注册

错误统一为 isError 结果,文本以稳定错误码开头,如 FORBIDDEN_INSTITUTION、RESOURCE_NOT_ACCESSIBLE、SQL_REJECTED、TABLE_NOT_IMPORTABLE、CONTENT_DIGEST_MISMATCH、TOO_LARGE、RATE_LIMITED、BUSY、DEADLINE_EXCEEDED、IMPORT_OUTCOME_UNKNOWN。跨机构拒绝与“不存在”返回同一错误。

部署

python3 -m pip install -e '.[dev]'
python3 -m pytest
export BIZDB_MCP_TOKEN=...            # 只有平台持有
biz-db-mcp --config /etc/biz-db-mcp/config.yaml --transport streamable-http --host 0.0.0.0 --port 8080

端点为 http://<host>:<port>/mcp,无状态模式,便于多副本。容器以非 root 用户运行,经内网或 TLS 反向代理暴露。反向代理/网关的请求体上限至少为 server.max_request_bytes,响应上限需容纳 20 MiB 文件的 base64(约 27 MiB)加 JSON。服务端端到端期限(默认 150 秒)须低于平台 timeoutMs(示例 180 秒)。

平台清单示例:

{
  "id": "bizdb",
  "url": "https://bizdb-mcp.internal.example/mcp",
  "authTokenRef": "BIZDB_MCP_TOKEN",
  "timeoutMs": 180000,
  "hostArguments": {"instituteid": {"description": "调用者机构号", "source": "user.instituteId"}},
  "artifactArguments": {
    "file_base64": {
      "description": "已提交的待导入数据产物",
      "modelArgument": "artifact_id",
      "filenameArgument": "filename",
      "sha256Argument": "content_sha256",
      "maxBytes": 10485760,
      "mimeTypes": ["text/csv", "application/x-ndjson", "application/vnd.apache.parquet"]
    }
  },
  "fileResults": {"maxBytes": 20971520}
}

启用导入前:DBA 执行 migrations/001_import_ledger.sql,按其中模板给独立导入账号授权;核对目标表唯一约束含机构列。启动时会检查账本表,缺失则拒绝启动。

本地开发(stdio,DBPM 关闭):

server: {transport: stdio}
dbpm: {enabled: false}
databases:
  primary: {dsn: "mysql://dev@127.0.0.1:3306/app", password_env: BIZDB_DEV_PASSWORD}
institutions:
  "00002000": {scope: self}

迁移说明(v0.2 → v0.3)

  • 配置从环境变量改为 config.yaml。BIZDB_MYSQL_DSN、BIZDB_DATABASES_JSON、BIZDB_DBPM_*、BIZDB_SANDBOX_*、BIZDB_SESSION_ID/ORG_ID/USER_ID/CONVERSATION_ID 等旧变量仍被设置时拒绝启动,并列出变量名。

  • 所有工具新增必填 instituteid;平台清单需同步配置 hostArguments。

  • export 不再上传 Sandbox,也不再返回 dataset_id;改为返回文本摘要 + embedded resource。

  • query 返回 {rows, row_count, truncated, truncated_reason, ...};dry_run 不再回显 SQL 与参数。

  • DBPM 从外部桥接命令改为原生 TCP 协议;BIZDB_DBPM_COMMAND/APP_NAME/APP_KEY/APP_IP 不再使用。

  • execute / execute_many 只在本地 stdio 开发可用。

Available Tools

5 tools
describe_tableB

Return column metadata for a table in one configured database.

NameRequiredDescriptionDefault
tableYes
databaseNo

Output Schema

NameRequiredDescription
resultYes

TDQS

B3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description must disclose behavioral traits. It only mentions the return of metadata and a vague scope ('one configured database'), without addressing read-only status, error handling, or permissions. The phrase is ambiguous and does not clarify the role of the optional database parameter.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence, succinct and front-loaded with the core action. It contains no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

While the output schema exists and the tool is simple, the description leaves ambiguity about the database scope and parameter usage. It is marginally adequate but lacks important context for an agent to invoke it confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Parameter documentation coverage is 0%, and the description does not explain the `table` and `database` parameters. It fails to mention required/optional status, formats, or defaults, which the schema alone must convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'Return column metadata for a table', clearly identifying a specific verb (return) and resource (column metadata). The scope 'in one configured database' distinguishes this from sibling tools that list databases or perform data operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no explicit guidance about when to use this tool versus alternatives. It does not mention prerequisites, use cases, or when not to use it, leaving the agent to infer context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

executeC

Execute one guarded DML statement when writes are explicitly enabled.

NameRequiredDescriptionDefault
sqlYes
paramsNo
databaseNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must disclose behavioral traits. It mentions 'guarded' and 'when writes are explicitly enabled', hinting at safety mechanisms, but does not explain what 'guarded' entails, whether changes are reversible, permission requirements, or likely side effects. For a mutating tool, this leaves significant ambiguity.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The entire description is one sentence with no filler. It conveys the core purpose in a compact, front-loaded manner. Every word earns its place, even if the content is thin.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 3 parameters, no annotations, and a write side-effect, the description is too sparse. It does not explain the return format, error behavior, or how to use params/database. The 'guarded' and 'enabled' context helps but is insufficient for safe invocation of a DML tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description provides zero information about the parameters (sql, params, database). The agent cannot learn what 'params' means (e.g., bind parameters) or how 'database' is used, leaving the tool's invocation underspecified.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool executes a DML statement, which distinguishes it from the sibling 'query' tool (reads). The qualifiers 'guarded' and 'when writes are explicitly enabled' add context, though 'guarded' is somewhat vague. It identifies the action and resource sufficiently.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this is for write operations ('DML statement') and is conditioned on writes being enabled, but it does not explicitly contrast with 'query' or state when NOT to use it. The context is clear enough for a user already familiar with the tool set, but lacks explicit alternative guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

exportA

Stream a SELECT to Parquet and register it as a Sandbox Dataset.

The destination session and acting identity come from process-level environment variables, never from model-supplied tool arguments.

NameRequiredDescriptionDefault
sqlYes
paramsNo
databaseNo
dataset_nameYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the transparency burden. It discloses a critical behavioral trait: 'The destination session and acting identity come from process-level environment variables, never from model-supplied tool arguments.' This goes beyond the generic action and warns against passing identity arguments. However, it does not mention potential side effects like overwriting existing datasets.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no redundant information. The first states the action, the second adds an essential behavioral note. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is sufficient for a simple tool but not for one with 4 undocumented parameters and no annotations. It fails to explain optional parameters, database usage, or any prerequisites. The behavioral note is valuable but does not compensate for missing parameter guidance.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, yet the description adds no explanatory detail for any of the four parameters (sql, params, database, dataset_name). It only hints that sql is a SELECT query, but params and database are entirely unexplained. This is a major gap for tool invocation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific action: 'Stream a SELECT to Parquet and register it as a Sandbox Dataset.' This distinguishes it from sibling tools like query/execute (which run queries) and list_databases/describe_table (which inspect metadata).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool's use case: exporting query results to a persistent dataset. It clearly differentiates from siblings by its purpose, but does not explicitly state when not to use it or list alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_databasesA

List configured database ids without exposing DSNs or credentials.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the transparency burden. It adds a meaningful security guarantee that DSNs and credentials are not exposed, and 'list' implies a read-only action. However, it does not explicitly discuss side effects or authentication requirements, though these are less critical for a zero-parameter read-only listing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that front-loads the action and resource. Every word earns its place, and there is no redundancy or fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity, zero parameters, and the presence of an output schema, the description is reasonably complete. It states the scope and a key security constraint, though it could have added a hint about use cases or ordering, but these are not essential.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the schema is empty and the baseline is 4. The description clarifies that the output is limited to database ids, which adds semantic value beyond the empty schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists configured database ids, using a specific verb and resource. It also distinguishes itself from siblings like describe_table, query, execute, and export, which target tables or data operations rather than database enumeration.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is used to enumerate available database ids, which is a natural first step before using other tools, but it does not explicitly state when to use this tool versus alternatives. No exclusions or alternative references are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

queryA

Run a bounded read-only SELECT. Use export for bulk pulls.

NameRequiredDescriptionDefault
sqlYes
limitNo
paramsNo
databaseNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It discloses key safety traits: read-only (no mutation) and bounded (limited results). This is valuable context, though it doesn't specify default limits or error behavior, which is acceptable for a simple query tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences, front-loaded with the core action. 'Bounded' and 'read-only' add essential context, and the export alternative is stated efficiently. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists and the tool is straightforward, the description is nearly sufficient. However, it doesn't clarify how 'bounded' maps to the limit parameter or what the database parameter does, leaving some ambiguity. It provides a basic but incomplete picture for a 4-parameter tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description mentions no parameters. It does not explain the sql, limit, params, or database parameters, leaving the agent without semantic guidance beyond type names. This is a major gap for a tool with multiple parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the tool runs a bounded read-only SELECT, clearly indicating a query operation. It distinguishes itself from siblings by specifying read-only (not execute) and bounded (not export for bulk pulls), making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Use export for bulk pulls,' providing a concrete alternative for a specific scenario. The 'read-only' qualifier implies it's not for writes, giving clear when/when-not guidance relative to sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.2.0
    • First observeddescribe_table
    • First observedexecute
    • First observedexport
    • First observedlist_databases
    • First observedquery

TDQS

A3.6/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clear, distinct purpose: listing databases, describing table metadata, running bounded reads, executing guarded writes, and exporting bulk data. Query and export both run SELECTs, but the descriptions clearly differentiate interactive reads from bulk dataset creation.

Naming Consistency3/5

Naming is mixed: list_databases and describe_table follow a verb_noun pattern with underscores, while query, execute, and export are single verbs with no underscore. The convention is not consistent across the set, though all names are simple and readable.

Tool Count5/5

Five tools is well-scoped for a database MCP server, covering exploration, schema inspection, querying, writing, and bulk export. Each tool earns its place without redundancy or omission.

Completeness4/5

The surface covers the core database lifecycle: list databases, describe tables, query, write, and export. A minor gap is the lack of a list_tables tool, but agents can work around it by querying information_schema or using describe_table directly.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Enables direct interaction with MySQL databases through SQL queries, table exploration, and schema inspection with support for prepared statements and connection pooling.
    -
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to safely query MySQL databases with read-only access, featuring SQL injection protection, connection pooling, and automatic query limits for secure database exploration.
    4
    84 npm
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables Claude Desktop to interact with MySQL databases through secure query execution, schema discovery, and multi-database support with configurable read/write permissions and built-in SQL injection protection.
    270 npm
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to securely connect to and manage MySQL databases with support for multiple database connections, complete CRUD operations, schema inspection, and dynamic connection management through natural language.
    8 npm
    81
    MIT