Atlas / MCP servers / apache / Doris

DorisBLOCK

mcp/apache/doris-2

Apache Doris MCP Server

Verdict
BLOCK
Grade
D
Trust score
62 /100
Exposed tools
33 32r · 1w · 0d
Transport
stdio · streamable-http
License
Apache-2.0
Stars
348
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

English | 简体中文

Apache Doris MCP Server exposes read-only Apache Doris capabilities to MCP Hosts and AI agents over MCP 2026-07-28. Version 1.0 replaces a large flat tool surface with eight stable domains and fifty-five progressively disclosed child capabilities, while keeping runtime availability, authorization, input schemas, output schemas, and failure behavior explicit.

Release status

The package version is 1.0.0. MCP 2026-07-28 protocol compatibility on master is Generally Available (GA) on Streamable HTTP and stdio. This GA statement is scoped to protocol compatibility; the Python package classifier remains Beta, and the documented deployment limits still apply.

Before upgrading, read the 1.0 release notes, the 1.0 migration guide, and the generated 8-domain/55-child registry. The detailed release record is Issue #189.

Architecture at a glance

MCP Host
-> stdio or Streamable HTTP
-> transport security and authentication
-> MCP protocol validation and authorization
-> stabl
Read from source at commit 4f1936516936OBSERVED · 2026-10-03
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code
claude mcp add doris-mcp-server --env ALLOW_UNAUTHENTICATED_NON_LOOPBACK=${ALLOW_UNAUTHENTICATED_NON_LOOPBACK} --env AUTH_TYPE=${AUTH_TYPE} --env BLOCKED_KEYWORDS=${BLOCKED_KEYWORDS} --env DEFAULT_TOKEN_EXPIRY_HOURS=${DEFAULT_TOKEN_EXPIRY_HOURS} -- uvx doris-mcp-server
claude-desktop
{
  "mcpServers": {
    "doris-mcp-server": {
      "command": "uvx",
      "args": [
        "doris-mcp-server"
      ],
      "env": {
        "ALLOW_UNAUTHENTICATED_NON_LOOPBACK": "${ALLOW_UNAUTHENTICATED_NON_LOOPBACK}",
        "AUTH_TYPE": "${AUTH_TYPE}",
        "BLOCKED_KEYWORDS": "${BLOCKED_KEYWORDS}",
        "DEFAULT_TOKEN_EXPIRY_HOURS": "${DEFAULT_TOKEN_EXPIRY_HOURS}"
      }
    }
  }
}
03

Exposed tools (33)

32 read · 1 write · 0 destructive.

ToolRiskDescription
analyze_columnsread
analyze_data_access_patternsread
analyze_data_flow_dependenciesread
analyze_resource_growth_curvesread
analyze_slow_queries_topnread
analyze_table_storageread
array_outputreadExercise non-object 2026-07-28 structured content.
bad_outputreadExercise server output-schema enforcement.
echoreadVerify process recovery after schema errors.
exec_querywrite
failreadReturn a model-readable tool error.
foxtrotreadnew item invalidates the snapshot
get_adbc_connection_inforead
get_catalog_listread
get_db_listread
get_db_table_listread
get_memory_statsread
get_monitoring_metricsread
get_recent_audit_logsread
get_sql_explainread
get_sql_profileread
get_table_basic_inforead
get_table_column_commentsread
get_table_commentread
get_table_data_sizeread
get_table_indexesread
get_table_schemaread
monitor_data_freshnessread
schema_guardreadExercise full JSON Schema 2020-12 input validation.
select_rowsreadSelect rows by identifier or name.
test_missing_capabilityreadExercise the required-client-capability boundary.
trace_column_lineageread
unclassified_toolreadUnclassified
04

Trust audit

BLOCKgrade D · trust 62/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (1 observation(s))
Network
declared (14 observation(s))
Shell
none-observed
Dependencies
not all pinned
Secrets in source
found

Findings (24)

