● Data Platform MCP Server
v0.5.0 · ETL Metadata / Lineage Integration

讓 AI Agent 安全理解資料平台

Production-oriented MCP Server 參考實作:把 PostgreSQL、Vertica、Airflow、Metadata、Lineage、Logs、Runbooks 與 producer-owned ETL metadata 轉成標準 MCP capabilities,並加入 OIDC、RBAC、Multi-tenancy、Audit、OpenTelemetry、Kubernetes / Helm 與 Air-gapped Delivery。

MCP SDK v2PostgreSQLVerticaAirflow 3SQLGlotOIDC/JWTOpenTelemetryKubernetesHelm
One sentence pitch

不是讓 LLM 直接連 DB,而是加一層「受控、可稽核、可治理」的 MCP Data Platform Gateway。

# MCP Host asks...
› 哪些資料表與 daily_sales 有關?

# Server performs...
✓ OIDC / Bearer validation
✓ RBAC scope check
✓ Tenant source boundary
✓ Catalog + Lineage lookup
✓ Audit + trace correlation

# No destructive write tool exists
21MCP Tools
2Database Adapters
4RBAC Roles
v0.5ETL Metadata Integration milestone

面試官 5 分鐘速讀

先回答「為什麼值得看」,再進入實作細節。

Problem

LLM 不該直接拿 DB 權限

直接暴露資料庫、排程器與 Logs 容易造成越權、Prompt Injection、credential expansion 與不可追蹤操作。

Architecture

MCP 作為受控介面層

Catalog、Metadata、Lineage、SQL Explain、Airflow 與 Log Search 被封裝成標準 MCP Tool,底層由 Adapter 隔離。

Production

不是 Demo-only

OIDC/JWT、RBAC、Tenant boundary、Audit、OTel、Helm、NetworkPolicy、External Secrets、Trivy 與 air-gap 都納入。

核心工程決策:Role 決定能做什麼,Tenant 決定能碰哪個 Data Source;SQL Policy 限制語句型態,Database Session 最後仍維持 Read Only。安全不是靠 Prompt 約束,而是 Defense-in-Depth。
P1 · Engineering Judgment

Engineering Decisions & Production Evidence

核心不是「把 DB 包成 Tool」,而是建立標準化、可治理、可稽核的 integration boundary,避免 AI client 直接取得 backend-native privilege。

Problem

若每個 Agent 自己連 PostgreSQL、Vertica、Airflow、Logs,identity、tenant、SQL safety、audit 與 backend error semantics 都會被複製。

Key Decision

MCP Tool Contract + Adapter Pattern。Role 決定 what,Tenant Policy 決定 which source,SQL safety 不靠 Prompt。

Defense-in-Depth

No destructive tool → SQLGlot AST policy → DB/session read-only → OIDC/RBAC/Tenant → Audit/OTel。

DecisionBenefitTrade-off
MCP Tool ContractClient 不需要 backend-specific credential / API semantics增加 protocol、schema、compatibility 維護
Adapter PatternPostgreSQL / Vertica / Airflow / Logs 可各自演進需維護 timeout、error normalization 與 backend 差異
RBAC + Tenant separationOperation 與 data-source authorization 可獨立 reason / auditv0.4 是 source-level isolation,不等同 row-level RLS
Failure ScenarioEngineering ResponseEvidence
Write / malformed SQL在 DB 執行前拒絕,DB session 本身仍維持 read-onlytest_security.py
OIDC / role / tenant violationFail closed,不降級成 anonymous privileged accesstest_auth_audit.py
Backend integration outage相關 Tool bounded failure,不以更高權限連線或放寬 policy 作為 fallbacktest_integrations.py
Interview signal:安全不是 system prompt,而是 Tool surface、AST policy、database read-only、RBAC、Tenant 與 Audit 的多層工程控制。

ETL Metadata / Lineage Integration

enterprise-etl-platform 產生 truth;MCP Server 只提供 governed read-only access。

Producer

enterprise-etl-platform

Pentaho / Hop parser、normalized metadata、migration analysis、structural / inferred lineage classification。

Access Layer

Data Platform MCP Server

讀取 exported JSON contract,套用 scope、audit、identity、telemetry;不重新解析 KTR/KJB/Hop。

Consumers

DataOps / MCP Hosts

可查 pipeline、steps、dependencies、table lineage 與 metadata;RCA 與 agent reasoning 仍留在 consumer layer。

