Skip to content

[POC] MCP Apps: interactive lineage via get_lineage#819

Draft
aricallen wants to merge 5 commits into
mainfrom
aric/mcp-lineage-poc
Draft

[POC] MCP Apps: interactive lineage via get_lineage#819
aricallen wants to merge 5 commits into
mainfrom
aric/mcp-lineage-poc

Conversation

@aricallen

Copy link
Copy Markdown

Summary

Proof of concept for MCP Apps (tools with an interactive UI) in the dbt MCP server, with get_lineage wired as the first one: it returns a structured lineage graph and links a UI resource that MCP-app-capable hosts (e.g. Claude Desktop) can render as an interactive DAG.

⚠️ Draft / proof of concept — not ready to merge. See Additional Notes for the remaining items.

What Changed

  • New apps/ module: register_app_resource() registers a ui://dbt-mcp/<app> resource that, on read, fetches a self-contained single-file HTML bundle from a configurable CDN (DBT_MCP_CDN_BASE) and serves it directly to the host.
  • get_lineage now returns a structured LineageGraph (nodes + edges) via structured_output, and links its UI via _meta (ui.resourceUri). Edges are derived from each node's parents.
  • Default lineage depth lowered 5 → 2 (5 produced very large graphs for well-connected models).
  • Published-app contract: skip hashing the content of text/html;profile=mcp-app resources — the UI bundle is released independently on the CDN, so its bytes are out-of-contract; this keeps snapshot generation deterministic and offline. Snapshot regenerated.
  • Unit tests for the get_lineage transformation and the contract behavior.

Why

Lineage is far more useful as an interactive graph than as text/JSON. MCP Apps let the server hand a host an interactive UI inline, reusing the lineage data the server already produces, with the UI hosted on a CDN so it can evolve independently of the server release.

Related Issues

N/A (proof of concept).

Checklist

  • I have performed a self-review of my code
  • I have made corresponding changes to the documentation (in https://github.com/dbt-labs/docs.getdbt.com) if required — N/A for this POC
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Additional Notes

This branch is a POC and intentionally not merge-ready. Before it can merge:

  • Gate the get-lineage resource registration — it currently registers unconditionally and points at a CDN path that 404s until the bundle is published; a release must not expose a dangling resource. Gate via config/env (e.g. only when the tool is enabled and/or the bundle is reachable).
  • Add a changelog entry (changie new).
  • Run task check.
  • Publish the UI bundle to the CDN and point the default DBT_MCP_CDN_BASE at it.

aricallen and others added 5 commits June 23, 2026 13:36
Introduce an apps/ module that registers ui://dbt-mcp/<app> resources. On read, the server fetches a self-contained single-file HTML bundle from a configurable CDN (DBT_MCP_CDN_BASE) and serves it directly to MCP-app-capable hosts.

- apps/register.py: register_app_resource() fetches and serves the app HTML
- AppsConfig + DBT_MCP_CDN_BASE setting
- register the get-lineage app resource on the dispatcher
- update test mock + regenerate the published-app contract snapshot

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
MCP App UIs are built and released on a CDN, independently of this server, so their rendered content is intentionally out-of-contract. Skip content hashing for resources whose mime is text/html;profile=mcp-app and don't fetch them during snapshot generation. The contract still guards the resource's existence/shape (uri/name/mime/_meta) and the linked tool's input/output schema + _meta.resourceUri.

Makes snapshot generation deterministic and network-free. Adds a test asserting mcp-app resource content is null and never fetched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…eage

get_lineage now returns a LineageGraph (nodes + edges) as structured output and links the ui://dbt-mcp/get-lineage MCP app via _meta, so MCP-app hosts can render an interactive lineage graph. Edges are derived from each node's parentIds, filtered to the connected node set.

Regenerate the contract snapshot (get_lineage output schema + meta) and add a transformation unit test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Depth 5 traverses far enough downstream from well-connected nodes (e.g. a staging model) to return huge graphs (768 nodes / 1390 edges in one real case), overwhelming the lineage view. Depth 2 gives useful context without the blowup; callers can still pass a larger depth or 0 for the full graph. Regenerate the contract snapshot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant