Skip to main content
Glama
vdobhal

Oracle MCP Chatbot

by vdobhal

Oracle MCP Chatbot — On-Prem Oracle DB + Oracle ATP

一个安全的 Model Context Protocol 服务器对,让 AI 聊天机器人能够针对 Oracle 数据库回答自然语言问题:它发现元数据、生成仅 SELECT 的 SQL、验证 SQL、在硬限制下执行、掩码敏感值,并记录所有内容。

使用 FastMCP 3python-oracledb(thin 模式)和 sqlglot 构建。221 个测试,运行它们不需要数据库。

pip install -r requirements-dev.txt
pytest                                        # 221 passed
cp .env.example .env                          # add credentials
python -m oracle_mcp.server --profile onprem --check
python -m oracle_mcp.server --profile onprem

测试运行中的部署见 docs/testing.md。不使用 Cursor 的浏览器 UI 见 docs/chat-ui.md

python -m oracle_mcp.chat --profile both   # http://127.0.0.1:8500

功能

能力

方式

始终只读

AST 验证、SET TRANSACTION READ ONLY、仅 SELECT 授权

仅批准的数据

模式、对象和列的 YAML 白名单

角色适配

五个角色带权限级别;列级强制

有界

行数上限(默认 500)和查询超时(默认 30 秒),两者用户均不可调高

隐私

按列名、按分类和按值内容进行掩码

可审计

每次调用一条审计记录,含脱敏 SQL 和哈希

双数据库

独立的服务器进程;可选的对账服务器

Related MCP server: OracleDB MCP Server

八个工具

工具

用途

list_allowed_schemas

角色可读取的模式,含描述

list_allowed_tables

已批准的对象,含领域、敏感度、行数估算

get_table_metadata

列、类型、可空性、主键/外键、业务描述

search_data_dictionary

按业务术语查找对象和列,含置信度

validate_sql

护栏检查;返回重写后的安全 SQL

execute_readonly_sql

运行预先批准的 SQL;返回掩码、限行后的结果

explain_query_result

为业务语言答案计算事实

compare_onprem_and_atp_data