Authority rule:structural、inferred-deterministic 與 AI interpretation classification 原樣保留。MCP 不會把 AI interpretation 升格成 deterministic lineage。
export DPMCP_ETL_METADATA_DIR=/srv/etl-metadata
export DPMCP_ETL_METADATA_MAX_FILES=500

# Kubernetes Helm: existing PVC is mounted read-only
etlMetadata:
  enabled: true
  existingClaim: etl-metadata

整體架構

從 MCP Host 到 Data Platform backend 的完整 request path。

ChatGPT / Claude / Codex / MCP HostStreamable HTTP / stdio MCP SDK v2 Resource ServerStatic Token / OIDC JWT + JWKS RBAC Scope → Tenant Policy → Audit + OTelwhat can you do? / which source can you touch? DataPlatformServiceAdapter abstraction CatalogPostgreSQL / VerticaMetadata / Statistics Lineage / SQLCatalog + SQLGlot AST OperationsAirflow 3 /api/v2 Logs / RunbooksOpenSearch / Loki

Adapter Pattern

MCP Tool 不直接知道 PostgreSQL、Vertica 或 Airflow 的細節。Backend-specific behavior 封裝在 Adapter,降低耦合。

Read-only by Design

沒有 INSERT / UPDATE / DELETE / DDL / DAG trigger / secret update 等 destructive Tool。

一次 MCP Request 發生什麼?

以取得 Vertica table metadata 為例。

Authenticate
OIDC 模式用 JWKS 驗 signature、issuer、audience、expiry、subject。
Authorize operation
get_table_metadata 需要 catalog:read。
Authorize tenant source
Tenant policy 確認 caller 是否允許存取 vertica。
Call Adapter
VerticaCatalogAdapter 查 v_catalog,session 維持 READ ONLY。
Audit + Observe
記 actor / tenant / role / action / outcome / latency,並關聯 trace ID。

版本演進

每版對應一個工程成熟度里程碑。

v0.1 · MCP Foundation

MCP SDK v2、stdio/HTTP、Demo、PostgreSQL read-only、Docker、pytest/Ruff、Trivy。

v0.2 · DataOps Integration

Airflow 3、OpenSearch、Loki、MCP Resources/Prompts、protocol tests。

v0.3 · Enterprise Data Platform

Vertica、Composite Catalog、Metadata、Lineage、SQLGlot AST、Bearer RBAC、Audit。

v0.4 · Production Delivery

OIDC/JWT、Multi-tenancy、OTel、Kubernetes/Helm、External Secrets、NetworkPolicy、Air-gap、gated Release。

v0.5 · ETL Metadata / Lineage Integration

Producer-owned ETL metadata、six read-only tools、ETL resource、classification preservation、read-only PVC。

MCP Tool Catalog

可搜尋 tool / scope / purpose。

ToolScopeTenantPurpose
healthplatform:read—health/version
whoamiplatform:read—actor / role / tenant / scopes
list_data_sourcescatalog:readfiltertenant-visible sources
list_schemascatalog:readyesschemas
list_tablescatalog:readyestables/views
describe_tablecatalog:readyescolumn metadata
table_statisticscatalog:readyeslightweight statistics
get_table_metadatacatalog:readyesowner/type/projections
get_table_lineagelineage:readyescatalog-backed lineage
analyze_sql_lineagelineage:read—SQL AST lineage
explain_sqlsql:explainyesguarded EXPLAIN
list_dagsoperations:read—DAG discovery
get_dag_statusoperations:read—latest DAG state
search_etl_logslogs:read—OpenSearch/Loki log search
search_runbooksrunbook:read—troubleshooting knowledge
list_etl_pipelinescatalog:read—producer pipeline discovery
get_etl_pipelinecatalog:read—normalized ETL contract
get_etl_pipeline_stepscatalog:read—ETL step metadata
get_etl_pipeline_dependencieslineage:read—step/workflow dependencies
get_etl_table_lineagelineage:read—producer lineage + boundary
search_etl_metadatacatalog:read—ETL metadata search
邊界:v0.5 保留 source-level tenant isolation。ETL metadata artifact 目前是 deployment-scoped;若多 tenant 共用,需先增加 tenant-aware artifact policy 或採隔離部署。

Metadata & Lineage

把 catalog fact、SQL AST derivation 與 ETL producer lineage 刻意分開。

Catalog-backed

資料庫觀察到的血緣

