The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Tableau Workbook Auditor listing page.
Find what is wrong with any Tableau workbook (.twbx), and map every dependency inside
it, entirely in your browser. Unused fields, duplicate calculations, performance
problems, full calculated-field lineage, filters, dashboards and stored SQL. Nothing is
uploaded, stored, or sent anywhere.
🔗 Live: https://tableau-lineage.com
📦 MCP server: tableau-lineage-mcp
Inheriting someone else's Tableau workbook means reverse-engineering dozens of calculated fields by hand to answer one question: where does this number come from, and what breaks if I change it?
Two more questions come up just as often and have no free answer:
This reads the workbook file itself and answers all three, free, with no licence and no
account. Because workbooks often carry sensitive data, everything runs locally: the
.twbx never leaves your machine, which is a property of the architecture rather than a
promise (there is no server to send it to).
unused, likely-unused, referenced-in-comment) with the reason spelled
out. Reported as candidates rather than certainties, because a workbook file cannot
prove a field is unreferenced everywhere.sqlproxy) sources, and refresh history where the workbook records it.RAWSQL_* calculation, each mapped to
the connection it targets. Runtime-generated live-connection queries are not stored in
workbook files, so they are explicitly out of scope.Drop in up to five versions of the same dashboard and get a semantic diff: which calculations were added, removed, renamed or edited, and for every edit the downstream fields it can break, plus changed parameters, filters, worksheets, dashboards, data sources and SQL. Reformatting a calculation is not reported as a change, and a field that disappears while an identical formula appears under a new name is reported as a rename.
A git diff of two .twbx files cannot do this: the workbook is one large XML blob where
layout coordinates and regenerated ids swamp the handful of real changes.
All generated in-browser, from the same parsed model:
.twbx parsing (unzip + XML) happens client-side. No
backend, no upload, no cookies. Analytics is an anonymous, aggregate page-view count.The packaged data extract inside a .twbx is never decompressed, which is why a 500 MB
workbook is fine and why the tool cannot see your rows even in principle.
The analytical core is a TypeScript port of the original Python service, with fixes that each exist because the naive version was wrong on a real workbook:
[Parameters].[Survival Target (Months)]) while the internal name differs
([Survival Benchmark]). The original leaked a phantom Parameters dependency.TOTAL inside [total_views] was
flagging ordinary fields as table calcs. Now matched as whole function calls; LOD
detection is brace-anchored.// comment is not a dependency, and treating it as one made unused
fields look used.[Sales]; merging them fused unrelated lineage into one node.Calculation_5431234567890123.<datasources> block is only real at the workbook root. Every worksheet carries
a reference list of the same shape, which counted one data source thirteen times on a
twelve-sheet workbook.All are covered by tests (npm test, npm run test:core).
Vite · React 19 · TypeScript · Tailwind CSS · fflate (unzip) · native DOMParser (XML) · vis-network (graph). No backend.
The same engine ships as an MCP server, so Claude, Cursor and other MCP clients can read and audit workbooks straight from your disk. Still 100% local, nothing uploaded.
Claude Desktop: download the extension and double-click it. One click, no terminal and no Node setup.
Claude Code (installs the MCP plus a skill that knows when to use it):
Cursor and other MCP clients:
Eleven tools: analyze_workbook, audit_workbook, diff_workbooks,
list_calculated_fields, get_field, trace_dependencies, list_parameters,
get_lineage_graph, list_sql_queries, list_filters, list_worksheets. Full docs in
mcp/.
Things worth asking it:
Other scripts:
The build pre-renders the landing page with react-dom/server and injects the markup
into dist/index.html, so crawlers get real content instead of an empty <div id="root">.
It stays a fully static site: there is no server at build time or run time.
This is a static site; the dist/ folder can go on any static host. The live site runs on
Cloudflare Workers static assets, configured by wrangler.jsonc in this repo:
wrangler.jsonc and serves dist/ as static assets.npm run buildnpx wrangler deploymain builds and deploys automatically.tableau-lineage.com
(leave the subdomain field blank for the apex). www is a proxied CNAME to the apex
plus a redirect rule. Moving the domain's nameservers to Cloudflare gives automatic
HTTPS.Note: this is Workers, not Pages. A Pages project built from the same repo would deploy a second, parallel copy of the site.
public/_headers ships a security baseline and a Content-Security-Policy that restricts
outbound connections to this origin and Cloudflare's analytics only, which is what makes
the "your data never leaves your browser" promise enforceable.
Visitor counts come from Cloudflare Web Analytics: cookieless, no personal data.
<script> in index.html.That single page-view beacon is the only data collected.
public/demo.twbx powers the "try a sample workbook" button. Replace it with any .twbx
you'd like to feature as the default example.
MIT © 2026 Sai Kiran Andey
Built by Sai Kiran Andey.