MySQL防护服务

MCP MariaDB/MySQL服务器为PHP提供安全的SQL访问,防止危险查询并优化生产环境性能。适用于需要在大规模生产数据库中安全探索的AI数据科学家。

  • by PmaControl
  • PHP
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 PmaControl/MariaDB-Guard-RO-MCP

使用说明

MCP MariaDB/MySQL服务器(PHP)

PHP for MariaDB/MySQL中的MCP(模型上下文协议)服务器将您的SQL访问转换为生产模式:安全读取、有毒查询保护、执行限制和可操作的解释诊断,以便在不破坏数据库的情况下更快地进行分析。对于人工智能数据科学家代理来说,这是一个非常有用的基础,他们必须在严格的安全框架内探索生产中的大型数据集。

英文版本: README_en.md

目标

无压力连接到生产,即使是非专家用户:MCP服务器充当守护代理,阻止有风险的请求,只允许那些能够在良好的实际条件(表大小、计划解释、索引和服务器负载)下运行的请求通过,以保护数据、性能和团队的宁静。

该MCP服务器专为具有大量表(数亿到数十亿行)的关键任务环境而设计,在保持快速操作分析能力的同时,大大降低了破坏性prod查询的风险。

索引

  1. 功能
  2. 生产警告
  3. 快速启动(5分钟)
  4. 测试服务器
  5. 已知限制
  6. 配置
  7. 安全模型
  8. 安装
  9. 配置MCP检查员
  10. 开发者指南
  11. 故障排除
  12. 日志
  13. 项目结构
  14. 作者/许可证

功能

实际上,MCP服务器添加了关键保护:

  • read-only 关于公开的SQL工具
  • 拒绝危险模式(FOR UPDATE, OR 不受控制, WITH RECURSIVE)
  • 超时SQL(MariaDB/MySQL selon版本)
  • 完整扫描策略 WHERE 根据桌子的大小
  • 结果上限(MAX_ROWS_DEFAULT / MAX_ROWS_HARD)
  • 托管:如果已经有太多请求,则临时拒绝(database busy retry in 1 second)
  • 日志请求+计划+时间+审核和调整返回的卷

生产警告

该MCP设计用于非常大的基地,但在生产中必须插入复制品(slave/读取副本)而不是在主服务器上(master主要的,重要的

注意安装:

  • 通过部署 install.sh 在容器中似乎不能可靠工作 LXC
  • 对于这种安装模式,请选择真正的虚拟机或物理服务器

快速启动(5分钟)

git clone https://github.com/PmaControl/MariaDB-Guard-RO-MCP.git mcp-mariadb
cd mcp-mariadb
./install.sh \
  --install-dir /srv/www/mcp-mariadb \
  --db-host 127.0.0.1 \
  --db-port 3306 \
  --db-name my_database \
  --db-user my_user_mcp_ro \
  --db-pass my_password \
  --mcp-token my_token
curl -sS http://127.0.0.1:13306/health

测试服务器

供应商 测试的次要版本
MySQL 5.5.62、5.6.51、5.7.44、8.0.45、8.1.0、8.2.0、8.3.0、8.4.8、9.1.0、9.2.0、9.3.0、9.4.0、9.5.0、9.6.0
MariaDB 5.5.64、10.0.38、10.2.44、10.3.39、10.4.34、10.5.29、10.6.25、10.7.8、10.8.8、10.9.8、10.10.7、10.11.16、11.0.6、11.1.6、11.3.2、11.4.10、11.5.2、11.6.2、11.8.6、12.0.2、12.1.2、12.2.2、12.3.1
Percona服务器 5.7.44、8.0.43、8.4.7

笔记:

  • 上述版本是在测试运行期间显式解析的次要版本(例如,图像变体可能包含分发后缀)。 -ubi9 或 -oraclelinux9).
  • 该列表持续维护:对于矩阵E2E验证的每个新版本, Serveurs Testés 在文档中更新。
  • 指令去维护(开发和人工智能): contrib/tested_servers_policy_dev_ai.md
  • 原则兼容性:服务器设计用于与MySQL兼容的引擎一起工作 MySQL 4.1+ (包括MariaDB和Percona服务器),取决于特定版本/功能差异。
  • SQL超时机制取决于服务器版本:
    • MariaDB:活动自 10.1.1
    • MySQL:活动于 5.7.4
    • Percona服务器:与MySQL相同的规则(5.7.4+)

附加电机

以下引擎尚未处于与MariaDB/MySQL/Percona Server相同的验证状态。

