Skip to main content
Glama
Databricks Domo Migration Accelerator MCP Server

Databricks Domo Migration Accelerator MCP Server

Databricks Domo Migration Accelerator

Assess a Domo estate and migrate it to Databricks — via an MCP server and a web console.

The Python package is pseudo_domo_mcp (it impersonates a Domo tenant's API surface so the whole workflow runs offline). The product is the Databricks Domo Migration Accelerator.

The methodology mirrors Databricks Lakebridge (Profiler + Analyzer → Convert → Reconcile), extended with a value-driven decision step:

Assess → Rationalize → Convert → Reconcile

  • Assess — inventory + governance inference + per-asset complexity, value, effort (1-5), and a usage proxy (dependent cards + refresh cadence + scale).

  • Rationalize — decide each asset's disposition (Retire · Repoint · Rebuild · Elevate · Consolidate) and target surface (AI/BI + Genie · Genie App Builder · Sigma Input Tables · Apps + Lakebase); suggestions are pre-filled from the assess signals. Filtered discovery narrows the estate, and a saved filter set is a migration wave.

  • Convert — transpile Magic ETL / SQL DataFlows to Lakeflow pipelines + Unity Catalog metric views; recover Domo orchestration (schedules + dataflow dependencies) and map it to Databricks Workflows.

  • Reconcile — schema-parity gate on the rebuilt gold.

A future-state estimate rolls the effort scores + decisions into migration FTE-weeks, a target consumption size, and (with your Domo spend) a savings frame.

It packages the Domo discovery / assessment / migration workflow two ways over one engine:

  • an MCP server (FastMCP, stdio + streamable-HTTP) so an AI client (Claude Code, Cursor, Genie Code, …) can drive the migration conversationally, and

  • an operator web console (FastAPI + a zero-build HTML/JS frontend) that lets you click a Magic ETL or dashboard, Analyze its data flow, Draft the Databricks pipeline code, and Create it — with catalog/schema config.

It runs fully offline on synthetic fixtures shaped after Domo's public REST API — no live tenant, no Databricks workspace, no network required. When you're ready, point it at a real Domo tenant (OAuth) and a real Databricks workspace (CLI/OAuth) via config, and the same tools deploy real Lakeflow Declarative Pipelines.

Everything ships customer-agnostic. The bundled data is a fictional company ("Northwind Manufacturing"). The industry data models under models/ are vendored from the open-source Databricks Industry Data Models; the MCP scaffold follows the ai-dev-kit databricks-mcp-server pattern.

Why "pseudo-Domo"

It impersonates the surface of a Domo tenant (datasets, dataflows, cards, pages, sources) so the whole discover → assess → analyze → draft → create workflow is exercisable before you have tenant credentials. All tenant reads go through a provider abstraction (pseudo_domo_mcp/providers/): FixtureProvider (default, offline) today; LiveProvider (real Domo REST — OAuth2 client_credentials) when creds land. Swapping is one config change; the tools never change.

Related MCP server: Databricks MCP Server

The workflow

The console is a wizard:

 Configure ─► Connect ─► Discover ─► Assess ─► Plan ─► Build & Deploy
  • Configure / Connect — set the Databricks target + Domo provider, then connect (fixture mode connects instantly to the bundled sample tenant).

  • Discover — a Discovery Scan builds a typed, searchable inventory of every asset: connectors, Magic ETL, SQL DataFlows, DataSets, cards, Beast Modes, pages. Search by name and filter by type. Connectors are first-class and each carries a Databricks ingestion remap plan (Lakeflow Connect / Auto Loader / Apps+Lakebase), because source connections are what must be explicitly re-mapped.

  • Assess — governed vs. shadow IT is inferred (Domo has no governance field) from source/connector type, writeback, owner shape, and refresh cadence, with a confidence score and the signals behind each call shown for confirm/override.

  • Plan — a value-driven wave plan + per-connector ingestion strategy.

  • Build & Deploy — pick a migratable asset →

    • Analyze: the Magic ETL DAG as a medallion-layered (bronze → silver → gold) SVG, built from the same parser that transpiles it.

    • Draft: the 6-agent transpiler returns bronze/silver/gold Spark SQL + a semantic view folding the card's Beast Modes + a PASS/FAIL reconcile gate.

    • Create (progressive): always writes a deployable Databricks Asset Bundle (databricks.yml + SQL) and shows the deploy command; deploys via databricks bundle deploy when a profile is set; optionally commits the bundle to a linked GitHub / Azure DevOps repo as a PR.

Config is reachable anytime via ⚙ Config.

The MCP tools

Tool

What it does

domo_discover

Inventory the tenant — datasets/dataflows/cards/pages/sources + an inferred governed/shadow split.

domo_inventory

Typed, searchable asset inventory (connector / magic_etl / sql_dataflow / dataset / card / beast_mode / page); connectors carry a Databricks remap plan.

domo_assess

Classify each object by data domain + source, infer governance (with signals + confidence), score complexity and value.

list_industry_models

List vendored industry models (automotive, transport_shipping) + their domains/tables.

industry_model_map

Draft-map a Domo DataSet's columns → a canonical industry-model table (similarity + confidence + unmapped flags).

lakeflow_feasibility

Score each source system GREEN/AMBER/RED for Lakeflow Connect ingestion + recommended pattern.

transpile_lineage

6-agent transpiler → medallion Spark SQL + folded Beast Modes + repoint plan + reconcile gate.

migration_plan

Aggregate all of the above into a prioritized, value-driven wave plan.

Requirements

Python 3.11+. Runtime dependencies are declared in pyproject.toml and mirrored in requirements.txt (the Databricks App runtime installs from the latter):

Package

Why

fastmcp

the MCP server (stdio + streamable-HTTP)

fastapi, uvicorn[standard], python-multipart

the web console + file uploads

databricks-sdk==0.137.0

Lakebase credentials + App service-principal auth. Pinned — a loose range lets the App runtime resolve a version without the w.database Lakebase API, which silently falls back to local storage.

psycopg[binary]

the Lakebase (Postgres) store backend

databricks-sdk + psycopg are only exercised when store_backend=lakebase (or when running as an App); with the default local file store the tool needs neither at runtime.

Databricks machines have no direct PyPI egress, so pyproject.toml's [tool.uv] pins the internal mirror. Off-network, override it with uv pip install -e . --index-url https://pypi.org/simple/.

Quick start

uv venv --python 3.11 .venv && source .venv/bin/activate
uv pip install -e .            # uses the mirror pinned in pyproject [tool.uv]

# 1) Web console (browse → analyze → draft → create)
python -m pseudo_domo_mcp.webapp.app        # http://127.0.0.1:8010

# 2) MCP server — stdio (for Claude Code / Cursor)
python -m pseudo_domo_mcp.server

# 3) MCP server — HTTP
PSEUDO_DOMO_TRANSPORT=http PORT=8000 python -m pseudo_domo_mcp.server

127.0.0.1:8000/mcp is the MCP protocol endpoint (it speaks text/event-stream), not a web page — open a browser at the web console port instead.

Connect the MCP to Claude Code

.mcp.json in this repo registers the stdio server. Then ask, e.g.:

"Discover the Domo tenant, give me the migration plan, then transpile the pilot."

Configuration

Set in the web console's ⚙ Config panel or via env (persisted to .pseudo_domo_config.json, git-ignored):

Setting

Purpose

catalog / schema

Default Unity Catalog target for generated pipelines. Overridable per asset at Create (a domain/BU can target its own catalog/schema).

pipeline_language

sql or python — the SDP source language. Overridable per asset.

industry_models

Which Databricks Industry Data Model(s) to draft-map onto (universal; references the open-source repo). Multi-select.

databricks_profile

Databricks CLI profile (databricks auth login). Empty = write bundle files only; set = deploy for real. OAuth handled by the CLI; no workspace secret stored.

domo_provider

fixture (offline) or live (Domo REST).

domo_client_id + DOMO_CLIENT_SECRET (env)

Domo OAuth2 client_credentials. The secret is read from the environment, never written to config.

store_backend + lakebase_instance

State persistence: local (JSON file, default) or lakebase (Databricks Postgres) for durable, shared scan history / migration status / bundle registry / saved config. As an App these come from env (PSEUDO_DOMO_STORE_BACKEND / PSEUDO_DOMO_LAKEBASE_INSTANCE).

llm_endpoint (+ DATABRICKS_TOKEN env locally)

Optional LLM enhancement via a Databricks model serving endpoint (e.g. databricks-claude-sonnet-5). Off by default — the tool stays fully deterministic and offline; when set, the LLM only augments (governance rationale, mapping second-opinion, SQL-flow / Beast-Mode drafts) and always falls back. Locally authenticates with DATABRICKS_TOKEN; in an App with the service-principal token (no static token).

git_provider + git_repo + GIT_TOKEN (env)

Optional: link a GitHub or Azure DevOps repo so Create commits the generated bundle as a PR. Token read from env, never stored.

Precedence: persisted config (local file, or the store in an App) is overlaid by environment variables, so app.yaml / shell env always win.

Staying current with Databricks conventions

The SDP/DAB patterns the tool generates against are not hardcoded — they track the ai-dev-kit repo. A pattern manifest is cached locally and refreshed on install; re-refresh anytime via ⚙ Config → Refresh patterns from ai-dev-kit. Fully offline-safe: with no network, built-in defaults apply.

Deploy as a Databricks App

The same codebase runs locally and as a fully managed Databricks App — no fork. core/runtime.py detects the App runtime (the DATABRICKS_APP_NAME env var the platform injects) and flips a few seams; local behaviour is untouched:

Seam

Local

Databricks App

Web bind

127.0.0.1:8010

0.0.0.0 on the App port

Config persistence

.pseudo_domo_config.json

the store (Lakebase) — an App's filesystem is ephemeral + per-replica

Store backend

from the config file

from injected env (PSEUDO_DOMO_STORE_BACKEND / PSEUDO_DOMO_LAKEBASE_INSTANCE)

LLM auth

DATABRICKS_TOKEN

the App service principal's OAuth token (via the SDK)

It ships as two apps over one engine:

  • Console — app.yaml (repo root): python -m pseudo_domo_mcp.webapp.app.

  • MCP server — deploy/mcp.app.yaml: python -m pseudo_domo_mcp.server over streamable-HTTP. For Genie Code discovery the app name must start with mcp-.

App env (set in app.yaml): PORT=8000, PSEUDO_DOMO_PROVIDER=fixture, PSEUDO_DOMO_STORE_BACKEND (lakebase for the console / local for the MCP), PSEUDO_DOMO_LAKEBASE_INSTANCE, PSEUDO_DOMO_LLM_ENDPOINT.

Deploy the console

P=<your-cli-profile>
WS=/Workspace/Users/<you>/domo-migration-console

# 1) Create the app (provisions its service principal)
databricks apps create domo-migration-console -p $P

# 2) Sync source + deploy
databricks sync . $WS --full \
  --exclude .venv --exclude .git --exclude __pycache__ \
  --exclude generated --exclude .pytest_cache -p $P
databricks apps deploy domo-migration-console --source-code-path $WS -p $P

Then attach two resources (CLI databricks apps update, or App UI → Edit):

  • Database → your Lakebase instance, permission Can connect and create (auto-injects PGHOST/PGUSER/PGDATABASE/PGPORT).

  • Model serving → the LLM endpoint, permission Can query.

…and register the app's service principal as a Lakebase Postgres role so its OAuth token can log in (Lakebase identity federation):

databricks api post /api/2.0/database/instances/<instance>/roles -p $P --json '{
  "name": "<app-service-principal-client-id>",
  "identity_type": "SERVICE_PRINCIPAL",
  "membership_role": "DATABRICKS_SUPERUSER"
}'

