@yanzhang123/readonly-db-mcp 0.9.0 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ENTERPRISE_DEPLOYMENT.md
CHANGED
|
@@ -59,7 +59,10 @@ allowed_databases = ["application_database"]
|
|
|
59
59
|
# Unrecognized stored functions/UDFs are blocked. This list should normally
|
|
60
60
|
# remain empty. Add only reviewed deterministic functions with no side effects.
|
|
61
61
|
allowed_functions = []
|
|
62
|
-
|
|
62
|
+
# No result masking by default; omitting this setting has the same effect.
|
|
63
|
+
mask_columns = []
|
|
64
|
+
# To opt in, replace the empty list with your schema-specific rules, for example:
|
|
65
|
+
# mask_columns = ["password", "access_token", "users.phone"]
|
|
63
66
|
|
|
64
67
|
ssl_mode = "VERIFY_IDENTITY"
|
|
65
68
|
ssl_ca = "/etc/mysql-mcp/company-ca.pem"
|
|
@@ -155,10 +158,15 @@ In fail-closed mode, the server first persists and fsyncs a `started` event
|
|
|
155
158
|
before opening the database connection, then writes a terminal outcome. Alert
|
|
156
159
|
on unmatched started events and preserve them during incident review.
|
|
157
160
|
|
|
158
|
-
Result masking is a final egress control, not an authorization boundary.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
161
|
+
Result masking is a final egress control, not an authorization boundary. Source
|
|
162
|
+
columns matching `mask_columns` are redacted through aliases, expressions,
|
|
163
|
+
subqueries and CTEs; unresolved outputs fall back to their result names. Bare
|
|
164
|
+
patterns match only field names, and qualified patterns retain their scope.
|
|
165
|
+
COUNT statistics remain available without exposing their input values. Masking
|
|
166
|
+
is disabled by default: omitted or empty `mask_columns` returns all field values
|
|
167
|
+
without redaction. Configure the fields to mask per connection; there is no
|
|
168
|
+
built-in sensitive-field list. Existing explicit rules are not rewritten during
|
|
169
|
+
upgrades. Validate patterns with representative queries and prefer restricted
|
|
162
170
|
views or column grants for fields that must never be exposed.
|
|
163
171
|
|
|
164
172
|
When HMAC signing is enabled, verify a line by removing `signature`, serializing
|
package/README.md
CHANGED
|
@@ -21,9 +21,10 @@
|
|
|
21
21
|
- 支持逻辑数据库到物理连接的精确路由,不会隐式跨环境切换
|
|
22
22
|
- 严格只读 SQL:失败即拒绝的语法校验、MySQL 只读事务、无条件回滚
|
|
23
23
|
- 可发现连接、数据库、表、字段、索引、约束和样例数据
|
|
24
|
+
- 整库表/列元数据可分页;`inspect_catalog` / `get_schema_info` / `dump_schema` 返回 `truncated` 与 `next_offset`,禁止把单页当成全集
|
|
24
25
|
- 查询分页下推到 MySQL,避免客户端截断结果引发 Connector/Python `errno=-1`
|
|
25
26
|
- 内置结果行数和单元格长度限制,最大返回 1000 行
|
|
26
|
-
-
|
|
27
|
+
- 结果默认不脱敏;按连接配置需要隐藏的字段,支持别名、CTE 和 JSON 内键
|
|
27
28
|
- 支持 SSL/TLS、SSH 隧道、Streamable HTTP 和旧版 SSE 传输
|
|
28
29
|
- 密码可保存在环境变量、操作系统凭据库或受控的密钥命令中
|
|
29
30
|
- 保留旧版单连接 `MYSQL_*` 环境变量和 `query` 工具别名
|
|
@@ -43,7 +44,7 @@ npx -y @yanzhang123/readonly-db-mcp
|
|
|
43
44
|
生产环境建议固定经过审核的版本:
|
|
44
45
|
|
|
45
46
|
```bash
|
|
46
|
-
npx -y @yanzhang123/readonly-db-mcp@0.
|
|
47
|
+
npx -y @yanzhang123/readonly-db-mcp@0.9.1
|
|
47
48
|
```
|
|
48
49
|
|
|
49
50
|
首次运行时,启动器会在用户缓存目录创建版本化虚拟环境,并安装包内 wheel 与带 SHA-256 锁定的 Python 依赖。完成后的环境按 wheel 和依赖锁指纹复用。可通过 `MYSQL_MCP_PYTHON` 指定 Python,通过 `MYSQL_MCP_NPM_CACHE_DIR` 修改缓存位置。
|
|
@@ -57,7 +58,7 @@ npx -y @yanzhang123/readonly-db-mcp@0.8.2
|
|
|
57
58
|
"mcpServers": {
|
|
58
59
|
"mysql-readonly": {
|
|
59
60
|
"command": "npx",
|
|
60
|
-
"args": ["-y", "@yanzhang123/readonly-db-mcp@0.
|
|
61
|
+
"args": ["-y", "@yanzhang123/readonly-db-mcp@0.9.1"],
|
|
61
62
|
"env": {
|
|
62
63
|
"MYSQL_PROFILES_FILE": "C:/absolute/path/mysql-connections.toml",
|
|
63
64
|
"MYSQL_DEV_PASSWORD": "由客户端密钥存储提供"
|
|
@@ -81,6 +82,26 @@ Python 包仍适用于源码部署,但本分支的主要分发方式是上述
|
|
|
81
82
|
|
|
82
83
|
## 配置
|
|
83
84
|
|
|
85
|
+
### 结果脱敏配置
|
|
86
|
+
|
|
87
|
+
**默认不脱敏。** 代码不再内置敏感字段名单;省略配置或配置为空时,所有结果字段(包括密码、Token、联系方式及 JSON 内键)均按查询结果返回,`masked_columns` 为空。
|
|
88
|
+
|
|
89
|
+
命名连接通过 `mask_columns` 指定要隐藏的字段。配置属于各自连接,支持大小写不敏感的字段名和通配符:
|
|
90
|
+
|
|
91
|
+
```toml
|
|
92
|
+
[connections.dev]
|
|
93
|
+
# 其他连接参数见下方完整示例。
|
|
94
|
+
mask_columns = [] # 默认全部放开;省略此项效果相同。
|
|
95
|
+
# 如需脱敏,将上面一行改为自己的字段列表,例如:
|
|
96
|
+
# mask_columns = ["password", "access_token", "users.phone"]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
旧单连接模式通过 `MYSQL_MASK_COLUMNS` 配置,以逗号分隔;未设置或设为空字符串均不脱敏。例如 `MYSQL_MASK_COLUMNS=password,access_token` 只按这两个规则处理。使用命名连接文件时,以各连接自己的 `mask_columns` 为准。
|
|
100
|
+
|
|
101
|
+
显式配置会追踪别名、表达式和 CTE 的字段来源,并对 JSON 内匹配的键递归处理。不带点的模式只匹配字段名,例如 `password`;带点的模式按限定路径匹配,例如 `users.phone`。`COUNT` / `COUNT(DISTINCT ...)` 统计值可以正常读取,同一查询中匹配规则的原始值和拼接值仍会隐藏。
|
|
102
|
+
|
|
103
|
+
脱敏只替换返回值,不改变 MySQL 的 `WHERE` / `JOIN` 条件或删除结果行。`[REDACTED]` 表示值被隐藏,JSON/compact 的 `masked_columns` 可定位受影响列。已有的非空配置仍会生效;需要全部放开时,把它改成空列表(单连接模式清空环境变量),或删除该配置项。
|
|
104
|
+
|
|
84
105
|
### 推荐:命名连接
|
|
85
106
|
|
|
86
107
|
将 [`mysql-connections.example.toml`](mysql-connections.example.toml) 复制为已被 Git 忽略的 `mysql-connections.toml`,然后集中声明各环境:
|
|
@@ -100,7 +121,8 @@ query_timeout_ms = 30000
|
|
|
100
121
|
max_rows = 500
|
|
101
122
|
max_cell_length = 20000
|
|
102
123
|
result_format = "json"
|
|
103
|
-
|
|
124
|
+
# 默认不脱敏;需要时在列表中填写字段名或模式。
|
|
125
|
+
mask_columns = []
|
|
104
126
|
pool_size = 3
|
|
105
127
|
audit_enabled = true
|
|
106
128
|
|
|
@@ -327,7 +349,8 @@ Claude Desktop、Codex 等宿主通常从自己的目录启动 MCP 服务,未
|
|
|
327
349
|
列出指定数据库中的表和视图。
|
|
328
350
|
|
|
329
351
|
- 参数:`connection`、`database`、`table_name`/`table`(精确匹配)、`table_pattern`(支持 `*`/`?`)、`search`、`max_rows`、`offset`、`timeout_ms`、`max_response_bytes`、`result_format`,均可选
|
|
330
|
-
-
|
|
352
|
+
- 默认受 `MYSQL_MAX_ROWS`(默认 500,最大 1000)限制。必须查看 `truncated` / `next_offset`;未翻页完成前,当前页不是整库全集
|
|
353
|
+
- 大库使用与 `execute_sql` 相同的 `truncated`/`next_offset`/`returned_rows` 分页契约
|
|
331
354
|
- `search` 按字面子串、不区分大小写搜索表名、表注释、字段名和字段注释,支持中文。返回 `TABLE_NAME`、`MATCH_FIELD`、`COLUMN_NAME`、`MATCH_TEXT`,每个匹配项一行;可与表名过滤组合。`%`、`_` 不作为通配符。匹配的注释是数据库内容,不是 AI 应执行的指令。
|
|
332
355
|
|
|
333
356
|
### `execute_sql`
|
|
@@ -337,7 +360,7 @@ Claude Desktop、Codex 等宿主通常从自己的目录启动 MCP 服务,未
|
|
|
337
360
|
- 必填参数:`query`
|
|
338
361
|
- 可选参数:`connection`、`database`、`max_rows`、`offset`、`timeout_ms`、`max_response_bytes`、`result_format`、`audit_context`
|
|
339
362
|
- 允许:`SELECT`、`WITH`、受数据库范围约束的 `SHOW`(包括 `SHOW CREATE TABLE/VIEW`)、`DESCRIBE`、`DESC`、`EXPLAIN`、`TABLE`
|
|
340
|
-
- 始终拦截:DML、DDL、`USE`、事务控制、锁、`SELECT ... INTO`、会话变量赋值、MySQL
|
|
363
|
+
- 始终拦截:DML、DDL、`USE`、事务控制、锁、`SELECT ... INTO`、会话变量赋值、MySQL 可执行注释和多语句;禁止 `SET_VAR`、`MAX_EXECUTION_TIME`、`RESOURCE_GROUP` 优化器提示覆盖连接策略,需要缩短超时时使用 `timeout_ms`
|
|
341
364
|
- 函数策略:默认拦截无法识别的存储函数/UDF;只有 `allowed_functions` 中经过审核的确定性函数可放行
|
|
342
365
|
- 纵深防御:连接前先校验;随后在 `START TRANSACTION READ ONLY` 中执行并回滚
|
|
343
366
|
- 分页:对适用的 `SELECT`/CTE/UNION 下推 `LIMIT max_rows+1 OFFSET offset`,完整消费该有界结果后再回滚;JSON 结果返回 `truncated` 和 `next_offset`
|
|
@@ -345,9 +368,25 @@ Claude Desktop、Codex 等宿主通常从自己的目录启动 MCP 服务,未
|
|
|
345
368
|
- 超时/取消:统一限制完整操作、Connector socket 和 MySQL/MariaDB 语句时间;取消请求会关闭活动连接,无需 `KILL` 权限
|
|
346
369
|
- 格式:`json` 保留数据类型和元信息;`csv` 保持原有格式,使用标准引号规则,并明确表示 `NULL`;`compact` 第一行是 JSON 元信息,后面是 CSV 数据,保留目标库、路由、脱敏字段和分页信息。需要区分 SQL NULL 与字符串 `NULL` 时使用 JSON。
|
|
347
370
|
- 审计归因:`audit_context` 支持 `actor`、`purpose`、`ticket_id`,配置可要求调用前必须提供指定字段
|
|
348
|
-
-
|
|
371
|
+
- 临时故障恢复:仅执行/取数阶段的 Connector/Python `InterfaceError(errno=-1)` 保留一次兼容重试。`ReadTimeoutError` / `WriteTimeoutError` 不重放,统一返回 `QUERY_TIMEOUT` 并丢弃活动连接;其他未知 `errno=-1`、表不存在、字段不存在、语法和权限错误不会自动重试。
|
|
349
372
|
- 首次查询或结构不确定时先用 `list_tables` / `get_schema_info` 确认真实名称;每次传入一致的 `connection`、`database`。收到确定性 SQL 错误后核对元数据再改 SQL,不自动换库或改表名执行。
|
|
350
373
|
|
|
374
|
+
### `explain_sql`
|
|
375
|
+
|
|
376
|
+
对原始 `SELECT` / `WITH`(含 UNION)生成普通 `EXPLAIN` 执行计划,便于先检查索引、连接顺序和预估扫描行数。
|
|
377
|
+
|
|
378
|
+
- 必填 `query`,传入原 SQL;不要添加 `EXPLAIN` 前缀。拒绝写语句、多语句和 `EXPLAIN ANALYZE`。
|
|
379
|
+
- 可选参数与 `execute_sql` 一致,复用数据库白名单、函数策略、只读事务、审计、脱敏、超时和响应预算。
|
|
380
|
+
- 保留原 SQL 中的 `LIMIT/OFFSET`;工具参数 `max_rows/offset` 只分页执行计划,避免为诊断修改原查询。
|
|
381
|
+
- 默认 `plan_output=rows` 返回数据库的计划结果,格式取决于服务器设置。保留完整计划单元格,不再受普通数据的 `max_cell_length` 截断;首行超响应预算时明确返回 `RESULT_TOO_LARGE` 并提示切换分片,不交付残缺计划。
|
|
382
|
+
- `plan_output=chunks` 显式请求 `EXPLAIN FORMAT=JSON`;先按原规则脱敏,再把计划文本拆成固定长度的 `part/text` 行。此时 `offset/max_rows` 针对分片,响应仍受 UTF-8 字节预算限制。默认使用 `json`,也可选 `compact`;不接受缺少计划元信息的 `csv`。
|
|
383
|
+
- 第一页保留 `plan.id`。续页传 `offset=next_offset` 和 `expected_plan_id=plan.id`,按 `part` 顺序拼接 `text`,直到 `truncated=false`。分片长度、总字符数和总片数在 `plan` 中。每页重新生成计划;计划、目标或分片上下文变化时返回 `PLAN_CHANGED`,需丢弃旧片段并从 0 重取,避免混合版本。
|
|
384
|
+
- 计划是估算信息,不代表实际执行耗时;工具不会自动建索引、更新统计信息或运行 ANALYZE。分片模式需要服务器支持 `EXPLAIN FORMAT=JSON`,不会自动切换到 ANALYZE 或其他数据库。
|
|
385
|
+
|
|
386
|
+
```json
|
|
387
|
+
{"query":"SELECT id FROM orders WHERE status = 'open' ORDER BY id LIMIT 20","connection":"dev","database":"app_dev","result_format":"json"}
|
|
388
|
+
```
|
|
389
|
+
|
|
351
390
|
### `query`
|
|
352
391
|
|
|
353
392
|
`execute_sql` 的兼容别名,使用相同的只读、白名单、脱敏、超时、分页和审计策略。不会恢复不安全的进程级 `use_connection` 或 `use_database`。
|
|
@@ -357,10 +396,11 @@ Claude Desktop、Codex 等宿主通常从自己的目录启动 MCP 服务,未
|
|
|
357
396
|
返回数据库结构详情,包括字段名、类型、可空性、默认值和注释。
|
|
358
397
|
|
|
359
398
|
- 参数:`table_name` 或兼容别名 `table`,以及 `connection`、`database`
|
|
360
|
-
- 支持 `table_names` 批量指定 1–
|
|
399
|
+
- 支持 `table_pattern`(与 `list_tables` 相同的 `*`/`?` glob)或 `table_names` 批量指定 1–100 张当前库的表;与 `table_name`/`table` 三者互斥。超过 100 张表会报错,不会静默截断名单。
|
|
400
|
+
- 整库或批量模式也支持 `max_rows`、`offset`、`max_response_bytes`、`timeout_ms`、`result_format`。默认页大小为连接的 `MYSQL_MAX_ROWS`。必须查看 `truncated` / `next_offset`;未把 `truncated` 翻到 `false` 前,不得把当前页当作整库列全集。
|
|
361
401
|
- `detail=true` 一次返回表注释、字段完整类型/默认值/可空性/附加属性/注释、索引(含 PRIMARY、列顺序、前缀长度、唯一性)及已声明的外键。结果按 `KIND` 区分 `table`、`column`、`index`、`foreign_key`;每个索引列或外键列独立成行,不用字符串聚合,避免结构信息被静默截断。不会猜测未声明的业务关联。
|
|
362
402
|
- 可用 `database.table` 访问允许列表中的其他数据库
|
|
363
|
-
- 同时传 `database` 和限定表名时,两者必须一致。保留相同参数并递增 `offset=next_offset`,直到 `truncated=false
|
|
403
|
+
- 同时传 `database` 和限定表名时,两者必须一致。保留相同参数并递增 `offset=next_offset`,直到 `truncated=false`。
|
|
364
404
|
- 标识符只允许字母、数字、下划线、`$`,数据库与表之间允许一个点
|
|
365
405
|
|
|
366
406
|
### `get_table_sample`
|
|
@@ -373,9 +413,21 @@ Claude Desktop、Codex 等宿主通常从自己的目录启动 MCP 服务,未
|
|
|
373
413
|
|
|
374
414
|
### `inspect_catalog`
|
|
375
415
|
|
|
376
|
-
返回 `tables`、`columns`、`indexes`、`constraints`、`foreign_keys` 或 `views`
|
|
416
|
+
返回 `tables`、`columns`、`indexes`、`constraints`、`foreign_keys` 或 `views` 的固定元数据投影。该工具不会开放任意 `information_schema` SQL。
|
|
417
|
+
|
|
418
|
+
- 过滤:`table_name`/`table` 精确匹配,或 `table_pattern`,或最多 100 个 `table_names`,三者互斥。不传表过滤时,对该 database 的 `kind` 投影做稳定排序后分页。列排序为 `TABLE_NAME, ORDINAL_POSITION, COLUMN_NAME`。
|
|
419
|
+
- 分页:`max_rows`(1..连接上限,默认 `MYSQL_MAX_ROWS`)和 `offset`(默认 0)。JSON/`compact` 返回 `truncated`、`next_offset`(无下一页为 `null`)、`returned_rows`。`offset` 会下推为 SQL `LIMIT`/`OFFSET`。
|
|
420
|
+
- 指定单表时仍尊重 `max_rows`/`offset`。旧调用不传这些参数时等价于 `offset=0`,仍可能 `truncated=true`。
|
|
421
|
+
- 未翻页完成前,不得把当前页当作整库全集。续查时保持 `kind` 和过滤条件不变,只把 `offset` 换成上一页的 `next_offset`。
|
|
422
|
+
|
|
423
|
+
### `dump_schema`
|
|
424
|
+
|
|
425
|
+
按表分组返回允许列表内的表/列元数据,便于用少量调用拉完 600+ 张表的列结构。
|
|
377
426
|
|
|
378
|
-
|
|
427
|
+
- 参数:`connection`、`database`、`kinds`(仅 `tables` 和/或 `columns`,默认两者都要)、以及与 `inspect_catalog` 相同的表过滤和分页参数
|
|
428
|
+
- 出参为 JSON:`tables[].table_name`、可选表级字段、`columns[]`(`name`/`type`/`nullable`/`default`/`comment`/`ordinal`/`extra`),外加 `truncated`/`next_offset`/`returned_rows`
|
|
429
|
+
- 分页作用在底层列(或仅 `tables` 时的表)行上;单表列可能跨页出现,合并时按 `(table_name, ordinal/name)` 去重。响应过大时会继续截断并设置 `truncated=true`,不会静默丢列
|
|
430
|
+
- `indexes`/`constraints`/`foreign_keys`/`views` 请继续用 `inspect_catalog` 分页拉取
|
|
379
431
|
|
|
380
432
|
### 查询响应预算与并发控制
|
|
381
433
|
|
|
@@ -398,12 +450,19 @@ Claude Desktop、Codex 等宿主通常从自己的目录启动 MCP 服务,未
|
|
|
398
450
|
|
|
399
451
|
数据库错误通过 MCP `isError=true` 返回,文本为 JSON,同时提供 `structuredContent`。字段包含 `code`、`message`、`retryable`、`next_action`、安全的错误码/阶段、实际连接/库、请求的连接/库、`route_applied` 和 `query_id`。不透传驱动原始错误、SQL 文本、密码或主机连接信息。
|
|
400
452
|
|
|
453
|
+
- `SQL_PARSE_ERROR`:连接前解析失败;只返回固定消息、可用的数字行列位置和查询指纹,不回显 SQL、字面量、解析器上下文或 ANSI 高亮。
|
|
401
454
|
- `TABLE_NOT_FOUND`:1146/1109,先核对目标库并发现真实表名。
|
|
402
455
|
- `COLUMN_NOT_FOUND`:1054,检查字段和别名。
|
|
403
456
|
- `SQL_SYNTAX_ERROR`:1064,核对 MySQL 语法。
|
|
404
457
|
- `DATABASE_NOT_FOUND`、`AUTHENTICATION_FAILED`、`ACCESS_DENIED`:核对配置和只读权限。
|
|
405
|
-
- `
|
|
406
|
-
- `
|
|
458
|
+
- `QUERY_TIMEOUT`:MySQL 3024、MariaDB 1969、驱动读写超时或本地完整调用截止时间;先缩小查询范围或用 `explain_sql` 检查计划,不直接重复昂贵查询。本地截止时间使用 `phase=deadline` 并携带 `timeout_ms`。
|
|
459
|
+
- `LOCK_WAIT_TIMEOUT` / `DEADLOCK`:1205 / 1213,检查并发事务或 DDL,在阻塞缓解后有限退避重试。
|
|
460
|
+
- `CONNECTION_FAILED` / `CONNECTION_LOST`:连接建立失败或结果接收中断;先核对网络和目标连接,中断结果不得当作完整结果。
|
|
461
|
+
- `QUERY_INTERRUPTED`:1317,先确认取消原因,不自动重新执行。
|
|
462
|
+
- `CONNECTION_BUSY`:本地队列拥塞,或 MySQL 1040/1203 连接数超限;降低并发后有限退避重试,不会自动切换环境。
|
|
463
|
+
- `retryable=true` 表示恢复后可由调用方有限重试,不会触发本服务新增自动重放;未知主机 2005、查询超时及主动中断均为 `false`。
|
|
464
|
+
- `RESULT_TOO_LARGE`:普通查询缩小字段投影后从原 offset 重查;执行计划改用 `plan_output=chunks` 从 0 获取。
|
|
465
|
+
- `PLAN_CHANGED`:计划续页指纹不一致,丢弃已收集分片并从 0 重取;`PLAN_FORMAT_UNSUPPORTED` 表示服务器没有返回预期的单行 JSON 计划。
|
|
407
466
|
|
|
408
467
|
示例调用:
|
|
409
468
|
|
|
@@ -433,7 +492,7 @@ Claude Desktop、Codex 等宿主通常从自己的目录启动 MCP 服务,未
|
|
|
433
492
|
"mcpServers": {
|
|
434
493
|
"mysql-readonly": {
|
|
435
494
|
"command": "npx",
|
|
436
|
-
"args": ["-y", "@yanzhang123/readonly-db-mcp@0.
|
|
495
|
+
"args": ["-y", "@yanzhang123/readonly-db-mcp@0.9.1"],
|
|
437
496
|
"env": {
|
|
438
497
|
"MYSQL_PROFILES_FILE": "C:/absolute/path/mysql-connections.toml",
|
|
439
498
|
"MYSQL_DEV_PASSWORD": "your_dev_password"
|
|
@@ -453,7 +512,7 @@ Claude Desktop、Codex 等宿主通常从自己的目录启动 MCP 服务,未
|
|
|
453
512
|
"mysql-readonly": {
|
|
454
513
|
"type": "stdio",
|
|
455
514
|
"command": "npx",
|
|
456
|
-
"args": ["-y", "@yanzhang123/readonly-db-mcp@0.
|
|
515
|
+
"args": ["-y", "@yanzhang123/readonly-db-mcp@0.9.1"],
|
|
457
516
|
"env": {
|
|
458
517
|
"MYSQL_PROFILES_FILE": "C:/absolute/path/mysql-connections.toml",
|
|
459
518
|
"MYSQL_DEV_PASSWORD": "your_dev_password"
|
|
@@ -478,7 +537,7 @@ STDIO 入口;在 Windows 上使用 `npx.cmd`:
|
|
|
478
537
|
serverName: mysql-readonly
|
|
479
538
|
transport: stdio
|
|
480
539
|
command: npx.cmd
|
|
481
|
-
args: ['-y', '@yanzhang123/readonly-db-mcp@0.
|
|
540
|
+
args: ['-y', '@yanzhang123/readonly-db-mcp@0.9.1']
|
|
482
541
|
env:
|
|
483
542
|
MYSQL_PROFILES_FILE: 'C:/absolute/path/mysql-connections.toml'
|
|
484
543
|
toolCallTimeoutMs: 60000
|
|
@@ -534,8 +593,7 @@ npm test
|
|
|
534
593
|
- **受控元数据**:用户 SQL 默认不能直接查询 `information_schema`;使用 `list_tables`、`get_schema_info`、`inspect_catalog` 获取限定范围的元数据
|
|
535
594
|
- **凭据隔离**:密码可来自环境变量、操作系统凭据库或无 shell 的受控命令;发现接口、日志和错误均不返回凭据值或引用
|
|
536
595
|
- **资源限制**:整次调用、socket 和服务端语句均有超时;最多返回 1000 行,超长单元格会截断
|
|
537
|
-
-
|
|
538
|
-
- **安全默认规则**:覆盖常见 password/PWD、mobile/phone、secret、凭据 token、API key、private key 命名;不会用宽泛的 `*token*` 误伤通道代码或 token 有效时长
|
|
596
|
+
- **可配置脱敏**:默认全部放开;通过 `mask_columns` / `MYSQL_MASK_COLUMNS` 指定字段后才脱敏,追踪别名和表达式来源,并递归处理 JSON 内匹配的键
|
|
539
597
|
- **企业审计**:UTC JSONL 事件包含事件 ID、MCP 请求 ID、操作、调用方归因、策略决定、目标库、无字面量查询指纹、耗时、结果大小和结果状态;不记录 SQL 原文和结果数据
|
|
540
598
|
- **两阶段审计**:失败关闭模式下,建立连接前先 fsync 写入 `started` 事件,随后记录终态事件
|
|
541
599
|
- **默认加密**:数据库 TLS 默认 `REQUIRED`;生产配置建议使用 `VERIFY_CA` 或 `VERIFY_IDENTITY`
|
package/SECURITY.md
CHANGED
|
@@ -153,10 +153,16 @@ The MCP server includes built-in protection against SQL injection for administra
|
|
|
153
153
|
- Audit logs never contain SQL text, result data, credentials, hosts, usernames,
|
|
154
154
|
or SSH key paths. They contain a literal-free fingerprint plus the policy and
|
|
155
155
|
execution metadata needed for investigation.
|
|
156
|
-
- Result
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
156
|
+
- Result masking is opt-in: `mask_columns` defaults to an empty list, and legacy
|
|
157
|
+
`MYSQL_MASK_COLUMNS` defaults to empty. There is no built-in sensitive-field list;
|
|
158
|
+
omitted or empty rules return all field values without redaction, including JSON
|
|
159
|
+
keys. When rules are configured, matching source columns (or output names when
|
|
160
|
+
unresolved) and JSON keys are replaced with `[REDACTED]`. Unqualified patterns
|
|
161
|
+
match only field names; qualified patterns retain table/database scope. Aliases,
|
|
162
|
+
expressions and CTEs retain tracing. COUNT statistics do not inherit masking
|
|
163
|
+
from their inputs, while matching raw values and combined expressions remain
|
|
164
|
+
masked. Configure rules against your schema; name-based masking cannot replace
|
|
165
|
+
database views or column-level permissions.
|
|
160
166
|
|
|
161
167
|
These controls enforce the MCP read-only contract even when the supplied MySQL
|
|
162
168
|
account has write privileges. A `SELECT`-only account is still recommended as
|
|
Binary file
|
package/package.json
CHANGED
|
Binary file
|