引擎 测试版本 支持的工具 防护装置/状态
TIDB 真实集群 v8.5.5 db_select, db_explain, db_explain_table, db_tables, db_schema, db_indexes, db_processlist, db_variables 在真实集群上验证的MCP工具; db_variables 如果帐户没有权限,可以返回0行 RESTRICTED_VARIABLES_ADMIN专用TIDB防护装置仍然不完整
Vitess vttestserver:mysql80 db_select, db_explain, db_explain_table, db_tables, db_schema, db_indexes, db_processlist, db_variables 有效期: GUARD-001, GUARD-010, GUARD-020, GUARD-100, GUARD-130;失败: GUARD-120;与此运行时无关: GUARD-140, GUARD-141, GUARD-900
专卖店 ghcr.io/singlestore-labs/singlestoredb-dev:0.2.30 目标:标准SQL工具(db_select, db_explain, db_explain_table, db_tables, db_schema, db_indexes, db_processlist, db_variables) 状态全局 partiel / prometteur;手动验证引擎,完整矩阵验证仍有待整合;图像 latest 无法在某些CPU上使用

已知限制

主题 观察到的限制 影响
install.sh 在 LXC Apache启动在某些容器中不可靠 LXC 选择真正的虚拟机或物理服务器
TiDB 在真实集群上验证的MCP工具 v8.5.5,但完整的E2E验证和专用防护尚未完成;全局变量的暴露可能需要特权 RESTRICTED_VARIABLES_ADMIN; tiup playground 不稳定 不将TIDB视为与MariaDB/MySQL/Percona相同级别的验证产品
Vitess GUARD-120 继续失败 vttestserver; GUARD-140, GUARD-141, GUARD-900 与此运行时无关 仅部分覆盖
SingleStore l图像 latest 在某些CPU上不可用;经验证的支持基于 0.2.30 冻结测试版本,不要假设 latest 可利用的
GUARD-900 SSL测试需要专用服务器/证书配置124不要将没有PKI的标准运行解释为SSL验证
完整矩阵E2E 一些辅助引擎仍然需要异常或目标跳过124矩阵结果必须逐引擎读取

配置

  • 复印机模板: cp -a .env.sample .env
  • 关键变量: DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASS, MCP_TOKEN
  • 安全限制/性能: MAX_ROWS_DEFAULT, MAX_ROWS_HARD, MAX_SELECT_TIME_S, WHERE_FULLSCAN_MAX_ROWS, MAX_CONCURRENT_DB_SELECT
  • 日志应用程序: MCP_QUERY_LOG=/srv/www/mcp-mariadb/mcp_mariadb_13306_query.log (后缀为HTTP端口)
  • DB帐户验证缓存: .account_tested (项目根)
  • 是 .env 比最近 .account_tested,缓存将自动无效,并强制进行新的权限测试。

安全模型

  • Surface SQL讲座控制
  • 阻止危险模式
  • SQL结果限制和超时
  • 警察局长(database busy retry in 1 second)
  • 建议在Read Replica en Prod上运行
  • 严格只读MySQL/MariaDB: SELECT 强制性(USAGE 隐含), SHOW VIEW 和 PROCESS 可选的。
  • 如果检测到写入/修改权限,MCP服务器将被阻止。
  • 乐工具 mcp_test 仍然可以运行安全检查表并指导补救。

安装

利用模式

该项目以两种模式运行:

  • Standalone (无作曲家):clonage+ .env +Apache/PHP,可回退 require_once 直接加载类。
  • Bibliothèque Composer:通过集成到另一个PHP项目中 composer require pmacontrol/mariadb-guard-ro-mcp.

Composer集成示例(在另一个项目中):

composer require pmacontrol/mariadb-guard-ro-mcp
<?php
require_once __DIR__ . '/vendor/autoload.php';

App::run();

Ubuntu 24.04/Debian 12/Debian 13上的快速安装(根):

chmod +x install.sh
./install.sh

使用install.sh

单个命令中参数的示例:

./install.sh \
  --install-dir /srv/www/mcp-mariadb \
  --http-port 13306 \
  --db-host 127.0.0.1 \
  --db-port 3306 \
  --db-name my_database \
  --db-user my_user_mcp_ro \
  --db-pass my_password \
  --mcp-token my_token

端口HTTP恢复 13306 默认情况下。使用 --http-port 换水器等 --install-dir 隔离同一服务器上的多个实例。

默认情况下, install.sh 扣除 Require ip 通过 hostname -I (第一个IPv4,网络 /24)的。您可以使用强制CIDR --allow-cidr.

选项(install.sh)

  • --install-dir <path>:安装文件夹(默认值: /srv/www/mcp-mariadb)
  • --http-port <port>:Apache HTTP端口(默认: 13306)
  • --db-host <host>:MariaDB/MySQL主机(默认: 127.0.0.1)
  • --db-port <port>:MariaDB/MySQL端口(默认: 3306)
  • --db-name <name>:数据库(默认值: my_database)
  • --db-user <user>:用户db(默认值: my_user_mcp_ro)
  • --db-pass <pass>:未通过DB(故障: my_password)
  • --mcp-token <token>:代币承载MCP(默认值: my_token)
  • --allow-cidr <cidr>:允许的网络 /mcp 和 /health (默认值:自动通过 hostname -I 英语 /24)
  • -h, --help:助手