HIGHNetwork egress · net.metadata_ip · CWE-200, CWE-319
doris_mcp_server/utils/doris_http_client.py:42
"metadata.google.internal",
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
HIGHNetwork egress · net.metadata_ip · CWE-200, CWE-319
doris_mcp_server/utils/doris_http_client.py:49
ipaddress.ip_address("169.254.169.254"),
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
doris_mcp_server/utils/query_executor.py:927
self.logger.debug(f"Using provided auth_context with token: {bool(hasattr(auth_context, 'token') and auth_context.token)}")
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
.env.example:730
#    curl -X POST http://127.0.0.1:3000/token/create
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
.env.example:734
#    curl -H "Authorization: Bearer $TOKEN_MANAGEMENT_ADMIN_TOKEN" http://127.0.0.1:3000/token/stats
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
Dockerfile:67
http://127.0.0.1:3000/live || exit 1
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
test/protocol/test_mcp_v2_protocol.py:605
secret = "must-not-echo-schema-secret"
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
test/protocol/test_mcp_v2_protocol.py:1318
secret = "stdio-secret-sec-016"
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
test/protocol/test_mcp_v2_protocol.py:1522
secret = "must-not-echo-stdio-schema-secret"
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
test/protocol/test_multiworker_config.py:466
secret = "test-shared-state-handle-secret-value"
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
test/protocol/test_protocol_pagination.py:291
secret = "pagination-shared-state-handle-secret-value"
LOWInventory / provenance · inv.hidden_file · CWE-1104
.asf.yaml
.asf.yaml
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.licenserc.yaml
.licenserc.yaml
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
test/deployment/test_github_actions_contract.py:38
return yaml.load(WORKFLOW_PATH.read_text(encoding="utf-8"), Loader=yaml.BaseLoader)
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
test/protocol/stdio_capability_server.py:164
fe_http_host="169.254.169.254",
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
test/protocol/test_mcp_v2_protocol.py:1258
assert fe_result["node_info"]["host"] == "169.254.169.254"
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
test/protocol/test_mcp_v2_protocol.py:1744
assert fe_result["node_info"]["host"] == "169.254.169.254"
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
.github/workflows/ci.yml:205
--url http://127.0.0.1:39124/mcp \
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
README.md:117
- MCP: `POST http://127.0.0.1:3000/mcp`
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
doris_mcp_server/state_handles.py:140
decoded = base64.b64decode(
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
requirements-dev.txt
bandit, mypy, pandas-stubs, pytest, pytest-asyncio, pytest-cov, pytest-mock, pytest-xdist
Why it matters. 10 requirement(s) not pinned with ==
Fix. pin exact versions
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
requirements.txt
mcp, aiomysql, PyMySQL, adbc-driver-manager, adbc-driver-flightsql, pyarrow, asyncio-mqtt, aiofiles
Why it matters. 39 requirement(s) not pinned with ==
Fix. pin exact versions
LOWPrompt injection · prompt.credential_read · CWE-94, CWE-1427
CHANGELOG.md:96
allowlist. Doris administrative, export, load, plugin, credential, backup,
Why it matters. asks the agent to read credentials
LOWPrompt injection · prompt.credential_read · CWE-94, CWE-1427
docs/custom-tool-providers.md:189
- Read credentials from environment variables or a secret manager. Never place
Why it matters. asks the agent to read credentials

Gates applied: no_behavioural_pass.

Audited 2026-10-03 · audit v0.4.1 · source sha 4f1936516936full audit observations/trust-audit/mcp-server/apache__doris-2.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-034f1936516936BLOCKD62first audit
06

Questions

What is the Doris MCP server?

Apache Doris MCP Server

What tools does Doris expose?

33 in total: 32 read-only, 1 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is Doris safe to connect to an agent?

No — not without reading the findings first. The audit graded it D (62/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What credentials does Doris need?

It reads ALLOW_UNAUTHENTICATED_NON_LOOPBACK, AUTH_TYPE, BLOCKED_KEYWORDS, DEFAULT_TOKEN_EXPIRY_HOURS, DORIS_OAUTH_ALLOW_INSECURE_HTTP, DORIS_OAUTH_BASE_URL, DORIS_OAUTH_CHILD_TOOLS_ENABLED, DORIS_OAUTH_CLIENTS_FILE, DORIS_OAUTH_DB_TOOLS_ENABLED, DORIS_OAUTH_DYNAMIC_CLIENT_REGISTRATION_MODE, DORIS_OAUTH_EXPLAIN_TOOLS_ENABLED and DORIS_OAUTH_LOGIN_PAGE_TITLE from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does Doris run?

It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on PyPI as doris-mcp-server.

How current is this page?

The grade is for one exact copy of the source (4f1936516936), read on 2026-10-03. The repository is watched and re-audited when it changes.

Advertisement