Vertica 使用 v_catalog.view_tables。

vertica.public.orders
        │
        ▼
vertica.mart.daily_sales
SQL-derived

SQL AST 推導血緣

analyze_sql_lineage 解析實際 input tables 與 CTE。

WITH recent AS (
  SELECT * FROM public.orders
)
SELECT * FROM recent
JOIN mart.customers c ...

Inputs:
- public.orders
- mart.customers
CTE:
- recent
ETL producer

ETL metadata lineage

保留 structural、inferred-deterministic 與 capability boundary;AI interpretation 不冒充 deterministic truth。

staging.orders
      │ structural / inferred
      ▼
analytics.orders_enriched

Security / Authorization

多層控制,而不是只做登入驗證。

OIDC / JWT

JWKS signature、algorithm allow-list、issuer、audience、expiration、subject、role mapping、tenant claim。

RBAC + Tenant

readeranalystoperatoradmin

Role 決定 operation;Tenant 決定 source。

SQL + DB boundary

SQLGlot AST 拒絕 DML/DDL/multi-statement/SELECT INTO/write CTE;PostgreSQL/Vertica session 仍維持 read-only。

Audit hygiene:Bearer token、password、DSN、raw SQL 不進 audit/telemetry;SQL 以 fingerprint 記錄,並可關聯 OpenTelemetry trace ID。

Multi-tenancy Example

Role 與 Tenant 是兩個不同的授權維度。

export DPMCP_TENANT_ENABLED=true
export DPMCP_TENANT_ALLOWED_SOURCES_JSON='{
  "tenant-a":["postgres"],
  "tenant-b":["vertica"],
  "platform-admin":["*"]
}'
tenant-a + analyst
├─ metadata(postgres)  ✓
├─ lineage(postgres)   ✓
├─ explain(postgres)   ✓
├─ metadata(vertica)   ✗
└─ list_dags           ✗
   lacks operations:read

Audit + OpenTelemetry

從 actor 一路追到 latency 與 distributed trace。

Signals

  • dpmcp.<action> spans
  • dpmcp.invocations
  • dpmcp.invocation.duration

透過 OTLP/HTTP 送至 Collector,再轉 Grafana/Tempo/Prometheus/Azure Monitor/Datadog 等。

{
  "action": "metadata.get_table",
  "actor": "agent-client",
  "tenant": "tenant-a",
  "role": "analyst",
  "outcome": "success",
  "trace_id": "012345...abcdef"
}

Kubernetes / Helm

安全預設直接進 Chart defaults。

Pod Security

  • runAsNonRoot
  • UID/GID 10001
  • readOnlyRootFilesystem
  • drop ALL capabilities
  • RuntimeDefault seccomp

Reliability

  • replicas = 2
  • ETL metadata PVC read-only mount
  • readiness/liveness
  • requests/limits
  • PDB
  • optional HPA

Secrets / Network

  • ServiceAccount token disabled
  • External Secrets Operator
  • Azure Key Vault example
  • NetworkPolicy
  • non-DNS egress denied by default
kubectl apply -f examples/kubernetes/namespace-restricted.yaml

helm upgrade --install dpmcp \
  deploy/helm/data-platform-mcp-server \
  --namespace data-platform-mcp
注意:預設 Egress 只有 DNS;PostgreSQL、Vertica、OIDC/JWKS、Airflow、OpenSearch、Loki、OTLP Collector 都應明確 allow。

使用方式

從 Demo 到 Multi-source / OIDC。

1. Local Demo
git clone https://github.com/kewinall/data-platform-mcp-server.git
cd data-platform-mcp-server
python -m venv .venv
source .venv/bin/activate
pip install -e '.[dev]'
cp .env.example .env
DPMCP_TRANSPORT=streamable-http data-platform-mcp

Endpoint: http://127.0.0.1:8000/mcp