Redeploy after attaching resources so the injected env is picked up. To verify, set PSEUDO_DOMO_DEBUG=1 in app.yaml and hit GET /api/debug/store (backend + connect error) and /api/debug/llm (a live model round-trip) — both behind the App's SSO, and both off unless the flag is set. Remove the flag once verified.

Deploy the MCP app

Apps only read app.yaml at the source root, so deploy the MCP manifest by importing it over that folder's app.yaml:

WS=/Workspace/Users/<you>/mcp-domo-migration
databricks apps create mcp-domo-migration -p $P
databricks sync . $WS --full --exclude .venv --exclude .git \
  --exclude __pycache__ --exclude generated --exclude .pytest_cache -p $P
databricks workspace import $WS/app.yaml --file deploy/mcp.app.yaml \
  --format RAW --overwrite -p $P
databricks apps deploy mcp-domo-migration --source-code-path $WS -p $P

The MCP app uses store_backend=local (assessment tools are stateless), so its service principal needs no Lakebase role.

Deploy gotchas

  • Pin databricks-sdk (see Requirements) — a loose range silently drops Lakebase to local storage.

  • App updates drop the SP's Lakebase grants — re-attach the Database resource after editing the app.

  • Two app.yamls, one repo — a databricks sync into the MCP app's folder overwrites its app.yaml with the console's; re-import deploy/mcp.app.yaml before deploying the MCP app.

  • Create in an App writes the bundle and (optionally) opens a git PR — it does not shell out to databricks bundle deploy (no CLI on the App path); use a configured CLI profile locally for in-place deploys.