曼努埃尔

1.部署代码

cd /srv/www
git clone https://github.com/PmaControl/MariaDB-Guard-RO-MCP.git mcp-mariadb
cd /srv/www/mcp-mariadb

2.配置环境

复制模板并进行调整:

cp -a .env.sample .env

示例 .env:

DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=my_database
DB_USER=my_user_mcp_ro
DB_PASS=my_password
MCP_TOKEN=my_token
MAX_ROWS_DEFAULT=1000
MAX_ROWS_HARD=5000
MAX_SELECT_TIME_S=5
WHERE_FULLSCAN_MAX_ROWS=30000
MAX_CONCURRENT_DB_SELECT=3
MCP_QUERY_LOG=/srv/www/mcp-mariadb/mcp_mariadb_13306_query.log

笔记:

  • MCP_TOKEN 视频(MCP_TOKEN=(没有auth)
  • MCP_TOKEN 非视频=>标题 Authorization: Bearer <token> 必修的
  • MAX_ROWS_DEFAULT=1000 应用1000行的默认限制
  • MAX_ROWS_HARD=5000 设置5000行的绝对最大限制
  • MAX_SELECT_TIME_S 限制请求的最大持续时间 SELECT
    • MariaDB(>=10.1.1):通过 SET STATEMENT max_statement_time=... FOR SELECT ...
    • MySQL(>=5.7.4):通过提示 /*+ MAX_EXECUTION_TIME(...) */
  • 推荐值: 5 (5s)。此阈值保护服务器免受生产中的长请求。
  • WHERE_FULLSCAN_MAX_ROWS=30000 设置完整扫描的拒绝阈值 WHERE.
  • MAX_CONCURRENT_DB_SELECT=3 设置最大请求数 db_select 允许同时进行。
  • MCP_QUERY_LOG 定义SQL MCP查询的JSONL日志文件(格式化SQL, rowCount, durationMs, plan).
  • 建议在多实例中使用:按端口后缀日志(例如: mcp_mariadb_13306_query.log, mcp_mariadb_13307_query.log).

MySQL示例:

SELECT /*+ MAX_EXECUTION_TIME(5000) */ *
FROM huge_table;

MariaDB示例:

SET STATEMENT max_statement_time=5 FOR
SELECT *
FROM huge_table;

创建MySQL/MariaDB用户(兼容示例):

CREATE USER IF NOT EXISTS `my_user_mcp_ro`@`%` IDENTIFIED BY 'my_password';
GRANT SELECT ON *.* TO `my_user_mcp_ro`@`%`;
-- Optionnel (lecture/diagnostic):
-- GRANT SHOW VIEW, PROCESS ON *.* TO `my_user_mcp_ro`@`%`;
FLUSH PRIVILEGES;

3.权限

chown -R www-data:www-data /srv/www/mcp-mariadb
find /srv/www/mcp-mariadb -type d -exec chmod 755 {} \;
find /srv/www/mcp-mariadb -type f -exec chmod 644 {} \;

4.启用必要的Apache模块

a2enmod rewrite headers setenvif

5.创建Apache虚拟主机

创建 /etc/apache2/sites-available/mcp-mariadb-13306.conf:

<VirtualHost *:13306>
    ServerName localhost
    DocumentRoot /srv/www/mcp-mariadb/public

    SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

    <Directory /srv/www/mcp-mariadb/public>
        AllowOverride All
        Require all granted
        DirectoryIndex index.php
    </Directory>

    <Location "^/(mcp|health)$">
        Require local
        Require ip <YOUR_ALLOWED_CIDR>
    </Location>

    ErrorLog ${APACHE_LOG_DIR}/mcp_mariadb_13306_error.log
    CustomLog ${APACHE_LOG_DIR}/mcp_mariadb_13306_access.log combined
</VirtualHost>

适配器:

  • ServerName
  • 网络规则 Require ip ...
  • Require ip <YOUR_ALLOWED_CIDR> 意味着:只有授权网络的IP才能访问 /mcp 和 /health,en+de Require local (本地主机)。

6.激活站点并重新启动Apache

a2ensite mcp-mariadb-13306.conf
a2dissite 000-default.conf
systemctl reload apache2
# ou
service apache2 restart

7.Apache验证

apache2ctl configtest
systemctl status apache2

使用Docker运行

见本节 码头工人.

功能测试

健康检查

curl -sS http://<HOST>:13306/health

初始化MCP(带令牌)

curl -sS -X POST http://<HOST>:13306/mcp \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer <MCP_TOKEN>' \
  --data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'

初始化器MCP(无令牌)

curl -sS -X POST http://<HOST>:13306/mcp \
  -H 'content-type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'

Ping MCP

curl -sS -X POST http://<HOST>:13306/mcp \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer <MCP_TOKEN>' \
  --data '{"jsonrpc":"2.0","id":2,"method":"ping","params":{}}'

工具 db_explain_table (解释清晰)

curl -sS -X POST http://<HOST>:13306/mcp \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer <MCP_TOKEN>' \
  --data '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"db_explain_table","arguments":{"sql":"SELECT id,id_mysql_server,port FROM alias_dns WHERE id_mysql_server = 113 ORDER BY id DESC LIMIT 50"}}}'

配置MCP检查员

  • 运输: 可流式传输的HTTP
  • 网址: http://<HOST>:13306/mcp
  • 身份验证: None
  • 是 MCP_TOKEN 定义,添加标题:
    • Authorization: Bearer <MCP_TOKEN>

安全模型(详细信息)

  • 使用最低特权DB帐户(建议只读)
  • 只给予必要的权利(SELECT 强制性的; SHOW VIEW 和 PROCESS 可选)
  • 限制Apache网络访问(Require ip)
  • 用户无需代币即可倾倒 MCP_TOKEN
  • 将服务放在HTTPS后面(反向代理/nginx/Apache TLS)
  • 请求 SELECT ... FOR UPDATE 被明确阻止
  • db_select 应用请求策略:
    • SELECT * 无 WHERE 仅允许在一张桌子上使用,无 JOIN
    • SELECT * 与 WHERE 仅当目标表超过30列时被阻止
    • 非递归CTE(WITH ...)允许
    • 递归CTE(WITH RECURSIVE ...)被封锁
    • OR 在 WHERE 被阻止(重写 UNION/UNION ALL)
    • 与 WHERE,如果表的最大值为 30000 线
    • 与 WHERE,如果表超过,则拒绝完整扫描 30000 线
    • 保留负载DB:如果已运行的SQL查询数达到 MAX_CONCURRENT_DB_SELECT (缺陷 3), db_select 送回 database busy retry in 1 second
    • 如果查询超过SQL超时,返回的错误将归一化为: guard [execution time reached]

故障排除

  • .env 缺少:复制模板,然后调整值:
cp -a .env.sample .env
  • MCP服务器被阻止(非只读帐户):运行 mcp_test,删除所有写入权限/ddl/admin,然后更新 .env (或删除 .account_tested)以强制重新测试。
  • 404 上 /mcp 与 curl:检查您是否正在 发布 (通过GET)
  • Unauthorized:令牌丢失或无效
  • CORS检查器错误:检查 OPTIONS /mcp (204)集合头CORS
  • 检查日志:
    • Apache访问: /var/log/apache2/mcp_mariadb_13306_access.log
    • Apache错误: /var/log/apache2/mcp_mariadb_13306_error.log
    • SQL-MCP(JSONL): /srv/www/mcp-mariadb/mcp_mariadb_13306_query.log

开发者指南

要安装开发平台、PHPUnit、CI/CD、Git挂钩和安全检查表:

  • docs/developer_setup.md

作曲家/包装师:

  • 依赖性: composer install
  • 测验: ./vendor/bin/phpunit --configuration phpunit.xml
  • 包裹: pmacontrol/mariadb-guard-ro-mcp

关于PHPUnit:

  • 标准:PHP 8.2
  • 矩阵兼容性: 8.2, 8.3, 8.4, 8.5 (最后一个未成年人按专业)

码头工人

本地构建:

docker build -t mariadb-guard-ro-mcp:local .

运行本地:

docker run --rm -p 13306:13306 \
  -e DB_HOST=127.0.0.1 \
  -e DB_PORT=3306 \
  -e DB_NAME=my_database \
  -e DB_USER=my_user_mcp_ro \
  -e DB_PASS=my_password \
  -e MCP_TOKEN=my_token \
  mariadb-guard-ro-mcp:local

日志

# Redémarrer Apache
service apache2 restart

# Voir les logs en direct
tail -f /var/log/apache2/mcp_mariadb_13306_access.log /var/log/apache2/mcp_mariadb_13306_error.log /srv/www/mcp-mariadb/mcp_mariadb_13306_query.log

项目结构

  • public/index.php (入口点WEB)
  • src/Env.php
  • src/Http.php
  • src/Db.php
  • src/SqlGuard.php
  • src/JsonRpc.php
  • src/Tools.php
  • src/App.php

作者/许可证

  • 奥雷连·莱奎伊 https://www.linkedin.com/in/aur%C3%A9lien-乐趣-30255473/
  • 许可证: GNU GPL v3 (GPL-3.0-or-later) https://www.gnu.org/licenses/gpl-3.0.html