2. PostgreSQL + Vertica Multi-source
export DPMCP_MODE=multi
export DPMCP_POSTGRES_DSN='postgresql://readonly_user:change-me@postgres:5432/analytics'
export DPMCP_VERTICA_DSN='vertica://readonly_user:change-me@vertica:5433/warehouse?tlsmode=require'
data-platform-mcp
3. OIDC
export DPMCP_TRANSPORT=streamable-http
export DPMCP_AUTH_ENABLED=true
export DPMCP_AUTH_MODE=oidc
export DPMCP_AUTH_ISSUER_URL='https://idp.example.com/realms/data-platform'
export DPMCP_AUTH_RESOURCE_URL='https://mcp.example.com/mcp'
export DPMCP_OIDC_JWKS_URL='https://idp.example.com/realms/data-platform/protocol/openid-connect/certs'
export DPMCP_OIDC_AUDIENCE='data-platform-mcp'
export DPMCP_OIDC_ROLE_CLAIM='realm_access.roles'
export DPMCP_OIDC_TENANT_CLAIM='tenant'
4. OpenTelemetry
export DPMCP_OTEL_ENABLED=true
export DPMCP_OTEL_SERVICE_NAME=data-platform-mcp-server
export DPMCP_OTEL_EXPORTER_OTLP_ENDPOINT='http://otel-collector.observability:4318'
export DPMCP_DEPLOYMENT_ENVIRONMENT=prod

Air-gapped Delivery

目標環境不需要連 PyPI / Docker Hub / GitHub。

Build

make airgap

Output: dist/data-platform-mcp-server-0.4.0-airgap.tar.gz

Bundle

wheelhouse/
images/
helm/
docs/
.env.example
README.md
LICENSE
SHA256SUMS
verify-airgap-bundle.sh

CI / Security / Release

同一 main commit 的 CI 與 Security 都成功才發布。

CI

  • Python 3.11 / 3.12
  • Ruff / pytest / compileall
  • Docker build
  • Shell syntax
  • Helm lint / template

Security

  • pip-audit
  • Trivy filesystem
  • render Kubernetes YAML
  • Trivy config scan
Release Gate:Both green → Git Tag → GitHub Release → Helm chart .tgz asset。
v0.4.0 已實際通過完整 pipeline

面試怎麼講

把「用了哪些工具」轉成「解了什麼工程問題」。

60 秒版本

「我做了一個 Data Platform MCP Server,把 PostgreSQL、Vertica、Airflow、Log Search 與 Metadata/Lineage 封裝成標準 MCP capabilities,讓 AI Agent 不需要拿到底層系統的直接寫入權限。安全上分成 OIDC authentication、RBAC scope、tenant source boundary、SQL AST policy 與 database read-only 多層控制,再把 Audit 與 OpenTelemetry 串起來。部署面有 Helm、Pod Security、NetworkPolicy、External Secrets、Trivy,也支援 air-gapped bundle。」

可追問的題目

  • 為何 MCP,而不是直接做 SQL Agent?
  • 如何防 Prompt Injection?
  • Role 與 Tenant 有什麼不同?
  • Multi-tenancy 做到哪一層?
  • 為何需要 DB-side read-only?
  • 如何部署到企業 Kubernetes / 封閉網路?
作品定位:證明的不只是「會接 LLM」,而是能把 Data Engineering / DataOps 經驗延伸到 MCP / Agentic / AI Platform Engineering。

FAQ

常見使用者與面試官問題。

會讓 AI 直接讀正式資料嗎?

Repository 預設 synthetic demo data;真實環境需自行設定 read-only DB 帳號、Secret 與 NetworkPolicy。

這算完整 Multi-tenant SaaS 嗎?

不是。v0.4 明確是 catalog source-level isolation reference;row/column security 應結合 DB RLS/CLS 或後續 OPA/Cedar 等 policy engine。

為什麼不直接 COUNT(*)?

定位為 operational metadata inspection,避免大表掃描;Vertica 使用 projection storage,PostgreSQL 使用 planner estimate。

為什麼要 Air-gapped?

企業資料平台常存在封閉網段;wheelhouse、container image、Helm chart 與 checksum 一起交付可展示離線部署思考。

English Executive Summary

For interviewers who prefer an English overview.

Data Platform MCP Server is a production-oriented reference implementation that exposes enterprise data-platform capabilities to MCP-compatible AI clients without granting unrestricted backend access.

It integrates PostgreSQL, Vertica, Airflow 3, OpenSearch/Loki, metadata and lineage through adapter abstractions. The security model combines bearer/OIDC authentication, role-based scopes, tenant-aware source authorization, AST-based read-only SQL validation, database-level read-only sessions, structured audit logging, and OpenTelemetry correlation.

The production layer includes a hardened Kubernetes Helm chart, NetworkPolicy, External Secrets Operator integration, CI/Security gates, Trivy scans, and an air-gapped deployment bundle. It demonstrates a transition from Data Engineering/DataOps into MCP and AI Platform Engineering.