Test

python -m pytest -q      # end-to-end: discover→assess→map→feasibility→transpile gate→plan

Going live

LiveProvider (pseudo_domo_mcp/providers/live_provider.py) documents the exact Domo REST endpoint map (verified against developer.domo.com). Domo has two API planes, and a full migration inventory needs both:

  • Public API (https://api.domo.com, OAuth2 client_credentials; scopes data user dashboard audit …) — the census + schemas: GET /v1/datasets, /v1/datasets/{id} (schema.columns), /v1/pages, /v1/cards (metadata only), /v1/streams, /v1/users, /v1/groups.

  • Instance API (https://{instance}.domo.com, X-DOMO-Developer-Token) — the transform internals: GET /api/dataprocessing/v1/dataflows[/{id}] (Magic ETL DAG + SQL body) and /api/content/v1/cards (Beast Mode expressions).

So the migration triplet = instance dataflow internals + public dataset schema + instance card export. The public API alone gives the census + schemas but not the transform logic or Beast Modes. To go live: set domo_provider=live + OAuth credentials (and DOMO_INSTANCE + DOMO_DEVELOPER_TOKEN for the transform triplet), then implement the stubbed reads.

Layout

app.yaml               Databricks App manifest — CONSOLE (repo root)
requirements.txt       runtime deps for the App runtime (mirrors pyproject)
deploy/
  mcp.app.yaml         Databricks App manifest — MCP server
pseudo_domo_mcp/
  server.py            FastMCP server (stdio + streamable-http)
  webapp/              FastAPI console + zero-build HTML/CSS/JS frontend
  tools/               thin @mcp.tool wrappers (one per capability)
  core/                engine: runtime (local vs App detection), provider
                       select, DDL parse, classify, governance inference, map,
                       feasibility, assets (typed inventory), graph (DAG),
                       config, store (local JSON | Lakebase), llm (optional
                       serving-endpoint enhancement), bundle (DAB writer), gitlink
  providers/           FixtureProvider (offline) | LiveProvider (Domo REST stub)
  transpiler/          6-agent Domo→Databricks transpiler + importable pipeline.run()
fixtures/
  tenant/              synthetic Domo census (datasets/dataflows/cards/pages)
  lineages/            full triplets (Magic ETL + schema + Beast Modes) for transpile
models/                vendored industry-model DDL (automotive, transport_shipping)
tests/                 end-to-end pytest

Documentation

  • docs/GUIDE.md — install, the full Assess → Rationalize → Convert → Reconcile workflow, the MCP tool + REST reference, and going live.

  • docs/FAQ.md — what it is, how it relates to Lakebridge, scoring/usage, dispositions & surfaces, orchestration, estimation, and more.

License

See LICENSE. Vendored industry-model DDL retains its upstream license (see models/README.md).

Available Tools

8 tools
domo_assessA

Assess the Domo estate: classify by data domain + source, score governance and migration complexity, and tag business value.

Inputs: scope. Returns: object

domo_discoverB

Inventory the Domo tenant for a migration assessment.

Inputs: scope. Returns: object

domo_inventoryB

Typed, searchable asset inventory of the Domo estate.

Domo work is organized by object type; this returns every asset with a common shape plus type-specific fields, optionally filtered.

Inputs: search, asset_type. Returns: object

industry_model_mapA

Draft-map a Domo DataSet's columns onto a canonical industry-model table.

Conforms a Domo output DataSet to the Databricks Industry Data Model ("silver") so the transpiled pipeline lands governed, standard entities rather than a like-for-like copy.

Inputs: industry, overrides, dataset_id, lineage_id, +2 more. Returns: object

lakeflow_feasibilityA

Score Domo source systems for Lakeflow Connect ingestion feasibility.

For each upstream source feeding the Domo estate, returns GREEN/AMBER/RED plus the recommended Databricks ingestion pattern (managed connector vs Auto Loader vs Lakebase re-platform) and a rationale — the input to sequencing the 28-source migration.

Inputs: source_system. Returns: object

list_industry_modelsB

List available Databricks Industry Data Models (and their domains).

Inputs: industry. Returns: object

migration_planA

Produce the prioritized Domo->Databricks migration plan.

Combines the tenant census, per-dataflow assessment, and per-source Lakeflow Connect feasibility into a wave-sequenced plan ranked by business value then migration complexity. This is the structured "assessment deliverable" a customer engagement produces.

Returns waves, the governance split, source feasibility rollup, and the recommended pilot. All figures are draft-grade until live tenant data.

Inputs: no named parameters. Returns: object

transpile_lineageA

Transpile one Domo lineage triplet into a Databricks SDP medallion.

Runs the 6-agent transpiler (Ingest -> Parse -> Emit -> BeastMode -> Repoint -> Reconcile) over a lineage's triplet (Magic ETL + DataSet schema

  • card Beast Modes) and returns the emitted bronze/silver/gold Spark SQL, the folded semantic-metrics view, the Domo->Databricks connector-swap plan, and the PASS/FAIL reconciliation gate.

Inputs: lineage_id (required), out_dir, industry. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.6/5.0

    Scored across 8 tools

    Disambiguation4/5

    Most tools have clearly distinct purposes, such as 'domo_inventory' for detailed typed inventory vs 'domo_discover' for initial assessment. The only potential overlap is between 'domo_discover' and 'domo_inventory', but descriptions clarify they serve different stages.

    Naming Consistency3/5

    Names use a mix of verb-first (domo_discover, domo_assess, transpile_lineage) and noun-first (domo_inventory, industry_model_map, migration_plan) patterns. While all snake_case, the inconsistent verb/noun ordering and varying prefixes reduce predictability.

    Tool Count5/5

    With 8 tools covering discovery, inventory, assessment, mapping, feasibility, transpilation, and planning, the count is well-scoped for a migration accelerator. Each tool serves a distinct, necessary function without redundancy.

    Completeness4/5

    The tool set covers the core migration workflow from discovery to planning, including industry model mapping and lineage transpilation. Minor gaps exist, such as no tool for post-migration execution or validation, but agents can work around these.

    Maintenance

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables AI assistants like Claude to interact with Databricks workspaces through custom prompts and tools. Supports running SQL queries, managing clusters, creating jobs, and accessing workspace resources via the Databricks SDK.
      2
      -
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI assistants to interact with Databricks workspaces programmatically, providing comprehensive tools for cluster management, notebook operations, job orchestration, Unity Catalog data governance, user management, permissions control, and FinOps cost analytics.
      321 npm
      MIT
    • A
      license
      Not graded
      quality
      Not graded
      maintenance
      Enables LLMs to manage Databricks clusters, jobs, and notebooks while providing schema references for gold and silver data layers. It allows agents to perform data discovery and execute SQL queries directly against Databricks environments.
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI agents to explore Unity Catalog metadata, execute SQL queries, and analyze data lineage including notebooks and jobs, empowering autonomous data discovery and query generation in Databricks.
      MIT