Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
0075046
Added mcp server draft
souravg-db2 Mar 13, 2026
0e8df4a
Restructured code
souravg-db2 Mar 16, 2026
a11e90d
Fix MCP server for Databricks Apps + Genie Code deployment
vb-dbrks Mar 19, 2026
cf51723
Remove development mode setting from Databricks configuration for the…
vb-dbrks Mar 19, 2026
7f88308
Fix Databricks Apps deployment: proper entry point and dependencies
vb-dbrks Mar 19, 2026
5f12914
comments
vb-dbrks Mar 19, 2026
b3bcad7
Add design spec: MCP server OBO support via Jobs API
souravg-db2 Jun 4, 2026
be128c5
Add implementation plan: MCP server OBO via Jobs API
souravg-db2 Jun 4, 2026
29f99ef
feat(mcp): add runner notebook for Jobs API dispatch
souravg-db2 Jun 4, 2026
75308d6
feat(mcp): replace Databricks Connect with Jobs API submit_notebook_j…
souravg-db2 Jun 4, 2026
8924398
feat(mcp): refactor tools to use Jobs API instead of Databricks Connect
souravg-db2 Jun 4, 2026
0762aec
chore(mcp): remove databricks-connect, add clusters scope, deploy not…
souravg-db2 Jun 4, 2026
64cd396
fix(mcp): use 'jobs' scope instead of invalid 'clusters' scope
souravg-db2 Jun 4, 2026
eb0c389
fix(mcp): use 'all-apis' scope for full API access including Jobs
souravg-db2 Jun 4, 2026
8914f87
fix(mcp): revert to known-valid scopes (sql, files.files)
souravg-db2 Jun 4, 2026
db67bff
fix(mcp): use SP with run_as for job submission instead of OBO token
souravg-db2 Jun 4, 2026
3a17418
added mcp changes
souravg-db2 Jun 10, 2026
876cf5b
updated mcp readme
souravg-db2 Jun 10, 2026
2f2f723
added changes for mcp server
souravg-db2 Jun 15, 2026
0644f57
Removed extra docs
souravg-db2 Jun 15, 2026
9b48b20
Updated documentation
souravg-db2 Jun 15, 2026
9c32530
Addedressed some review comments
souravg-db2 Jun 17, 2026
b3f0c1b
made fix per review comment
souravg-db2 Jun 22, 2026
1e6e9e5
added fix as per review comment . Also added test to CI
souravg-db2 Jun 22, 2026
30a2550
added changes for restricting allowed origins to databricks domains
souravg-db2 Jun 23, 2026
fd5da47
Merge branch 'main' into dqx/mcp
mwojtyczka Jun 24, 2026
2d16c24
feat(mcp): add checks persistence, table output, and data-contract tools
vb-dbrks Jun 24, 2026
e02e8c2
chore(mcp): trim server deps and remove dead code (review feedback)
vb-dbrks Jun 24, 2026
20996db
docs(mcp): note runner DQX dependency should be pinned in production
vb-dbrks Jun 24, 2026
3f3e0d9
fix(mcp): make app SP own the temp schema so it can clean up temp views
vb-dbrks Jun 24, 2026
77e5c8f
refactor(mcp): make temp-view cleanup stateless and restart/replica-safe
vb-dbrks Jun 24, 2026
a90f5d9
perf(mcp): make get_run_status a single non-blocking poll
vb-dbrks Jun 24, 2026
30e0ae1
test(mcp): add protocol-level and HTTP integration tests
vb-dbrks Jun 24, 2026
9b57b25
test(mcp): add agent-in-the-loop integration test (gated)
vb-dbrks Jun 24, 2026
da7fcc6
style(mcp): apply black formatting to satisfy make fmt
vb-dbrks Jun 24, 2026
27fbe75
test(mcp): scaffold and tear down an isolated table in the agent inte…
vb-dbrks Jun 24, 2026
3514dd7
build(mcp): runner installs the in-repo DQX wheel, not a PyPI release
vb-dbrks Jun 24, 2026
312d40e
ci(mcp): add MCP integration workflow that deploys to a CI workspace
vb-dbrks Jun 24, 2026
e8140ae
ci(mcp): gate integration workflow on CI config; clearer preflight
vb-dbrks Jun 24, 2026
1d9b6d2
test(mcp): run MCP integration via the acceptance harness (reuse work…
vb-dbrks Jun 24, 2026
7a2932b
test(mcp): resolve workspace auth from SDK instead of requiring DATAB…
vb-dbrks Jun 24, 2026
e31be73
ci(mcp): install Databricks CLI before the acceptance run
vb-dbrks Jun 25, 2026
0566855
test(mcp): surface full deploy output on failure
vb-dbrks Jun 25, 2026
bac43da
ci(mcp): retry bundle deploy to survive flaky terraform provider fetch
vb-dbrks Jun 25, 2026
ae2a7dc
ci(mcp): route terraform init through the Databricks registry proxy
vb-dbrks Jun 25, 2026
c7f91cd
docs(mcp): document all 12 tools, fix stale behavior, add examples
vb-dbrks Jun 25, 2026
4e88d66
test(mcp): add deterministic integration coverage for all 12 tools + …
vb-dbrks Jun 25, 2026
5dc91b3
ci(mcp): deploy the bundle with engine: direct (no Terraform)
vb-dbrks Jun 25, 2026
2dde58c
test(mcp): restructure integration suite as one self-contained test
vb-dbrks Jun 25, 2026
943c678
docs(mcp): overhaul the MCP server guide + add make mcp-deploy
vb-dbrks Jun 26, 2026
377e8ca
docs(mcp): match the "Getting help" wording used in the DQX Studio guide
vb-dbrks Jun 26, 2026
d93b60a
feat(mcp): grant-on-write table access + structured request logging
vb-dbrks Jun 26, 2026
6228ed5
docs(mcp): add Beta status badge and Feature lifecycle page
vb-dbrks Jun 26, 2026
a52a4bd
fix(mcp): make `make mcp-deploy` resolve build-constraints from repo …
vb-dbrks Jun 26, 2026
45dc2f6
docs(mcp): pin Feature lifecycle changelog links to released version
vb-dbrks Jun 26, 2026
1689228
ci(mcp): upload MCP integration test coverage to Codecov
vb-dbrks Jun 26, 2026
6cfb1ef
test(mcp): authenticate /mcp E2E with OAuth M2M (front-door requires it)
vb-dbrks Jun 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions .github/workflows/mcp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# MCP server integration tests.
#
# Runs the tests/integration_mcp suite via the shared acceptance harness (same workspace,
# auth, and Model Serving endpoint as the anomaly/integration suites). The suite deploys an
# isolated MCP app from the bundle, drives it as an agent would, and tears it down — see
# tests/integration_mcp/conftest.py. No MCP-specific secrets are needed; auth comes from the
# acceptance action exactly like the other integration workflows.
name: mcp

on:
pull_request:
types: [opened, synchronize, ready_for_review]
paths:
- "mcp-server/**"
- "src/databricks/labs/dqx/**" # the runner installs the in-repo DQX wheel
- "tests/integration_mcp/**"
- ".github/workflows/mcp.yml"
merge_group:
types: [checks_requested]

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: false # let teardown finish so the isolated app/bundle is removed

jobs:
# Gate downstream work: fork PRs (no access to the tool environment) and drafts do not run.
not-a-fork:
runs-on:
group: databrickslabs-protected-runner-group
labels: linux-ubuntu-latest
if: github.event_name == 'pull_request' && !github.event.pull_request.draft && !github.event.pull_request.head.repo.fork
steps:
- run: echo "Not a fork PR, proceeding"

mcp-tests:
needs: not-a-fork
environment: tool
runs-on:
group: larger-runners
labels: larger
permissions:
id-token: write
pull-requests: write
steps:
- name: Checkout Code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

- name: Setup environment
uses: ./.github/actions/setup-env

- name: Pre-build DQX wheel
uses: ./.github/actions/prebuild-wheel

- name: Prepare code coverage configuration for MCP tests
run: |
cat > tests/integration_mcp/.coveragerc << EOF
[run]
source = ../../src
relative_files = true
parallel = true
EOF

# Required for the DAB (Databricks Asset Bundle) deploy the MCP suite runs (ci_deploy.sh).
# The CLI lands on PATH (via GITHUB_PATH) for the acceptance action's test subprocess.
- name: Install Databricks CLI
uses: databricks/setup-cli@596b0a354ba14aa59921aca1b02bd67c2b0a81a5 # v0.297.2

- name: Run MCP integration tests
uses: databrickslabs/sandbox/acceptance@83461e5dd7021feabb1a9ca3ee10d6f46b72092a # acceptance/v0.4.6
with:
vault_uri: ${{ secrets.VAULT_URI }}
timeout: 1h
codegen_path: tests/integration_mcp/.codegen.json
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
COVERAGE_FILE: ${{ github.workspace }}/.coverage # make sure the coverage report is preserved

- name: Merge coverage reports and convert them to XML
run: make combine-coverage

- name: Publish test coverage
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
with:
use_oidc: true
files: coverage-combined.xml
flags: mcp
17 changes: 17 additions & 0 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,20 @@ jobs:
- name: Run app backend tests
run: make app-test
working-directory: .

mcp:
needs: not-a-fork
name: Build and Check MCP Server
runs-on:
group: databrickslabs-protected-runner-group
labels: linux-ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Setup environment
uses: ./.github/actions/setup-env

- name: Run MCP server tests
run: make mcp-test
41 changes: 41 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ perf: ## Run performance benchmarks (long timeout)
anomaly: ## Run anomaly integration tests (long timeout, with reruns)
$(UV_RUN) pytest tests/integration_anomaly/ -v -n 10 --timeout 1200 --durations 20 --reruns 2 --reruns-delay 5

mcp-integration: ## Run MCP server integration tests (deploys an isolated app; requires workspace auth + Databricks CLI)
$(UV_RUN) pytest tests/integration_mcp/ -v --timeout 1800 --durations 10

coverage: ## Run all tests (excl. e2e/perf) and open HTML coverage report
$(UV_TEST) --ignore=tests/e2e --ignore=tests/perf --cov --cov-report=html tests/
open htmlcov/index.html
Expand Down Expand Up @@ -177,6 +180,36 @@ app-test: ## Run app backend pytest suite (K=<expr> filter, COV=1 for coverage)
$(if $(K),-k "$(K)") \
$(if $(COV),--cov=src/databricks_labs_dqx_app/backend --cov-report=term-missing --cov-report=xml:coverage-app.xml)

# Run the MCP server's unit-test suite (pytest, no Databricks/Spark dependencies).
# Usage: make mcp-test # run everything
# make mcp-test K=expr # forward -k filter to pytest
#
# pytest is not declared in mcp-server's pyproject/uv.lock — the suite only
# needs anyio, which ships transitively. With UV_FROZEN=1 we can't add pytest
# to the lock from here, so inject it ephemerally with ``uv run --with pytest``
# over the synced runtime env (anyio's pytest plugin handles the async tests).
mcp-test: ## Run MCP server pytest suite (K=<expr> filter)
cd mcp-server && uv run --with pytest pytest tests/ \
$(if $(K),-k "$(K)")

# One-command MCP server deploy (parity with app-deploy). Deploys the bundle (app + runner
# job + setup job), runs the one-time setup job (UC grants + temp-schema ownership), then
# deploys & starts the app via ``bundle run``. The catalog-name secret must already be set
# (see the deploy guide) — the setup job and app read it from the secret scope.
#
# Usage: make mcp-deploy PROFILE=my-profile
# make mcp-deploy PROFILE=my-profile BUNDLE_VARS='--var catalog_name=main'
# TARGET defaults to the bundle's default target (dev); override with TARGET=<t>.
# The bundle artifact build runs `uv build ../` from inside mcp-server/, so the global
# relative UV_BUILD_CONSTRAINT (.build-constraints.txt) would resolve against the wrong
# directory. Pin it to the absolute repo-root path so the wheel build finds it.
mcp-deploy: export UV_BUILD_CONSTRAINT := $(CURDIR)/.build-constraints.txt
mcp-deploy: ## Deploy the MCP server bundle, run setup, and (re)deploy + start the app
@test -n "$(PROFILE)" || (echo "Usage: make mcp-deploy PROFILE=<databricks-profile> [TARGET=<bundle-target>] [BUNDLE_VARS=...]"; exit 1)
cd mcp-server && databricks bundle deploy -p $(PROFILE) $(if $(TARGET),-t $(TARGET)) $(BUNDLE_VARS)
cd mcp-server && databricks bundle run dqx_setup -p $(PROFILE) $(if $(TARGET),-t $(TARGET)) $(BUNDLE_VARS)
cd mcp-server && databricks bundle run mcp-dqx -p $(PROFILE) $(if $(TARGET),-t $(TARGET)) $(BUNDLE_VARS)

##@ App deploy (require PROFILE=<databricks-profile>; most also need TARGET=<bundle-target>)

# Grant Unity Catalog permissions after bundle deploy.
Expand Down Expand Up @@ -273,6 +306,14 @@ lock-app-dependencies: ## Regenerate app/uv.lock, app/yarn.lock, app/.build-cons
uv pip compile --generate-hashes --universal --no-header - > app/build-constraints-new.txt
mv app/build-constraints-new.txt app/.build-constraints.txt

# Regenerate the MCP server lockfile and scrub private-proxy URLs so the
# committed file resolves against whatever registry the install environment
# is configured for (JFrog in CI, public in fork PRs).
lock-mcp-dependencies: export UV_FROZEN := 0
lock-mcp-dependencies: ## Regenerate mcp-server/uv.lock
cd mcp-server && uv lock --exclude-newer "7 days"
perl -pi -e 's|registry = "https://[^"]*"|registry = "https://pypi.org/simple"|g' mcp-server/uv.lock

lock-dependencies: export UV_FROZEN := 0
lock-dependencies: ## Regenerate top-level uv.lock and .build-constraints.txt
uv lock --exclude-newer "7 days"
Expand Down
Loading
Loading