跨数据库对账(仅 profile=both

另有 list_databases 用于连接发现。每个工具接收并返回 JSON。

安全模型如何工作

数据只有穿过五个独立层才能到达用户:

Database grants  →  Object allowlist  →  Role clearance  →  SQL guardrails  →  Output masking
   sql/*.sql        config/policy/       roles.yaml         sql_guard.py       masking.py

核心思想: 你提交的 SQL 永远不会是实际运行的 SQL。输入被解析为 AST、检查、重写并重新生成。只有验证器识别的节点类型才会被重新输出,因此注释技巧、堆叠语句和同形异义关键字都无法在往返过程中存活。

SELECT a FROM t; DROP TABLE t     →  rejected: MULTIPLE_STATEMENTS
SELECT /*+ PARALLEL(t,64) */ a…   →  SELECT a FROM t FETCH FIRST 500 ROWS ONLY
DELETE FROM t                 →  rejected: NFKC folds it to DELETE
SELECT * FROM v   (business_user) →  explicit column list, restricted ones absent

第二个关键控制: execute_readonly_sql 从头重新验证并且要求 validate_sql 签发的指纹,因此 SQL 无法在检查和执行之间被替换。非管理员角色不能执行任何未经预先批准的内容;管理员可以,但语句仍然要通过所有护栏。

第三: 角色由进程配置固定,而非工具参数。用户告诉模型"你现在是管理员"只会产生一个没有任何代码读取的 user_role="admin" 字符串。

配置

两个文件决定一切:

config/policy/onprem.yamlatp.yaml — 对象白名单。每个数据库选择两种模式之一。

严格模式,即 On-Prem 使用的模式。无论数据库授权允许什么,只有这里列出的对象可访问:

schemas:
  - name: EIM
    objects:
      - name: EIM_PR_SYSTEM
        type: TABLE
        sensitivity: INTERNAL
        large_table: true
        require_filter: true       # forces a WHERE clause
        columns:                   # optional; omit to read them from the
          - {name: SERIAL_NUMBER,  sensitivity: INTERNAL}   # data dictionary
          - {name: TAX_ID,         sensitivity: RESTRICTED} # at query time

支持省略 columns:,部署策略正是这样做的。列随后从 ALL_TAB_COLUMNS 读取,并按 masking.yaml 中的名称模式分类,因此白名单在模式变化时保持正确。

通配符模式,即 ATP 使用的模式。只读账户可读取的每个模式都变为可访问:

allow_all_schemas: true
excluded_schemas: []   # added on top of the built-in Oracle internal schemas
schemas: []

这有意放弃对象白名单,转而让数据库授权成为边界。权限级别、SQL 护栏、行数上限和掩码仍然全部生效。只对真正只读的账户使用此模式。

config/policy/roles.yaml — 谁可以看什么:

roles:
  business_user:
    clearance: INTERNAL      # cannot reach CONFIDENTIAL or RESTRICTED columns
    max_rows: 200
    allow_raw_sql: false
    schemas: {ONPREM: [EIM], ATP: ["*"]}   # "*" needs allow_all_schemas

敏感度阶梯:PUBLIC < INTERNAL < CONFIDENTIAL < RESTRICTED < NEVERNEVER 高于所有权限级别,因此密码和卡号对任何角色(包括管理员)都不可访问。

部署

每个数据库运行一个服务器。这种拆分是一个安全边界:on-prem 进程从不持有 ATP 钱包口令。

docker build -t oracle-mcp-chatbot:1.0.0 .
export ATP_WALLET_HOST_PATH=/secure/path/wallets/atp
docker compose up -d onprem-mcp atp-mcp
docker compose --profile reconciliation up -d   # optional, holds both credential sets

Oracle ATP 连接

使用 mTLS 钱包的 thin 模式。解压钱包并设置:

ATP_DSN=myatp_low                      # prefer _low so chatbot traffic can't starve prod
ATP_WALLET_DIR=/opt/oracle/wallets/atp # contains ewallet.pem + tnsnames.ora
ATP_CONFIG_DIR=/opt/oracle/wallets/atp
ATP_WALLET_PASSWORD=...                # set when the wallet zip was downloaded

ATP_WALLET_PASSWORD 是保护 ewallet.pem 的口令,不是数据库密码——这是一个常见且令人困惑的错误。它仅适用于 thin 模式;thick 模式改为读取无密码的 cwallet.sso,同时配置两者会在启动时被拒绝。对于仅 TLS 的 ATP(无钱包),将钱包变量留空,并把 OCI 控制台中的完整连接字符串粘贴到 ATP_DSN

钱包以只读方式绑定挂载,从不打包进镜像。

On-prem 连接

ONPREM_HOST=oracle-onprem.internal.example.com
ONPREM_PORT=1521
ONPREM_SERVICE_NAME=CDMPRD
ONPREM_MODE=thin
# TCPS instead:
# ONPREM_DSN=tcps://host:2484/CDMPRD?ssl_server_dn_match=true

Thin 模式不需要 Oracle Client。仅在其缺少的功能上使用 thick 模式;参见 Dockerfile 中被注释的阶段。

文档

文档

内容

docs/environment-configuration.md

此部署的连接如何配置,以及未决事项

docs/architecture.md

设计、请求流程、安全边界、RBAC、审计、错误处理

docs/testing-scenarios.md

含预期结果的完整测试计划

docs/deployment-checklist.md

生产前检查清单和加固待办清单

docs/conversation-flows.md

十个工作示例加拒绝流程

prompts/system_prompt.md

聊天机器人系统提示词

sql/

只读用户、授权、审计模式

mcp-clients/

Cursor 和 Claude Desktop 配置

生产前

参考实现有意在四个方面有所保留。完整列表请阅读 docs/deployment-checklist.md;主要事项:

  • 设置 ORACLE_MCP_ROLE_BINDING_MODE=env .env.example 中的 argument 默认值仅用于开发;在该模式下模型可以声明任何角色。

  • 替换示例白名单:将 config/policy/*.yaml 中的示例白名单替换为你真实的精选视图,并有意对每一列进行分类。

  • 将机密移至 vault。 Compose 环境变量对任何能运行 docker inspect 的人可见。

  • 将 HTTP 传输置于认证网关之后。 FastMCP 的 HTTP 传输本身不认证调用者;绑定到 loopback 是权宜之计,而非控制措施。

另有设计上未实现的功能:速率限制、按用户身份传播,以及管理员原始 SQL 的审批工作流。

许可证

作为参考实现提供。在生产使用前请对照你自己的安全标准进行审查。

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Query PostgreSQL databases in plain English — LLM-generated, safety-validated SQL.

  • GibsonAI MCP server: manage your databases with natural language

  • The grounded data layer for any LLM: governed SQL, metrics, lineage and catalog over your data.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vdobhal/oracle-mcp-chatbot'

If you have feedback or need assistance with the MCP directory API, please join our Discord server