Apache Doris
官方Apache Doris 的 MCP 服务器,一个基于 MPP 架构的实时数据仓库。
你可以用 Apache Doris MCP 做什么?
- 对 Apache Doris 执行 SQL 查询 — 让 AI 运行临时 SQL 并通过
doris_query.execute_query返回结果。 - 探索数据库 schema 和元数据 — 通过 schema 提取工具发现内部和外部 catalog 中的表、列和数据类型。
- 将自然语言转换为 SQL(NL2SQL) — 描述你需要的数据,让 AI 生成并运行相应的 Doris SQL。
- 分析查询性能 — 请求 SQL 执行计划和性能分析信息,以理解和优化查询执行。
- 监控集群健康与指标 — 通过监控工具模块从 Doris FE 和 BE 实例检索内存、连接和节点级指标。
文档
Doris MCP 服务器
Doris MCP(模型上下文协议)服务器是一个使用 Python 和 FastAPI 构建的后端服务。它实现了 MCP,允许客户端通过定义的“工具”与之交互。它主要用于连接 Apache Doris 数据库,可能利用大语言模型(LLM)执行将自然语言查询转换为 SQL(NL2SQL)、执行查询以及进行元数据管理和分析等任务。
发布状态
当前包元数据和最新 Git 标签为 0.6.1。master
分支还包含该标签之后所做的更改;这些更改记录在
Unreleased 下,直到选择并发布下一个版本。
MCP 2026-07-28 协议在 master 上的兼容性为正式发布
(GA),适用于 Streamable HTTP 和 stdio。受支持的协议契约已通过
完整测试套件(警告视为错误)、官方无状态一致性套件、干净的 wheel 安装,
以及通过两种传输方式对真实 Apache Doris 的测试。
此 GA 声明仅限于受支持传输方式上的协议兼容性。项目包元数据仍为 Beta, 且不扩展受支持的部署形态或移除已记录的操作约束。在受控环境之外部署之前, 请查看变更日志、 协议支持矩阵和 部署约束。
v0.6.0 亮点
- 🔐 企业级认证系统:革命性的令牌绑定数据库配置,支持全面的 Token、JWT 和 OAuth 认证,实现安全的多租户访问,具备细粒度控制开关和企业级安全默认值
- ⚡ 即时数据库验证:连接时实时验证数据库配置,减少查询时的阻塞,为无效配置提供更早的反馈
- 🔄 热重载配置管理:运行时配置更新,支持 tokens.json 的智能热重载、自动令牌重新验证,以及带回滚机制的全面错误处理
- 🏗️ 高级连接架构:会话缓存和连接池优化,具备智能连接池重建和自动资源管理
- 🌐 多工作进程可扩展性:无状态 HTTP 请求处理,支持多工作进程;认证相关的工作进程限制仍然适用
- 🔒 增强的安全框架:全面的访问控制和 SQL 安全验证,具备即时验证、基于角色的权限和增强的注入检测模式
- 🛠️ 统一配置系统:简化的配置管理,具备正确的命令行优先级、Docker 兼容性改进和跨平台部署支持
- 📊 令牌管理仪表板:完整的令牌生命周期管理,包括创建、撤销、统计和全面的审计跟踪,用于企业令牌治理
- 🌐 基于 Web 的管理界面:仅限本地主机的安全令牌管理,具备直观的仪表板、数据库绑定配置、实时操作和企业级访问控制
发布说明:v0.6.0 引入了上述总结的认证、令牌管理、连接和多工作进程功能。这些功能不会移除当前代码库中记录的 Beta 状态或部署限制。
v0.5.1 中也包含的内容
- 🔥 关键的 at_eof 连接修复:通过智能健康监控和自愈恢复,彻底消除连接池错误
- 🔧 企业级日志系统:基于级别的文件分离,具备自动清理和毫秒级精度时间戳
- 📊 高级数据分析套件:7 个企业级数据治理工具,包括质量分析、血缘追踪和性能监控
- 🏃♂️ 高性能 ADBC 集成:Apache Arrow Flight SQL 支持,大型数据集性能提升 3-10 倍
- ⚙️ 增强的配置管理:完整的 ADBC 配置系统,具备智能参数验证
核心功能
- MCP 协议实现:提供标准 MCP 接口,支持工具调用、资源管理和提示交互。
- 可流式 HTTP 通信:统一 HTTP 端点,同时支持请求/响应和流式通信,以实现最佳性能和可靠性。
- Stdio 通信:标准输入/输出模式,用于与 Cursor 等 MCP 客户端直接集成。
- 企业级架构:模块化设计,功能全面:
- 工具管理器:集中式工具注册和路由,具备统一接口(
doris_mcp_server/tools/tools_manager.py) - 增强的监控工具模块:高级内存跟踪、指标收集和灵活的 BE 节点发现,采用模块化、可扩展设计
- 查询信息工具:增强的 SQL 解释和性能分析,支持可配置的内容截断、用于 LLM 附件的文件导出以及高级查询分析
- 资源管理器:资源管理和元数据暴露(
doris_mcp_server/tools/resources_manager.py) - 提示管理器:用于数据分析的智能提示模板(
doris_mcp_server/tools/prompts_manager.py)
- 工具管理器:集中式工具注册和路由,具备统一接口(
- 高级数据库功能:
- 查询执行:高性能 SQL 执行,具备高级缓存和优化、增强的连接稳定性和自动重试机制(
doris_mcp_server/utils/query_executor.py) - 安全管理:全面的 SQL 安全验证,支持可配置的阻止关键字、SQL 注入防护、数据脱敏和统一安全配置管理(
doris_mcp_server/utils/security.py) - 元数据提取:全面的数据库元数据,支持目录联邦(
doris_mcp_server/utils/schema_extractor.py) - 性能分析:高级列分析、性能监控和数据分析工具(
doris_mcp_server/utils/analysis_tools.py)
- 查询执行:高性能 SQL 执行,具备高级缓存和优化、增强的连接稳定性和自动重试机制(
- 目录联邦支持:完全支持多目录环境(内部 Doris 表和外部数据源,如 Hive、MySQL 等)
- 企业级安全:全面的安全框架,具备认证、授权、SQL 注入防护和数据脱敏能力,支持环境变量配置
- 基于 Web 的令牌管理:仅限本地主机的安全界面,用于完整的令牌生命周期管理,具备数据库绑定、实时统计和企业级访问控制(
doris_mcp_server/auth/token_handlers.py) - 统一配置框架:通过
config.py进行集中配置管理,具备全面验证、标准化参数命名和智能默认数据库处理,自动回退到information_schema
系统要求
- Python:3.12+
- 数据库:Apache Doris 连接信息(主机、端口、用户、密码、数据库)
🚀 快速开始
从 PyPI 安装
# Install the latest version
pip install doris-mcp-server
# Install specific version
pip install doris-mcp-server==0.6.1
💡 打包命令:
doris-mcp-server启动 MCP 服务器。doris-mcp-client是用于通过 Streamable HTTP 或 stdio 连接服务器的独立客户端;这两个命令不可互换。
启动 Streamable HTTP 模式(Web 服务)
主要通信模式,提供最佳性能和可靠性:
# Full configuration with database connection
doris-mcp-server \
--transport http \
--host 127.0.0.1 \
--port 3000 \
--db-host 127.0.0.1 \
--db-port 9030 \
--db-user root \
--db-password your_password
启动 Stdio 模式(用于 Cursor 和其他 MCP 客户端)
标准输入/输出模式,用于与 MCP 客户端直接集成:
# For direct integration with MCP clients like Cursor
doris-mcp-server --transport stdio
🌐 令牌管理界面(v0.6.0 新增)
访问基于 Web 的令牌管理仪表板,进行企业级令牌管理:
安全访问要求
- 仅限本地主机访问:界面仅限于
127.0.0.1和::1,以确保最大安全性 - 管理员认证:需要
TOKEN_MANAGEMENT_ADMIN_TOKEN才能访问 - 配置前提条件:
# Generate separate high-entropy credentials; do not commit them. export TOKEN_ADMIN="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')" export TOKEN_MANAGEMENT_ADMIN_TOKEN="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')" export ENABLE_HTTP_TOKEN_MANAGEMENT=true export ENABLE_TOKEN_AUTH=true export TOKEN_MANAGEMENT_ALLOWED_IPS=127.0.0.1,::1
界面访问
管理请求仅接受 HTTP 头中的管理员令牌。查询字符串中的 令牌将被拒绝,不得放置在 URL、浏览器历史记录或访问 日志中。
curl -H "Authorization: Bearer $TOKEN_MANAGEMENT_ADMIN_TOKEN" \
http://127.0.0.1:3000/token/stats
可选的 /token/management 页面必须通过提供相同头的客户端或本地
代理打开。其 API 请求使用页面内密码字段,不会在 URL 中持久化或传播令牌。
可用操作
- 📊 令牌统计:活动、过期和总令牌的实时概览
- ➕ 创建令牌:
- 基本信息(ID、描述、过期时间)
- 数据库绑定(主机、端口、用户、密码、数据库)
- 自定义令牌值或自动生成的安全令牌
- 📋 令牌管理:
- 列出所有令牌及其数据库绑定状态
- 一键令牌撤销
- 自动清理过期令牌
- 🔒 企业级安全:
- 所有操作都需要管理员认证
- 实时 IP 验证
- 完整的审计日志
- 仅摘要持久化到
tokens.json;明文在令牌创建时仅返回一次 - 多工作进程一致性,通过进程共享锁、原子读-修改-写更新和仅摘要撤销记录实现
🔐 安全说明:该界面仅用于本地主机管理。无法远程访问,确保令牌管理操作的最大安全性。
验证安装
# Check installation
doris-mcp-server --version
doris-mcp-client --version
doris-mcp-server --help
doris-mcp-client --help
# Test HTTP mode (in another terminal)
curl --fail http://localhost:3000/live
curl --fail http://localhost:3000/ready
环境变量(可选)
除了命令行参数,您还可以使用环境变量:
# Basic Database Configuration
export DORIS_HOST="127.0.0.1"
export DORIS_PORT="9030"
export DORIS_USER="root"
export DORIS_PASSWORD="your_password"
# Keep the isolated legacy HTTP migration adapter disabled unless an
# identified 2025-11-25 client still needs /mcp/legacy.
export ENABLE_LEGACY_HTTP_ADAPTER=false
# Bound each resources/list, tools/list, and prompts/list response.
export MCP_LIST_PAGE_SIZE=100
# Expose eight progressive-disclosure domains by default. Set flat to expose
# the same 47 children under exact collision-free formal names.
export MCP_TOOL_EXPOSURE_MODE=hierarchical
# Load only these installed custom tool providers. Empty disables extensions.
export MCP_TOOL_PROVIDERS="orders_api"
# A launch-local key is generated automatically. Configure one shared
# high-entropy value when independently launched replicas share traffic.
export MCP_STATE_HANDLE_SECRET="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
export MCP_STATE_HANDLE_TTL_SECONDS=300
# Token Management Interface (Security-Critical)
export TOKEN_ADMIN="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
export TOKEN_MANAGEMENT_ADMIN_TOKEN="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
export ENABLE_HTTP_TOKEN_MANAGEMENT=true
export ENABLE_TOKEN_AUTH=true
export TOKEN_MANAGEMENT_ALLOWED_IPS="127.0.0.1,::1"
# Then start with simplified command
doris-mcp-server --transport http --host 127.0.0.1 --port 3000
命令行参数
doris-mcp-server 命令支持以下参数:
| 参数 | 描述 | 默认值 | 必需 |
|---|---|---|---|
--transport | 传输模式:http 或 stdio | http | 否 |
--host | HTTP 服务器主机(仅 HTTP 模式) | localhost | 否 |
--port | HTTP 服务器端口(仅 HTTP 模式) | 3000 | 否 |
--db-host | Doris 数据库主机 | localhost | 否 |
--db-port | Doris 数据库端口 | 9030 | 否 |
--db-user | Doris 数据库用户名 | root | 否 |
--db-password | Doris 数据库密码 | - | 是(除非在环境中) |
开发设置
对于希望从源码构建的开发者:
1. 克隆仓库
# Replace with the actual repository URL if different
git clone https://github.com/apache/doris-mcp-server.git
cd doris-mcp-server
2. 安装依赖
dev 依赖组包含 CI 使用的测试和质量工具:
uv sync --frozen --group dev
对于基于 pip 的工作流程,requirements.txt 仅包含生产依赖。
requirements-dev.txt 包含该运行时清单,并添加了相同的精简测试和质量工具链:
pip install -r requirements-dev.txt
生产镜像和运行时环境必须仅安装包或
requirements.txt;pytest、linters、类型检查器和构建后端不是
运行时依赖。
3. 配置环境变量
将 .env.example 文件复制到 .env,并根据您的环境修改设置:
cp .env.example .env
关键环境变量:
- 数据库连接:
DORIS_HOST:数据库主机名(默认:localhost)DORIS_HOSTS:单个 Doris 集群的有序 FE MySQL 故障转移主机(逗号分隔;当两者都设置时,DORIS_HOST会被前置)DORIS_PORT:数据库端口(默认:9030)DORIS_USER:数据库用户名(默认:root)DORIS_PASSWORD:数据库密码DORIS_DATABASE:默认数据库名称(默认:information_schema)DORIS_MIN_CONNECTIONS:最小连接池大小(默认:5)DORIS_MAX_CONNECTIONS:最大连接池大小(默认:20)DORIS_FE_HTTP_HOST:用于 profile、表大小和监控工具的独立 FE HTTP 主机(默认:空,回退到DORIS_HOST)DORIS_FE_HTTP_HOSTS:同一 Doris 集群的有序 FE HTTP 故障转移主机(逗号分隔)DORIS_FE_HTTP_PORT:独立的 FE HTTP API 端口(默认:8030)DORIS_BE_HOSTS:用于监控的显式 BE HTTP 允许列表(逗号分隔;为空时禁用 BE HTTP 指标)DORIS_BE_WEBSERVER_PORT:用于监控工具的 BE Web 服务器端口(默认:8040)DORIS_HTTP_CONNECT_TIMEOUT_SECONDS:FE/BE HTTP 连接超时(默认:3)DORIS_HTTP_READ_TIMEOUT_SECONDS:FE/BE HTTP 套接字读取超时(默认:15)DORIS_HTTP_TOTAL_TIMEOUT_SECONDS:FE/BE HTTP 总超时(默认:30;硬性上限:60)DORIS_HTTP_MAX_RESPONSE_BYTES:FE/BE HTTP 响应限制(默认:4 MiB;硬性上限:16 MiB)FE_ARROW_FLIGHT_SQL_PORT:用于 ADBC 的前端 Arrow Flight SQL 端口(v0.5.0 新增)BE_ARROW_FLIGHT_SQL_PORT:用于 ADBC 的后端 Arrow Flight SQL 端口(v0.5.0 新增)
- MCP HTTP 配置:
ENABLE_LEGACY_HTTP_ADAPTER:在/mcp/legacy暴露隔离的2025-11-25迁移适配器(默认:false); 现代流量始终使用POST /mcpMCP_LIST_PAGE_SIZE:每个协议页面返回的最大资源、工具或提示数量 (默认:100;范围:1-1000)MCP_TOOL_EXPOSURE_MODE:工具暴露模式。hierarchical返回 八个领域工具并支持渐进式子项发现;flat返回 相同的 47 个子项,使用精确的无冲突正式名称 (默认:hierarchical)MCP_TOOL_PROVIDERS:已安装的doris_mcp_server.tool_providers入口点的逗号分隔允许列表(默认:空)MCP_STATE_HANDLE_SECRET:可选的共享高熵密钥(至少 32 字节),用于认证显式跨调用状态句柄MCP_STATE_HANDLE_TTL_SECONDS:显式状态句柄的生存时间 (默认:300 秒;范围:1-3600)
- 认证配置(v0.6.0 增强):
ENABLE_TOKEN_AUTH:启用基于令牌的认证(默认:false)ENABLE_JWT_AUTH:启用 JWT 认证(默认:false)ENABLE_OAUTH_AUTH:启用 OAuth 认证(默认:false)OAUTH_ISSUER:精确的外部授权服务器签发者OAUTH_RESOURCE:规范的 MCP 受保护资源 URIOAUTH_AUDIENCE:预期的访问令牌受众(默认为OAUTH_RESOURCE)OAUTH_INTROSPECTION_URL:受信任的 RFC 7662 令牌 introspection 端点OAUTH_SCOPE/OAUTH_REQUIRED_SCOPE:允许和强制的外部 OAuth 范围ENABLE_DORIS_OAUTH_AUTH:启用 Doris 支持的 OAuth 认证(默认:false)DORIS_OAUTH_BASE_URL:Doris 支持的 OAuth 发现和令牌端点使用的公共基础 URLDORIS_OAUTH_CIMD_FETCH_TIMEOUT_SECONDS:客户端 ID 元数据文档获取超时(默认:5)DORIS_OAUTH_CIMD_MAX_DOCUMENT_BYTES:客户端 ID 元数据文档的最大大小(默认:5120)DORIS_OAUTH_CIMD_DEFAULT_CACHE_SECONDS:文档未提供缓存生存时间时的缓存生命周期(默认:300)DORIS_OAUTH_CIMD_MAX_CACHE_SECONDS:接受的最大文档缓存生存时间(默认:3600)DORIS_OAUTH_CIMD_MAX_CLIENTS:内存中保存的最大已发现客户端 ID 元数据客户端数量(默认:1000)TOKEN_FILE_PATH:用于令牌管理的 tokens.json 文件路径(默认:tokens.json)TOKEN_HOT_RELOAD:启用令牌配置的热重载(默认:true)TOKEN_HASH_ALGORITHM:新创建的静态令牌的摘要算法(sha256或sha512;默认:sha256)TOKEN_<ID>:显式静态承载令牌;每个活动令牌必须是 至少 32 个字符的安全生成值
- 旧版安全配置:
AUTH_TYPE:旧版认证类型(token/basic/oauth,已弃用 - 使用单独的开关)ENABLE_SECURITY_CHECK:启用/禁用 SQL 安全验证(默认:true)BLOCKED_KEYWORDS:被阻止的 SQL 关键字的逗号分隔列表ENABLE_MASKING:启用数据掩码(默认:true)MAX_RESULT_ROWS:返回查询行的部署上限 (默认:10000;绝对硬性上限:100000)DEFAULT_RESULT_ROWS:当doris_query.execute_query.max_rows被省略时的默认行预算(默认:100;不能超过MAX_RESULT_ROWS)
- ADBC 配置(v0.5.0 新增):
ADBC_DEFAULT_MAX_ROWS:ADBC 查询的默认最大行数 (默认:10000;不能超过MAX_RESULT_ROWS)ADBC_DEFAULT_TIMEOUT:默认 ADBC 查询超时(秒)(默认:60)ADBC_DEFAULT_RETURN_FORMAT:默认返回格式 - arrow/pandas/dict(默认:arrow)ADBC_CONNECTION_TIMEOUT:ADBC 连接超时(秒)(默认:30)ADBC_ENABLED:启用/禁用 ADBC 工具(默认:true)
- 性能配置:
ENABLE_QUERY_CACHE:启用查询缓存(默认:true)CACHE_TTL:缓存生存时间(秒)(默认:300)MAX_CONCURRENT_QUERIES:最大并发查询数(默认:50)QUERY_TIMEOUT:查询执行时间的部署上限 (默认和绝对硬性上限:300 秒)MAX_RESULT_BYTES:UTF-8 JSON 行数据的部署上限 (默认:1048576;允许范围:256-16777216 字节)MAX_RESPONSE_CONTENT_SIZE:LLM 兼容性的最大响应内容大小(默认:4096,v0.4.0 新增)
- 增强日志配置(v0.5.0 改进):
LOG_LEVEL:日志级别(DEBUG/INFO/WARNING/ERROR,默认:INFO)LOG_FILE_PATH:日志文件路径(自动按级别组织)ENABLE_AUDIT:启用审计日志(默认:true)ENABLE_LOG_CLEANUP:启用自动日志清理(默认:true,v0.5.0 增强)LOG_MAX_AGE_DAYS:日志文件的最大保留天数(默认:30,v0.5.0 增强)LOG_CLEANUP_INTERVAL_HOURS:日志清理检查间隔(小时)(默认:24,v0.5.0 增强)- v0.5.0 新功能:
- 基于级别的文件分离:自动分离到
debug.log、info.log、warning.log、error.log、critical.log - 时间戳格式:增强的格式化,具有毫秒精度和正确的对齐
- 后台清理调度器:自动清理,具有可配置的保留策略
- 审计跟踪:专用的
audit.log,具有单独的保留管理 - 性能优化:最小开销的异步日志记录,支持轮转
- 基于级别的文件分离:自动分离到
可用的 MCP 工具
MCP tools/list 暴露了八个稳定的只读领域工具。使用
空对象调用领域以逐步发现其精确的授权子
工具、模式、版本支持、可用性、证据和风险注释。
参见 docs/tool-registry.md。检入的目录是
从运行时使用的相同验证领域定义生成的。
tool:list 授权 OAuth 会话的领域清单发现;它不
授权子执行。没有发现权限的子项被
省略,而授权但不可用的子项保持可见,带有
callable=false。Doris RBAC 仍然是所有
Doris 对象访问的最终数据授权后端。
4. 运行服务
执行以下命令启动服务器:
./start_server.sh
此命令启动带有 Streamable HTTP MCP 服务的 FastAPI 应用程序。
5. 在 Docker 上部署
如果您只想在 Docker 中运行 Doris MCP Server:
cd doris-mcp-server
docker build -t doris-mcp-server .
docker run -d -p <host-port>:3000 -v /*your-host*/doris-mcp-server/.env:/app/.env --name <your-mcp-server-name> doris-mcp-server:latest
容器始终监听端口 3000。捆绑的 Compose 部署
默认将其发布到主机端口 3000,并将 Grafana 发布到主机端口
3003,因此这两个服务不会争用同一端口。使用
MCP_HTTP_PORT 和 GRAFANA_HTTP_PORT 覆盖这些默认值:
MCP_HTTP_PORT=3100 GRAFANA_HTTP_PORT=3103 docker compose up -d
在启动捆绑的堆栈之前,创建 Compose 使用的五个被忽略的机密
文件。没有数据库、MCP、Redis 或 Grafana 凭据存储在
docker-compose.yml、.env.example 或渲染的服务环境中:
mkdir -p .secrets
chmod 700 .secrets
python -c 'import secrets; print(secrets.token_urlsafe(32))' > .secrets/doris_password
python -c 'import secrets; print(secrets.token_urlsafe(32))' > .secrets/mcp_static_token
python -c 'import secrets; print(secrets.token_urlsafe(32))' > .secrets/redis_password
python -c 'import secrets; print(secrets.token_urlsafe(32))' > .secrets/grafana_admin_password
python -c 'import hashlib, pathlib; p=pathlib.Path(".secrets/doris_password").read_text().rstrip("\n").encode(); print("initial_root_password = *" + hashlib.sha1(hashlib.sha1(p).digest()).hexdigest().upper())' > .secrets/doris_fe_custom.conf
chmod 0444 .secrets/*
docker compose up -d
doris_fe_custom.conf 包含 Doris 的两阶段 SHA-1 密码验证器,而不是
明文密码,并作为 FE 初始 root 配置挂载。
匹配的明文文件仅挂载到必须
向 Doris 认证的服务中。将两个文件都视为凭据。父目录
保持模式 0700,而文件对非 root MCP 进程是主机只读和容器可读的。
要将机密文件放在其他位置,请复制
.env.example 到 .env,并且只更改 COMPOSE_*_FILE 主机路径。
Compose 模型中的所有第三方镜像都使用显式的上游版本
和不可变的 OCI 摘要。通过同时更改版本标签和摘要来谨慎升级它们,
然后重新运行部署契约和传输测试;
不要用 latest 或其他浮动标签替换它们。
镜像级 Docker 健康检查使用 /live,因此暂时的 Doris 中断
不会导致 MCP 进程被视为死亡。Compose 使用
/ready 覆盖该探测,并且仅在有限的 Doris
探测成功后标记服务就绪。两个探测都使用端口 3000 上的实际内部监听器。
Compose 默认允许 127.0.0.1:* 和 localhost:* Host 头。通过
其他主机名、IP 地址或反向代理访问的部署必须
设置显式的逗号分隔允许列表;允许所有 * 值被拒绝:
MCP_ALLOWED_HOSTS='mcp.example.com,mcp.example.com:*' docker compose up -d
服务端点:
- Streamable HTTP:
http://<host>:<port>/mcp(MCP 消息使用POST;不要依赖GET或DELETE兼容性行为) - 存活:
http://<host>:<port>/live— 进程和协议服务正在运行;不依赖 Doris - 就绪:
http://<host>:<port>/ready— 仅当有限的 DorisSELECT 1探测成功时返回 200;否则返回 503 - 旧版健康检查:
http://<host>:<port>/health— 向后兼容的存活别名;不要使用它来决定是否路由数据库工作
就绪探测具有固定的短超时,并且只暴露稳定的状态 字段,不暴露连接错误或凭据。Stdio 模式没有 HTTP 健康 表面;监督进程并使用 MCP 初始化/发现 握手进行传输级可用性。
注意:服务器使用 Streamable HTTP 进行基于 Web 的通信,提供统一的请求/响应和流式功能。
MCP 协议支持和迁移
Doris MCP Server 使用官方 Python SDK v2 协议核心,用于 Streamable HTTP 和 stdio。线上使用的 MCP 协议修订版是 独立于 Doris MCP Server 包版本和 Python SDK 包 版本的。
权威协议参考是 MCP 2026-07-28 规范、 2026-07-28 关键更改、 和 Streamable HTTP 传输规范。
协议和传输矩阵
| 客户端协议 | Streamable HTTP | stdio | 连接行为 | Doris MCP Server 状态 |
|---|---|---|---|---|
2026-07-28 | 支持且推荐 | 支持且推荐 | 无状态、自包含请求;无初始化握手或协议会话 | 由现代 HTTP 和真实进程 stdio 测试覆盖 |
2025-11-25 | 在 /mcp/legacy 处选择启用 | 支持迁移 | 接受旧版 initialize,但服务器保持无状态且不发出 Mcp-Session-Id | HTTP 适配器默认禁用;由旧版 HTTP 和 stdio 测试覆盖 |
2025-06-18 及更早版本 | 不保证 | 不保证 | 旧版协商和传输行为不在支持的兼容性契约范围内 | 连接前请升级客户端 |
HTTP+SSE (2024-11-05) | 不支持 | 不适用 | 已退役的独立 SSE 端点不再暴露 | 迁移至 /mcp 处的 Streamable HTTP |
2025-11-25 的 HTTP 兼容路径与现代端点隔离,且默认禁用。新的集成应针对 POST /mcp 处的 2026-07-28。
MCP 2026-07-28 请求契约
现代客户端可在调用任何其他方法之前调用 server/discover,以检查支持的协议版本、能力和服务器身份。发现是可选的;每个正常请求仍然是自包含的。
每个现代请求必须在 params._meta 中携带以下值:
io.modelcontextprotocol/protocolVersion:2026-07-28io.modelcontextprotocol/clientCapabilities:该请求可用的能力,或空对象io.modelcontextprotocol/clientInfo:客户端名称和版本;规范建议提供此项
对于 Streamable HTTP,每个 POST /mcp 发送一个 JSON-RPC 请求,并包含:
| 请求头 | 必需 | 值 |
|---|---|---|
Content-Type | 是 | application/json |
Accept | 是 | 同时包含 application/json 和 text/event-stream |
MCP-Protocol-Version | 是 | 必须与 _meta 中的协议版本匹配 |
Mcp-Method | 是 | 必须与 JSON-RPC method 匹配 |
Mcp-Name | 对于 tools/call、resources/read 和 prompts/get | 必须匹配 params.name 或 params.uri |
请求头名称不区分大小写,但方法和名称值区分大小写。缺少必需请求头或请求头与请求体不一致时,将返回 HTTP 400 和协议 HeaderMismatch 错误(-32020)。不支持的协议版本将返回 UnsupportedProtocolVersion(-32022)。如果名称或 URI 不适合作为纯 ASCII 请求头值,请将其 UTF-8 字节编码为 Base64,并按传输规范发送 Mcp-Name: =?base64?{value}?=。
示例发现请求:
curl --request POST http://127.0.0.1:3000/mcp \
--header 'Content-Type: application/json' \
--header 'Accept: application/json, text/event-stream' \
--header 'MCP-Protocol-Version: 2026-07-28' \
--header 'Mcp-Method: server/discover' \
--data '{
"jsonrpc": "2.0",
"id": 1,
"method": "server/discover",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {},
"io.modelcontextprotocol/clientInfo": {
"name": "example-client",
"version": "1.0.0"
}
}
}
}'
Stdio 在消息体中携带相同的 JSON-RPC 请求元数据,但不使用 HTTP 请求头。在 stdio 模式下,请勿将日志或其他诊断信息写入 stdout;stdout 保留用于 MCP 协议消息。
OpenTelemetry 追踪上下文
客户端可在 params._meta 中传播 W3C traceparent、tracestate 和 baggage 载体字段,如 MCP SEP-414、W3C Trace Context 和 W3C Baggage 所定义。相同的消息级载体适用于 Streamable HTTP 和 stdio;这些值不是单独的 MCP HTTP 请求头。
当配置了 OpenTelemetry 提供程序和导出器时,每个 MCP 操作跨度都归属于有效的传入追踪上下文。活动上下文在该操作的生命周期内可供已接入的下游工作使用,并在下一个请求之前重置。追踪载体字段永远不会传递给 Doris 工具、资源或提示管理器,也永远不会复制到模型内容或结构化结果中。
服务器在 SDK 传播器看到追踪载体值之前对其进行验证。格式错误、过大、重复或孤立的字段会被独立忽略,警告日志仅标识字段名称——绝不标识其提供的值。在类似凭据的行李键(如 token、secret 或 authorization)下的值会在传播前替换为 [REDACTED]。baggage 仍可能包含其他部署敏感的关联数据,因此客户端应仅发送经其遥测数据处理策略批准的值。
列表分页
resources/list、tools/list 和 prompts/list 在 Streamable HTTP 和 stdio 上每次响应最多返回 MCP_LIST_PAGE_SIZE 条条目。结果按其稳定的资源 URI、工具名称或提示名称排序。当存在 nextCursor 时,将该不透明值作为下一个请求的 cursor 传递;不要解析或构造游标。
游标是经过 HMAC 认证的显式状态句柄,绑定到其列表类型、作用域、资源、当前可见列表快照、授权上下文和过期时间。它不依赖于 MCP 协议会话、传输连接或工作进程本地内存。将其用于另一个列表、可见性变化后、过期后、修改后或在不同主体下使用时,将返回 Invalid Params。在这种情况下,请不带游标重新开始列表遍历。这可以防止多页遍历静默重复、丢弃或跨越权限范围的条目。
服务器默认生成一个启动本地的句柄密钥,并将其传递给同一 CLI 进程创建的所有工作进程。当负载均衡器可能将连续页面路由到不同实例时,请在独立启动的副本上设置一个共享的 MCP_STATE_HANDLE_SECRET。句柄负载包含有界的延续元数据,并且是签名而非加密的;凭据、SQL 文本和查询结果绝不能放入其中。参见 ADR 0002。
列表失败绝不会表示为成功的空集合。Doris 元数据中断返回 List backend unavailable;Doris 元数据权限失败返回 List operation permission denied;意外的工具/资源/提示注册表失败返回 Internal server error。这些响应使用 JSON-RPC 代码 -32603,且仅包含列表操作和有界的错误类别/代码,绝不包含后端异常文本。因此,带有空 resources、tools 或 prompts 数组的成功响应意味着调用方的可见集合确实为空。相同的契约适用于 Streamable HTTP 和 stdio,失败的请求不会阻止下一个列表请求成功。
订阅和变更通知
服务器当前不公布或提供 subscriptions/listen。工具和提示没有运行时变更通道,Doris 目录元数据也不会为此进程提供可靠的跨工作进程变更事件源。缓存过期和周期性目录轮询不被视为变更事件。
因此,MCP 2026-07-28 发现报告工具、提示和资源的 listChanged: false,以及资源的 subscribe: false。subscriptions/listen 请求返回 Method not found;客户端应显式刷新列表。Streamable HTTP 和真实子进程 stdio 测试强制执行此边界。参见 订阅决策记录 了解启用该能力所需的条件。
工具 JSON Schema 验证
工具 inputSchema 和 outputSchema 使用 JSON Schema 2020-12。服务器在公布或执行每个可见工具定义之前对其进行验证,然后在调用 Doris 之前验证每个调用的参数。无效参数返回 Invalid Params,且不回显被拒绝的值。当工具声明 outputSchema 时,成功的结构化结果也会被检查;服务器端 schema 不匹配隐藏在 Internal error 之后。
Schema 是自包含的。仅接受同文档的 $ref 和 $dynamicRef 片段;服务器绝不会通过 HTTP、文件 URI 或相对 URI 获取 schema。递归引用被有界验证策略拒绝。每个 schema 的默认硬限制为 64 KiB、2,048 个节点、深度 32、64 个组合分支和 64 个引用。每个输入或结构化输出限制为 1 MiB、10,000 个节点、深度 32 和每个字符串 262,144 个字符。最多报告 16 个验证违规,报告仅包含实例路径和失败的关键字。
这些检查在共享协议处理器中运行,因此 Streamable HTTP、现代 stdio 和旧版 stdio 使用相同的强制执行。MCP 2026-07-28 客户端在声明匹配的 outputSchema 时,还可以接收数组、字符串、数字或布尔类型的 structuredContent。
从 MCP 2025-11-25 迁移
- 将客户端升级到支持
2026-07-28的 MCP SDK。 - 继续使用
/mcp端点进行 Streamable HTTP,但将每条 JSON-RPC 消息作为独立的 POST 请求发送。 - 移除
initialize、notifications/initialized、Mcp-Session-Id以及对粘性会话的任何依赖。 - 在每个请求的
_meta中添加协议版本和客户端能力。尽可能在每个请求中添加客户端身份。 - 在每个 HTTP 请求中添加
MCP-Protocol-Version和Mcp-Method,并为命名的工具、资源和提示请求添加Mcp-Name。 - 停止使用已移除的 HTTP GET 流、
Last-Event-ID和可恢复的 SSE 行为。使用新的 JSON-RPC 请求 ID 重新发出被中断的请求。 - 接受现代结果中必需的
resultType字段,并处理协议定义的错误,如-32020、-32021和-32022。 - 如果集成支持两种传输方式,请针对 Streamable HTTP 和 stdio 验证迁移后的客户端。
无法立即迁移的客户端可以继续在 stdio 上使用 2025-11-25 initialize 流程。对于 Streamable HTTP,操作员必须显式设置 ENABLE_LEGACY_HTTP_ADAPTER=true 并将该客户端指向 /mcp/legacy;/mcp 绝不会回退到旧版传输。适配器保持无状态,不会创建 HTTP 协议会话。
部署约束
- 将本地部署绑定到
127.0.0.1、localhost或::1。传输会验证Host和Origin,以防止 DNS 重绑定攻击。 - 绑定地址不是公共服务身份。特别是,
0.0.0.0不授权任意的 Host 或 Origin 值。 - 当前的 Host/Origin 策略不提供操作员配置的公共允许列表。因此,公共主机名和重写 Host 或 Origin 的反向代理尚不是受支持的部署形态。
- 当绑定主机不是回环地址且未启用任何身份验证方法时,HTTP 启动失败。
ALLOW_UNAUTHENTICATED_NON_LOOPBACK=true是仅用于隔离测试的显式危险覆盖;不要将其用作部署捷径。 - 无状态 MCP 请求不需要粘性 HTTP 会话,可以使用多个工作进程。身份验证模式可能有更严格的限制:Doris 支持的 OAuth 将令牌和每用户池存储在进程内存中,必须使用
WORKERS=1运行。 - 只要流量离开本地机器,请使用 HTTPS,并将凭据保存在请求头或进程环境中,而不是 URL 中。
用法
与 Doris MCP Server 的交互需要 MCP 客户端。客户端连接到服务器的 Streamable HTTP 端点,并根据 MCP 规范发送请求以调用服务器的工具。
主要交互流程:
- (可选)发现服务器:现代客户端可以调用
server/discover来检查支持的协议版本、能力和身份。 - 发现域:在默认的
hierarchical模式下,tools/list返回八个有界的只读域。不带参数调用某个域,以发现其确切的子名称、模式和可用性。 - 调用确切的子项:使用
child_tool、arguments以及已发现的manifest_version调用同一域。- 示例:获取表结构部分
name:doris_catalogchild_tool:get_table_contextarguments:包含database、table、可选的catalog以及sections: ["schema"]。
- 在
flat模式下,直接使用无冲突的正式名称doris_catalog_get_table_context及子参数进行调用。
- 示例:获取表结构部分
- 处理响应:
- 非流式:客户端收到包含
content或isError的响应。 - 流式:客户端收到一系列进度通知,随后是最终响应。
- 非流式:客户端收到包含
传统的 2025-11-25 stdio 客户端照常初始化。HTTP 客户端需要
显式启用的 /mcp/legacy 适配器,并且仍然受上述无状态兼容性限制的约束。
Catalog 联邦支持
Doris MCP Server 支持 catalog 联邦,能够在统一接口内与多个数据 catalog(内部 Doris 表以及 Hive、MySQL 等外部数据源)进行交互。
主要特性:
- 多 Catalog 元数据访问:
doris_catalog子项在适用时接受可选的catalog参数。 - 跨 Catalog SQL 查询:使用
doris_query.execute_query并采用三段式表命名。 - Catalog 发现:使用
doris_catalog.list_catalogs。
三段式命名要求:
所有 SQL 查询在引用表时必须使用三段式命名:
- 内部表:
internal.database_name.table_name - 外部表:
catalog_name.database_name.table_name
示例:
-
获取可用 Catalogs:
{ "tool_name": "doris_catalog", "arguments": { "child_tool": "list_catalogs", "manifest_version": "<value returned by domain discovery>", "arguments": {} } } -
获取特定 Catalog 中的数据库:
{ "tool_name": "doris_catalog", "arguments": { "child_tool": "list_databases", "manifest_version": "<value returned by domain discovery>", "arguments": {"catalog": "mysql"} } } -
查询内部 Catalog:
{ "tool_name": "doris_query", "arguments": { "child_tool": "execute_query", "manifest_version": "<value returned by domain discovery>", "arguments": { "sql": "SELECT COUNT(*) FROM internal.ssb.customer" } } } -
查询外部 Catalog:
{ "tool_name": "doris_query", "arguments": { "child_tool": "execute_query", "manifest_version": "<value returned by domain discovery>", "arguments": { "sql": "SELECT COUNT(*) FROM mysql.ssb.customer" } } } -
跨 Catalog 查询:
{ "tool_name": "doris_query", "arguments": { "child_tool": "execute_query", "arguments": { "sql": "SELECT i.c_name, m.external_data FROM internal.ssb.customer i JOIN mysql.test.user_info m ON i.c_custkey = m.customer_id" } } }
安全配置
Doris MCP Server 包含一个全面的企业级安全框架,具有高级身份验证、授权、SQL 安全验证和数据脱敏功能,这些功能在 v0.6.0 中得到了增强。
安全特性(v0.6.0 增强)
- 🔐 多身份验证系统:完整的 Token、JWT 和 OAuth 身份验证,具有独立的控制开关
- 🔗 Token 绑定数据库配置:革命性的方法,允许 token 携带自己的数据库连接参数
- 🔄 热重载安全:零停机安全配置更新,具有智能 token 重新验证功能
- ⚡ 路由安全验证:Token 绑定的 Doris 路由通过其专用连接池进行验证,并带有短暂的成功缓存,因此 ping 不会在每次请求时重新连接
- 🛡️ 基于角色的授权:高级 RBAC,具有四级安全分类
- 🚫 增强的 SQL 安全:改进的模式检测,提供高级 SQL 注入保护
- 🎭 智能数据脱敏:基于用户权限的自动敏感数据脱敏
- 📊 安全分析:全面的审计跟踪和安全监控
身份验证配置(v0.6.0)
使用精细控制配置新的身份验证系统:
# Generate a deployment-specific token before enabling static authentication.
export TOKEN_ADMIN="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
# Individual Authentication Control (New in v0.6.0)
ENABLE_TOKEN_AUTH=true # Enable token-based authentication
ENABLE_JWT_AUTH=false # Enable JWT authentication
ENABLE_OAUTH_AUTH=false # Enable OAuth authentication
# Token Management (New in v0.6.0)
TOKEN_FILE_PATH=tokens.json # Token configuration file
TOKEN_HOT_RELOAD=true # Enable hot reloading
TOKEN_DB_VALIDATION_TTL_SECONDS=30 # Cache successful Doris route checks
# Legacy Configuration (Deprecated)
# AUTH_TYPE=token # Use individual switches instead
该仓库不附带任何可用的静态 token 或旧版密钥。当启用静态 token 身份验证而没有至少一个活跃的、高熵的 TOKEN_<ID> 值或 TOKEN_FILE_PATH 中的等效条目时,启动将失败。
外部 OAuth/OIDC 访问令牌验证
外部 OAuth 是故障关闭的。在服务器请求用户信息之前,它使用受信任的 RFC 7662 内省端点,并要求一个活跃的、未过期的 token,该 token 必须具有确切配置的签发者、预期的受众、MCP 资源绑定、所需的范围以及一个主体。成功的 userinfo 请求不被视为该 token 是为这个 MCP 服务器签发的证明。userinfo 主体还必须与内省后的 token 主体匹配。
OAUTH_RESOURCE 在授权码和刷新令牌请求时发送。OAUTH_AUDIENCE 默认为该资源 URI。OAUTH_REQUIRED_SCOPE 默认为 OAUTH_SCOPE 中的所有范围;授权服务器返回但未出现在 OAUTH_SCOPE 中的范围将从身份验证上下文中排除。
ENABLE_OAUTH_AUTH=true
OAUTH_CLIENT_ID=your_oauth_client_id
OAUTH_CLIENT_SECRET=your_oauth_client_secret
OAUTH_REDIRECT_URI=https://mcp.example.com/auth/callback
OAUTH_ISSUER=https://issuer.example.com
OAUTH_RESOURCE=https://mcp.example.com/mcp
OAUTH_AUDIENCE=https://mcp.example.com/mcp
OAUTH_INTROSPECTION_URL=https://issuer.example.com/introspect
OAUTH_USERINFO_URL=https://issuer.example.com/userinfo
OAUTH_SCOPE="tool:list tool:call:exec_query resource:list resource:read"
OAUTH_REQUIRED_SCOPE="tool:list resource:read"
授权服务器发现文档可以提供内省和 userinfo 端点,但其 issuer 必须与 OAUTH_ISSUER 完全匹配。可以配置专用的 OAUTH_INTROSPECTION_CLIENT_ID 和
OAUTH_INTROSPECTION_CLIENT_SECRET 值;否则使用常规的 OAuth 客户端凭据。远程签发者、发现、内省和 userinfo URL 必须使用 HTTPS。
对于 HTTP 部署,服务器在 /.well-known/oauth-protected-resource 发布 RFC 9728 元数据。缺失或无效的凭据会收到包含 resource_metadata 和最小配置范围的 HTTP 401 Bearer 质询。缺少操作范围的有效 token 会收到 HTTP 403,其中包含 error="insufficient_scope" 和升级授权所需的确切范围。访问令牌和提供程序内部的错误详细信息不会复制到这些响应中。这些 HTTP OAuth 质询不适用于 stdio 传输,在 stdio 传输中,凭据通过本地进程环境提供。
外部 OAuth 操作范围是精确的:列出工具需要 tool:list,调用工具需要 tool:call:<tool-name>,列出和读取资源需要 resource:list 和 resource:read,Prompt 操作需要 prompt:list 和 prompt:get。将每个可调用工具范围添加到 OAUTH_SCOPE;* 和不相关的范围永远不能满足操作检查。静态 token、JWT、匿名回环和本地 stdio 授权保持其现有的非 OAuth 权限行为。
Doris 支持的 OAuth 身份验证
Doris 支持的 OAuth 是一种独立的 OAuth 模式,其中 Doris 本身是授权后端。MCP 客户端发现此服务器的 OAuth 元数据,用户使用 Doris 用户名和密码登录,服务器通过创建按用户划分的 Doris 连接池来验证这些凭据,并且签发的 doa_ 访问令牌通过该 Doris 用户的连接池路由工具调用。MCP 范围控制可以调用哪些 MCP 操作;Doris RBAC 控制用户可以查看哪些 catalog、数据库、表和元数据。
此模式与外部 OAuth/OIDC 不同。ENABLE_DORIS_OAUTH_AUTH=true 与 ENABLE_OAUTH_AUTH=true、OAUTH_ENABLED=true 和旧版 AUTH_TYPE=oauth 冲突;如果同时配置了两种模式,启动将快速失败。标准 MCP 代理输入一个 MCP URL,并且应该为该 URL 发现恰好一种 OAuth 行为,因此在 Doris 支持的 OAuth 模式下不使用现有的 /auth/* 外部 OAuth 登录流程。
每个 Doris OAuth token 记录都绑定到授权期间选择的资源。受保护的 MCP 端点仅接受确切的规范资源 ${DORIS_OAUTH_BASE_URL}/mcp;为授权服务器或任何其他资源签发的 token 会在使用按用户划分的 Doris 连接池之前被 invalid_token 质询拒绝。客户端必须在授权请求和授权码 token 请求中都发送该规范 resource。如果值缺失或与绑定到授权码的资源不完全匹配,token 端点将返回 RFC 8707 invalid_target。
最小本地配置
以下示例适用于单 worker 上的本地开发:
TRANSPORT=http
WORKERS=1
DORIS_HOST=localhost
DORIS_PORT=9030
DORIS_USER=root
DORIS_PASSWORD=<service-account-password>
DORIS_DATABASE=information_schema
ENABLE_DORIS_OAUTH_AUTH=true
DORIS_OAUTH_BASE_URL=http://localhost:3000
ENABLE_OAUTH_AUTH=false
DORIS_OAUTH_DB_TOOLS_ENABLED=true
DORIS_OAUTH_DB_TOOL_ALLOWLIST=get_db_list,get_db_table_list,get_table_schema,get_table_comment,get_table_column_comments,get_table_indexes,get_catalog_list
DORIS_OAUTH_QUERY_TOOLS_ENABLED=true
DORIS_OAUTH_EXPLAIN_TOOLS_ENABLED=true
# Optional: let Doris RBAC, not the legacy MCP SQL guard, decide DDL/DML.
ENABLE_SECURITY_CHECK=false
配置的服务 Doris 账户仍然是启动验证和非 Doris-OAuth 兼容路径所必需的。如果按用户划分的连接池缺失,Doris 支持的 OAuth 请求将故障关闭,并且不得回退到服务/全局账户。
Doris OAuth 工具访问
DORIS_OAUTH_DB_TOOLS_ENABLED=true 打开已审查的元数据存储桶。已审查的工具是:
get_db_listget_db_table_listget_table_schemaget_table_commentget_table_column_commentsget_table_indexesget_catalog_list
对于正常的 MCP OAuth 流程,客户端无需传递长的 --scopes 列表。如果 OAuth 请求省略了范围,服务器将授予配置的 Doris OAuth 能力包。对于 MySQL 通道操作,Doris RBAC 决定登录的 Doris 用户是否真的可以读取元数据、运行 SQL 或解释 SQL。
DORIS_OAUTH_QUERY_TOOLS_ENABLED=true 打开 exec_query。DORIS_OAUTH_EXPLAIN_TOOLS_ENABLED=true 打开 get_sql_explain。如果 ENABLE_SECURITY_CHECK=true,旧版 MCP SQL 安全层仍然可以在 Doris 看到某些 SQL 之前拒绝它。当预期策略是让 Doris RBAC 决定 SQL/DDL/DML 时,设置 ENABLE_SECURITY_CHECK=false。
Doris 支持的 OAuth 在此阶段仍然不打开 prompts、ADBC、FE HTTP profile/监控、审计/治理或性能分析,除非这些路径通过按用户凭据单独路由或给予明确的服务账户/管理员设计。
OAuth 客户端注册
首选的客户端注册顺序是:
- 当操作员配置了客户端时,使用该客户端。
- 通过发送其 HTTPS URL 作为
client_id来使用客户端 ID 元数据文档(CIMD)。 - 仅作为兼容性回退使用动态客户端注册(DCR)。
授权服务器元数据通告 client_id_metadata_document_supported=true。CIMD 必须是 JSON 对象,其 client_id 必须与请求的 URL 完全相等,并且其 client_name 和 redirect_uris 必须有效。此服务器目前接受具有 token_endpoint_auth_method=none、授权码加可选刷新令牌授权、code 响应类型以及精确重定向 URI 匹配的公共 CIMD 客户端。原生客户端可以使用反向域自定义方案或回环 HTTP URI;Web 客户端必须使用非回环 HTTPS。
CIMD 检索是故障关闭的。URL 必须使用 HTTPS,包含路径,并且没有 userinfo、片段、反斜杠或点路径段。解析器拒绝特殊用途的目标地址,固定请求的已验证 DNS 结果,不遵循重定向,要求 JSON,默认将响应限制为 5 KiB,拒绝嵌入的共享密钥或私钥材料,并且仅根据 HTTP 缓存控制缓存有效文档。仅当 Doris OAuth 签发者本身是回环开发签发者时,才接受回环元数据主机。登录页面显示客户端和重定向主机名,并在 localhost 重定向之前发出警告。
CIMD 控件可以使用 DORIS_OAUTH_CIMD_FETCH_TIMEOUT_SECONDS、DORIS_OAUTH_CIMD_MAX_DOCUMENT_BYTES、DORIS_OAUTH_CIMD_DEFAULT_CACHE_SECONDS、DORIS_OAUTH_CIMD_MAX_CACHE_SECONDS 和 DORIS_OAUTH_CIMD_MAX_CLIENTS 进行调整。
当 DORIS_OAUTH_DYNAMIC_CLIENT_REGISTRATION_MODE 允许时,DCR 仍然可用于旧客户端。DCR 请求必须包含 application_type 作为 native 或 web;相同的类型特定和精确重定向 URI 规则适用。生产环境中的 DCR 仍然需要 ENABLE_DORIS_OAUTH_PRODUCTION_DCR=true。
授权成功和可重定向的错误响应在 RFC 9207 iss 参数中包含确切的授权服务器签发者。发现通告 authorization_response_iss_parameter_supported=true;客户端必须在接受响应之前,将返回的值与发现的签发者进行比较,而不进行 URI 规范化。
当前操作限制
Doris 支持的 OAuth 目前是单进程和单 worker 的:
WORKERS=1是必需的。WORKERS=0会扩展为 CPU 核心数,并在启用 Doris 支持的 OAuth 时失败。- OAuth 客户端、授权事务、授权码、访问令牌、刷新令牌和 DCR 客户端仅存储在内存中,且仅限进程本地。
- 每个用户的 Doris 连接池仅限进程本地。
- 进程重启后,用户需要重新登录。
- 令牌和连接池不会在工作进程、进程或节点之间共享。
- 目前尚不支持基于 Doris 的 OAuth 的无状态水平扩展和多节点部署。
如果访问令牌本身有效但其对应的 Doris 用户池已不存在,请求将失败并返回需要登录 / DORIS_OAUTH_POOL_MISSING。服务器不会存储原始 Doris 密码来自动重建连接池。
生产环境加固
对于生产环境部署:
- 对任何非回环地址使用 HTTPS
DORIS_OAUTH_BASE_URL。 - 保持
DORIS_OAUTH_ALLOW_INSECURE_HTTP=false;除非为开发环境显式覆盖,否则拒绝非回环http://。 - 仅在受控的反向代理后启用
DORIS_OAUTH_TRUST_PROXY_HEADERS,并设置DORIS_OAUTH_TRUSTED_PROXY_CIDRS。 - 保持登录、授权、令牌、刷新、撤销和 DCR 的速率限制处于启用状态。
- 使用 Doris RBAC 作为最终的数据授权边界,并仅授予 Doris 用户其应查看的数据权限。
- 不要记录 Doris 密码、授权头、访问令牌、刷新令牌、授权码、PKCE 验证器或客户端密钥。
- 将
doa_前缀视为保留给基于 Doris 的 OAuth 访问令牌;静态令牌和 JWT 承载值不得使用此前缀。 - 优先使用预配置的客户端或客户端 ID 元数据文档。将 DCR 作为兼容性回退方案;生产环境使用 DCR 需要
ENABLE_DORIS_OAUTH_PRODUCTION_DCR=true。
令牌绑定的数据库配置(v0.6.0 新增)
托管令牌创建仅返回一次承载值,并仅将其摘要写入
tokens.json。对于手动配置,请在仓库外部生成承载值和摘要,
将承载值存储在客户端密钥库中,并仅将摘要放入服务器文件中:
python - <<'PY'
import hashlib
import secrets
token = secrets.token_urlsafe(32)
print(f"Bearer token (store once): {token}")
print(f"token_digest: sha256:{hashlib.sha256(token.encode()).hexdigest()}")
PY
v2 文件格式使用生成的摘要:
{
"version": "2.0",
"tokens": [
{
"token_id": "customer-a-token",
"token_digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000",
"created_at": "2026-07-29T00:00:00Z",
"expires_at": null,
"last_used": null,
"description": "Customer A dedicated database access",
"is_active": true,
"database_config": {
"host": "customer-a-db.example.com",
"port": 9030,
"user": "customer_a_user",
"password": "secure_password",
"database": "customer_a_data",
"charset": "UTF8",
"fe_http_port": 8030
}
}
]
}
将全零示例替换为生成的摘要;该示例故意不是
可用的凭据。托管写入是原子的,并将文件模式设置为 0600。
包含 token 明文的第一版文件仅被接受一次以用于迁移,
随后会立即被包含摘要记录的版本 2 文件替换。服务器无法
从 token_digest 恢复或显示原始承载值。
热重载配置更新(v0.6.0 新增)
系统会自动检测并应用配置更改:
- 自动检测:每 10 秒监控文件修改
- 即时验证:对新令牌进行即时数据库配置验证
- 零停机:配置更新不会中断服务
- 回滚保护:配置错误时自动回滚
- 审计跟踪:完整记录配置更改日志
令牌认证示例
# Client authentication with token
auth_info = {
"type": "token",
"token": "your_jwt_token",
"session_id": "unique_session_id"
}
基本认证示例
# Client authentication with username/password
auth_info = {
"type": "basic",
"username": "analyst",
"password": "secure_password",
"session_id": "unique_session_id"
}
授权与安全级别
系统支持四个安全级别,具有层级访问控制:
| 安全级别 | 访问范围 | 典型用例 |
|---|---|---|
| 公开 | 无限制访问 | 公开报告、一般统计 |
| 内部 | 公司员工 | 内部仪表盘、业务指标 |
| 机密 | 授权人员 | 客户数据、财务报告 |
| 秘密 | 高级管理层 | 战略数据、敏感分析 |
角色配置
外部 OAuth 角色映射通过环境变量配置:
# Roles supplied when the provider returns no role claim
OAUTH_DEFAULT_ROLES=oauth_user
# Fallbacks for users whose roles do not occur in the JSON mappings
OAUTH_DEFAULT_SECURITY_LEVEL=internal
OAUTH_DEFAULT_PERMISSIONS=read_data
# Exact domains only. Domain elevation is applied only when the provider
# returns email_verified=true.
OAUTH_TRUSTED_DOMAINS=example.com,internal.example.com
OAUTH_TRUSTED_DOMAIN_SECURITY_LEVEL=confidential
# Each JSON value replaces the complete built-in mapping.
OAUTH_ROLE_SECURITY_LEVELS_JSON={"analyst":"internal","executive":"secret"}
OAUTH_ROLE_PERMISSIONS_JSON={"analyst":["read_data","query_database"],"executive":["read_data","query_database","admin"]}
角色名称和受信任域名的匹配不区分大小写。支持的
安全级别为 public、internal、confidential 和 secret。显式的
空权限数组会拒绝该角色的应用权限;空的
OAUTH_DEFAULT_PERMISSIONS 值会使未知角色默认失败关闭。
内置角色默认值保留了 admin、
administrator、data_admin、super_admin、data_analyst、developer、
manager、viewer、user 和 oauth_user 的先前行为。默认情况下不信任任何电子邮件域名。
这些设置管理 MCP 应用权限和安全分类。 数据库、表、列和行的访问仍必须通过 Doris 用户、 角色、授权、视图和行策略来强制执行;OAuth 映射不会绕过 Doris 授权。请参阅 Doris 细粒度访问控制指南 了解端到端的列和行策略示例、MCP 身份路由选择 以及验证清单。
SQL 安全验证
系统会自动验证 SQL 查询是否存在安全风险:
被阻止的操作
使用环境变量配置被阻止的 SQL 操作(v0.4.2 新增):
# Enable/disable SQL security check (New in v0.4.2)
ENABLE_SECURITY_CHECK=true
# Customize blocked keywords via environment variable (New in v0.4.2)
BLOCKED_KEYWORDS="DROP,DELETE,TRUNCATE,ALTER,CREATE,INSERT,UPDATE,GRANT,REVOKE,EXEC,EXECUTE,SHUTDOWN,KILL"
# Maximum query complexity score
MAX_QUERY_COMPLEXITY=100
默认阻止的关键字(v0.4.2 统一):
- DDL 操作:DROP、CREATE、ALTER、TRUNCATE
- DML 操作:DELETE、INSERT、UPDATE
- DCL 操作:GRANT、REVOKE
- 系统操作:EXEC、EXECUTE、SHUTDOWN、KILL
SQL 注入防护
系统会自动检测并阻止:
- 基于联合的注入:
UNION SELECT攻击 - 基于布尔的注入:
OR 1=1模式 - 基于时间的注入:
SLEEP()、WAITFOR函数 - 注释注入:
--、/**/模式 - 堆叠查询:由
;分隔的多个语句
安全验证示例
# This query would be blocked
dangerous_sql = "SELECT * FROM users WHERE id = 1; DROP TABLE users;"
# This query would be allowed
safe_sql = "SELECT name, email FROM users WHERE department = 'sales'"
数据脱敏配置
为敏感信息配置自动数据脱敏:
内置脱敏规则
# Default masking rules
masking_rules = [
{
"column_pattern": r".*phone.*|.*mobile.*",
"algorithm": "phone_mask",
"parameters": {
"mask_char": "*",
"keep_prefix": 3,
"keep_suffix": 4
},
"security_level": "internal"
},
{
"column_pattern": r".*email.*",
"algorithm": "email_mask",
"parameters": {"mask_char": "*"},
"security_level": "internal"
},
{
"column_pattern": r".*id_card.*|.*identity.*",
"algorithm": "id_mask",
"parameters": {
"mask_char": "*",
"keep_prefix": 6,
"keep_suffix": 4
},
"security_level": "confidential"
}
]
脱敏算法
| 算法 | 描述 | 示例 |
|---|---|---|
phone_mask | 对电话号码进行脱敏 | 138****5678 |
email_mask | 对电子邮件地址进行脱敏 | j***n@example.com |
id_mask | 对身份证号码进行脱敏 | 110101****1234 |
name_mask | 对个人姓名进行脱敏 | 张*明 |
partial_mask | 按比例进行部分脱敏 | abc***xyz |
自定义脱敏规则
在配置中添加自定义脱敏规则:
# Custom masking rule
custom_rule = {
"column_pattern": r".*salary.*|.*income.*",
"algorithm": "partial_mask",
"parameters": {
"mask_char": "*",
"mask_ratio": 0.6
},
"security_level": "confidential"
}
安全配置示例
环境变量
# Generate this outside source control, then inject it into the process.
export TOKEN_SECURITY_ADMIN="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
export ENABLE_TOKEN_AUTH=true
ENABLE_MASKING=true
MAX_RESULT_ROWS=10000
BLOCKED_SQL_OPERATIONS=DROP,DELETE,TRUNCATE,ALTER
MAX_QUERY_COMPLEXITY=100
ENABLE_AUDIT=true
敏感表配置
# Configure sensitive tables with security levels
sensitive_tables = {
"user_profiles": "confidential",
"payment_records": "secret",
"employee_salaries": "secret",
"customer_data": "confidential",
"public_reports": "public"
}
安全最佳实践
- 🔑 强认证:使用具有适当过期时间的 JWT 令牌
- 🎯 最小权限原则:仅授予所需的最低权限
- 🔍 定期审计:启用审计日志以进行安全监控
- 🛡️ 输入验证:所有 SQL 查询都会自动验证
- 🎭 数据分类:使用安全级别正确分类数据
- 🔄 定期更新:保持安全规则和配置的更新
- 基于 Doris 的 OAuth 加固:使用 HTTPS,在此模式下保持外部 OAuth 禁用,保持
WORKERS=1,依赖 Doris RBAC 进行 MySQL 通道的数据访问,并且仅公开已配置并验证使用已登录 Doris 用户凭据的操作。
安全监控
系统提供全面的安全监控:
# Security audit log example
{
"timestamp": "2024-01-15T10:30:00Z",
"user_id": "analyst_user",
"action": "query_execution",
"resource": "customer_data",
"result": "blocked",
"reason": "insufficient_permissions",
"risk_level": "medium"
}
⚠️ 重要:在部署到生产环境之前,务必在开发环境中测试安全配置。根据组织的需求定期审查和更新安全策略。
连接 Cursor
您可以使用 Stdio 模式(推荐)或 Streamable HTTP 模式将 Cursor 连接到该 MCP 服务器。
Stdio 模式
Stdio 模式允许 Cursor 直接管理服务器进程。配置在 Cursor 的 MCP 服务器设置文件中完成(通常为 ~/.cursor/mcp.json 或类似文件)。
方法 1:使用 PyPI 安装(推荐)
从 PyPI 安装包并配置 Cursor 使用它:
pip install doris-mcp-server
配置 Cursor: 在您的 Cursor MCP 配置中添加类似以下条目:
{
"mcpServers": {
"doris-stdio": {
"command": "doris-mcp-server",
"args": ["--transport", "stdio"],
"env": {
"DORIS_HOST": "127.0.0.1",
"DORIS_PORT": "9030",
"DORIS_USER": "root",
"DORIS_PASSWORD": "your_db_password"
}
}
}
}
方法 2:使用 uv(开发)
如果您已安装 uv 并希望从源代码运行:
uv run --project /path/to/doris-mcp-server doris-mcp-server
注意: 将 /path/to/doris-mcp-server 替换为项目目录的实际绝对路径。
配置 Cursor: 在您的 Cursor MCP 配置中添加类似以下条目:
{
"mcpServers": {
"doris-stdio": {
"command": "uv",
"args": ["run", "--project", "/path/to/your/doris-mcp-server", "doris-mcp-server"],
"env": {
"DORIS_HOST": "127.0.0.1",
"DORIS_PORT": "9030",
"DORIS_USER": "root",
"DORIS_PASSWORD": "your_db_password"
}
}
}
}
Streamable HTTP 模式
Streamable HTTP 模式要求您先独立运行 MCP 服务器,然后配置 Cursor 连接它。
-
配置
.env: 确保数据库凭据和任何其他必要设置已在项目目录中的.env文件中正确配置。 -
启动服务器: 在项目的根目录中从终端运行服务器:
./start_server.sh此脚本读取
.env文件,并默认在127.0.0.1上启动 Streamable HTTP 服务器。非回环监听器需要至少一种 认证方法。 -
配置 Cursor: 在您的 Cursor MCP 配置中添加类似以下条目,指向正在运行的服务器的 Streamable HTTP 端点:
{ "mcpServers": { "doris-http": { "url": "http://127.0.0.1:3000/mcp" } } }注意:如果您的服务器运行在不同的地址,请调整主机/端口。
/mcp端点是统一的 Streamable HTTP 接口。
在 Cursor 中配置任一模式后,您应该能够选择服务器(例如,doris-stdio 或 doris-http)并使用其工具。
连接 Kiro
或者将以下内容添加到您的 Kiro MCP 配置文件中(~/.kiro/settings/mcp.json 用于全局,或 .kiro/settings/mcp.json 用于项目范围)。有关更多详细信息,请参阅 Kiro MCP 文档。
{
"mcpServers": {
"doris-stdio": {
"command": "doris-mcp-server",
"args": ["--transport", "stdio"],
"env": {
"DORIS_HOST": "127.0.0.1",
"DORIS_PORT": "9030",
"DORIS_USER": "root",
"DORIS_PASSWORD": "your_db_password"
}
}
}
}
目录结构
doris-mcp-server/
├── doris_mcp_server/ # Main server package
│ ├── main.py # Main entry point and FastAPI app
│ ├── multiworker_app.py # Multi-worker application module (New in v0.6.0)
│ ├── auth/ # Authentication modules (New in v0.6.0)
│ │ ├── token_manager.py # Enterprise token management with hot reload
│ │ ├── jwt_manager.py # JWT authentication provider
│ │ ├── oauth_provider.py # OAuth authentication provider
│ │ ├── oauth_handlers.py # OAuth HTTP endpoint handlers
│ │ ├── token_handlers.py # Token management HTTP endpoints
│ │ ├── auth_middleware.py # Authentication middleware
│ │ └── __init__.py
│ ├── tools/ # MCP tools implementation
│ │ ├── tools_manager.py # Centralized tools management and registration
│ │ ├── resources_manager.py # Resource management and metadata exposure
│ │ ├── prompts_manager.py # Intelligent prompt templates for data analysis
│ │ └── __init__.py
│ ├── utils/ # Core utility modules
│ │ ├── config.py # Configuration management with validation
│ │ ├── db.py # Enhanced database connection management with token binding (Enhanced in v0.6.0)
│ │ ├── query_executor.py # High-performance SQL execution with caching
│ │ ├── security.py # Advanced security management and authentication (Enhanced in v0.6.0)
│ │ ├── schema_extractor.py # Metadata extraction with catalog federation
│ │ ├── analysis_tools.py # Data analysis and performance monitoring
│ │ ├── data_governance_tools.py # Data lineage and freshness monitoring (v0.5.0)
│ │ ├── data_quality_tools.py # Comprehensive data quality analysis (v0.5.0)
│ │ ├── data_exploration_tools.py # Advanced statistical analysis (v0.5.0)
│ │ ├── security_analytics_tools.py # Access pattern analysis (v0.5.0)
│ │ ├── dependency_analysis_tools.py # Impact analysis and dependency mapping (v0.5.0)
│ │ ├── performance_analytics_tools.py # Query optimization and capacity planning (v0.5.0)
│ │ ├── adbc_query_tools.py # High-performance Arrow Flight SQL operations (v0.5.0)
│ │ ├── logger.py # Logging configuration
│ │ └── __init__.py
│ └── __init__.py
├── doris_mcp_client/ # MCP client implementation
│ ├── client.py # Unified MCP client for testing and integration
│ ├── README.md # Client documentation
│ └── __init__.py
├── logs/ # Log files directory
├── tokens.json # Token configuration file (New in v0.6.0)
├── README.md # This documentation
├── CHANGELOG.md # Tagged release history and unreleased changes
├── .env.example # Environment variables template
├── requirements.txt # Runtime-only Python dependencies
├── requirements-dev.txt # Runtime plus test and quality dependencies
├── pyproject.toml # Project configuration and entry points
├── uv.lock # UV package manager lock file
├── generate_requirements.py # Requirements generation script
├── start_server.sh # Server startup script
└── restart_server.sh # Server restart script
开发新工具
本节概述了基于统一模块化架构和集中式工具管理,向 Doris MCP 服务器添加新 MCP 工具的流程。
现有的业务 API 不需要构建到此仓库中。请将它们打包为显式安装的、已列入白名单的自定义工具提供程序。该 自定义工具提供程序指南 定义了入口 点契约、生命周期、进程本地 QPS 限制、认证边界、 FastGPT 集成和生产安全清单。
1. 利用现有工具模块
服务器为常见的数据库操作提供了全面的工具模块:
doris_mcp_server/utils/db.py:数据库连接管理,支持连接池和健康监控。doris_mcp_server/utils/query_executor.py:高性能 SQL 执行,具有高级缓存、优化和性能监控功能。doris_mcp_server/utils/schema_extractor.py:元数据提取,支持完整的目录联合。doris_mcp_server/utils/security.py:全面的安全管理、SQL 验证和数据脱敏。doris_mcp_server/utils/analysis_tools.py:高级数据分析和统计工具。doris_mcp_server/utils/config.py:带验证的配置管理。doris_mcp_server/utils/data_governance_tools.py:数据血缘追踪和新鲜度监控(v0.5.0 新增)。doris_mcp_server/utils/data_quality_tools.py:全面的数据质量分析框架(v0.5.0 新增)。doris_mcp_server/utils/adbc_query_tools.py:高性能 Arrow Flight SQL 操作(v0.5.0 新增)。
2. 实现工具逻辑
在 DorisToolsManager 中的
doris_mcp_server/tools/tools_manager.py 添加一个私有处理器。处理器名称遵循
_<tool_name>_tool;注册表会解析此名称,并在管理器构造期间验证
处理器是否存在。
示例: 添加一个新的分析工具:
# In doris_mcp_server/tools/tools_manager.py
async def _your_new_analysis_tool(
self,
arguments: dict[str, Any],
) -> dict[str, Any]:
"""
Your new analysis tool implementation
Args:
arguments: Tool arguments from MCP client
Returns:
JSON-serializable tool result
"""
try:
# Use existing utilities
result = await self.query_executor.execute_sql_for_mcp(
sql="SELECT COUNT(*) FROM your_table",
max_rows=arguments.get("max_rows", 100)
)
return result
except Exception as e:
logger.error(f"Tool execution failed: {str(e)}", exc_info=True)
return {"success": False, "error": "Analysis failed"}
3. 添加注册表定义
在
doris_mcp_server/tools/tool_catalog.py::build_tool_registry 中添加一个 Tool 模式,
然后将其策略在 doris_mcp_server/tools/tool_registry.py 中分类一次。不要添加装饰器
包装器或 if/elif 分发分支:
# In doris_mcp_server/tools/tool_catalog.py
Tool(
name="your_new_analysis_tool",
description="Description of your new analysis tool",
input_schema={
"type": "object",
"properties": {
"parameter1": {
"type": "string",
"description": "Description of parameter1"
},
"parameter2": {
"type": "integer",
"description": "Description of parameter2",
"default": 100
}
},
"required": ["parameter1"],
},
)
自定义提供方是内部能力来源,不会创建额外的顶层 MCP 工具。请将每个提供方能力集成到一个正式的域子项中,并附带支持合同、授权策略、输入/输出模式以及确定性的处理程序绑定。测试套件会拒绝公共目录漂移。
4. 高级功能
对于更复杂的工具,您可以利用全面的框架:
- 高级缓存:使用查询执行器内置的缓存来提升性能
- 企业级安全:通过安全管理器应用全面的 SQL 验证和数据脱敏
- 智能提示:使用提示管理器进行高级查询生成
- 资源管理:通过资源管理器公开元数据
- 性能监控:与分析工具集成以实现监控能力
5. 测试
使用附带的 MCP 客户端测试您的新工具:
# Using doris_mcp_client/client.py
from doris_mcp_client.client import DorisUnifiedMCPClient
async def test_new_tool():
client = DorisUnifiedMCPClient()
result = await client.call_tool("your_new_analysis_tool", {
"parameter1": "test_value",
"parameter2": 50
})
print(result)
运行发布测试门禁:
uv run pytest -q -W error
uv run coverage json -o coverage.json
uv run python test/deployment/check_coverage_domains.py coverage.json
测试套件强制要求整个仓库的覆盖率至少达到 55%。生成的覆盖率报告在协议、身份验证和核心管理器域中也需达到 80% 的最低标准,因此高风险运行时代码不能通过无关的覆盖率来隐藏。
MCP 客户端
该项目包含一个统一的 MCP 客户端(doris_mcp_client/),用于测试和集成目的。该客户端支持多种连接模式,并提供了与 MCP 服务器交互的便捷接口。
有关详细的客户端文档,请参阅 doris_mcp_client/README.md。
贡献
欢迎通过 Issues 或 Pull Requests 进行贡献。
许可证
本项目根据 Apache 2.0 许可证授权。详情请参阅 LICENSE 文件。
常见问题解答
问:为什么 Qwen3-32b 和其他小参数模型在调用工具时总是失败?
答: 这是一个常见问题。主要原因是这些模型需要更明确的指导才能正确使用 MCP 工具。建议为模型添加以下指令提示:
- 中文版本:
<instruction>
尽可能使用MCP工具完成任务,仔细阅读每个工具的注解、方法名、参数说明等内容。请按照以下步骤操作:
1. 仔细分析用户的问题,从已有的Tools列表中匹配最合适的工具。
2. 确保工具名称、方法名和参数完全按照工具注释中的定义使用,不要自行创造工具名称或参数。
3. 传入参数时,严格遵循工具注释中规定的参数格式和要求。
4. 调用工具时,根据需要直接调用工具,但参数请求参考以下请求格式:{"mcp_sse_call_tool": {"tool_name": "$tools_name", "arguments": "{}"}}
5. 输出结果时,不要包含任何XML标签,仅返回纯文本内容。
<input>
用户问题:user_query
</input>
<output>
返回工具调用结果或最终答案,以及对结果的分析。
</output>
</instruction>
- 英文版本:
<instruction>
Use MCP tools to complete tasks as much as possible. Carefully read the annotations, method names, and parameter descriptions of each tool. Please follow these steps:
1. Carefully analyze the user's question and match the most appropriate tool from the existing Tools list.
2. Ensure tool names, method names, and parameters are used exactly as defined in the tool annotations. Do not create tool names or parameters on your own.
3. When passing parameters, strictly follow the parameter format and requirements specified in the tool annotations.
4. When calling tools, call them directly as needed, but refer to the following request format for parameters: {"mcp_sse_call_tool": {"tool_name": "$tools_name", "arguments": "{}"}}
5. When outputting results, do not include any XML tags, return plain text content only.
<input>
User question: user_query
</input>
<output>
Return tool call results or final answer, along with analysis of the results.
</output>
</instruction>
如果您对返回结果有进一步的要求,可以在 <output> 标签中描述具体要求。
问:如何配置不同的数据库连接?
答: 您可以通过以下几种方式配置数据库连接:
-
环境变量(推荐):
export DORIS_HOST="your_doris_host" export DORIS_PORT="9030" export DORIS_USER="root" export DORIS_PASSWORD="your_password" -
命令行参数:
doris-mcp-server --db-host your_host --db-port 9030 --db-user root --db-password your_password -
配置文件: 修改
.env文件中的相应配置项。
问:如何为监控工具配置 BE 节点?
答: 当代理、隧道或拆分网络在不同地址暴露 SQL、FE HTTP 和 BE HTTP 端点时,请独立配置它们:
# SQL/MySQL protocol endpoint
DORIS_HOST=sql-gateway.internal
DORIS_HOSTS=sql-gateway.internal,fe-2.internal,fe-3.internal
DORIS_PORT=9030
# FE HTTP endpoint; omit DORIS_FE_HTTP_HOST to reuse DORIS_HOST
DORIS_FE_HTTP_HOST=fe-http-proxy.internal
DORIS_FE_HTTP_HOSTS=fe-http-proxy.internal,fe-2.internal,fe-3.internal
DORIS_FE_HTTP_PORT=8030
# Explicit BE HTTP allowlist
DORIS_BE_HOSTS=10.1.1.100,10.1.1.101,10.1.1.102
DORIS_BE_WEBSERVER_PORT=8040
BE HTTP 端点绝不会从 SHOW BACKENDS 推断:SQL 元数据不是出站 HTTP 允许列表。如果 DORIS_BE_HOSTS 为空,则禁用 BE HTTP 指标。DORIS_FE_HTTP_HOST 仅出于向后兼容性回退到 DORIS_HOST;显式值用于每个 FE 监控、配置文件、跟踪和表大小 HTTP 请求。FE 和 BE 请求仅使用配置的主机和端口,为每个请求固定验证后的 DNS 结果,拒绝元数据/链路本地目标,禁用重定向,并强制执行连接/读取/总超时以及响应字节限制。私有地址和环回地址仍可用于正常的内部 Doris 部署和 SSH 隧道。
DORIS_HOSTS 和 DORIS_FE_HTTP_HOSTS 是有序的故障转移列表,而非负载均衡或集群发现设置。一个列表中的每个主机必须属于同一个 Doris 集群,并使用配置的共享端口和凭据。服务器在全局/静态令牌池创建和恢复期间按顺序探测候选者;FE HTTP 请求仅在传输错误或 502/503/504 时移动到下一个配置的端点。Doris 支持的 OAuth 在登录期间尝试候选者,但失败后无法重建已建立的每用户池,因为服务器有意不保留用户的原始密码;用户必须重新登录。对于大型生产部署,仍建议使用稳定的负载均衡器或 SQL 网关。
问:如何将 SQL Explain/Profile 文件与 LLM 结合用于优化?
答: 这些工具为 LLM 分析提供截断内容和完整文件:
-
获取分析结果:
{ "content": "Truncated plan for immediate review", "file_path": "/tmp/explain_12345.txt", "is_content_truncated": true } -
LLM 分析工作流程:
- 查看截断内容以快速获取见解
- 将完整文件作为附件上传到您的 LLM
- 请求优化建议或性能分析
- 实施推荐的改进
-
配置内容大小:
MAX_RESPONSE_CONTENT_SIZE=4096 # Adjust as needed
问:如何启用数据安全和脱敏功能?
答: 在您的 .env 文件中设置以下配置:
# Enable data masking
ENABLE_MASKING=true
# Set maximum result rows
MAX_RESULT_ROWS=10000
问:Stdio 模式和 HTTP 模式有什么区别?
答:
- Stdio 模式:适用于与 MCP 客户端(如 Cursor)直接集成,客户端管理服务器进程
- HTTP 模式:独立的 Web 服务,支持多个客户端连接,适用于生产环境
建议:
- 开发和个⼈使用:Stdio 模式
- 生产环境和多用户环境:HTTP 模式
问:如何解决连接超时问题?
答: 尝试以下解决方案:
-
增加超时设置:
# Set in .env file QUERY_TIMEOUT=60 CONNECTION_TIMEOUT=30 -
检查网络连接:
# /live verifies the process; /ready also verifies Doris curl --fail http://localhost:3000/live curl --fail http://localhost:3000/ready -
优化连接池配置:
DORIS_MAX_CONNECTIONS=20
问:如何解决 at_eof 连接错误?(已在 v0.5.0 中完全修复)
答: 版本 0.5.0 通过全面的连接池重新设计完全解决了关键的 at_eof 连接错误:
问题:
- 由于连接池预创建和不当的连接状态管理,导致
at_eof错误 - MySQL aiomysql 读取器状态在连接生命周期中变得不一致
- 并发负载下连接池不稳定
解决方案(v0.5.0):
-
连接池策略全面改革:
- 零最小连接:将
min_connections从默认值更改为 0,以防止预创建问题 - 按需创建连接:仅在需要时创建连接,消除陈旧连接问题
- 全新连接策略:始终从池中获取全新连接,不进行会话级缓存
- 零最小连接:将
-
增强的健康监控:
- 基于超时的健康检查:连接验证查询 3 秒超时
- 后台健康监控器:每 30 秒持续监控池健康状态
- 主动陈旧检测:自动检测并清理问题连接
-
智能恢复系统:
- 自动池恢复:具有全面错误处理的自愈池
- 指数退避重试:智能重试机制,最多 3 次尝试
- 连接特定错误检测:精确识别与连接相关的错误
-
性能优化:
- 池预热:智能连接池预热以获得最佳性能
- 后台清理:定期清理陈旧连接,不影响活动操作
- 连接诊断:实时连接健康监控和报告
监控连接健康:
# Monitor connection pool health in real-time
tail -f logs/doris_mcp_server_info.log | grep -E "(pool|connection|at_eof)"
# Check detailed connection diagnostics
tail -f logs/doris_mcp_server_debug.log | grep "connection health"
# Check process liveness and Doris readiness
curl --fail http://localhost:8000/live
curl --fail http://localhost:8000/ready
最佳连接性能配置:
# Recommended connection pool settings in .env
DORIS_MAX_CONNECTIONS=20 # Adjust based on workload
CONNECTION_TIMEOUT=30 # Connection establishment timeout
QUERY_TIMEOUT=60 # Query execution timeout
# Health monitoring settings
HEALTH_CHECK_INTERVAL=60 # Pool health check frequency
结果:重新设计的生命周期减少了陈旧连接故障并改善了恢复行为。在生产使用前,请在目标工作负载下验证配置的池。
问:支持哪些 MCP 协议修订版本?
答: 新的集成应使用 MCP 2026-07-28。Doris MCP Server 通过 stdio 接受 2025-11-25 初始化流程,并在 ENABLE_LEGACY_HTTP_ADAPTER=true 时,在隔离的 /mcp/legacy HTTP 端点接受。现代 /mcp 端点仅支持 POST,且永远不会回退到旧版传输。较旧的修订版本和已退役的 HTTP+SSE 传输不属于支持兼容性合同的一部分。
不要从 Doris MCP Server 包版本或 Python mcp 依赖版本推断线协议支持。请参阅 MCP 协议支持与迁移 了解请求元数据、HTTP 头、迁移步骤和部署限制。
问:如何启用 ADBC 高性能功能?(v0.5.0 新增)
答: ADBC(Arrow Flight SQL)为大型数据集提供 3-10 倍的性能提升:
-
ADBC 依赖(v0.5.0+ 自动包含):
# ADBC dependencies are now included by default in doris-mcp-server>=0.5.0 # No separate installation required -
配置 Arrow Flight SQL 端口:
# Add to your .env file FE_ARROW_FLIGHT_SQL_PORT=8096 BE_ARROW_FLIGHT_SQL_PORT=8097 -
可选的 ADBC 自定义:
# Customize ADBC behavior (optional) ADBC_DEFAULT_MAX_ROWS=10000 ADBC_DEFAULT_TIMEOUT=120 ADBC_DEFAULT_RETURN_FORMAT=pandas # arrow/pandas/dict -
测试 ADBC 连接:
# Discover doris_query, then call its get_adbc_connection_info child # Should show "status": "ready" and port connectivity
问:如何使用数据治理和管道工具?
答: 首先发现相关域,保留其 manifest_version,然后使用模式有效参数调用确切的子项:
列分析:
{
"tool_name": "doris_governance",
"arguments": {
"child_tool": "analyze_columns",
"manifest_version": "<value returned by domain discovery>",
"arguments": {
"database": "analytics",
"table": "customer_data",
"sample_ratio": 0.1
}
}
}
列血缘跟踪:
{
"tool_name": "doris_governance",
"arguments": {
"child_tool": "trace_column_lineage",
"manifest_version": "<value returned by domain discovery>",
"arguments": {
"object": "internal.analytics.orders",
"column": "customer_id",
"direction": "both",
"depth": 3
}
}
}
数据新鲜度监控:
{
"tool_name": "doris_pipeline",
"arguments": {
"child_tool": "monitor_data_freshness",
"manifest_version": "<value returned by domain discovery>",
"arguments": {
"database": "analytics",
"table": "orders",
"threshold_seconds": 86400
}
}
}
性能分析:
{
"tool_name": "doris_query",
"arguments": {
"child_tool": "list_slow_queries",
"manifest_version": "<value returned by domain discovery>",
"arguments": {
"window_minutes": 10080,
"limit": 20
}
}
}
问:如何使用增强的日志系统?(v0.5.0 改进)
答: 版本 0.5.0 引入了全面的日志系统,具有自动管理和基于级别的组织:
日志文件结构(v0.5.0 新增):
logs/
├── doris_mcp_server_debug.log # DEBUG level messages
├── doris_mcp_server_info.log # INFO level messages
├── doris_mcp_server_warning.log # WARNING level messages
├── doris_mcp_server_error.log # ERROR level messages
├── doris_mcp_server_critical.log # CRITICAL level messages
├── doris_mcp_server_all.log # Combined log (all levels)
└── doris_mcp_server_audit.log # Audit trail (separate)
增强的日志功能:
- 基于级别的文件分离:按日志级别自动组织,便于故障排除
- 时间戳格式:毫秒精度,适当对齐,实现专业日志记录
- 自动日志轮转:通过可配置的文件大小限制防止磁盘空间问题
- 后台清理:智能清理调度器,具有可配置的保留策略
- 审计跟踪:单独的审计日志,用于合规性和安全监控
查看日志:
# View real-time logs by level
tail -f logs/doris_mcp_server_info.log # General operational info
tail -f logs/doris_mcp_server_error.log # Error tracking
tail -f logs/doris_mcp_server_debug.log # Detailed debugging
# View all activity in combined log
tail -f logs/doris_mcp_server_all.log
# Monitor specific operations
tail -f logs/doris_mcp_server_info.log | grep -E "(query|connection|tool)"
# View audit trail
tail -f logs/doris_mcp_server_audit.log
配置:
# Enhanced logging configuration in .env
LOG_LEVEL=INFO # Base log level
ENABLE_AUDIT=true # Enable audit logging
ENABLE_LOG_CLEANUP=true # Enable automatic cleanup
LOG_MAX_AGE_DAYS=30 # Keep logs for 30 days
LOG_CLEANUP_INTERVAL_HOURS=24 # Check for cleanup daily
# Advanced settings
LOG_FILE_PATH=logs # Log directory (auto-organized)
使用增强日志进行故障排除:
# Debug connection issues
grep -E "(connection|pool|at_eof)" logs/doris_mcp_server_error.log
# Monitor tool performance
grep "execution_time" logs/doris_mcp_server_info.log
# Check system health
tail -20 logs/doris_mcp_server_warning.log
# View recent critical issues
cat logs/doris_mcp_server_critical.log
日志清理管理:
- 自动:后台调度器删除超过
LOG_MAX_AGE_DAYS的文件 - 手动:日志达到 10MB 时自动轮转
- 备份:每个日志级别保留 5 个备份文件
- 性能:对服务器性能影响最小
问:如何使用新的令牌绑定数据库配置?(v0.6.0 新增)
答: 革命性的令牌绑定数据库配置允许每个令牌携带自己的数据库连接参数,以实现安全的多租户访问:
-
启用令牌身份验证:
# In your .env file ENABLE_TOKEN_AUTH=true TOKEN_HOT_RELOAD=true TOKEN_FILE_PATH=tokens.json -
创建一次承载令牌,并仅在 tokens.json 中存储其摘要:
{ "version": "2.0", "tokens": [ { "token_id": "tenant-alpha", "token_digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000", "created_at": "2026-07-29T00:00:00Z", "expires_at": null, "last_used": null, "description": "Tenant Alpha database access", "is_active": true, "database_config": { "host": "tenant-alpha-db.company.com", "hosts": [ "tenant-alpha-fe-1.company.com", "tenant-alpha-fe-2.company.com" ], "port": 9030, "user": "alpha_user", "password": "secure_password", "database": "alpha_analytics", "charset": "UTF8", "fe_http_hosts": [ "tenant-alpha-fe-1.company.com", "tenant-alpha-fe-2.company.com" ], "fe_http_port": 8030 } } ] }使用 令牌绑定数据库配置 中的命令生成真实的承载令牌和摘要。 上述全零值故意不可用。将承载值一次性提供给客户端;不要将其放入文件中。
-
配置优先级(v0.6.0 新增):
- 令牌绑定数据库配置(最高优先级)
- 环境变量(.env)
- 如果两者均不可用则报错
-
热重载优势:
- 无需重启服务即可添加新租户
- 实时更新数据库凭据
- 自动验证和错误回滚
- 完整的变更审计跟踪
-
多租户使用:
# Different tokens access different databases automatically curl -H "Authorization: Bearer $TOKEN_TENANT_ALPHA" http://localhost:3000/mcp curl -H "Authorization: Bearer $TOKEN_TENANT_BETA" http://localhost:3000/mcp
每个令牌可绑定不同的 Doris 集群。在同一个令牌绑定内,
hosts 和 fe_http_hosts 是该同一集群的有序 FE 候选。
经过身份验证的令牌固定路由;MCP 工具参数无法选择
或覆盖另一个集群。此多实例模式要求使用 HTTP
传输并采用静态令牌认证。stdio 进程只有一个全局
数据库路由,因此当客户端需要不同集群时,请运行独立的 stdio 进程。
exec_adbc_query 在令牌绑定路由上刻意采用故障关闭策略,
因为当前的 Arrow Flight 客户端是进程全局的;请使用
doris_query.execute_query 或为该集群运行单独的 MCP 进程。
问:Doris 支持的 OAuth 与外部 OAuth/OIDC 有何不同?
答: 外部 OAuth/OIDC 将身份验证委托给外部提供商,如 Google、Azure AD、GitHub、GitLab 或 Keycloak。Doris 支持的 OAuth 由本 MCP 服务器在用户使用 Doris 凭据登录后签发。服务器验证 Doris 用户名/密码,创建每用户 Doris 连接池,签发 doa_ 访问令牌和刷新令牌,并让 Doris RBAC 决定该用户可以访问哪些数据和元数据。
这两种模式在同一个 MCP URL 上互斥。不要将 ENABLE_DORIS_OAUTH_AUTH=true 与 ENABLE_OAUTH_AUTH=true、OAUTH_ENABLED=true 或 AUTH_TYPE=oauth 一起启用;如果同时配置了两种 OAuth 模式,启动时会快速失败。
Doris 支持的 OAuth 当前以禁用资源元数据缓存的方式暴露 MCP 资源。当 DORIS_OAUTH_DB_TOOLS_ENABLED=true 时暴露已审核的元数据工具,当 DORIS_OAUTH_QUERY_TOOLS_ENABLED=true 时暴露 exec_query,当 DORIS_OAUTH_EXPLAIN_TOOLS_ENABLED=true 时暴露 SQL 解释。普通客户端无需传递冗长的作用域列表;省略 OAuth 作用域将授予配置的 Doris OAuth 能力包。Doris RBAC 仍然是这些 MySQL 通道操作的最终数据授权后端。
问:Doris 支持的 OAuth 能否与多个工作进程或多个节点一起运行?
答: 当前实现中不能。Doris 支持的 OAuth 使用仅内存的 OAuth 存储和进程本地的每用户 Doris 池。访问令牌、刷新令牌、授权码、DCR 客户端和池不会在工作进程、进程或节点之间共享。
请将 WORKERS=1 与 Doris 支持的 OAuth 一起使用。WORKERS=0 会扩展到 CPU 数量并失败,因为它会创建多个有效工作进程。无状态水平扩展、共享令牌存储、共享加密 Doris 凭据、粘性会话恢复和池重建是未来设计,而非当前能力。
问:热重载如何工作,它安全吗?(v0.6.0 新增)
答: 热重载系统专为企业生产环境设计,并具备全面的安全措施:
工作原理:
- 请求时同步:每次令牌查找都会比较共享 文件签名,因此另一个本地工作进程的创建或撤销会在 下一个经过身份验证的请求时被观察到,而无需等待轮询间隔
- 后台监控:10 秒监控器仍会刷新空闲工作进程
- 串行化更新:
tokens.json.lock保护每个受管理的 跨本地工作进程的读-修改-写操作 - 原子更新:同目录临时文件被刷新并以仅所有者权限 原子替换
- 回滚保护:无效的外部编辑状态不会部分 替换工作进程当前的内存视图
- 共享撤销:
revoked_tokens仅存储令牌摘要,并且还会 在每个工作进程中禁用匹配的TOKEN_<ID>环境凭据
安全特性:
- 无丢失更新:并发创建/撤销操作在持有进程共享锁时 重新加载最新文档
- 无持有者令牌明文持久化:活动及已撤销的持有者值 仅以自描述摘要表示
- 仅所有者状态文件:受管状态和锁文件使用模式
0600 - 错误隔离:无效状态在替换完整本地令牌映射之前被拒绝
最佳实践:
# Monitor hot reload activity
tail -f logs/doris_mcp_server_info.log | grep "hot reload"
# Test configuration before applying
cp tokens.json tokens.json.backup
# Make changes to tokens.json
# System will automatically validate and apply or rollback
问:如何管理令牌生命周期和安全性?(v0.6.0 新增)
答: 令牌管理采用基于文件的安全方法,并带有可选的管理端点,这些端点具有全面的安全控制。
主要令牌管理方法(推荐):
# 1. Keep the management endpoint disabled unless local administration is needed.
# 2. When enabled, create a token through the protected localhost endpoint.
curl -X POST \
-H "Authorization: Bearer $TOKEN_MANAGEMENT_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
--data '{"token_id":"service-a","expires_hours":720}' \
http://127.0.0.1:3000/token/create
# 3. Capture the returned bearer token once and place it in the client secret store.
# 4. The server writes only token_digest to tokens.json.
# 5. Monitor hot reload in logs.
tail -f logs/doris_mcp_server_info.log | grep "hot reload"
对于没有 HTTP 令牌管理的部署,请使用高熵 TOKEN_<ID>
环境密钥,或如上所示离线生成持有者/摘要对。手动
tokens.json 条目必须使用 token_digest;明文 token 条目
仅用于从版本 1 进行单向迁移。
文件后端协调同一主机上的多个工作进程。每个
工作进程必须使用相同的 TOKEN_FILE_PATH,并且底层文件系统必须
提供可靠的文件锁定和原子重命名语义。多个主机或
没有共享锁定文件系统的容器需要外部
事务性状态后端;复制单独的 tokens.json 文件无法
提供集群范围的撤销。
管理端点(安全,仅限本地访问):
🛡️ 安全:这些端点受全面安全控制保护,并且默认禁用。
# Security Requirements (ALL must be met):
# ✓ HTTP token management explicitly enabled in configuration
# ✓ Access only from localhost (127.0.0.1/::1) - IP restrictions enforced
# ✓ Valid admin authentication token required
# ✓ Admin authentication enabled in configuration
# Enable HTTP token management (disabled by default)
export TOKEN_MANAGEMENT_ADMIN_TOKEN="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
export ENABLE_HTTP_TOKEN_MANAGEMENT=true
export REQUIRE_ADMIN_AUTH=true
export TOKEN_MANAGEMENT_ALLOWED_IPS=127.0.0.1,::1
# Access with proper authentication
curl -H "Authorization: Bearer $TOKEN_MANAGEMENT_ADMIN_TOKEN" http://127.0.0.1:3000/token/stats
# Demo page (local access only, with authentication)
# Access: http://127.0.0.1:3000/token/demo
推荐的令牌管理工作流:
-
开发/测试:
// tokens.json { "version": "2.0", "tokens": [ { "token_id": "dev-token", "token_digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000", "created_at": "2026-07-29T00:00:00Z", "expires_at": "2026-07-30T00:00:00Z", "last_used": null, "description": "Development environment access", "is_active": true } ] }将全零摘要替换为从安全生成的持有者令牌派生的摘要, 并将该持有者令牌保存在服务器文件之外。
-
生产部署:
# Use secure token generation openssl rand -hex 32 # Generate secure token # Store in secure configuration management # Never commit tokens to version control # Use environment variables for sensitive tokens
安全特性:
- 仅摘要持久化:持有者明文仅在创建时返回; 版本 2 文件包含自描述的 SHA-256/SHA-512 摘要
- 原子文件管理:受管写入使用同目录替换并
强制仅所有者
0600权限 - 热重载:无需中断服务即可自动更新配置
- 旧版迁移:版本 1 明文条目在首次成功加载时 被仅摘要记录替换
- 审计跟踪:完整记录所有令牌操作和更改
- 过期管理:自动清理过期令牌
- 仅限本地管理:管理端点限制为 localhost 访问
- 配置验证:立即验证令牌和数据库配置
安全最佳实践:
- 将持有者值存储在客户端密钥管理中;服务器上仅保留摘要
- 切勿将令牌管理端点暴露给外部网络
- 对生产环境使用强随机生成的令牌
- 保持手动管理的
tokens.json文件仅所有者可读;受管写入 强制0600 - 定期审计活动令牌及其使用模式
- 监控热重载日志以发现未经授权的配置更改
对于其他问题,请查看 GitHub Issues 或提交新问题。